1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <lib/fdio/util.h>
6 #include <lib/zx/channel.h>
7 #include <lib/zx/socket.h>
8 #include <lib/syslog/logger.h>
9 
10 // TODO: Remove this hack once FIDL-182  is fixed.
11 typedef zx_handle_t fuchsia_logger_LogListener;
12 #include <fuchsia/logger/c/fidl.h>
13 
14 #include "fx_logger.h"
15 
16 namespace {
17 
connect_to_logger()18 zx::socket connect_to_logger() {
19     zx::socket invalid;
20     zx::channel logger, logger_request;
21     if (zx::channel::create(0, &logger, &logger_request) != ZX_OK) {
22         return invalid;
23     }
24     if (fdio_service_connect("/svc/fuchsia.logger.LogSink", logger_request.release()) != ZX_OK) {
25         return invalid;
26     }
27     zx::socket local, remote;
28     if (zx::socket::create(ZX_SOCKET_DATAGRAM, &local, &remote) != ZX_OK) {
29         return invalid;
30     }
31     fuchsia_logger_LogSinkConnectRequest req;
32     memset(&req, 0, sizeof(req));
33     req.hdr.ordinal = fuchsia_logger_LogSinkConnectOrdinal;
34     req.socket = FIDL_HANDLE_PRESENT;
35     zx_handle_t handles[1] = {remote.release()};
36     if (logger.write(0, &req, sizeof(req), handles, 1) != ZX_OK) {
37         close(handles[0]);
38         return invalid;
39     }
40     return local;
41 }
42 
43 } // namespace
fx_logger_logf(fx_logger_t * logger,fx_log_severity_t severity,const char * tag,const char * format,...)44 zx_status_t fx_logger_logf(fx_logger_t* logger, fx_log_severity_t severity,
45                            const char* tag, const char* format, ...) {
46     if (logger == nullptr) {
47         return ZX_ERR_BAD_STATE;
48     }
49     va_list args;
50     va_start(args, format);
51     zx_status_t s = logger->VLogWrite(severity, tag, format, args);
52     va_end(args);
53     return s;
54 }
55 
fx_logger_log(fx_logger_t * logger,fx_log_severity_t severity,const char * tag,const char * msg)56 zx_status_t fx_logger_log(fx_logger_t* logger, fx_log_severity_t severity,
57                           const char* tag, const char* msg) {
58     if (logger == nullptr) {
59         return ZX_ERR_BAD_STATE;
60     }
61     return logger->LogWrite(severity, tag, msg);
62 }
63 
fx_vlogf(fx_logger_t * logger,fx_log_severity_t severity,const char * tag,const char * format,va_list args)64 zx_status_t fx_vlogf(fx_logger_t* logger, fx_log_severity_t severity,
65                      const char* tag, const char* format, va_list args) {
66     if (logger == nullptr) {
67         return ZX_ERR_BAD_STATE;
68     }
69     return logger->VLogWrite(severity, tag, format, args);
70 }
71 
fx_logger_get_min_severity(fx_logger_t * logger)72 fx_log_severity_t fx_logger_get_min_severity(fx_logger_t* logger) {
73     if (logger == nullptr) {
74         return FX_LOG_FATAL;
75     }
76     return logger->GetSeverity();
77 }
78 
fx_logger_set_min_severity(fx_logger_t * logger,fx_log_severity_t severity)79 void fx_logger_set_min_severity(fx_logger_t* logger,
80                                 fx_log_severity_t severity) {
81     return logger->SetSeverity(severity);
82 }
83 
fx_logger_activate_fallback(fx_logger_t * logger,int fallback_fd)84 void fx_logger_activate_fallback(fx_logger_t* logger,
85                                  int fallback_fd) {
86     logger->ActivateFallback(fallback_fd);
87 }
88 
fx_logger_create(const fx_logger_config_t * config,fx_logger_t ** out_logger)89 zx_status_t fx_logger_create(const fx_logger_config_t* config,
90                              fx_logger_t** out_logger) {
91     if (config->num_tags > FX_LOG_MAX_TAGS) {
92         return ZX_ERR_INVALID_ARGS;
93     }
94     fx_logger_config_t c = *config;
95     if (config->console_fd == -1 &&
96         config->log_service_channel == ZX_HANDLE_INVALID) {
97         zx::socket sock = connect_to_logger();
98         if (sock.is_valid()) {
99             c.log_service_channel = sock.release();
100         } else {
101             int newfd = dup(STDERR_FILENO);
102             if (newfd < 0) {
103                 return ZX_ERR_INTERNAL;
104             }
105             c.console_fd = newfd;
106         }
107     }
108     *out_logger = new fx_logger(&c);
109     return ZX_OK;
110 }
111 
fx_logger_destroy(fx_logger_t * logger)112 void fx_logger_destroy(fx_logger_t* logger) {
113     delete logger;
114 }
115