logd: use libbase logging

We can use libbase logging to output to the kernel log instead of the
'prdebug' function, so use that instead.

Bonus #1: we can now use CHECK().
Bonus #2: logging unit tests automatically output to stderr.
Bonus #3: We see dependent library's logs instead of losing them to
the void.

Test: logging unit tests
Test: logs show appropriately in dmesg / stderr
Test: CHECK() works
Change-Id: I92f8056b4820dc4998996cf46460568085299700
diff --git a/logd/ChattyLogBuffer.cpp b/logd/ChattyLogBuffer.cpp
index 62c8629..f92fe65 100644
--- a/logd/ChattyLogBuffer.cpp
+++ b/logd/ChattyLogBuffer.cpp
@@ -217,12 +217,12 @@
     log_id_for_each(i) {
         for (auto b : mLastWorst[i]) {
             if (bad == b.second) {
-                android::prdebug("stale mLastWorst[%d] key=%d mykey=%d\n", i, b.first, key);
+                LOG(ERROR) << StringPrintf("stale mLastWorst[%d] key=%d mykey=%d", i, b.first, key);
             }
         }
         for (auto b : mLastWorstPidOfSystem[i]) {
             if (bad == b.second) {
-                android::prdebug("stale mLastWorstPidOfSystem[%d] pid=%d\n", i, b.first);
+                LOG(ERROR) << StringPrintf("stale mLastWorstPidOfSystem[%d] pid=%d", i, b.first);
             }
         }
     }
diff --git a/logd/CommandListener.cpp b/logd/CommandListener.cpp
index c6ab22d..9764c44 100644
--- a/logd/CommandListener.cpp
+++ b/logd/CommandListener.cpp
@@ -31,6 +31,7 @@
 
 #include <string>
 
+#include <android-base/logging.h>
 #include <android-base/stringprintf.h>
 #include <cutils/sockets.h>
 #include <log/log_properties.h>
@@ -298,7 +299,7 @@
                                            char** /*argv*/) {
     setname();
 
-    android::prdebug("logd reinit");
+    LOG(INFO) << "logd reinit";
     buf()->Init();
     prune()->init(nullptr);
 
diff --git a/logd/LogBufferTest.cpp b/logd/LogBufferTest.cpp
index ced4a21..e651b4f 100644
--- a/logd/LogBufferTest.cpp
+++ b/logd/LogBufferTest.cpp
@@ -43,14 +43,6 @@
 }
 #endif
 
-void android::prdebug(const char* fmt, ...) {
-    va_list ap;
-    va_start(ap, fmt);
-    vfprintf(stderr, fmt, ap);
-    fprintf(stderr, "\n");
-    va_end(ap);
-}
-
 char* android::uidToName(uid_t) {
     return nullptr;
 }
diff --git a/logd/LogReader.cpp b/logd/LogReader.cpp
index 42d4574..f71133d 100644
--- a/logd/LogReader.cpp
+++ b/logd/LogReader.cpp
@@ -23,6 +23,7 @@
 
 #include <chrono>
 
+#include <android-base/logging.h>
 #include <android-base/stringprintf.h>
 #include <cutils/sockets.h>
 #include <private/android_filesystem_config.h>
@@ -201,9 +202,9 @@
         }
     }
 
-    android::prdebug(
+    LOG(INFO) << android::base::StringPrintf(
             "logdr: UID=%d GID=%d PID=%d %c tail=%lu logMask=%x pid=%d "
-            "start=%" PRIu64 "ns deadline=%" PRIi64 "ns\n",
+            "start=%" PRIu64 "ns deadline=%" PRIi64 "ns",
             cli->getUid(), cli->getGid(), cli->getPid(), nonBlock ? 'n' : 'b', tail, logMask,
             (int)pid, start.nsec(), static_cast<int64_t>(deadline.time_since_epoch().count()));
 
diff --git a/logd/LogTags.cpp b/logd/LogTags.cpp
index 3afe3ee..8e18f9d 100644
--- a/logd/LogTags.cpp
+++ b/logd/LogTags.cpp
@@ -29,6 +29,7 @@
 #include <string>
 
 #include <android-base/file.h>
+#include <android-base/logging.h>
 #include <android-base/macros.h>
 #include <android-base/scopeguard.h>
 #include <android-base/stringprintf.h>
@@ -115,10 +116,11 @@
     }
 
     if (warn) {
-        android::prdebug(
-            ((fd < 0) ? "%s failed to rebuild"
-                      : "%s missing, damaged or truncated; rebuilt"),
-            filename);
+        if (fd < 0) {
+            LOG(ERROR) << filename << " failed to rebuild";
+        } else {
+            LOG(ERROR) << filename << " missing, damaged or truncated; rebuilt";
+        }
     }
 
     if (fd >= 0) {
@@ -182,8 +184,7 @@
         WritePersistEventLogTags(tag, uid, source);
     } else if (warn && !newOne && source) {
         // For the files, we want to report dupes.
-        android::prdebug("Multiple tag %" PRIu32 " %s %s %s", tag, Name.c_str(),
-                         Format.c_str(), source);
+        LOG(DEBUG) << "Multiple tag " << tag << " " << Name << " " << Format << " " << source;
     }
 }
 
