Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add the ability to redirect log messages to a dedicated file.

  • Loading branch information...
commit 8ac573bc94f5c679fba7373be645b2dcab365a6e 1 parent 76ae2b2
@jedisct1 authored
View
2  configure.ac
@@ -1,5 +1,5 @@
AC_PREREQ([2.65])
-AC_INIT([pincaster], [0.3], [bugs at puretpd dot org])
+AC_INIT([pincaster], [0.4], [bugs at puretpd dot org])
AC_CONFIG_SRCDIR([src/app.c])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE([1.9 dist-bzip2])
View
6 pincaster.conf
@@ -28,6 +28,12 @@ ServerIP 0.0.0.0
ServerPort 4269
+# Log file - You should probably change this for a decent location
+# Comment out to log to stderr
+
+# LogFileName /tmp/pincaster.log
+
+
# Client connection timeout
Timeout 20
View
2  src/Makefile.am
@@ -19,6 +19,8 @@ pincaster_SOURCES = \
app_config.h \
utils.c \
utils.h \
+ log.c \
+ log.h \
cqueue.c \
cqueue.h \
keys.c \
View
25 src/app_config.c
@@ -7,6 +7,7 @@ int parse_config(const char * const file)
{
char *cfg_server_ip = NULL;
char *cfg_server_port = NULL;
+ char *cfg_log_file_name = NULL;
char *cfg_timeout_s = NULL;
char *cfg_nb_workers_s = NULL;
char *cfg_max_queued_replies_s = NULL;
@@ -21,7 +22,8 @@ int parse_config(const char * const file)
ConfigKeywords config_keywords[] = {
{ "ServerIP", &cfg_server_ip },
{ "ServerPort", &cfg_server_port },
- { "Timeout", &cfg_timeout_s },
+ { "LogFileName", &cfg_log_file_name },
+ { "Timeout", &cfg_timeout_s },
{ "Workers", &cfg_nb_workers_s },
{ "MaxQueuedReplies", &cfg_max_queued_replies_s },
{ "DefaultLayerType", &cfg_default_layer_type_s },
@@ -35,6 +37,7 @@ int parse_config(const char * const file)
};
app_context.server_ip = NULL;
app_context.server_port = strdup(DEFAULT_SERVER_PORT);
+ app_context.log_file_name = NULL;
app_context.timeout = DEFAULT_CLIENT_TIMEOUT;
app_context.nb_workers = NB_WORKERS;
app_context.max_queued_replies = MAX_QUEUED_REPLIES;
@@ -65,6 +68,14 @@ int parse_config(const char * const file)
app_context.server_port = cfg_server_port;
}
}
+ if (cfg_log_file_name != NULL) {
+ if (*cfg_log_file_name == 0) {
+ ret = -1;
+ } else {
+ free(app_context.log_file_name);
+ app_context.log_file_name = cfg_log_file_name;
+ }
+ }
if (cfg_timeout_s != NULL) {
app_context.timeout = (int) strtol(cfg_timeout_s, &endptr, 10);
if (endptr == NULL || endptr == cfg_timeout_s ||
@@ -176,8 +187,9 @@ int check_sys_config(void)
if ((fp = fopen("/proc/sys/vm/overcommit_memory", "r")) != NULL) {
if (fgets(tmp, sizeof tmp, fp) != NULL) {
if (atoi(tmp) <= 0) {
- fputs("* Please add vm.overcommit_memory=1 "
- "to /etc/sysctl.conf\n", stderr);
+ logfile_noformat(NULL, LOG_WARNING,
+ "Please add vm.overcommit_memory=1 "
+ "to /etc/sysctl.conf");
ret = -1;
}
}
@@ -186,8 +198,9 @@ int check_sys_config(void)
if ((fp = fopen("/proc/sys/net/ipv4/tcp_tw_reuse", "r")) != NULL) {
if (fgets(tmp, sizeof tmp, fp) != NULL) {
if (atoi(tmp) <= 0) {
- fputs("* Please add net.ipv4.tcp_tw_reuse=1 "
- "to /etc/sysctl.conf\n", stderr);
+ logfile_noformat(NULL, LOG_WARNING,
+ "Please add net.ipv4.tcp_tw_reuse=1 "
+ "to /etc/sysctl.conf");
}
}
fclose(fp);
@@ -202,6 +215,8 @@ void free_config(void)
app_context.server_ip = NULL;
free(app_context.server_port);
app_context.server_port = NULL;
+ free(app_context.log_file_name);
+ app_context.log_file_name = NULL;
free(app_context.db_log.db_log_file_name);
app_context.db_log.db_log_file_name = NULL;
}
View
11 src/common.h
@@ -3,6 +3,14 @@
#define __COMMON_H__ 1
#include <config.h>
+
+#ifndef __GNUC__
+# ifdef __attribute__
+# undef __attribute__
+# endif
+# define __attribute__(a)
+#endif
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -20,6 +28,7 @@
#include <sys/wait.h>
#include <poll.h>
#include <pthread.h>
+#include <syslog.h>
#include "ext/queue.h"
#include "ext/tree.h"
#include "../src/yajl/api/yajl_parse.h"
@@ -36,10 +45,12 @@
#include "key_nodes.h"
#include "utils.h"
#include "db_log.h"
+#include "log.h"
typedef struct AppContext_ {
char *server_ip;
char *server_port;
+ char *log_file_name;
int timeout;
unsigned int nb_workers;
size_t max_queued_replies;
View
15 src/db_log.c
@@ -43,8 +43,8 @@ int open_db_log(void)
#endif
db_log->db_log_fd = open(db_log_file_name, flags, (mode_t) 0600);
if (db_log->db_log_fd == -1) {
- fprintf(stderr, "Can't open [%s]: [%s]\n",
- db_log_file_name, strerror(errno));
+ logfile(NULL, LOG_ERR, "Can't open [%s]: [%s]", db_log_file_name,
+ strerror(errno));
free_db_log();
return -1;
}
@@ -336,18 +336,21 @@ int replay_log(HttpHandlerContext * const context)
BufferedReadContext brc;
if (db_log->db_log_fd == -1 || db_log->db_log_file_name == NULL) {
- puts("No journal");
+ logfile_noformat(context, LOG_INFO, "No journal");
+
return 0;
}
init_buffered_read(&brc, db_log->db_log_fd);
- puts("Replaying journal...");
+ logfile_noformat(context, LOG_INFO, "Replaying journal...");
while ((res = replay_log_record(context, &brc)) == 0) {
counter++;
}
free_buffered_read(&brc);
- printf("%" PRIuMAX " transactions replayed.\n", counter);
+ logfile(context, LOG_INFO, "%" PRIuMAX " transactions replayed.",
+ counter);
if (res < 0) {
- puts("Possibly corrupted journal.");
+ logfile_noformat(context, LOG_ERR, "Possibly corrupted journal.");
+
return -1;
}
return 0;
View
26 src/domain_system.c
@@ -270,7 +270,8 @@ static int rebuild_journal_layer_cb(void *context_, void *entry,
Layer * const layer = entry;
int ret = 0;
assert(layer->name != NULL && *layer->name != 0);
- printf("Dumping layer: [%s] ...\n", layer->name);
+ logfile(context->context, LOG_INFO, "Dumping layer: [%s] ...",
+ layer->name);
struct evbuffer *log_buffer;
if ((log_buffer = evbuffer_new()) == NULL) {
return -1;
@@ -358,7 +359,8 @@ int rewrite_child(HttpHandlerContext * const context)
close(db_log->db_log_fd);
}
nice(BGREWRITEAOF_NICENESS);
- puts("Creating a new journal as a background process...");
+ logfile_noformat(context, LOG_INFO,
+ "Creating a new journal as a background process...");
char *tmp_log_file_name = get_tmp_log_file_name();
if (tmp_log_file_name == NULL) {
return -1;
@@ -374,12 +376,13 @@ int rewrite_child(HttpHandlerContext * const context)
flags |= O_LARGEFILE;
#endif
int db_log_fd = open(tmp_log_file_name, flags, (mode_t) 0600);
- free(tmp_log_file_name);
if (db_log_fd == -1) {
- fprintf(stderr, "Can't create [%s]: [%s]\n", tmp_log_file_name,
- strerror(errno));
+ logfile(context, LOG_ERR, "Can't create [%s]: [%s]", tmp_log_file_name,
+ strerror(errno));
+ free(tmp_log_file_name);
return -1;
}
+ free(tmp_log_file_name);
rebuild_journal(context, db_log_fd);
fsync(db_log_fd);
close(db_log_fd);
@@ -486,7 +489,8 @@ int system_rewrite_after_fork_cb(void)
if (tmp_log_file_name == NULL) {
return -1;
}
- puts("Completing the new journal with recent transactions...");
+ logfile_noformat(NULL, LOG_INFO,
+ "Completing the new journal with recent transactions...");
assert(db_log->offset_before_fork != (off_t) -1);
if (lseek(db_log->db_log_fd, db_log->offset_before_fork,
SEEK_SET) == (off_t) -1) {
@@ -506,7 +510,7 @@ int system_rewrite_after_fork_cb(void)
#endif
int tmp_log_fd = open(tmp_log_file_name, flags, (mode_t) 0600);
if (tmp_log_fd == -1) {
- fprintf(stderr, "Can't reopen [%s]: [%s]\n", tmp_log_file_name,
+ logfile(NULL, LOG_ERR, "Can't reopen [%s]: [%s]", tmp_log_file_name,
strerror(errno));
unlink(tmp_log_file_name);
}
@@ -522,17 +526,19 @@ int system_rewrite_after_fork_cb(void)
printf("Renaming [%s] to [%s]\n", tmp_log_file_name,
db_log->db_log_file_name);
if (rename(tmp_log_file_name, db_log->db_log_file_name) != 0) {
- perror("rename()");
+ logfile(NULL, LOG_ERR, "Unable to rename [%s] to [%s]: [%s]",
+ tmp_log_file_name, db_log->db_log_file_name,
+ strerror(errno));
unlink(tmp_log_file_name);
free(tmp_log_file_name);
return -1;
}
free(tmp_log_file_name);
if (close(db_log->db_log_fd) != 0) {
- perror("Unable to close the previous journal");
+ logfile_error(NULL, "Unable to close the previous journal");
}
db_log->db_log_fd = tmp_log_fd;
- puts("Done - New journal activated");
+ logfile_noformat(NULL, LOG_INFO, "Done - New journal activated");
return 0;
}
View
52 src/http_server.c
@@ -166,11 +166,13 @@ static int worker_do_work(HttpHandlerContext * const context)
static void *worker_thread(void *context_)
{
HttpHandlerContext * const context = context_;
- printf("Worker thread: [%p]\n", (void *) pthread_self());
+ logfile(context, LOG_INFO, "Starting worker thread: [%p]",
+ (void *) pthread_self());
while (worker_do_work(context) == 0);
- printf("Exited worker thread: [%p]\n", (void *) pthread_self());
+ logfile(context, LOG_INFO, "Exited worker thread: [%p]",
+ (void *) pthread_self());
return NULL;
}
@@ -462,6 +464,41 @@ static void expiration_cron(evutil_socket_t fd, short event,
evtimer_add(&context->ev_expiration_cron, &tv);
}
+static int open_log_file(HttpHandlerContext * const context)
+{
+ int flags = O_RDWR | O_CREAT | O_APPEND;
+#ifdef O_EXLOCK
+ flags |= O_EXLOCK;
+#endif
+#ifdef O_NOATIME
+ flags |= O_NOATIME;
+#endif
+#ifdef O_LARGEFILE
+ flags |= O_LARGEFILE;
+#endif
+ assert(context->log_fd == -1);
+ if (app_context.log_file_name == NULL) {
+ return 0;
+ }
+ context->log_fd = open(context->log_file_name, flags, (mode_t) 0600);
+ if (context->log_fd == -1) {
+ logfile(NULL, LOG_ERR, "Can't open [%s]: [%s]", context->log_file_name,
+ strerror(errno));
+ return -1;
+ }
+ return 0;
+}
+
+static int close_log_file(HttpHandlerContext * const context)
+{
+ if (context->log_fd != -1) {
+ fsync(context->log_fd);
+ close(context->log_fd);
+ context->log_fd = -1;
+ }
+ return 0;
+}
+
int http_server(void)
{
HttpHandlerContext http_handler_context = {
@@ -473,11 +510,19 @@ int http_server(void)
.cqueue = NULL,
.publisher_bev = NULL,
.consumer_bev = NULL,
- .nb_layers = (size_t) 0U
+ .nb_layers = (size_t) 0U,
+ .log_file_name = NULL,
+ .log_fd = -1
};
if (time(&http_handler_context.now) == (time_t) -1) {
return -1;
}
+ http_handler_context.log_file_name = app_context.log_file_name;
+ if (open_log_file(&http_handler_context) != 0) {
+ return -1;
+ }
+ logfile_noformat(&http_handler_context, LOG_INFO,
+ PACKAGE_STRING " started.");
struct evhttp *event_http;
struct bufferevent *bev_pair[2];
set_signals();
@@ -565,6 +610,7 @@ int http_server(void)
free_slab(&http_handler_context.layers_slab, free_layer_slab_entry_cb);
free_slab(&http_handler_context.expirables_slab,
free_expirables_slab_entry_cb);
+ close_log_file(&http_handler_context);
return 0;
}
View
2  src/http_server.h
@@ -279,6 +279,8 @@ typedef struct HttpHandlerContext_ {
struct event ev_expiration_cron;
Slab expirables_slab;
time_t now;
+ char *log_file_name;
+ int log_fd;
} HttpHandlerContext;
typedef int (*DomainHandler)(struct evhttp_request * const req,
View
66 src/log.c
@@ -0,0 +1,66 @@
+
+#include "common.h"
+#include "http_server.h"
+#include "log.h"
+
+int logfile(struct HttpHandlerContext_ * const context,
+ const int crit, const char * const format, ...)
+{
+ const char *urgency;
+ va_list va;
+ char line[MAX_LOG_LINE];
+
+#ifndef DEBUG
+ if (crit == LOG_DEBUG) {
+ return 0;
+ }
+#endif
+ switch (crit) {
+ case LOG_INFO:
+ urgency = "[INFO] ";
+ break;
+ case LOG_WARNING:
+ urgency = "[WARNING] ";
+ break;
+ case LOG_ERR:
+ urgency = "[ERROR] ";
+ break;
+ case LOG_NOTICE:
+ urgency = "[NOTICE] ";
+ break;
+ case LOG_DEBUG:
+ urgency = "[DEBUG] ";
+ break;
+ default:
+ urgency = "";
+ }
+ va_start(va, format);
+ vsnprintf(line, sizeof line, format, va);
+ va_end(va);
+
+ int log_fd;
+ if (context == NULL || context->log_fd == -1) {
+ log_fd = STDERR_FILENO;
+ } else {
+ log_fd = context->log_fd;
+ }
+ safe_write(log_fd, urgency, strlen(urgency), LOG_WRITE_TIMEOUT);
+ safe_write(log_fd, line, strlen(line), LOG_WRITE_TIMEOUT);
+ safe_write(log_fd, "\n", (size_t) 1U, LOG_WRITE_TIMEOUT);
+
+ return 0;
+}
+
+int logfile_noformat(struct HttpHandlerContext_ * const context,
+ const int crit, const char * const msg)
+{
+ return logfile(context, crit, "%s", msg);
+}
+
+int logfile_error(struct HttpHandlerContext_ * const context,
+ const char * const msg)
+{
+ const char *const err_msg = strerror(errno);
+
+ return logfile(context, LOG_ERR, "%s: %s", msg, err_msg);
+}
View
28 src/log.h
@@ -0,0 +1,28 @@
+
+#ifndef __LOG_H__
+#define __LOG_H__ 1
+
+#ifndef MAX_LOG_LINE
+# define MAX_LOG_LINE 1024U
+#endif
+#ifndef LOG_WRITE_TIMEOUT
+# define LOG_WRITE_TIMEOUT 10
+#endif
+
+#ifdef DEBUG
+# define XDEBUG(X) do { X } while(0)
+#else
+# define XDEBUG(X)
+#endif
+
+int logfile(struct HttpHandlerContext_ * const context,
+ const int crit, const char * const format, ...)
+__attribute__ ((format(printf, 3, 4)));
+
+int logfile_noformat(struct HttpHandlerContext_ * const context,
+ const int crit, const char * const msg);
+
+int logfile_error(struct HttpHandlerContext_ * const context,
+ const char * const msg);
+
+#endif
View
10 src/slipmap.c
@@ -457,11 +457,11 @@ int dump_slip_map(SlipMap * const * const slip_map_pnt)
printf("(empty, free: [%zu])\n", slot_free);
fflush(stdout);
} else {
- if (write(1, "[", sizeof "[" - (size_t) 1U) <= 0 ||
- write(1, scanned_key, scanned_key_len) <= 0 ||
- write(1, "] => [", sizeof "] => [" - (size_t) 1U) <= 0 ||
- write(1, scanned_value, scanned_value_len) <= 0 ||
- write(1, "] ", sizeof "] " - (size_t) 1U) <= 0) {
+ if (write(STDOUT_FILENO, "[", sizeof "[" - (size_t) 1U) <= 0 ||
+ write(STDOUT_FILENO, scanned_key, scanned_key_len) <= 0 ||
+ write(STDOUT_FILENO, "] => [", sizeof "] => [" - (size_t) 1U) <= 0 ||
+ write(STDOUT_FILENO, scanned_value, scanned_value_len) <= 0 ||
+ write(STDOUT_FILENO, "] ", sizeof "] " - (size_t) 1U) <= 0) {
return 0;
}
printf("(free: [%zu])\n", slot_free);
Please sign in to comment.
Something went wrong with that request. Please try again.