summaryrefslogtreecommitdiff
path: root/accel-pppd
diff options
context:
space:
mode:
authorKozlov Dmitry <xeb@mail.ru>2011-12-27 12:45:22 +0400
committerKozlov Dmitry <xeb@mail.ru>2011-12-27 12:45:22 +0400
commit89d62818266b6b7f6e0f99542b0fb795f0768107 (patch)
treee34c4af7f822642af63eea163abc1fdb64617511 /accel-pppd
parentd9252bc63289ec0b431e95a0c0814397421651bf (diff)
downloadaccel-ppp-89d62818266b6b7f6e0f99542b0fb795f0768107.tar.gz
accel-ppp-89d62818266b6b7f6e0f99542b0fb795f0768107.zip
implemented logging to system logger
Diffstat (limited to 'accel-pppd')
-rw-r--r--accel-pppd/accel-ppp.conf3
-rw-r--r--accel-pppd/accel-ppp.conf.54
-rw-r--r--accel-pppd/logs/CMakeLists.txt38
-rw-r--r--accel-pppd/logs/log_syslog.c194
-rw-r--r--accel-pppd/triton/triton.c1
5 files changed, 233 insertions, 7 deletions
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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <syslog.h>
+
+#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);
}