summaryrefslogtreecommitdiffstats
path: root/src/libserver/logger/logger_syslog.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libserver/logger/logger_syslog.c')
-rw-r--r--src/libserver/logger/logger_syslog.c143
1 files changed, 143 insertions, 0 deletions
diff --git a/src/libserver/logger/logger_syslog.c b/src/libserver/logger/logger_syslog.c
new file mode 100644
index 0000000..3c4f7f7
--- /dev/null
+++ b/src/libserver/logger/logger_syslog.c
@@ -0,0 +1,143 @@
+/*-
+ * 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;
+
+ if (!cfg) {
+ g_set_error(err, SYSLOG_LOG_QUARK, EINVAL,
+ "no log config specified");
+ return NULL;
+ }
+
+ 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",
+ RSPAMD_LOG_ID_LEN, 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;
+}