xref: /aosp_15_r20/external/cronet/base/fuchsia/scoped_fx_logger.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2020 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "base/fuchsia/scoped_fx_logger.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <lib/component/incoming/cpp/protocol.h>
8*6777b538SAndroid Build Coastguard Worker #include <lib/fdio/directory.h>
9*6777b538SAndroid Build Coastguard Worker #include <stdio.h>
10*6777b538SAndroid Build Coastguard Worker 
11*6777b538SAndroid Build Coastguard Worker #include <string_view>
12*6777b538SAndroid Build Coastguard Worker 
13*6777b538SAndroid Build Coastguard Worker #include "base/command_line.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/files/file_path.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/fuchsia/fuchsia_component_connect.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/fuchsia/fuchsia_logging.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/process/process.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/threading/platform_thread.h"
19*6777b538SAndroid Build Coastguard Worker 
20*6777b538SAndroid Build Coastguard Worker namespace base {
21*6777b538SAndroid Build Coastguard Worker 
22*6777b538SAndroid Build Coastguard Worker ScopedFxLogger::ScopedFxLogger() = default;
23*6777b538SAndroid Build Coastguard Worker ScopedFxLogger::~ScopedFxLogger() = default;
24*6777b538SAndroid Build Coastguard Worker 
25*6777b538SAndroid Build Coastguard Worker ScopedFxLogger::ScopedFxLogger(ScopedFxLogger&& other) = default;
26*6777b538SAndroid Build Coastguard Worker ScopedFxLogger& ScopedFxLogger::operator=(ScopedFxLogger&& other) = default;
27*6777b538SAndroid Build Coastguard Worker 
28*6777b538SAndroid Build Coastguard Worker // static
CreateForProcess(std::vector<std::string_view> tags)29*6777b538SAndroid Build Coastguard Worker ScopedFxLogger ScopedFxLogger::CreateForProcess(
30*6777b538SAndroid Build Coastguard Worker     std::vector<std::string_view> tags) {
31*6777b538SAndroid Build Coastguard Worker   // CHECK()ing or LOG()ing inside this function is safe, since it is only
32*6777b538SAndroid Build Coastguard Worker   // called to initialize logging, not during individual logging operations.
33*6777b538SAndroid Build Coastguard Worker 
34*6777b538SAndroid Build Coastguard Worker   auto log_sink_client_end = component::Connect<fuchsia_logger::LogSink>();
35*6777b538SAndroid Build Coastguard Worker   if (log_sink_client_end.is_error()) {
36*6777b538SAndroid Build Coastguard Worker     LOG(ERROR) << FidlConnectionErrorMessage(log_sink_client_end);
37*6777b538SAndroid Build Coastguard Worker     return {};
38*6777b538SAndroid Build Coastguard Worker   }
39*6777b538SAndroid Build Coastguard Worker 
40*6777b538SAndroid Build Coastguard Worker   // Rather than relying on automatic LogSink attribution via COMPONENT_NAME,
41*6777b538SAndroid Build Coastguard Worker   // prepend a tag based on the calling process' name.  COMPONENT_NAME may be
42*6777b538SAndroid Build Coastguard Worker   // mis-attributed, in some Component configurations, to a parent or caller
43*6777b538SAndroid Build Coastguard Worker   // component, from which the process' LogSink service is routed.
44*6777b538SAndroid Build Coastguard Worker   std::string program_name = base::CommandLine::ForCurrentProcess()
45*6777b538SAndroid Build Coastguard Worker                                  ->GetProgram()
46*6777b538SAndroid Build Coastguard Worker                                  .BaseName()
47*6777b538SAndroid Build Coastguard Worker                                  .AsUTF8Unsafe();
48*6777b538SAndroid Build Coastguard Worker   tags.insert(tags.begin(), program_name);
49*6777b538SAndroid Build Coastguard Worker 
50*6777b538SAndroid Build Coastguard Worker   return CreateFromLogSink(std::move(log_sink_client_end.value()),
51*6777b538SAndroid Build Coastguard Worker                            std::move(tags));
52*6777b538SAndroid Build Coastguard Worker }
53*6777b538SAndroid Build Coastguard Worker 
54*6777b538SAndroid Build Coastguard Worker // static
CreateFromLogSink(fidl::ClientEnd<fuchsia_logger::LogSink> log_sink_client_end,std::vector<std::string_view> tags)55*6777b538SAndroid Build Coastguard Worker ScopedFxLogger ScopedFxLogger::CreateFromLogSink(
56*6777b538SAndroid Build Coastguard Worker     fidl::ClientEnd<fuchsia_logger::LogSink> log_sink_client_end,
57*6777b538SAndroid Build Coastguard Worker     std::vector<std::string_view> tags) {
58*6777b538SAndroid Build Coastguard Worker   // CHECK()ing or LOG()ing inside this function is safe, since it is only
59*6777b538SAndroid Build Coastguard Worker   // called to initialize logging, not during individual logging operations.
60*6777b538SAndroid Build Coastguard Worker 
61*6777b538SAndroid Build Coastguard Worker   // Attempts to create a kernel socket object should never fail.
62*6777b538SAndroid Build Coastguard Worker   zx::socket local, remote;
63*6777b538SAndroid Build Coastguard Worker   zx_status_t socket_status =
64*6777b538SAndroid Build Coastguard Worker       zx::socket::create(ZX_SOCKET_DATAGRAM, &local, &remote);
65*6777b538SAndroid Build Coastguard Worker   ZX_CHECK(socket_status == ZX_OK, socket_status)
66*6777b538SAndroid Build Coastguard Worker       << "zx_socket_create() failed";
67*6777b538SAndroid Build Coastguard Worker 
68*6777b538SAndroid Build Coastguard Worker   // ConnectStructured() may fail if e.g. the LogSink has disconnected already.
69*6777b538SAndroid Build Coastguard Worker   fidl::SyncClient log_sink(std::move(log_sink_client_end));
70*6777b538SAndroid Build Coastguard Worker   auto connect_structured_result =
71*6777b538SAndroid Build Coastguard Worker       log_sink->ConnectStructured(std::move(remote));
72*6777b538SAndroid Build Coastguard Worker   if (connect_structured_result.is_error()) {
73*6777b538SAndroid Build Coastguard Worker     ZX_LOG(ERROR, connect_structured_result.error_value().status())
74*6777b538SAndroid Build Coastguard Worker         << "ConnectStructured() failed";
75*6777b538SAndroid Build Coastguard Worker     return {};
76*6777b538SAndroid Build Coastguard Worker   }
77*6777b538SAndroid Build Coastguard Worker 
78*6777b538SAndroid Build Coastguard Worker   return ScopedFxLogger(std::move(tags), std::move(local));
79*6777b538SAndroid Build Coastguard Worker }
80*6777b538SAndroid Build Coastguard Worker 
LogMessage(std::string_view file,uint32_t line_number,std::string_view msg,FuchsiaLogSeverity severity)81*6777b538SAndroid Build Coastguard Worker void ScopedFxLogger::LogMessage(std::string_view file,
82*6777b538SAndroid Build Coastguard Worker                                 uint32_t line_number,
83*6777b538SAndroid Build Coastguard Worker                                 std::string_view msg,
84*6777b538SAndroid Build Coastguard Worker                                 FuchsiaLogSeverity severity) {
85*6777b538SAndroid Build Coastguard Worker   if (!socket_.is_valid())
86*6777b538SAndroid Build Coastguard Worker     return;
87*6777b538SAndroid Build Coastguard Worker 
88*6777b538SAndroid Build Coastguard Worker   // It is not safe to use e.g. CHECK() or LOG() macros here, since those
89*6777b538SAndroid Build Coastguard Worker   // may result in reentrancy if this instance is used for routing process-
90*6777b538SAndroid Build Coastguard Worker   // global logs to the system logger.
91*6777b538SAndroid Build Coastguard Worker 
92*6777b538SAndroid Build Coastguard Worker   fuchsia_syslog::LogBuffer buffer;
93*6777b538SAndroid Build Coastguard Worker   buffer.BeginRecord(severity, cpp17::string_view(file.data(), file.size()),
94*6777b538SAndroid Build Coastguard Worker                      line_number, cpp17::string_view(msg.data(), msg.size()),
95*6777b538SAndroid Build Coastguard Worker                      socket_.borrow(), 0, base::Process::Current().Pid(),
96*6777b538SAndroid Build Coastguard Worker                      base::PlatformThread::CurrentId());
97*6777b538SAndroid Build Coastguard Worker   for (const auto& tag : tags_) {
98*6777b538SAndroid Build Coastguard Worker     buffer.WriteKeyValue("tag", tag);
99*6777b538SAndroid Build Coastguard Worker   }
100*6777b538SAndroid Build Coastguard Worker   if (!buffer.FlushRecord())
101*6777b538SAndroid Build Coastguard Worker     fprintf(stderr, "fuchsia_syslog.LogBuffer.FlushRecord() failed\n");
102*6777b538SAndroid Build Coastguard Worker }
103*6777b538SAndroid Build Coastguard Worker 
ScopedFxLogger(std::vector<std::string_view> tags,zx::socket socket)104*6777b538SAndroid Build Coastguard Worker ScopedFxLogger::ScopedFxLogger(std::vector<std::string_view> tags,
105*6777b538SAndroid Build Coastguard Worker                                zx::socket socket)
106*6777b538SAndroid Build Coastguard Worker     : tags_(tags.begin(), tags.end()), socket_(std::move(socket)) {}
107*6777b538SAndroid Build Coastguard Worker 
108*6777b538SAndroid Build Coastguard Worker }  // namespace base
109