xref: /aosp_15_r20/system/update_engine/aosp/logging_android.cc (revision 5a9231315b4521097b8dc3750bc806fcafe0c72f)
1*5a923131SAndroid Build Coastguard Worker //
2*5a923131SAndroid Build Coastguard Worker // Copyright (C) 2020 The Android Open Source Project
3*5a923131SAndroid Build Coastguard Worker //
4*5a923131SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
5*5a923131SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
6*5a923131SAndroid Build Coastguard Worker // You may obtain a copy of the License at
7*5a923131SAndroid Build Coastguard Worker //
8*5a923131SAndroid Build Coastguard Worker //      http://www.apache.org/licenses/LICENSE-2.0
9*5a923131SAndroid Build Coastguard Worker //
10*5a923131SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
11*5a923131SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
12*5a923131SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*5a923131SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
14*5a923131SAndroid Build Coastguard Worker // limitations under the License.
15*5a923131SAndroid Build Coastguard Worker //
16*5a923131SAndroid Build Coastguard Worker 
17*5a923131SAndroid Build Coastguard Worker #include <inttypes.h>
18*5a923131SAndroid Build Coastguard Worker #include <stdio.h>
19*5a923131SAndroid Build Coastguard Worker #include <sys/stat.h>
20*5a923131SAndroid Build Coastguard Worker #include <unistd.h>
21*5a923131SAndroid Build Coastguard Worker 
22*5a923131SAndroid Build Coastguard Worker #include <algorithm>
23*5a923131SAndroid Build Coastguard Worker #include <functional>
24*5a923131SAndroid Build Coastguard Worker #include <iomanip>
25*5a923131SAndroid Build Coastguard Worker #include <sstream>
26*5a923131SAndroid Build Coastguard Worker #include <string>
27*5a923131SAndroid Build Coastguard Worker #include <string_view>
28*5a923131SAndroid Build Coastguard Worker #include <vector>
29*5a923131SAndroid Build Coastguard Worker 
30*5a923131SAndroid Build Coastguard Worker #include <android-base/file.h>
31*5a923131SAndroid Build Coastguard Worker #include <android-base/strings.h>
32*5a923131SAndroid Build Coastguard Worker #include <android-base/unique_fd.h>
33*5a923131SAndroid Build Coastguard Worker #include <base/files/dir_reader_posix.h>
34*5a923131SAndroid Build Coastguard Worker #include <base/logging.h>
35*5a923131SAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
36*5a923131SAndroid Build Coastguard Worker #include <log/log.h>
37*5a923131SAndroid Build Coastguard Worker 
38*5a923131SAndroid Build Coastguard Worker #include "android/log.h"
39*5a923131SAndroid Build Coastguard Worker #include "update_engine/common/utils.h"
40*5a923131SAndroid Build Coastguard Worker 
41*5a923131SAndroid Build Coastguard Worker using std::string;
42*5a923131SAndroid Build Coastguard Worker 
43*5a923131SAndroid Build Coastguard Worker #ifdef _UE_SIDELOAD
44*5a923131SAndroid Build Coastguard Worker constexpr bool kSideload = true;
45*5a923131SAndroid Build Coastguard Worker #else
46*5a923131SAndroid Build Coastguard Worker constexpr bool kSideload = false;
47*5a923131SAndroid Build Coastguard Worker #endif
48*5a923131SAndroid Build Coastguard Worker 
49*5a923131SAndroid Build Coastguard Worker namespace chromeos_update_engine {
50*5a923131SAndroid Build Coastguard Worker namespace {
51*5a923131SAndroid Build Coastguard Worker 
52*5a923131SAndroid Build Coastguard Worker constexpr char kSystemLogsRoot[] = "/data/misc/update_engine_log";
53*5a923131SAndroid Build Coastguard Worker constexpr size_t kLogCount = 5;
54*5a923131SAndroid Build Coastguard Worker 
55*5a923131SAndroid Build Coastguard Worker // Keep the most recent |kLogCount| logs but remove the old ones in
56*5a923131SAndroid Build Coastguard Worker // "/data/misc/update_engine_log/".
DeleteOldLogs(const string & kLogsRoot)57*5a923131SAndroid Build Coastguard Worker void DeleteOldLogs(const string& kLogsRoot) {
58*5a923131SAndroid Build Coastguard Worker   base::DirReaderPosix reader(kLogsRoot.c_str());
59*5a923131SAndroid Build Coastguard Worker   if (!reader.IsValid()) {
60*5a923131SAndroid Build Coastguard Worker     LOG(ERROR) << "Failed to read " << kLogsRoot;
61*5a923131SAndroid Build Coastguard Worker     return;
62*5a923131SAndroid Build Coastguard Worker   }
63*5a923131SAndroid Build Coastguard Worker 
64*5a923131SAndroid Build Coastguard Worker   std::vector<string> old_logs;
65*5a923131SAndroid Build Coastguard Worker   while (reader.Next()) {
66*5a923131SAndroid Build Coastguard Worker     if (reader.name()[0] == '.')
67*5a923131SAndroid Build Coastguard Worker       continue;
68*5a923131SAndroid Build Coastguard Worker 
69*5a923131SAndroid Build Coastguard Worker     // Log files are in format "update_engine.%Y%m%d-%H%M%S",
70*5a923131SAndroid Build Coastguard Worker     // e.g. update_engine.20090103-231425
71*5a923131SAndroid Build Coastguard Worker     uint64_t date;
72*5a923131SAndroid Build Coastguard Worker     uint64_t local_time;
73*5a923131SAndroid Build Coastguard Worker     if (sscanf(reader.name(),
74*5a923131SAndroid Build Coastguard Worker                "update_engine.%" PRIu64 "-%" PRIu64 "",
75*5a923131SAndroid Build Coastguard Worker                &date,
76*5a923131SAndroid Build Coastguard Worker                &local_time) == 2) {
77*5a923131SAndroid Build Coastguard Worker       old_logs.push_back(reader.name());
78*5a923131SAndroid Build Coastguard Worker     } else {
79*5a923131SAndroid Build Coastguard Worker       LOG(WARNING) << "Unrecognized log file " << reader.name();
80*5a923131SAndroid Build Coastguard Worker     }
81*5a923131SAndroid Build Coastguard Worker   }
82*5a923131SAndroid Build Coastguard Worker 
83*5a923131SAndroid Build Coastguard Worker   std::sort(old_logs.begin(), old_logs.end(), std::greater<string>());
84*5a923131SAndroid Build Coastguard Worker   for (size_t i = kLogCount; i < old_logs.size(); i++) {
85*5a923131SAndroid Build Coastguard Worker     string log_path = kLogsRoot + "/" + old_logs[i];
86*5a923131SAndroid Build Coastguard Worker     if (unlink(log_path.c_str()) == -1) {
87*5a923131SAndroid Build Coastguard Worker       PLOG(WARNING) << "Failed to unlink " << log_path;
88*5a923131SAndroid Build Coastguard Worker     }
89*5a923131SAndroid Build Coastguard Worker   }
90*5a923131SAndroid Build Coastguard Worker }
91*5a923131SAndroid Build Coastguard Worker 
SetupLogFile(const string & kLogsRoot)92*5a923131SAndroid Build Coastguard Worker string SetupLogFile(const string& kLogsRoot) {
93*5a923131SAndroid Build Coastguard Worker   DeleteOldLogs(kLogsRoot);
94*5a923131SAndroid Build Coastguard Worker 
95*5a923131SAndroid Build Coastguard Worker   return android::base::StringPrintf(
96*5a923131SAndroid Build Coastguard Worker       "%s/update_engine.%s",
97*5a923131SAndroid Build Coastguard Worker       kLogsRoot.c_str(),
98*5a923131SAndroid Build Coastguard Worker       utils::GetTimeAsString(::time(nullptr)).c_str());
99*5a923131SAndroid Build Coastguard Worker }
100*5a923131SAndroid Build Coastguard Worker 
LogPriorityToCString(int priority)101*5a923131SAndroid Build Coastguard Worker const char* LogPriorityToCString(int priority) {
102*5a923131SAndroid Build Coastguard Worker   switch (priority) {
103*5a923131SAndroid Build Coastguard Worker     case ANDROID_LOG_VERBOSE:
104*5a923131SAndroid Build Coastguard Worker       return "VERBOSE";
105*5a923131SAndroid Build Coastguard Worker     case ANDROID_LOG_DEBUG:
106*5a923131SAndroid Build Coastguard Worker       return "DEBUG";
107*5a923131SAndroid Build Coastguard Worker     case ANDROID_LOG_INFO:
108*5a923131SAndroid Build Coastguard Worker       return "INFO";
109*5a923131SAndroid Build Coastguard Worker     case ANDROID_LOG_WARN:
110*5a923131SAndroid Build Coastguard Worker       return "WARN";
111*5a923131SAndroid Build Coastguard Worker     case ANDROID_LOG_ERROR:
112*5a923131SAndroid Build Coastguard Worker       return "ERROR";
113*5a923131SAndroid Build Coastguard Worker     case ANDROID_LOG_FATAL:
114*5a923131SAndroid Build Coastguard Worker       return "FATAL";
115*5a923131SAndroid Build Coastguard Worker     default:
116*5a923131SAndroid Build Coastguard Worker       return "UNKNOWN";
117*5a923131SAndroid Build Coastguard Worker   }
118*5a923131SAndroid Build Coastguard Worker }
119*5a923131SAndroid Build Coastguard Worker 
120*5a923131SAndroid Build Coastguard Worker using LoggerFunction = std::function<void(const struct __android_log_message*)>;
121*5a923131SAndroid Build Coastguard Worker 
122*5a923131SAndroid Build Coastguard Worker class FileLogger {
123*5a923131SAndroid Build Coastguard Worker  public:
FileLogger(const string & path)124*5a923131SAndroid Build Coastguard Worker   explicit FileLogger(const string& path) {
125*5a923131SAndroid Build Coastguard Worker     fd_.reset(TEMP_FAILURE_RETRY(
126*5a923131SAndroid Build Coastguard Worker         open(path.c_str(),
127*5a923131SAndroid Build Coastguard Worker              O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
128*5a923131SAndroid Build Coastguard Worker              0644)));
129*5a923131SAndroid Build Coastguard Worker     if (fd_ == -1) {
130*5a923131SAndroid Build Coastguard Worker       // Use ALOGE that logs to logd before __android_log_set_logger.
131*5a923131SAndroid Build Coastguard Worker       ALOGE("Cannot open persistent log %s: %s", path.c_str(), strerror(errno));
132*5a923131SAndroid Build Coastguard Worker       return;
133*5a923131SAndroid Build Coastguard Worker     }
134*5a923131SAndroid Build Coastguard Worker     // The log file will have AID_LOG as group ID; this GID is inherited from
135*5a923131SAndroid Build Coastguard Worker     // the parent directory "/data/misc/update_engine_log" which sets the SGID
136*5a923131SAndroid Build Coastguard Worker     // bit.
137*5a923131SAndroid Build Coastguard Worker     if (fchmod(fd_.get(), 0640) == -1) {
138*5a923131SAndroid Build Coastguard Worker       // Use ALOGE that logs to logd before __android_log_set_logger.
139*5a923131SAndroid Build Coastguard Worker       ALOGE("Cannot chmod 0640 persistent log %s: %s",
140*5a923131SAndroid Build Coastguard Worker             path.c_str(),
141*5a923131SAndroid Build Coastguard Worker             strerror(errno));
142*5a923131SAndroid Build Coastguard Worker       return;
143*5a923131SAndroid Build Coastguard Worker     }
144*5a923131SAndroid Build Coastguard Worker   }
145*5a923131SAndroid Build Coastguard Worker   // Copy-constructor needed to be converted to std::function.
FileLogger(const FileLogger & other)146*5a923131SAndroid Build Coastguard Worker   FileLogger(const FileLogger& other) { fd_.reset(dup(other.fd_)); }
operator ()(const struct __android_log_message * log_message)147*5a923131SAndroid Build Coastguard Worker   void operator()(const struct __android_log_message* log_message) {
148*5a923131SAndroid Build Coastguard Worker     if (fd_ == -1) {
149*5a923131SAndroid Build Coastguard Worker       return;
150*5a923131SAndroid Build Coastguard Worker     }
151*5a923131SAndroid Build Coastguard Worker 
152*5a923131SAndroid Build Coastguard Worker     std::string_view message_str =
153*5a923131SAndroid Build Coastguard Worker         log_message->message != nullptr ? log_message->message : "";
154*5a923131SAndroid Build Coastguard Worker 
155*5a923131SAndroid Build Coastguard Worker     WriteToFd(GetPrefix(log_message));
156*5a923131SAndroid Build Coastguard Worker     WriteToFd(message_str);
157*5a923131SAndroid Build Coastguard Worker     WriteToFd("\n");
158*5a923131SAndroid Build Coastguard Worker     fsync(fd_);
159*5a923131SAndroid Build Coastguard Worker   }
160*5a923131SAndroid Build Coastguard Worker 
161*5a923131SAndroid Build Coastguard Worker  private:
162*5a923131SAndroid Build Coastguard Worker   android::base::unique_fd fd_;
WriteToFd(std::string_view message)163*5a923131SAndroid Build Coastguard Worker   void WriteToFd(std::string_view message) {
164*5a923131SAndroid Build Coastguard Worker     ignore_result(
165*5a923131SAndroid Build Coastguard Worker         android::base::WriteFully(fd_, message.data(), message.size()));
166*5a923131SAndroid Build Coastguard Worker   }
167*5a923131SAndroid Build Coastguard Worker 
GetPrefix(const struct __android_log_message * log_message)168*5a923131SAndroid Build Coastguard Worker   string GetPrefix(const struct __android_log_message* log_message) {
169*5a923131SAndroid Build Coastguard Worker     std::stringstream ss;
170*5a923131SAndroid Build Coastguard Worker     timeval tv;
171*5a923131SAndroid Build Coastguard Worker     gettimeofday(&tv, nullptr);
172*5a923131SAndroid Build Coastguard Worker     time_t t = tv.tv_sec;
173*5a923131SAndroid Build Coastguard Worker     struct tm local_time;
174*5a923131SAndroid Build Coastguard Worker     localtime_r(&t, &local_time);
175*5a923131SAndroid Build Coastguard Worker     struct tm* tm_time = &local_time;
176*5a923131SAndroid Build Coastguard Worker     ss << "[" << std::setfill('0') << std::setw(2) << 1 + tm_time->tm_mon
177*5a923131SAndroid Build Coastguard Worker        << std::setw(2) << tm_time->tm_mday << '/' << std::setw(2)
178*5a923131SAndroid Build Coastguard Worker        << tm_time->tm_hour << std::setw(2) << tm_time->tm_min << std::setw(2)
179*5a923131SAndroid Build Coastguard Worker        << tm_time->tm_sec << '.' << std::setw(6) << tv.tv_usec << "] ";
180*5a923131SAndroid Build Coastguard Worker     // libchrome logs prepends |message| with severity, file and line, but
181*5a923131SAndroid Build Coastguard Worker     // leave logger_data->file as nullptr.
182*5a923131SAndroid Build Coastguard Worker     // libbase / liblog logs doesn't. Hence, add them to match the style.
183*5a923131SAndroid Build Coastguard Worker     // For liblog logs that doesn't set logger_data->file, not printing the
184*5a923131SAndroid Build Coastguard Worker     // priority is acceptable.
185*5a923131SAndroid Build Coastguard Worker     if (log_message->file) {
186*5a923131SAndroid Build Coastguard Worker       ss << "[" << LogPriorityToCString(log_message->priority) << ':'
187*5a923131SAndroid Build Coastguard Worker          << log_message->file << '(' << log_message->line << ")] ";
188*5a923131SAndroid Build Coastguard Worker     }
189*5a923131SAndroid Build Coastguard Worker     return ss.str();
190*5a923131SAndroid Build Coastguard Worker   }
191*5a923131SAndroid Build Coastguard Worker };
192*5a923131SAndroid Build Coastguard Worker 
193*5a923131SAndroid Build Coastguard Worker class CombinedLogger {
194*5a923131SAndroid Build Coastguard Worker  public:
CombinedLogger(bool log_to_system,bool log_to_file)195*5a923131SAndroid Build Coastguard Worker   CombinedLogger(bool log_to_system, bool log_to_file) {
196*5a923131SAndroid Build Coastguard Worker     if (log_to_system) {
197*5a923131SAndroid Build Coastguard Worker       if (kSideload) {
198*5a923131SAndroid Build Coastguard Worker         // No logd in sideload. Use stdout.
199*5a923131SAndroid Build Coastguard Worker         // recovery has already redirected stdio properly.
200*5a923131SAndroid Build Coastguard Worker         loggers_.push_back(__android_log_stderr_logger);
201*5a923131SAndroid Build Coastguard Worker       } else {
202*5a923131SAndroid Build Coastguard Worker         loggers_.push_back(__android_log_logd_logger);
203*5a923131SAndroid Build Coastguard Worker       }
204*5a923131SAndroid Build Coastguard Worker     }
205*5a923131SAndroid Build Coastguard Worker     if (log_to_file) {
206*5a923131SAndroid Build Coastguard Worker       loggers_.push_back(std::move(FileLogger(SetupLogFile(kSystemLogsRoot))));
207*5a923131SAndroid Build Coastguard Worker     }
208*5a923131SAndroid Build Coastguard Worker   }
operator ()(const struct __android_log_message * log_message)209*5a923131SAndroid Build Coastguard Worker   void operator()(const struct __android_log_message* log_message) {
210*5a923131SAndroid Build Coastguard Worker     if (log_message->file != nullptr && log_message->line != 0) {
211*5a923131SAndroid Build Coastguard Worker       __android_log_message formatted = *log_message;
212*5a923131SAndroid Build Coastguard Worker       std::stringstream ss;
213*5a923131SAndroid Build Coastguard Worker       ss << "[" << LogPriorityToCString(formatted.priority) << ":"
214*5a923131SAndroid Build Coastguard Worker          << formatted.file << "(" << formatted.line << ")] "
215*5a923131SAndroid Build Coastguard Worker          << formatted.message;
216*5a923131SAndroid Build Coastguard Worker       formatted.file = nullptr;
217*5a923131SAndroid Build Coastguard Worker       formatted.line = 0;
218*5a923131SAndroid Build Coastguard Worker       const auto str = ss.str();
219*5a923131SAndroid Build Coastguard Worker       formatted.message = str.c_str();
220*5a923131SAndroid Build Coastguard Worker       for (auto&& logger : loggers_) {
221*5a923131SAndroid Build Coastguard Worker         logger(&formatted);
222*5a923131SAndroid Build Coastguard Worker       }
223*5a923131SAndroid Build Coastguard Worker     } else {
224*5a923131SAndroid Build Coastguard Worker       for (auto&& logger : loggers_) {
225*5a923131SAndroid Build Coastguard Worker         logger(log_message);
226*5a923131SAndroid Build Coastguard Worker       }
227*5a923131SAndroid Build Coastguard Worker     }
228*5a923131SAndroid Build Coastguard Worker   }
229*5a923131SAndroid Build Coastguard Worker 
230*5a923131SAndroid Build Coastguard Worker  private:
231*5a923131SAndroid Build Coastguard Worker   std::vector<LoggerFunction> loggers_;
232*5a923131SAndroid Build Coastguard Worker };
233*5a923131SAndroid Build Coastguard Worker 
234*5a923131SAndroid Build Coastguard Worker // Redirect all libchrome logs to liblog using our custom handler that does
235*5a923131SAndroid Build Coastguard Worker // not call __android_log_write and explicitly write to stderr at the same
236*5a923131SAndroid Build Coastguard Worker // time. The preset CombinedLogger already writes to stderr properly.
RedirectToLiblog(int severity,const char * file,int line,size_t message_start,const std::string & str_newline)237*5a923131SAndroid Build Coastguard Worker bool RedirectToLiblog(int severity,
238*5a923131SAndroid Build Coastguard Worker                       const char* file,
239*5a923131SAndroid Build Coastguard Worker                       int line,
240*5a923131SAndroid Build Coastguard Worker                       size_t message_start,
241*5a923131SAndroid Build Coastguard Worker                       const std::string& str_newline) {
242*5a923131SAndroid Build Coastguard Worker   android_LogPriority priority =
243*5a923131SAndroid Build Coastguard Worker       (severity < 0) ? ANDROID_LOG_VERBOSE : ANDROID_LOG_UNKNOWN;
244*5a923131SAndroid Build Coastguard Worker   switch (severity) {
245*5a923131SAndroid Build Coastguard Worker     case logging::LOG_INFO:
246*5a923131SAndroid Build Coastguard Worker       priority = ANDROID_LOG_INFO;
247*5a923131SAndroid Build Coastguard Worker       break;
248*5a923131SAndroid Build Coastguard Worker     case logging::LOG_WARNING:
249*5a923131SAndroid Build Coastguard Worker       priority = ANDROID_LOG_WARN;
250*5a923131SAndroid Build Coastguard Worker       break;
251*5a923131SAndroid Build Coastguard Worker     case logging::LOG_ERROR:
252*5a923131SAndroid Build Coastguard Worker       priority = ANDROID_LOG_ERROR;
253*5a923131SAndroid Build Coastguard Worker       break;
254*5a923131SAndroid Build Coastguard Worker     case logging::LOG_FATAL:
255*5a923131SAndroid Build Coastguard Worker       priority = ANDROID_LOG_FATAL;
256*5a923131SAndroid Build Coastguard Worker       break;
257*5a923131SAndroid Build Coastguard Worker   }
258*5a923131SAndroid Build Coastguard Worker   std::string_view sv = str_newline;
259*5a923131SAndroid Build Coastguard Worker   ignore_result(android::base::ConsumeSuffix(&sv, "\n"));
260*5a923131SAndroid Build Coastguard Worker   std::string str(sv.data(), sv.size());
261*5a923131SAndroid Build Coastguard Worker 
262*5a923131SAndroid Build Coastguard Worker   if (priority == ANDROID_LOG_FATAL) {
263*5a923131SAndroid Build Coastguard Worker     // Abort the program for priority FATAL. __android_log_assert will log the
264*5a923131SAndroid Build Coastguard Worker     // message to stderr and CombinedLogger.
265*5a923131SAndroid Build Coastguard Worker     __android_log_assert(nullptr, nullptr, "%s", str.c_str());
266*5a923131SAndroid Build Coastguard Worker   } else {
267*5a923131SAndroid Build Coastguard Worker     // This will eventually be redirected to CombinedLogger.
268*5a923131SAndroid Build Coastguard Worker     // Use nullptr as tag so that liblog infers log tag from getprogname().
269*5a923131SAndroid Build Coastguard Worker     if (file == nullptr || file[0] == 0 || line == 0 || message_start != 0) {
270*5a923131SAndroid Build Coastguard Worker       __android_log_write(priority, nullptr /* tag */, str.c_str());
271*5a923131SAndroid Build Coastguard Worker     } else {
272*5a923131SAndroid Build Coastguard Worker       __android_log_print(priority,
273*5a923131SAndroid Build Coastguard Worker                           nullptr,
274*5a923131SAndroid Build Coastguard Worker                           "[%s:%s(%d)] %s",
275*5a923131SAndroid Build Coastguard Worker                           LogPriorityToCString(priority),
276*5a923131SAndroid Build Coastguard Worker                           file,
277*5a923131SAndroid Build Coastguard Worker                           line,
278*5a923131SAndroid Build Coastguard Worker                           str.c_str());
279*5a923131SAndroid Build Coastguard Worker     }
280*5a923131SAndroid Build Coastguard Worker   }
281*5a923131SAndroid Build Coastguard Worker   return true;
282*5a923131SAndroid Build Coastguard Worker }
283*5a923131SAndroid Build Coastguard Worker 
284*5a923131SAndroid Build Coastguard Worker }  // namespace
285*5a923131SAndroid Build Coastguard Worker 
SetupLogging(bool log_to_system,bool log_to_file)286*5a923131SAndroid Build Coastguard Worker void SetupLogging(bool log_to_system, bool log_to_file) {
287*5a923131SAndroid Build Coastguard Worker   // Note that libchrome logging uses liblog.
288*5a923131SAndroid Build Coastguard Worker   // By calling liblog's __android_log_set_logger function, all of libchrome
289*5a923131SAndroid Build Coastguard Worker   // (used by update_engine) / libbase / liblog (used by depended modules)
290*5a923131SAndroid Build Coastguard Worker   // logging eventually redirects to CombinedLogger.
291*5a923131SAndroid Build Coastguard Worker   static auto g_logger =
292*5a923131SAndroid Build Coastguard Worker       std::make_unique<CombinedLogger>(log_to_system, log_to_file);
293*5a923131SAndroid Build Coastguard Worker   __android_log_set_logger([](const struct __android_log_message* log_message) {
294*5a923131SAndroid Build Coastguard Worker     (*g_logger)(log_message);
295*5a923131SAndroid Build Coastguard Worker   });
296*5a923131SAndroid Build Coastguard Worker 
297*5a923131SAndroid Build Coastguard Worker   // libchrome logging should not log to file.
298*5a923131SAndroid Build Coastguard Worker   logging::LoggingSettings log_settings;
299*5a923131SAndroid Build Coastguard Worker   log_settings.lock_log = logging::DONT_LOCK_LOG_FILE;
300*5a923131SAndroid Build Coastguard Worker   log_settings.logging_dest =
301*5a923131SAndroid Build Coastguard Worker       static_cast<logging::LoggingDestination>(logging::LOG_NONE);
302*5a923131SAndroid Build Coastguard Worker   log_settings.log_file = nullptr;
303*5a923131SAndroid Build Coastguard Worker   logging::InitLogging(log_settings);
304*5a923131SAndroid Build Coastguard Worker   logging::SetLogItems(false /* enable_process_id */,
305*5a923131SAndroid Build Coastguard Worker                        false /* enable_thread_id */,
306*5a923131SAndroid Build Coastguard Worker                        false /* enable_timestamp */,
307*5a923131SAndroid Build Coastguard Worker                        false /* enable_tickcount */);
308*5a923131SAndroid Build Coastguard Worker   logging::SetLogMessageHandler(&RedirectToLiblog);
309*5a923131SAndroid Build Coastguard Worker }
310*5a923131SAndroid Build Coastguard Worker 
311*5a923131SAndroid Build Coastguard Worker }  // namespace chromeos_update_engine
312