| /* |
| * (C) 2020 by Vadim Yanitskiy <axilirator@gmail.com> |
| * All Rights Reserved |
| * |
| * SPDX-License-Identifier: GPL-2.0+ |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License along |
| * with this program; if not, write to the Free Software Foundation, Inc., |
| * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| */ |
| |
| /*! \addtogroup logging |
| * @{ |
| * \file logging_systemd.c */ |
| |
| #include <stdio.h> |
| #include <syslog.h> |
| |
| /* Do not use this file as location in sd_journal_print() */ |
| #define SD_JOURNAL_SUPPRESS_LOCATION |
| |
| #include <systemd/sd-journal.h> |
| |
| #include <osmocom/core/talloc.h> |
| #include <osmocom/core/utils.h> |
| #include <osmocom/core/logging.h> |
| |
| /* FIXME: copy-pasted from logging_syslog.c */ |
| static int logp2syslog_level(unsigned int level) |
| { |
| if (level >= LOGL_FATAL) |
| return LOG_CRIT; |
| else if (level >= LOGL_ERROR) |
| return LOG_ERR; |
| else if (level >= LOGL_NOTICE) |
| return LOG_NOTICE; |
| else if (level >= LOGL_INFO) |
| return LOG_INFO; |
| else |
| return LOG_DEBUG; |
| } |
| |
| static void _systemd_output(struct log_target *target, |
| unsigned int level, const char *log) |
| { |
| /* systemd accepts the same level constants as syslog */ |
| sd_journal_print(logp2syslog_level(level), "%s", log); |
| } |
| |
| static void _systemd_raw_output(struct log_target *target, int subsys, |
| unsigned int level, const char *file, |
| int line, int cont, const char *format, |
| va_list ap) |
| { |
| char buf[4096]; |
| int rc; |
| |
| rc = vsnprintf(buf, sizeof(buf), format, ap); |
| if (rc < 0) { |
| sd_journal_print(LOG_ERR, "vsnprintf() failed to render a message " |
| "originated from %s:%d (rc=%d)\n", |
| file, line, rc); |
| return; |
| } |
| |
| sd_journal_send("CODE_FILE=%s, CODE_LINE=%d", file, line, |
| "PRIORITY=%d", logp2syslog_level(level), |
| "OSMO_SUBSYS=%s", log_category_name(subsys), |
| "OSMO_SUBSYS_HEX=%4.4x", subsys, |
| "MESSAGE=%s", buf, |
| NULL); |
| } |
| |
| /*! Create a new logging target for systemd journal logging. |
| * \param[in] raw whether to offload rendering of the meta information |
| * (location, category) to systemd-journal. |
| * \returns Log target in case of success, NULL in case of error. |
| */ |
| struct log_target *log_target_create_systemd(bool raw) |
| { |
| struct log_target *target; |
| |
| target = log_target_create(); |
| if (!target) |
| return NULL; |
| |
| target->type = LOG_TGT_TYPE_SYSTEMD; |
| log_target_systemd_set_raw(target, raw); |
| |
| return target; |
| } |
| |
| /*! Change meta information handling of an existing logging target. |
| * \param[in] target logging target to be modified. |
| * \param[in] raw whether to offload rendering of the meta information |
| * (location, category) to systemd-journal. |
| */ |
| void log_target_systemd_set_raw(struct log_target *target, bool raw) |
| { |
| target->sd_journal.raw = raw; |
| if (raw) { |
| target->raw_output = _systemd_raw_output; |
| target->output = NULL; |
| } else { |
| target->output = _systemd_output; |
| target->raw_output = NULL; |
| } |
| } |
| |
| /* @} */ |