@@ -216,7 +217,7 @@
                 } else if (isdigit(*cp)) {
                     unsigned long Tag = strtoul(cp, &cp, 10);
                     if (warn && (Tag > emptyTag)) {
-                        android::prdebug("tag too large %lu", Tag);
+                        LOG(WARNING) << "tag too large " << Tag;
                     }
                     while ((cp < endp) && (*cp != '\n') && isspace(*cp)) ++cp;
                     if (cp >= endp) break;
@@ -231,9 +232,8 @@
                     std::string Name(name, cp - name);
 #ifdef ALLOW_NOISY_LOGGING_OF_PROBLEM_WITH_LOTS_OF_TECHNICAL_DEBT
                     static const size_t maximum_official_tag_name_size = 24;
-                    if (warn &&
-                        (Name.length() > maximum_official_tag_name_size)) {
-                        android::prdebug("tag name too long %s", Name.c_str());
+                    if (warn && (Name.length() > maximum_official_tag_name_size)) {
+                        LOG(WARNING) << "tag name too long " << Name;
                     }
 #endif
                     if (hasAlpha &&
@@ -264,8 +264,8 @@
                                         filename, warn);
                     } else {
                         if (warn) {
-                            android::prdebug("tag name invalid %.*s",
-                                             (int)(cp - name + 1), name);
+                            LOG(ERROR) << android::base::StringPrintf("tag name invalid %.*s",
+                                                                      (int)(cp - name + 1), name);
                         }
                         lineStart = nullptr;
                     }
@@ -276,7 +276,7 @@
             cp++;
         }
     } else if (warn) {
-        android::prdebug("Cannot read %s", filename);
+        LOG(ERROR) << "Cannot read " << filename;
     }
 }
 
@@ -479,8 +479,8 @@
 
 static int openFile(const char* name, int mode, bool warning) {
     int fd = TEMP_FAILURE_RETRY(open(name, mode));
-    if ((fd < 0) && warning) {
-        android::prdebug("Failed open %s (%d)", name, errno);
+    if (fd < 0 && warning) {
+        PLOG(ERROR) << "Failed to open " << name;
     }
     return fd;
 }
diff --git a/logd/LogUtils.h b/logd/LogUtils.h
index 96aa1d3..df78a50 100644
--- a/logd/LogUtils.h
+++ b/logd/LogUtils.h
@@ -30,7 +30,6 @@
 
 // Furnished in main.cpp. Caller must own and free returned value
 char* uidToName(uid_t uid);
-void prdebug(const char* fmt, ...) __attribute__((__format__(printf, 1, 2)));
 
 // Caller must own and free returned value
 char* pidToName(pid_t pid);
diff --git a/logd/SimpleLogBuffer.cpp b/logd/SimpleLogBuffer.cpp
index b4b3546..292a7e4 100644
--- a/logd/SimpleLogBuffer.cpp
+++ b/logd/SimpleLogBuffer.cpp
@@ -16,6 +16,8 @@
 
 #include "SimpleLogBuffer.h"
 
+#include <android-base/logging.h>
+
 #include "LogBufferElement.h"
 
 SimpleLogBuffer::SimpleLogBuffer(LogReaderList* reader_list, LogTags* tags, LogStatistics* stats)
@@ -232,8 +234,8 @@
                 auto reader_threads_lock = std::lock_guard{reader_list_->reader_threads_lock()};
                 for (const auto& reader_thread : reader_list_->reader_threads()) {
                     if (reader_thread->IsWatching(id)) {
-                        android::prdebug("Kicking blocked reader, %s, from LogBuffer::clear()\n",
-                                         reader_thread->name().c_str());
+                        LOG(WARNING) << "Kicking blocked reader, " << reader_thread->name()
+                                     << ", from LogBuffer::clear()";
                         reader_thread->release_Locked();
                     }
                 }
@@ -350,16 +352,16 @@
     if (stats_->Sizes(id) > (2 * max_size_[id])) {  // +100%
         // A misbehaving or slow reader has its connection
         // dropped if we hit too much memory pressure.
-        android::prdebug("Kicking blocked reader, %s, from LogBuffer::kickMe()\n",
-                         reader->name().c_str());
+        LOG(WARNING) << "Kicking blocked reader, " << reader->name()
+                     << ", from LogBuffer::kickMe()";
         reader->release_Locked();
     } else if (reader->deadline().time_since_epoch().count() != 0) {
         // Allow a blocked WRAP deadline reader to trigger and start reporting the log data.
         reader->triggerReader_Locked();
     } else {
         // tell slow reader to skip entries to catch up
-        android::prdebug("Skipping %lu entries from slow reader, %s, from LogBuffer::kickMe()\n",
-                         prune_rows, reader->name().c_str());
+        LOG(WARNING) << "Skipping " << prune_rows << " entries from slow reader, " << reader->name()
+                     << ", from LogBuffer::kickMe()";
         reader->triggerSkip_Locked(id, prune_rows);
     }
 }
