blob: 7c9668634854eac94cca3dbd56b5bf710c682e53 [file] [log] [blame]
Vadim Yanitskiye7bf4352020-09-09 03:36:48 +07001/*
2 * (C) 2020 by Vadim Yanitskiy <axilirator@gmail.com>
3 * All Rights Reserved
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 */
22
23/*! \addtogroup logging
24 * @{
25 * \file logging_systemd.c */
26
27#include <stdio.h>
28#include <syslog.h>
29
30/* Do not use this file as location in sd_journal_print() */
31#define SD_JOURNAL_SUPPRESS_LOCATION
32
33#include <systemd/sd-journal.h>
34
35#include <osmocom/core/talloc.h>
36#include <osmocom/core/utils.h>
37#include <osmocom/core/logging.h>
38
39/* FIXME: copy-pasted from logging_syslog.c */
40static int logp2syslog_level(unsigned int level)
41{
42 if (level >= LOGL_FATAL)
43 return LOG_CRIT;
44 else if (level >= LOGL_ERROR)
45 return LOG_ERR;
46 else if (level >= LOGL_NOTICE)
47 return LOG_NOTICE;
48 else if (level >= LOGL_INFO)
49 return LOG_INFO;
50 else
51 return LOG_DEBUG;
52}
53
54static void _systemd_output(struct log_target *target,
55 unsigned int level, const char *log)
56{
57 /* systemd accepts the same level constants as syslog */
58 sd_journal_print(logp2syslog_level(level), "%s", log);
59}
60
61static void _systemd_raw_output(struct log_target *target, int subsys,
62 unsigned int level, const char *file,
63 int line, int cont, const char *format,
64 va_list ap)
65{
66 char buf[4096];
67 int rc;
68
69 rc = vsnprintf(buf, sizeof(buf), format, ap);
70 if (rc < 0) {
71 sd_journal_print(LOG_ERR, "vsnprintf() failed to render a message "
72 "originated from %s:%d (rc=%d)\n",
73 file, line, rc);
74 return;
75 }
76
77 sd_journal_send("CODE_FILE=%s, CODE_LINE=%d", file, line,
78 "PRIORITY=%d", logp2syslog_level(level),
79 "OSMO_SUBSYS=%s", log_category_name(subsys),
80 "OSMO_SUBSYS_HEX=%4.4x", subsys,
81 "MESSAGE=%s", buf,
82 NULL);
83}
84
85/*! Create a new logging target for systemd journal logging.
86 * \param[in] raw whether to offload rendering of the meta information
87 * (location, category) to systemd-journal.
88 * \returns Log target in case of success, NULL in case of error.
89 */
90struct log_target *log_target_create_systemd(bool raw)
91{
92 struct log_target *target;
93
94 target = log_target_create();
95 if (!target)
96 return NULL;
97
98 target->type = LOG_TGT_TYPE_SYSTEMD;
99 log_target_systemd_set_raw(target, raw);
100
101 return target;
102}
103
104/*! Change meta information handling of an existing logging target.
105 * \param[in] target logging target to be modified.
106 * \param[in] raw whether to offload rendering of the meta information
107 * (location, category) to systemd-journal.
108 */
109void log_target_systemd_set_raw(struct log_target *target, bool raw)
110{
111 target->sd_journal.raw = raw;
112 if (raw) {
113 target->raw_output = _systemd_raw_output;
114 target->output = NULL;
115 } else {
116 target->output = _systemd_output;
117 target->raw_output = NULL;
118 }
119}
120
121/* @} */