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