From 89d62818266b6b7f6e0f99542b0fb795f0768107 Mon Sep 17 00:00:00 2001 From: Kozlov Dmitry Date: Tue, 27 Dec 2011 12:45:22 +0400 Subject: implemented logging to system logger --- accel-pppd/accel-ppp.conf | 3 +- accel-pppd/accel-ppp.conf.5 | 4 + accel-pppd/logs/CMakeLists.txt | 38 ++++++-- accel-pppd/logs/log_syslog.c | 194 +++++++++++++++++++++++++++++++++++++++++ accel-pppd/triton/triton.c | 1 + 5 files changed, 233 insertions(+), 7 deletions(-) create mode 100644 accel-pppd/logs/log_syslog.c (limited to 'accel-pppd') diff --git a/accel-pppd/accel-ppp.conf b/accel-pppd/accel-ppp.conf index b8cf8a1..7219ba3 100644 --- a/accel-pppd/accel-ppp.conf +++ b/accel-pppd/accel-ppp.conf @@ -1,6 +1,7 @@ [modules] #path=/usr/local/lib/accel-ppp log_file +#log_syslog #log_tcp #log_pgsql pptp @@ -108,6 +109,7 @@ log-file=/var/log/accel-ppp/accel-ppp.log log-emerg=/var/log/accel-ppp/emerg.log log-fail-file=/var/log/accel-ppp/auth-fail.log #log-debug=/dev/stdout +#syslog=accel-pppd,daemon #log-tcp=127.0.0.1:3000 copy=1 #color=1 @@ -115,7 +117,6 @@ copy=1 #per-session-dir=per_session #per-session=1 level=3 -#log-tcp=127.0.0.1:3000 [log-pgsql] conninfo=user=log diff --git a/accel-pppd/accel-ppp.conf.5 b/accel-pppd/accel-ppp.conf.5 index 4e15afb..955f167 100644 --- a/accel-pppd/accel-ppp.conf.5 +++ b/accel-pppd/accel-ppp.conf.5 @@ -363,6 +363,10 @@ Path to file to write authentication failed session log. .BI "log-tcp=" x.x.x.x:port Send logs to specified host. .TP +.BI "syslog=" ident[,facility] +Send logs to system logger. +Facility may be: daemon, local0-local7 or numeric value. +.TP .BI "copy=" n If this options is given and greater then zero logging engine will duplicate session log in general log. (Useful when per-session/per-user logs are not used) diff --git a/accel-pppd/logs/CMakeLists.txt b/accel-pppd/logs/CMakeLists.txt index ce909b6..b10163f 100644 --- a/accel-pppd/logs/CMakeLists.txt +++ b/accel-pppd/logs/CMakeLists.txt @@ -1,11 +1,37 @@ -ADD_LIBRARY(log_file SHARED log_file.c) -TARGET_LINK_LIBRARIES(log_file rt) +IF(NOT DEFINED LOG_FILE) + SET(LOG_FILE TRUE) +ENDIF(NOT DEFINED LOG_FILE) -ADD_LIBRARY(log_tcp SHARED log_tcp.c) +IF(NOT DEFINED LOG_TCP) + SET(LOG_TCP TRUE) +ENDIF(NOT DEFINED LOG_TCP) -INSTALL(TARGETS log_file log_tcp - LIBRARY DESTINATION lib/accel-ppp -) +IF(NOT DEFINED LOG_SYSLOG) + SET(LOG_SYSLOG TRUE) +ENDIF(NOT DEFINED LOG_SYSLOG) + + +IF(LOG_FILE) + ADD_LIBRARY(log_file SHARED log_file.c) + TARGET_LINK_LIBRARIES(log_file rt) + INSTALL(TARGETS log_file + LIBRARY DESTINATION lib/accel-ppp + ) +ENDIF(LOG_FILE) + +IF(LOG_TCP) + ADD_LIBRARY(log_tcp SHARED log_tcp.c) + INSTALL(TARGETS log_tcp + LIBRARY DESTINATION lib/accel-ppp + ) +ENDIF(LOG_TCP) + +IF(LOG_SYSLOG) + ADD_LIBRARY(log_syslog SHARED log_syslog.c) + INSTALL(TARGETS log_syslog + LIBRARY DESTINATION lib/accel-ppp + ) +ENDIF(LOG_SYSLOG) IF(LOG_PGSQL) ADD_LIBRARY(log_pgsql SHARED log_pgsql.c) diff --git a/accel-pppd/logs/log_syslog.c b/accel-pppd/logs/log_syslog.c new file mode 100644 index 0000000..7dfa260 --- /dev/null +++ b/accel-pppd/logs/log_syslog.c @@ -0,0 +1,194 @@ +#include +#include +#include + +#include + +#include "triton.h" +#include "spinlock.h" +#include "log.h" +#include "list.h" +#include "events.h" +#include "ppp.h" + +#include "memdebug.h" + +static int conf_queue_max = 1000; + +static void syslog_close(struct triton_context_t *ctx); + +static struct triton_context_t syslog_ctx = { + .close = syslog_close, + .before_switch = log_switch, +}; + +static LIST_HEAD(msg_queue); +static int queue_size; +static int sleeping = 1; +static spinlock_t queue_lock = SPINLOCK_INITIALIZER; +static char *log_buf; +static int need_close; +static char *ident; +static int prio_map[] = {LOG_INFO, LOG_ERR, LOG_WARNING, LOG_INFO, LOG_INFO, LOG_DEBUG}; + +static void unpack_msg(struct log_msg_t *msg) +{ + struct log_chunk_t *chunk; + int pos; + + strcpy(log_buf, msg->hdr->msg); + pos = strlen(log_buf); + + list_for_each_entry(chunk, msg->chunks, entry) { + memcpy(log_buf + pos, chunk->msg, chunk->len); + pos += chunk->len; + } + + if (pos > 1) + log_buf[pos - 1] = 0; + else + log_buf[0] = 0; +} + +static void set_hdr(struct log_msg_t *msg, struct ppp_t *ppp) +{ + if (ppp) + sprintf(msg->hdr->msg, "%s:%s: ", ppp->ifname, ppp->username ? ppp->username : ""); + else + msg->hdr->msg[0] = 0; +} + +static void do_syslog(void) +{ + struct log_msg_t *msg; + + while (1) { + spin_lock(&queue_lock); + if (list_empty(&msg_queue)) { + sleeping = 1; + spin_unlock(&queue_lock); + if (need_close) + triton_context_unregister(&syslog_ctx); + return; + } + + msg = list_entry(msg_queue.next, typeof(*msg), entry); + list_del(&msg->entry); + --queue_size; + spin_unlock(&queue_lock); + + unpack_msg(msg); + syslog(prio_map[msg->level], "%s", log_buf); + log_free_msg(msg); + } +} + +static void queue_log(struct log_msg_t *msg) +{ + int r = 0, f = 0; + spin_lock(&queue_lock); + if (queue_size < conf_queue_max) { + list_add_tail(&msg->entry, &msg_queue); + ++queue_size; + r = sleeping; + sleeping = 0; + } else + f = 1; + spin_unlock(&queue_lock); + + if (r) + triton_context_call(&syslog_ctx, (void (*)(void*))do_syslog, NULL); + else if (f) + log_free_msg(msg); +} + + +static void general_log(struct log_target_t *t, struct log_msg_t *msg, struct ppp_t *ppp) +{ + set_hdr(msg, ppp); + + if (syslog_ctx.tpd) + queue_log(msg); + else { + unpack_msg(msg); + syslog(prio_map[msg->level], "%s", log_buf); + log_free_msg(msg); + } +} + +static void syslog_close(struct triton_context_t *ctx) +{ + spin_lock(&queue_lock); + if (sleeping) { + triton_context_unregister(&syslog_ctx); + } else + need_close = 1; + spin_unlock(&queue_lock); +} + +static struct log_target_t target = { + .log = general_log, +}; + +static void parse_opt(const char *opt, char **ident, int *facility) +{ + char *str = _strdup(opt); + char *ptr, *endptr; + int n; + const char *facility_name[] = {"daemon", "local0", "local1", "local2", "local3", "local4", "local5", "local6", "local7"}; + const int facility_num[] = {LOG_DAEMON, LOG_LOCAL0, LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4, LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7}; + + ptr = strchr(str, ','); + if (ptr) { + *ptr = 0; + n = strtol(ptr + 1, &endptr, 10); + if (*endptr) { + for (n = 0; n < sizeof(facility_name); n++) { + if (!strcasecmp(ptr + 1, facility_name[n])) + break; + } + if (n == sizeof(facility_name)) + log_emerg("log_syslog: unknown facility name '%s'\n", ptr + 1); + else + *facility = facility_num[n]; + } else + *facility = n; + } + + *ident = str; +} + +static void load_config() +{ + const char *opt; + int facility = LOG_DAEMON; + + if (ident) { + closelog(); + _free(ident); + } + + opt = conf_get_opt("log", "syslog"); + if (opt) + parse_opt(opt, &ident, &facility); + else + ident = _strdup("accel-pppd"); + + openlog(ident, 0, facility); +} + +static void init(void) +{ + log_buf = malloc(LOG_MAX_SIZE + 1); + + load_config(); + + triton_context_register(&syslog_ctx, NULL); + triton_context_wakeup(&syslog_ctx); + + log_register_target(&target); + + triton_event_register_handler(EV_CONFIG_RELOAD, (triton_event_func)load_config); +} + +DEFINE_INIT(1, init); diff --git a/accel-pppd/triton/triton.c b/accel-pppd/triton/triton.c index 97c277a..4e3e75a 100644 --- a/accel-pppd/triton/triton.c +++ b/accel-pppd/triton/triton.c @@ -171,6 +171,7 @@ cont: if (thread->ctx->need_free) { log_debug2("- context %p removed\n", thread->ctx); + thread->ctx->ud->tpd = NULL; mempool_free(thread->ctx); } -- cgit v1.2.3