Merge changes from topic "no_logd"
* changes:
Remove logd.microdroid and logcat.microdroid
Default logger can be configured via sysprops
GitOrigin-RevId: 1a94375a953d64f10f051ac9de468b9883ac2a0c
Change-Id: Ide9b5515bacaaf30de697bfc7e3f4ae940d6963a
diff --git a/liblog/logger_write.cpp b/liblog/logger_write.cpp
index 9a9a126..a8d85db 100644
--- a/liblog/logger_write.cpp
+++ b/liblog/logger_write.cpp
@@ -52,6 +52,14 @@
#include <windows.h>
#endif
+// The preferred way to access system properties is using android::base::GetProperty in libbase.
+// However, adding dependency to libbase requires that if liblog was statically linked to a client,
+// that client now has additional dependency to libbase as well because static dependencies of
+// static library is not exported. (users of liblog.so however is fine).
+#ifdef __ANDROID__
+#include <sys/system_properties.h>
+#endif
+
using android::base::ErrnoRestorer;
#define LOG_BUF_SIZE 1024
@@ -157,11 +165,29 @@
}
#ifdef __ANDROID__
-static __android_logger_function logger_function = __android_log_logd_logger;
-#else
-static __android_logger_function logger_function = __android_log_stderr_logger;
+static char* file_logger_path = []() {
+ static char path[PROP_VALUE_MAX] = {};
+ if (__system_property_get("ro.log.file_logger.path", path) > 0) {
+ return path;
+ }
+ return (char*)nullptr; // means file_logger should not be used
+}();
#endif
+static void file_logger(const struct __android_log_message* log_message);
+
+static __android_logger_function logger_function = []() {
+#if __ANDROID__
+ if (file_logger_path != nullptr) {
+ return file_logger;
+ } else {
+ return __android_log_logd_logger;
+ }
+#else
+ return file_logger;
+#endif
+}();
+
void __android_log_set_logger(__android_logger_function logger) {
logger_function = logger;
}
@@ -243,7 +269,7 @@
#endif
}
-void __android_log_stderr_logger(const struct __android_log_message* log_message) {
+static void filestream_logger(const struct __android_log_message* log_message, FILE* stream) {
struct tm now;
time_t t = time(nullptr);
@@ -265,16 +291,45 @@
uint64_t tid = GetThreadId();
if (log_message->file != nullptr) {
- fprintf(stderr, "%s %c %s %5d %5" PRIu64 " %s:%u] %s\n",
+ fprintf(stream, "%s %c %s %5d %5" PRIu64 " %s:%u] %s\n",
log_message->tag ? log_message->tag : "nullptr", priority_char, timestamp, getpid(),
tid, log_message->file, log_message->line, log_message->message);
} else {
- fprintf(stderr, "%s %c %s %5d %5" PRIu64 "] %s\n",
+ fprintf(stream, "%s %c %s %5d %5" PRIu64 "] %s\n",
log_message->tag ? log_message->tag : "nullptr", priority_char, timestamp, getpid(),
tid, log_message->message);
}
}
+static void file_logger(const struct __android_log_message* log_message) {
+ static FILE* stream = []() {
+#ifdef __ANDROID__
+ if (file_logger_path != nullptr) {
+ FILE* f = fopen(file_logger_path, "ae");
+ if (f != nullptr) return f;
+ using namespace std::string_literals;
+ std::string err_msg = "Cannot open "s + file_logger_path + " for logging: (" + strerror(errno) +
+ "). Falling back to stderr";
+ __android_log_message m = {sizeof(__android_log_message),
+ LOG_ID_DEFAULT,
+ ANDROID_LOG_WARN,
+ "liblog",
+ __FILE__,
+ __LINE__,
+ err_msg.c_str()};
+ filestream_logger(&m, stderr);
+ }
+#endif
+ // defaults to stderr if the sysprop is not set or the file is not available
+ return stderr;
+ }();
+ filestream_logger(log_message, stream);
+}
+
+void __android_log_stderr_logger(const struct __android_log_message* log_message) {
+ filestream_logger(log_message, stderr);
+}
+
void __android_log_logd_logger(const struct __android_log_message* log_message) {
int buffer_id = log_message->buffer_id == LOG_ID_DEFAULT ? LOG_ID_MAIN : log_message->buffer_id;