liblog: Add android_set_log_frontend am: 850d06e1c9 am: 9d68551f47
am: b6c6c7e3d3
Change-Id: I942aff87d5a45b5e18bb03c2ea2ebf7bfebd976d
This commit is contained in:
commit
94acd67ba8
4 changed files with 180 additions and 1 deletions
|
|
@ -108,6 +108,11 @@ SYNOPSIS
|
|||
|
||||
int android_log_destroy(android_log_context *ctx)
|
||||
|
||||
#include <log/log_frontend.h>
|
||||
|
||||
int android_set_log_frontend(int frontend_flag)
|
||||
int android_get_log_frontend()
|
||||
|
||||
Link with -llog
|
||||
|
||||
DESCRIPTION
|
||||
|
|
@ -162,6 +167,12 @@ DESCRIPTION
|
|||
when opening the sub-log. It is recommended to open the log
|
||||
ANDROID_LOG_RDONLY in these cases.
|
||||
|
||||
android_set_log_frontend() selects frontend filters. Argument is either
|
||||
LOGGER_DEFAULT, LOGGER_LOGD or LOGGER_NULL. The latter drops all
|
||||
content on the floor. Both android_set_log_frontend() and
|
||||
android_get_log_frontend() return the current frontend mask, or a
|
||||
negative errno for any problems.
|
||||
|
||||
ERRORS
|
||||
If messages fail, a negative error code will be returned to the caller.
|
||||
|
||||
|
|
@ -194,4 +205,4 @@ SEE ALSO
|
|||
|
||||
|
||||
|
||||
17 Oct 2016 LIBLOG(3)
|
||||
08 Feb 2017 LIBLOG(3)
|
||||
|
|
|
|||
33
liblog/include/log/log_frontend.h
Normal file
33
liblog/include/log/log_frontend.h
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
**
|
||||
** Copyright 2017, The Android Open Source Project
|
||||
**
|
||||
** This file is dual licensed. It may be redistributed and/or modified
|
||||
** under the terms of the Apache 2.0 License OR version 2 of the GNU
|
||||
** General Public License.
|
||||
*/
|
||||
|
||||
#ifndef _LIBS_LOG_FRONTEND_H
|
||||
#define _LIBS_LOG_FRONTEND_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Logging frontends, bit mask to select features. Function returns selection.
|
||||
*/
|
||||
#define LOGGER_DEFAULT 0x0
|
||||
#define LOGGER_LOGD 0x1
|
||||
#define LOGGER_KERNEL 0x2 /* Reserved/Deprecated */
|
||||
#define LOGGER_NULL 0x4 /* Does not release resources of other selections */
|
||||
|
||||
/* Both return the selected frontend flag mask, or negative errno */
|
||||
int android_set_log_frontend(int frontend_flag);
|
||||
int android_get_log_frontend();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LIBS_LOG_FRONTEND_H */
|
||||
|
|
@ -25,6 +25,7 @@
|
|||
#endif
|
||||
|
||||
#include <log/event_tag_map.h>
|
||||
#include <log/log_frontend.h>
|
||||
#include <private/android_filesystem_config.h>
|
||||
#include <private/android_logger.h>
|
||||
|
||||
|
|
@ -618,3 +619,67 @@ LIBLOG_ABI_PUBLIC int __android_log_security_bswrite(int32_t tag,
|
|||
|
||||
return write_to_log(LOG_ID_SECURITY, vec, 4);
|
||||
}
|
||||
|
||||
static int __write_to_log_null(log_id_t log_id, struct iovec* vec, size_t nr)
|
||||
{
|
||||
size_t len, i;
|
||||
|
||||
if ((log_id < LOG_ID_MIN) || (log_id >= LOG_ID_MAX)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (len = i = 0; i < nr; ++i) {
|
||||
len += vec[i].iov_len;
|
||||
}
|
||||
if (!len) {
|
||||
return -EINVAL;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Following functions need access to our internal write_to_log status */
|
||||
|
||||
LIBLOG_ABI_PUBLIC int android_set_log_frontend(int frontend_flag)
|
||||
{
|
||||
if (frontend_flag < 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
__android_log_lock();
|
||||
|
||||
if (frontend_flag & LOGGER_NULL) {
|
||||
write_to_log = __write_to_log_null;
|
||||
|
||||
__android_log_unlock();
|
||||
|
||||
return LOGGER_NULL;
|
||||
}
|
||||
|
||||
/* Anything else, act as if LOGGER_DEFAULT */
|
||||
|
||||
/* generically we only expect these two values for write_to_log */
|
||||
if ((write_to_log != __write_to_log_init) &&
|
||||
(write_to_log != __write_to_log_daemon)) {
|
||||
write_to_log = __write_to_log_init;
|
||||
}
|
||||
|
||||
__android_log_unlock();
|
||||
|
||||
return LOGGER_DEFAULT;
|
||||
}
|
||||
|
||||
LIBLOG_ABI_PUBLIC int android_get_log_frontend()
|
||||
{
|
||||
int ret = LOGGER_DEFAULT;
|
||||
|
||||
__android_log_lock();
|
||||
if (write_to_log == __write_to_log_null) {
|
||||
ret = LOGGER_NULL;
|
||||
} else if ((write_to_log != __write_to_log_init) &&
|
||||
(write_to_log != __write_to_log_daemon)) {
|
||||
ret = -EINVAL;
|
||||
}
|
||||
__android_log_unlock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include <gtest/gtest.h>
|
||||
#include <log/logprint.h>
|
||||
#include <log/log_event_list.h>
|
||||
#include <log/log_frontend.h>
|
||||
#include <private/android_filesystem_config.h>
|
||||
#include <private/android_logger.h>
|
||||
|
||||
|
|
@ -225,6 +226,75 @@ TEST(liblog, __android_log_btwrite__android_logger_list_read) {
|
|||
#endif
|
||||
}
|
||||
|
||||
// This test makes little sense standalone, and requires the tests ahead
|
||||
// and behind us, to make us whole. We could incorporate a prefix and
|
||||
// suffix test to make this standalone, but opted to not complicate this.
|
||||
TEST(liblog, android_set_log_frontend) {
|
||||
#ifdef __ANDROID__
|
||||
int logger = android_get_log_frontend();
|
||||
EXPECT_NE(LOGGER_NULL, logger);
|
||||
|
||||
EXPECT_EQ(LOGGER_NULL, android_set_log_frontend(LOGGER_NULL));
|
||||
EXPECT_EQ(LOGGER_NULL, android_get_log_frontend());
|
||||
|
||||
pid_t pid = getpid();
|
||||
|
||||
struct logger_list *logger_list;
|
||||
ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
|
||||
LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
|
||||
|
||||
log_time ts(CLOCK_MONOTONIC);
|
||||
ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
|
||||
|
||||
usleep(1000000);
|
||||
|
||||
int count = 0;
|
||||
|
||||
for (;;) {
|
||||
log_msg log_msg;
|
||||
if (android_logger_list_read(logger_list, &log_msg) <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
ASSERT_EQ(log_msg.entry.pid, pid);
|
||||
|
||||
if ((log_msg.entry.len != sizeof(android_log_event_long_t))
|
||||
|| (log_msg.id() != LOG_ID_EVENTS)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
android_log_event_long_t* eventData;
|
||||
eventData = reinterpret_cast<android_log_event_long_t*>(log_msg.msg());
|
||||
|
||||
if (!eventData || (eventData->payload.type != EVENT_TYPE_LONG)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
log_time tx(reinterpret_cast<char*>(&eventData->payload.data));
|
||||
if (ts == tx) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
android_logger_list_close(logger_list);
|
||||
|
||||
EXPECT_EQ(logger, android_set_log_frontend(logger));
|
||||
EXPECT_EQ(logger, android_get_log_frontend());
|
||||
|
||||
// False negative if liblog.__android_log_btwrite__android_logger_list_read
|
||||
// fails above, so we will likely succeed. But we will have so many
|
||||
// failures elsewhere that it is probably not worthwhile for us to
|
||||
// highlight yet another disappointment.
|
||||
EXPECT_EQ(0, count);
|
||||
// We also expect failures in the following tests if the set does not
|
||||
// react in an appropriate manner internally, yet passes, so we depend
|
||||
// on this test being in the middle of a series of tests performed in
|
||||
// the same process.
|
||||
#else
|
||||
GTEST_LOG_(INFO) << "This test does nothing.\n";
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __ANDROID__
|
||||
static inline int32_t get4LE(const char* src)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue