Browse Source

[Rework] Add console and syslog modules

tags/2.4
Vsevolod Stakhov 4 years ago
parent
commit
4de514b49c

+ 0
- 1
src/libserver/cfg_file.h View File

@@ -76,7 +76,6 @@ enum rspamd_log_cfg_flags {
RSPAMD_LOG_FLAG_USEC = (1 << 3),
RSPAMD_LOG_FLAG_RSPAMADM = (1 << 4),
RSPAMD_LOG_FLAG_ENFORCED = (1 << 5),
RSPAMD_LOG_FLAG_TTY = (1 << 6),
};

struct rspamd_worker_log_pipe {

+ 2
- 0
src/libutil/CMakeLists.txt View File

@@ -12,6 +12,8 @@ SET(LIBRSPAMDUTILSRC
${CMAKE_CURRENT_SOURCE_DIR}/http_context.c
${CMAKE_CURRENT_SOURCE_DIR}/logger.c
${CMAKE_CURRENT_SOURCE_DIR}/logger_file.c
${CMAKE_CURRENT_SOURCE_DIR}/logger_syslog.c
${CMAKE_CURRENT_SOURCE_DIR}/logger_console.c
${CMAKE_CURRENT_SOURCE_DIR}/map.c
${CMAKE_CURRENT_SOURCE_DIR}/map_helpers.c
${CMAKE_CURRENT_SOURCE_DIR}/mem_pool.c

+ 1
- 38
src/libutil/logger.c View File

@@ -22,10 +22,6 @@
#include "unix-std.h"
#include "logger_private.h"

#ifdef HAVE_SYSLOG_H
#include <syslog.h>
#endif


static rspamd_logger_t *default_logger = NULL;
static struct rspamd_log_modules *log_modules = NULL;
@@ -278,7 +274,6 @@ rspamd_set_logger (struct rspamd_config *cfg,
}

logger->log_type = cfg->log_type;
logger->log_facility = cfg->log_facility;

if (!(logger->flags & RSPAMD_LOG_FLAG_ENFORCED)) {
logger->log_level = cfg->log_level;
@@ -346,39 +341,7 @@ void
rspamd_log_update_pid (GQuark ptype, rspamd_logger_t *rspamd_log)
{
rspamd_log->pid = getpid ();
rspamd_log->process_type = ptype;

/* We also need to clear all messages pending */
if (rspamd_log->repeats > 0) {
rspamd_log->repeats = 0;
if (rspamd_log->saved_message) {
g_free (rspamd_log->saved_message);
g_free (rspamd_log->saved_function);
g_free (rspamd_log->saved_module);
g_free (rspamd_log->saved_id);
rspamd_log->saved_message = NULL;
rspamd_log->saved_function = NULL;
rspamd_log->saved_module = NULL;
rspamd_log->saved_id = NULL;
}
}
}

/**
* Flush logging buffer
*/
void
rspamd_log_flush (rspamd_logger_t *rspamd_log)
{
if (rspamd_log->is_buffered &&
(rspamd_log->type == RSPAMD_LOG_CONSOLE ||
rspamd_log->type == RSPAMD_LOG_FILE)) {
direct_write_log_line (rspamd_log,
rspamd_log->io_buf.buf,
rspamd_log->io_buf.used,
FALSE, rspamd_log->log_level);
rspamd_log->io_buf.used = 0;
}
rspamd_log->process_type = g_quark_to_string (ptype);
}

static inline gboolean

+ 13
- 18
src/libutil/logger.h View File

@@ -22,7 +22,7 @@ enum rspamd_log_flags {
};

typedef struct rspamd_logger_s rspamd_logger_t;
typedef void (*rspamd_log_func_t) (const gchar *module, const gchar *id,
typedef bool (*rspamd_log_func_t) (const gchar *module, const gchar *id,
const gchar *function,
gint level_flags,
const gchar *message,
@@ -62,22 +62,22 @@ void rspamd_set_logger (struct rspamd_config *cfg,
/**
* Open log file or initialize other structures
*/
gint rspamd_log_open (rspamd_logger_t *logger);
bool rspamd_log_open (rspamd_logger_t *logger);

/**
* Close log file or destroy other structures
*/
void rspamd_log_close (rspamd_logger_t *logger, gboolean termination);
bool rspamd_log_close (rspamd_logger_t *logger, gboolean termination);

/**
* Close and open log again
*/
gint rspamd_log_reopen (rspamd_logger_t *logger);
bool rspamd_log_reopen (rspamd_logger_t *logger);

/**
* Open log file or initialize other structures for privileged processes
*/
gint rspamd_log_open_priv (rspamd_logger_t *logger, uid_t uid, gid_t gid);
bool rspamd_log_open_priv (rspamd_logger_t *logger, uid_t uid, gid_t gid);

/**
* Close log file or destroy other structures for privileged processes
@@ -87,18 +87,13 @@ void rspamd_log_close_priv (rspamd_logger_t *logger, gboolean termination, uid_t
/**
* Close and open log again for privileged processes
*/
gint rspamd_log_reopen_priv (rspamd_logger_t *logger, uid_t uid, gid_t gid);
bool rspamd_log_reopen_priv (rspamd_logger_t *logger, uid_t uid, gid_t gid);

/**
* Set log pid
*/
void rspamd_log_update_pid (GQuark ptype, rspamd_logger_t *logger);

/**
* Flush log buffer for some types of logging
*/
void rspamd_log_flush (rspamd_logger_t *logger);

/**
* Log function that is compatible for glib messages
*/
@@ -113,12 +108,12 @@ void rspamd_glib_printerr_function (const gchar *message);
/**
* Function with variable number of arguments support
*/
void rspamd_common_log_function (rspamd_logger_t *logger,
bool rspamd_common_log_function (rspamd_logger_t *logger,
gint level_flags,
const gchar *module, const gchar *id,
const gchar *function, const gchar *fmt, ...);

void rspamd_common_logv (rspamd_logger_t *logger, gint level_flags,
bool rspamd_common_logv (rspamd_logger_t *logger, gint level_flags,
const gchar *module, const gchar *id, const gchar *function,
const gchar *fmt, va_list args);

@@ -149,16 +144,16 @@ void rspamd_logger_configure_modules (GHashTable *mods_enabled);
/**
* Conditional debug function
*/
void rspamd_conditional_debug (rspamd_logger_t *logger,
bool rspamd_conditional_debug (rspamd_logger_t *logger,
rspamd_inet_addr_t *addr, const gchar *module, const gchar *id,
const gchar *function, const gchar *fmt, ...);

void rspamd_conditional_debug_fast (rspamd_logger_t *logger,
bool rspamd_conditional_debug_fast (rspamd_logger_t *logger,
rspamd_inet_addr_t *addr,
guint mod_id,
const gchar *module, const gchar *id,
const gchar *function, const gchar *fmt, ...);
void rspamd_conditional_debug_fast_num_id (rspamd_logger_t *logger,
bool rspamd_conditional_debug_fast_num_id (rspamd_logger_t *logger,
rspamd_inet_addr_t *addr,
guint mod_id,
const gchar *module, guint64 id,
@@ -167,7 +162,7 @@ void rspamd_conditional_debug_fast_num_id (rspamd_logger_t *logger,
/**
* Function with variable number of arguments support that uses static default logger
*/
void rspamd_default_log_function (gint level_flags,
bool rspamd_default_log_function (gint level_flags,
const gchar *module, const gchar *id,
const gchar *function,
const gchar *fmt,
@@ -180,7 +175,7 @@ void rspamd_default_log_function (gint level_flags,
* @param fmt
* @param args
*/
void rspamd_default_logv (gint level_flags,
bool rspamd_default_logv (gint level_flags,
const gchar *module, const gchar *id,
const gchar *function,
const gchar *fmt,

+ 290
- 0
src/libutil/logger_console.c View File

@@ -0,0 +1,290 @@
/*-
* Copyright 2020 Vsevolod Stakhov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "config.h"
#include "logger.h"
#include "libserver/cfg_file.h"
#include "libcryptobox/cryptobox.h"
#include "unix-std.h"

#include "logger_private.h"

#define CONSOLE_LOG_QUARK g_quark_from_static_string ("console_logger")

static const gchar lf_chr = '\n';
struct rspamd_console_logger_priv {
gint fd;
gint crit_fd;
gboolean log_color;
gboolean log_rspamadm;
gboolean log_tty;
};

/* Copy & paste :( */
static inline void
log_time (gdouble now, rspamd_logger_t *rspamd_log, gchar *timebuf,
size_t len)
{
time_t sec = (time_t)now;
gsize r;
struct tm tms;

rspamd_localtime (sec, &tms);
r = strftime (timebuf, len, "%F %H:%M:%S", &tms);

if (rspamd_log->flags & RSPAMD_LOG_FLAG_USEC) {
gchar usec_buf[16];

rspamd_snprintf (usec_buf, sizeof (usec_buf), "%.5f",
now - (gdouble)sec);
rspamd_snprintf (timebuf + r, len - r,
"%s", usec_buf + 1);
}
}

void *
rspamd_log_console_init (rspamd_logger_t *logger, struct rspamd_config *cfg,
uid_t uid, gid_t gid, GError **err)
{
struct rspamd_console_logger_priv *priv;

priv = g_malloc0 (sizeof (*priv));
priv->log_color = (logger->flags & RSPAMD_LOG_FLAG_COLOR);
priv->log_rspamadm (logger->flags & RSPAMD_LOG_FLAG_RSPAMADM);

if (priv->log_rspamadm) {
priv->fd = dup (STDOUT_FILENO);
priv->crit_fd = dup (STDERR_FILENO);
}
else {
priv->fd = dup (STDERR_FILENO);
priv->crit_fd = priv->fd;
}

if (priv->fd == -1) {
g_set_error (err, CONSOLE_LOG_QUARK, errno,
"open_log: cannot dup console fd: %s, %s\n",
strerror (errno));
rspamd_log_console_dtor (priv);

return NULL;
}

if (isatty (priv->fd)) {
priv->log_tty = true;
}

return priv;
}

void *
rspamd_log_console_reload (rspamd_logger_t *logger, struct rspamd_config *cfg,
gpointer arg, uid_t uid, gid_t gid, GError **err)
{
struct rspamd_console_logger_priv *npriv;

npriv = rspamd_log_console_init (logger, cfg, uid, gid, err);

if (npriv) {
/* Close old */
rspamd_log_console_dtor (logger, arg);
}

return npriv;
}

void
rspamd_log_console_dtor (rspamd_logger_t *logger, gpointer arg)
{
struct rspamd_console_logger_priv *priv = (struct rspamd_console_logger_priv *)arg;

if (priv->fd != -1) {
if (priv->fd != priv->crit_fd) {
/* Two different FD case */
if (close (priv->crit_fd) == -1) {
rspamd_fprintf (stderr, "cannot close log crit_fd %d: %s\n",
priv->crit_fd, strerror (errno));
}
}

if (close (priv->fd) == -1) {
rspamd_fprintf (stderr, "cannot close log fd %d: %s\n",
priv->fd, strerror (errno));
}

/* Avoid the next if to be executed as crit_fd is equal to fd */
priv->crit_fd = -1;
}

if (priv->crit_fd != -1) {
if (close (priv->crit_fd) == -1) {
rspamd_fprintf (stderr, "cannot close log crit_fd %d: %s\n",
priv->crit_fd, strerror (errno));
}
}

g_free (priv);
}

bool
rspamd_log_console_log (const gchar *module, const gchar *id,
const gchar *function,
gint level_flags,
const gchar *message,
gsize mlen,
rspamd_logger_t *rspamd_log,
gpointer arg)
{
struct rspamd_console_logger_priv *priv = (struct rspamd_console_logger_priv *)arg;
static gchar timebuf[64], modulebuf[64];
gchar tmpbuf[256];
gchar *m;
struct iovec iov[6];
gulong r = 0, mr = 0;
size_t mremain;
gint fd, niov = 0;

if (level_flags & G_LOG_LEVEL_CRITICAL) {
fd = priv->crit_fd;
}
else {
fd = priv->fd;
}

#ifndef DISABLE_PTHREAD_MUTEX
if (rspamd_log->mtx) {
rspamd_mempool_lock_mutex (rspamd_log->mtx);
}
else {
rspamd_file_lock (fd, FALSE);
}
#else
rspamd_file_lock (fd, FALSE);
#endif

log_time (rspamd_get_calendar_ticks (),
rspamd_log, timebuf, sizeof (timebuf));
if (priv->log_color) {
if (level_flags & (G_LOG_LEVEL_INFO|G_LOG_LEVEL_MESSAGE)) {
/* White */
r = rspamd_snprintf (tmpbuf, sizeof (tmpbuf), "\033[0;37m");
}
else if (level_flags & G_LOG_LEVEL_WARNING) {
/* Magenta */
r = rspamd_snprintf (tmpbuf, sizeof (tmpbuf), "\033[0;32m");
}
else if (level_flags & G_LOG_LEVEL_CRITICAL) {
/* Red */
r = rspamd_snprintf (tmpbuf, sizeof (tmpbuf), "\033[1;31m");
}
}
else {
r = 0;
}

if (priv->log_rspamadm) {
if (rspamd_log->log_level == G_LOG_LEVEL_DEBUG) {
log_time (rspamd_get_calendar_ticks (),
rspamd_log, timebuf, sizeof (timebuf));
iov[niov].iov_base = (void *) timebuf;
iov[niov++].iov_len = strlen (timebuf);
iov[niov].iov_base = (void *) " ";
iov[niov++].iov_len = 1;
}

iov[niov].iov_base = (void *) message;
iov[niov++].iov_len = mlen;
iov[niov].iov_base = (void *) &lf_chr;
iov[niov++].iov_len = 1;
}
else {
r += rspamd_snprintf (tmpbuf + r,
sizeof (tmpbuf) - r,
"%s #%P(%s) ",
timebuf,
rspamd_log->pid,
rspamd_log->process_type);

modulebuf[0] = '\0';
mremain = sizeof (modulebuf);
m = modulebuf;

if (id != NULL) {
guint slen = strlen (id);
slen = MIN (LOG_ID, slen);
mr = rspamd_snprintf (m, mremain, "<%*.s>; ", slen,
id);
m += mr;
mremain -= mr;
}
if (module != NULL) {
mr = rspamd_snprintf (m, mremain, "%s; ", module);
m += mr;
mremain -= mr;
}
if (function != NULL) {
mr = rspamd_snprintf (m, mremain, "%s: ", function);
m += mr;
mremain -= mr;
}
else {
mr = rspamd_snprintf (m, mremain, ": ");
m += mr;
mremain -= mr;
}

iov[niov].iov_base = tmpbuf;
iov[niov++].iov_len = r;
iov[niov].iov_base = modulebuf;
iov[niov++].iov_len = m - modulebuf;
iov[niov].iov_base = (void *) message;
iov[niov++].iov_len = mlen;
iov[niov].iov_base = (void *) &lf_chr;
iov[niov++].iov_len = 1;
}

if (priv->log_color) {
iov[niov].iov_base = "\033[0m";
iov[niov++].iov_len = sizeof ("\033[0m") - 1;
}

again:
r = writev (fd, iov, niov);

if (r == -1) {
if (errno == EAGAIN || errno == EINTR) {
goto again;
}

if (rspamd_log->mtx) {
rspamd_mempool_unlock_mutex (rspamd_log->mtx);
}
else {
rspamd_file_unlock (fd, FALSE);
}

return false;
}

if (rspamd_log->mtx) {
rspamd_mempool_unlock_mutex (rspamd_log->mtx);
}
else {
rspamd_file_unlock (fd, FALSE);
}

return true;
}

+ 41
- 42
src/libutil/logger_file.c View File

@@ -45,7 +45,6 @@ struct rspamd_file_logger_priv {
gchar *saved_module;
gchar *saved_id;
guint saved_loglevel;
guint64 log_cnt[4];
};

/**
@@ -82,7 +81,7 @@ log_time (gdouble now, rspamd_logger_t *rspamd_log, gchar *timebuf,
/*
* Write a line to log file (unbuffered)
*/
static void
static bool
direct_write_log_line (rspamd_logger_t *rspamd_log,
struct rspamd_file_logger_priv *priv,
void *data,
@@ -114,7 +113,7 @@ direct_write_log_line (rspamd_logger_t *rspamd_log,
tlen = count;
}

if (tlen > PIPE_BUF || rspamd_log->flags & RSPAMD_LOG_FLAG_TTY) {
if (tlen > PIPE_BUF) {
locked = TRUE;

#ifndef DISABLE_PTHREAD_MUTEX
@@ -155,14 +154,9 @@ direct_write_log_line (rspamd_logger_t *rspamd_log,
/* We cannot write message to file, so we need to detect error and make decision */
if (errno == EINTR) {
/* Try again */
direct_write_log_line (rspamd_log, priv, data, count, is_iov, level_flags);
return;
return direct_write_log_line (rspamd_log, priv, data, count, is_iov, level_flags);
}

r = rspamd_snprintf (errmsg,
sizeof (errmsg),
"direct_write_log_line: cannot write log line: %s",
strerror (errno));
if (errno == EFAULT || errno == EINVAL || errno == EFBIG ||
errno == ENOSPC) {
/* Rare case */
@@ -173,10 +167,14 @@ direct_write_log_line (rspamd_logger_t *rspamd_log,
/* We write to some pipe and it disappears, disable logging or we has opened bad file descriptor */
rspamd_log->enabled = FALSE;
}

return false;
}
else if (priv->throttling) {
priv->throttling = FALSE;
}

return true;
}

/**
@@ -198,10 +196,24 @@ fill_buffer (rspamd_logger_t *rspamd_log,

}

static void
rspamd_log_flush (rspamd_logger_t *rspamd_log, struct rspamd_file_logger_priv *priv)
{
if (priv->is_buffered) {
direct_write_log_line (rspamd_log,
priv,
priv->io_buf.buf,
priv->io_buf.used,
FALSE,
rspamd_log->log_level);
priv->io_buf.used = 0;
}
}

/*
* Write message to buffer or to file (using direct_write_log_line function)
*/
static void
static bool
file_log_helper (rspamd_logger_t *rspamd_log,
struct rspamd_file_logger_priv *priv,
const struct iovec *iov,
@@ -213,7 +225,7 @@ file_log_helper (rspamd_logger_t *rspamd_log,

if (!priv->is_buffered) {
/* Write string directly */
direct_write_log_line (rspamd_log, priv, (void *) iov, iovcnt,
return direct_write_log_line (rspamd_log, priv, (void *) iov, iovcnt,
TRUE, level_flags);
}
else {
@@ -224,13 +236,13 @@ file_log_helper (rspamd_logger_t *rspamd_log,
/* Fill buffer */
if (priv->io_buf.size < len) {
/* Buffer is too small to hold this string, so write it directly */
rspamd_log_flush (rspamd_log);
direct_write_log_line (rspamd_log, priv, (void *) iov, iovcnt,
rspamd_log_flush (rspamd_log, priv);
return direct_write_log_line (rspamd_log, priv, (void *) iov, iovcnt,
TRUE, level_flags);
}
else if (priv->io_buf.used + len >= priv->io_buf.size) {
/* Buffer is full, try to write it directly */
rspamd_log_flush (rspamd_log);
rspamd_log_flush (rspamd_log, priv);
fill_buffer (rspamd_log, priv, iov, iovcnt);
}
else {
@@ -238,6 +250,8 @@ file_log_helper (rspamd_logger_t *rspamd_log,
fill_buffer (rspamd_log, priv, iov, iovcnt);
}
}

return true;
}

static void
@@ -283,6 +297,7 @@ rspamd_log_reset_repeated (rspamd_logger_t *rspamd_log,
r,
rspamd_log,
priv);
rspamd_log_flush (rspamd_log, priv);
}
}
}
@@ -365,6 +380,7 @@ rspamd_log_file_dtor (rspamd_logger_t *logger, gpointer arg)
struct rspamd_file_logger_priv *priv = (struct rspamd_file_logger_priv *)arg;

rspamd_log_reset_repeated (logger, priv);
rspamd_log_flush (logger, priv);

if (priv->fd != -1) {
if (close (priv->fd) == -1) {
@@ -377,7 +393,7 @@ rspamd_log_file_dtor (rspamd_logger_t *logger, gpointer arg)
g_free (priv);
}

void
bool
rspamd_log_file_log (const gchar *module, const gchar *id,
const gchar *function,
gint level_flags,
@@ -400,19 +416,20 @@ rspamd_log_file_log (const gchar *module, const gchar *id,


if (!(level_flags & RSPAMD_LOG_FORCED) && !rspamd_log->enabled) {
return;
return false;
}

/* Check throttling due to write errors */
if (!(level_flags & RSPAMD_LOG_FORCED) && priv->throttling) {
now = rspamd_get_calendar_ticks ();

if (priv->throttling_time != now) {
priv->throttling_time = now;
got_time = TRUE;
}
else {
/* Do not try to write to file too often while throttling */
return;
return false;
}
}

@@ -442,12 +459,12 @@ rspamd_log_file_log (const gchar *module, const gchar *id,
priv->saved_loglevel = level_flags;
}

return;
return true;
}
else if (priv->repeats > REPEATS_MAX) {
rspamd_log_reset_repeated (rspamd_log, priv);

rspamd_log_file_log (module, id,
bool ret = rspamd_log_file_log (module, id,
function,
level_flags,
message,
@@ -458,7 +475,7 @@ rspamd_log_file_log (const gchar *module, const gchar *id,
/* Probably we have more repeats in future */
priv->repeats = REPEATS_MIN + 1;

return;
return ret;
}
}
else {
@@ -467,14 +484,13 @@ rspamd_log_file_log (const gchar *module, const gchar *id,

if (priv->repeats > REPEATS_MIN) {
rspamd_log_reset_repeated (rspamd_log, priv);
rspamd_log_file_log (module, id,
return rspamd_log_file_log (module, id,
function,
level_flags,
message,
mlen,
rspamd_log,
arg);
return;
}
else {
priv->repeats = 0;
@@ -489,25 +505,8 @@ rspamd_log_file_log (const gchar *module, const gchar *id,
log_time (now, rspamd_log, timebuf, sizeof (timebuf));
}

cptype = g_quark_to_string (rspamd_log->process_type);

if (rspamd_log->flags & RSPAMD_LOG_FLAG_COLOR) {
if (level_flags & (G_LOG_LEVEL_INFO|G_LOG_LEVEL_MESSAGE)) {
/* White */
r = rspamd_snprintf (tmpbuf, sizeof (tmpbuf), "\033[0;37m");
}
else if (level_flags & G_LOG_LEVEL_WARNING) {
/* Magenta */
r = rspamd_snprintf (tmpbuf, sizeof (tmpbuf), "\033[0;32m");
}
else if (level_flags & G_LOG_LEVEL_CRITICAL) {
/* Red */
r = rspamd_snprintf (tmpbuf, sizeof (tmpbuf), "\033[1;31m");
}
}
else {
r = 0;
}
cptype = rspamd_log->process_type;
r = 0;

if (!(rspamd_log->flags & RSPAMD_LOG_FLAG_SYSTEMD)) {
r += rspamd_snprintf (tmpbuf + r,
@@ -562,7 +561,7 @@ rspamd_log_file_log (const gchar *module, const gchar *id,
iov[3].iov_base = (void *) &lf_chr;
iov[3].iov_len = 1;

file_log_helper (rspamd_log, priv, iov, 4, level_flags);
return file_log_helper (rspamd_log, priv, iov, 4, level_flags);
}

void *

+ 49
- 3
src/libutil/logger_private.h View File

@@ -60,7 +60,6 @@ struct rspamd_logger_error_log {
*/
struct rspamd_logger_s {
struct rspamd_logger_funcs ops;
gint log_facility;
gint log_level;

struct rspamd_logger_error_log *errlog;
@@ -74,9 +73,10 @@ struct rspamd_logger_s {
gboolean opened;

pid_t pid;
GQuark process_type;
const gchar *process_type;
struct rspamd_radix_map_helper *debug_ip;
rspamd_mempool_mutex_t *mtx;
guint64 log_cnt[4];
};

/*
@@ -91,7 +91,7 @@ void * rspamd_log_file_init (rspamd_logger_t *logger, struct rspamd_config *cfg,
void * rspamd_log_file_reload (rspamd_logger_t *logger, struct rspamd_config *cfg,
gpointer arg, uid_t uid, gid_t gid, GError **err);
void rspamd_log_file_dtor (rspamd_logger_t *logger, gpointer arg);
void rspamd_log_file_log (const gchar *module, const gchar *id,
bool rspamd_log_file_log (const gchar *module, const gchar *id,
const gchar *function,
gint level_flags,
const gchar *message,
@@ -106,4 +106,50 @@ const static struct rspamd_logger_funcs file_log_funcs = {
.log = rspamd_log_file_log,
};

/*
* Syslog logging
*/
void * rspamd_log_syslog_init (rspamd_logger_t *logger, struct rspamd_config *cfg,
uid_t uid, gid_t gid, GError **err);
void * rspamd_log_syslog_reload (rspamd_logger_t *logger, struct rspamd_config *cfg,
gpointer arg, uid_t uid, gid_t gid, GError **err);
void rspamd_log_syslog_dtor (rspamd_logger_t *logger, gpointer arg);
bool rspamd_log_syslog_log (const gchar *module, const gchar *id,
const gchar *function,
gint level_flags,
const gchar *message,
gsize mlen,
rspamd_logger_t *rspamd_log,
gpointer arg);

const static struct rspamd_logger_funcs syslog_log_funcs = {
.init = rspamd_log_syslog_init,
.dtor = rspamd_log_syslog_dtor,
.reload = rspamd_log_syslog_reload,
.log = rspamd_log_syslog_log,
};

/*
* Console logging
*/
void * rspamd_log_console_init (rspamd_logger_t *logger, struct rspamd_config *cfg,
uid_t uid, gid_t gid, GError **err);
void * rspamd_log_console_reload (rspamd_logger_t *logger, struct rspamd_config *cfg,
gpointer arg, uid_t uid, gid_t gid, GError **err);
void rspamd_log_console_dtor (rspamd_logger_t *logger, gpointer arg);
bool rspamd_log_console_log (const gchar *module, const gchar *id,
const gchar *function,
gint level_flags,
const gchar *message,
gsize mlen,
rspamd_logger_t *rspamd_log,
gpointer arg);

const static struct rspamd_logger_funcs console_log_funcs = {
.init = rspamd_log_console_init,
.dtor = rspamd_log_console_dtor,
.reload = rspamd_log_console_reload,
.log = rspamd_log_console_log,
};

#endif

+ 142
- 0
src/libutil/logger_syslog.c View File

@@ -0,0 +1,142 @@
/*-
* Copyright 2020 Vsevolod Stakhov
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "config.h"
#include "logger.h"
#include "libserver/cfg_file.h"
#include "logger_private.h"

#define SYSLOG_LOG_QUARK g_quark_from_static_string ("syslog_logger")

struct rspamd_syslog_logger_priv {
gint log_facility;
};

#ifdef HAVE_SYSLOG_H
#include <syslog.h>

void *
rspamd_log_syslog_init (rspamd_logger_t *logger, struct rspamd_config *cfg,
uid_t uid, gid_t gid, GError **err)
{
struct rspamd_syslog_logger_priv *priv;

priv = g_malloc0 (sizeof (*priv));

priv->log_facility = cfg->log_facility;
openlog ("rspamd", LOG_NDELAY | LOG_PID, priv->log_facility);

return priv;
}

void
rspamd_log_syslog_dtor (rspamd_logger_t *logger, gpointer arg)
{
struct rspamd_syslog_logger_priv *priv = (struct rspamd_syslog_logger_priv *)arg;

closelog ();
g_free (priv);
}
bool
rspamd_log_syslog_log (const gchar *module, const gchar *id,
const gchar *function,
gint level_flags,
const gchar *message,
gsize mlen,
rspamd_logger_t *rspamd_log,
gpointer arg)
{
static const struct {
GLogLevelFlags glib_level;
gint syslog_level;
} levels_match[] = {
{G_LOG_LEVEL_DEBUG, LOG_DEBUG},
{G_LOG_LEVEL_INFO, LOG_INFO},
{G_LOG_LEVEL_WARNING, LOG_WARNING},
{G_LOG_LEVEL_CRITICAL, LOG_ERR}
};
unsigned i;
gint syslog_level;

if (!(level_flags & RSPAMD_LOG_FORCED) && !rspamd_log->enabled) {
return false;
}

/* Detect level */
syslog_level = LOG_DEBUG;

for (i = 0; i < G_N_ELEMENTS (levels_match); i ++) {
if (level_flags & levels_match[i].glib_level) {
syslog_level = levels_match[i].syslog_level;
break;
}
}

syslog (syslog_level, "<%.*s>; %s; %s: %*.s",
LOG_ID, id != NULL ? id : "",
module != NULL ? module : "",
function != NULL ? function : "",
(gint)mlen, message);

return true;
}

#else

void *
rspamd_log_syslog_init (rspamd_logger_t *logger, struct rspamd_config *cfg,
uid_t uid, gid_t gid, GError **err)
{
g_set_error (err, SYSLOG_LOG_QUARK, EINVAL, "syslog support is not compiled in");

return NULL;
}

bool
rspamd_log_syslog_log (const gchar *module, const gchar *id,
const gchar *function,
gint level_flags,
const gchar *message,
gsize mlen,
rspamd_logger_t *rspamd_log,
gpointer arg)
{
return false;
}

void
rspamd_log_syslog_dtor (rspamd_logger_t *logger, gpointer arg)
{
/* Left blank intentionally */
}

#endif

void *
rspamd_log_syslog_reload (rspamd_logger_t *logger, struct rspamd_config *cfg,
gpointer arg, uid_t uid, gid_t gid, GError **err)
{
struct rspamd_syslog_logger_priv *npriv;

npriv = rspamd_log_syslog_init (logger, cfg, uid, gid, err);

if (npriv) {
/* Close old */
rspamd_log_syslog_dtor (logger, arg);
}

return npriv;
}

Loading…
Cancel
Save