diff --git a/logd/fuzz/log_buffer_log_fuzzer.cpp b/logd/fuzz/log_buffer_log_fuzzer.cpp
index 8f90f50..b576ddf 100644
--- a/logd/fuzz/log_buffer_log_fuzzer.cpp
+++ b/logd/fuzz/log_buffer_log_fuzzer.cpp
@@ -79,13 +79,6 @@
     return 1;
 }
 
-// Because system/core/logd/main.cpp redefines these.
-void prdebug(char const* fmt, ...) {
-    va_list ap;
-    va_start(ap, fmt);
-    vfprintf(stderr, fmt, ap);
-    va_end(ap);
-}
 char* uidToName(uid_t) {
     return strdup("fake");
 }
diff --git a/logd/main.cpp b/logd/main.cpp
index c2b5a1d..773ffb8 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -36,7 +36,9 @@
 
 #include <memory>
 
+#include <android-base/logging.h>
 #include <android-base/macros.h>
+#include <android-base/stringprintf.h>
 #include <cutils/android_get_control_file.h>
 #include <cutils/sockets.h>
 #include <log/event_tag_map.h>
@@ -70,19 +72,18 @@
     sched_param param = {};
 
     if (set_sched_policy(0, SP_BACKGROUND) < 0) {
-        android::prdebug("failed to set background scheduling policy");
+        PLOG(ERROR) << "failed to set background scheduling policy";
         return -1;
     }
 
     if (sched_setscheduler((pid_t)0, SCHED_BATCH, &param) < 0) {
-        android::prdebug("failed to set batch scheduler");
+        PLOG(ERROR) << "failed to set batch scheduler";
         return -1;
     }
 
-    if (!__android_logger_property_get_bool("ro.debuggable",
-                                            BOOL_DEFAULT_FALSE) &&
+    if (!__android_logger_property_get_bool("ro.debuggable", BOOL_DEFAULT_FALSE) &&
         prctl(PR_SET_DUMPABLE, 0) == -1) {
-        android::prdebug("failed to clear PR_SET_DUMPABLE");
+        PLOG(ERROR) << "failed to clear PR_SET_DUMPABLE";
         return -1;
     }
 
@@ -105,40 +106,13 @@
         return -1;
     }
     if (cap_set_proc(caps.get()) < 0) {
-        android::prdebug("failed to set CAP_SYSLOG or CAP_AUDIT_CONTROL (%d)", errno);
+        PLOG(ERROR) << "failed to set CAP_SYSLOG or CAP_AUDIT_CONTROL";
         return -1;
     }
 
     return 0;
 }
 
-static int fdDmesg = -1;
-void android::prdebug(const char* fmt, ...) {
-    if (fdDmesg < 0) {
-        return;
-    }
-
-    static const char message[] = {
-        KMSG_PRIORITY(LOG_DEBUG), 'l', 'o', 'g', 'd', ':', ' '
-    };
-    char buffer[256];
-    memcpy(buffer, message, sizeof(message));
-
-    va_list ap;
-    va_start(ap, fmt);
-    int n = vsnprintf(buffer + sizeof(message),
-                      sizeof(buffer) - sizeof(message), fmt, ap);
-    va_end(ap);
-    if (n > 0) {
-        buffer[sizeof(buffer) - 1] = '\0';
-        if (!strchr(buffer, '\n')) {
-            buffer[sizeof(buffer) - 2] = '\0';
-            strlcat(buffer, "\n", sizeof(buffer));
-        }
-        write(fdDmesg, buffer, strlen(buffer));
-    }
-}
-
 char* android::uidToName(uid_t u) {
     struct Userdata {
         uid_t uid;
@@ -246,8 +220,20 @@
         return issueReinit();
     }
 
+    android::base::InitLogging(
+            argv, [](android::base::LogId log_id, android::base::LogSeverity severity,
+                     const char* tag, const char* file, unsigned int line, const char* message) {
+                if (tag && strcmp(tag, "logd") != 0) {
+                    auto prefixed_message = android::base::StringPrintf("%s: %s", tag, message);
+                    android::base::KernelLogger(log_id, severity, "logd", file, line,
+                                                prefixed_message.c_str());
+                } else {
+                    android::base::KernelLogger(log_id, severity, "logd", file, line, message);
+                }
+            });
+
     static const char dev_kmsg[] = "/dev/kmsg";
-    fdDmesg = android_get_control_file(dev_kmsg);
+    int fdDmesg = android_get_control_file(dev_kmsg);
     if (fdDmesg < 0) {
         fdDmesg = TEMP_FAILURE_RETRY(open(dev_kmsg, O_WRONLY | O_CLOEXEC));
     }
@@ -263,7 +249,7 @@
             fdPmesg = TEMP_FAILURE_RETRY(
                 open(proc_kmsg, O_RDONLY | O_NDELAY | O_CLOEXEC));
         }
-        if (fdPmesg < 0) android::prdebug("Failed to open %s\n", proc_kmsg);
+        if (fdPmesg < 0) PLOG(ERROR) << "Failed to open " << proc_kmsg;
     }
 
     bool auditd = __android_logger_property_get_bool("ro.logd.auditd", BOOL_DEFAULT_TRUE);