From: Jason Ish Date: Tue, 4 Mar 2014 16:43:36 +0000 (-0600) Subject: Add signal based file rotation for: X-Git-Tag: suricata-2.0.2~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e1b97fed70c6389ea22c56a0a8a436117c0a7754;p=thirdparty%2Fsuricata.git Add signal based file rotation for: - alert debug log - fast log - stats log - dns log - drop log - file log - http log - tls log - eve/json log --- diff --git a/src/alert-debuglog.c b/src/alert-debuglog.c index 19f400df6d..d095382b72 100644 --- a/src/alert-debuglog.c +++ b/src/alert-debuglog.c @@ -382,8 +382,8 @@ static TmEcode AlertDebugLogDecoderEvent(ThreadVars *tv, const Packet *p, void * GET_PKT_DATA(p), GET_PKT_LEN(p)); SCMutexLock(&aft->file_ctx->fp_mutex); - (void)MemBufferPrintToFPAsString(aft->buffer, aft->file_ctx->fp); - fflush(aft->file_ctx->fp); + aft->file_ctx->Write((const char *)MEMBUFFER_BUFFER(aft->buffer), + MEMBUFFER_OFFSET(aft->buffer), aft->file_ctx); aft->file_ctx->alerts += p->alerts.cnt; SCMutexUnlock(&aft->file_ctx->fp_mutex); @@ -472,6 +472,7 @@ static OutputCtx *AlertDebugLogInitCtx(ConfNode *conf) if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME) < 0) { goto error; } + OutputRegisterFileRotationFlag(&file_ctx->rotation_flag); OutputCtx *output_ctx = SCMalloc(sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) diff --git a/src/alert-fastlog.c b/src/alert-fastlog.c index 1ca45bd974..05d97d5e5c 100644 --- a/src/alert-fastlog.c +++ b/src/alert-fastlog.c @@ -252,6 +252,7 @@ OutputCtx *AlertFastLogInitCtx(ConfNode *conf) LogFileFreeCtx(logfile_ctx); return NULL; } + OutputRegisterFileRotationFlag(&logfile_ctx->rotation_flag); OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) diff --git a/src/counters.c b/src/counters.c index f17dc8294c..4bea047635 100644 --- a/src/counters.c +++ b/src/counters.c @@ -35,6 +35,7 @@ #include "util-privs.h" #include "util-signal.h" #include "unix-manager.h" +#include "output.h" /** \todo Get the default log directory from some global resource. */ #define SC_PERF_DEFAULT_LOG_FILENAME "stats.log" @@ -167,6 +168,23 @@ static char *SCPerfGetLogFilename(ConfNode *stats) return log_filename; } +/** + * \brief Reopen the log file. + * + * \retval 1 if successful, otherwise 0. + */ +static int SCPerfFileReopen(SCPerfOPIfaceContext *sc_perf_op_ctx) +{ + fclose(sc_perf_op_ctx->fp); + if ((sc_perf_op_ctx->fp = fopen(sc_perf_op_ctx->file, "w+")) == NULL) { + SCLogError(SC_ERR_FOPEN, "Failed to reopen file \"%s\"." + "Stats logging will now be disabled.", + sc_perf_op_ctx->file); + return 0; + } + return 1; +} + /** * \brief Initializes the output interface context * @@ -238,6 +256,10 @@ static void SCPerfInitOPCtx(void) exit(EXIT_FAILURE); } } + else { + /* File opened, register for rotation notification. */ + OutputRegisterFileRotationFlag(&sc_perf_op_ctx->rotation_flag); + } /* init the lock used by SCPerfClubTMInst */ if (SCMutexInit(&sc_perf_op_ctx->pctmi_lock, NULL) != 0) { @@ -631,6 +653,15 @@ static int SCPerfOutputCounterFileIface() return 0; } + if (sc_perf_op_ctx->rotation_flag) { + SCLogDebug("Rotating log file"); + sc_perf_op_ctx->rotation_flag = 0; + if (!SCPerfFileReopen(sc_perf_op_ctx)) { + /* Rotation failed, error already logged. */ + return 0; + } + } + memset(&tval, 0, sizeof(struct timeval)); gettimeofday(&tval, NULL); diff --git a/src/counters.h b/src/counters.h index 0b82042b15..123a34f723 100644 --- a/src/counters.h +++ b/src/counters.h @@ -158,6 +158,10 @@ typedef struct SCPerfOPIfaceContext_ { SCPerfClubTMInst *pctmi; SCMutex pctmi_lock; + + /* Flag set on file rotation notification. */ + int rotation_flag; + } SCPerfOPIfaceContext; /* the initialization functions */ diff --git a/src/log-dnslog.c b/src/log-dnslog.c index 0b8aedc9d9..42f102a63d 100644 --- a/src/log-dnslog.c +++ b/src/log-dnslog.c @@ -95,8 +95,8 @@ static void LogQuery(LogDnsLogThread *aft, char *timebuf, char *srcip, char *dst record, srcip, sp, dstip, dp); SCMutexLock(&hlog->file_ctx->fp_mutex); - (void)MemBufferPrintToFPAsString(aft->buffer, hlog->file_ctx->fp); - fflush(hlog->file_ctx->fp); + hlog->file_ctx->Write((const char *)MEMBUFFER_BUFFER(aft->buffer), + MEMBUFFER_OFFSET(aft->buffer), hlog->file_ctx); SCMutexUnlock(&hlog->file_ctx->fp_mutex); } @@ -155,8 +155,8 @@ static void LogAnswer(LogDnsLogThread *aft, char *timebuf, char *srcip, char *ds srcip, sp, dstip, dp); SCMutexLock(&hlog->file_ctx->fp_mutex); - (void)MemBufferPrintToFPAsString(aft->buffer, hlog->file_ctx->fp); - fflush(hlog->file_ctx->fp); + hlog->file_ctx->Write((const char *)MEMBUFFER_BUFFER(aft->buffer), + MEMBUFFER_OFFSET(aft->buffer), hlog->file_ctx); SCMutexUnlock(&hlog->file_ctx->fp_mutex); } @@ -310,6 +310,7 @@ static OutputCtx *LogDnsLogInitCtx(ConfNode *conf) LogFileFreeCtx(file_ctx); return NULL; } + OutputRegisterFileRotationFlag(&file_ctx->rotation_flag); LogDnsFileCtx *dnslog_ctx = SCMalloc(sizeof(LogDnsFileCtx)); if (unlikely(dnslog_ctx == NULL)) { diff --git a/src/log-droplog.c b/src/log-droplog.c index 549cfb2de5..c8abd3c8ba 100644 --- a/src/log-droplog.c +++ b/src/log-droplog.c @@ -154,6 +154,7 @@ static OutputCtx *LogDropLogInitCtx(ConfNode *conf) LogFileFreeCtx(logfile_ctx); return NULL; } + OutputRegisterFileRotationFlag(&logfile_ctx->rotation_flag); OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) { @@ -186,6 +187,18 @@ static int LogDropLogNetFilter (ThreadVars *tv, const Packet *p, void *data) SCMutexLock(&dlt->file_ctx->fp_mutex); + if (dlt->file_ctx->rotation_flag) { + dlt->file_ctx->rotation_flag = 0; + if (SCConfLogReopen(dlt->file_ctx) != 0) { + /* Rotation failed, error already logged. */ + return TM_ECODE_FAILED; + } + } + + if (dlt->file_ctx == NULL) { + return TM_ECODE_FAILED; + } + char srcip[46] = ""; char dstip[46] = ""; diff --git a/src/log-file.c b/src/log-file.c index e7398fbf13..a2cdb37825 100644 --- a/src/log-file.c +++ b/src/log-file.c @@ -145,6 +145,21 @@ static void LogFileMetaGetUserAgent(FILE *fp, const Packet *p, const File *ff) { static void LogFileWriteJsonRecord(LogFileLogThread *aft, const Packet *p, const File *ff, int ipver) { SCMutexLock(&aft->file_ctx->fp_mutex); + /* As writes are done via the LogFileCtx, check for rotation here. */ + if (aft->file_ctx->rotation_flag) { + aft->file_ctx->rotation_flag = 0; + if (SCConfLogReopen(aft->file_ctx) != 0) { + SCLogWarning(SC_ERR_FOPEN, "Failed to re-open log file. " + "Logging for this module will be disabled."); + } + } + + /* Bail early if no file pointer to write to (in the unlikely + * event file rotation failed. */ + if (aft->file_ctx->fp == NULL) { + return; + } + FILE *fp = aft->file_ctx->fp; char timebuf[64]; AppProto alproto = FlowGetAppProtocol(p->flow); @@ -351,6 +366,7 @@ static OutputCtx *LogFileLogInitCtx(ConfNode *conf) LogFileFreeCtx(logfile_ctx); return NULL; } + OutputRegisterFileRotationFlag(&logfile_ctx->rotation_flag); OutputCtx *output_ctx = SCCalloc(1, sizeof(OutputCtx)); if (unlikely(output_ctx == NULL)) diff --git a/src/log-httplog.c b/src/log-httplog.c index 8ae7d13d75..b6a0f979d7 100644 --- a/src/log-httplog.c +++ b/src/log-httplog.c @@ -504,8 +504,8 @@ static TmEcode LogHttpLogIPWrapper(ThreadVars *tv, void *data, const Packet *p, aft->uri_cnt ++; SCMutexLock(&hlog->file_ctx->fp_mutex); - (void)MemBufferPrintToFPAsString(aft->buffer, hlog->file_ctx->fp); - fflush(hlog->file_ctx->fp); + hlog->file_ctx->Write((const char *)MEMBUFFER_BUFFER(aft->buffer), + MEMBUFFER_OFFSET(aft->buffer), hlog->file_ctx); SCMutexUnlock(&hlog->file_ctx->fp_mutex); end: @@ -600,6 +600,7 @@ OutputCtx *LogHttpLogInitCtx(ConfNode *conf) LogFileFreeCtx(file_ctx); return NULL; } + OutputRegisterFileRotationFlag(&file_ctx->rotation_flag); LogHttpFileCtx *httplog_ctx = SCMalloc(sizeof(LogHttpFileCtx)); if (unlikely(httplog_ctx == NULL)) { diff --git a/src/log-tlslog.c b/src/log-tlslog.c index 64959991b5..18d2d0e61c 100644 --- a/src/log-tlslog.c +++ b/src/log-tlslog.c @@ -438,6 +438,7 @@ static OutputCtx *LogTlsLogInitCtx(ConfNode *conf) if (SCConfLogOpenGeneric(conf, file_ctx, DEFAULT_LOG_FILENAME) < 0) { goto filectx_error; } + OutputRegisterFileRotationFlag(&file_ctx->rotation_flag); LogTlsFileCtx *tlslog_ctx = SCCalloc(1, sizeof(LogTlsFileCtx)); if (unlikely(tlslog_ctx == NULL)) @@ -574,8 +575,8 @@ static int LogTlsLogger(ThreadVars *tv, void *thread_data, const Packet *p) { aft->tls_cnt++; SCMutexLock(&hlog->file_ctx->fp_mutex); - MemBufferPrintToFPAsString(aft->buffer, hlog->file_ctx->fp); - fflush(hlog->file_ctx->fp); + hlog->file_ctx->Write((const char *)MEMBUFFER_BUFFER(aft->buffer), + MEMBUFFER_OFFSET(aft->buffer), hlog->file_ctx); SCMutexUnlock(&hlog->file_ctx->fp_mutex); /* we only log the state once */ diff --git a/src/output-json.c b/src/output-json.c index 5cfdef5f7c..daf6c2577e 100644 --- a/src/output-json.c +++ b/src/output-json.c @@ -303,8 +303,8 @@ int OutputJSONBuffer(json_t *js, LogFileCtx *file_ctx, MemBuffer *buffer) { syslog(alert_syslog_level, "%s", js_s); } else if (json_out == ALERT_FILE) { MemBufferWriteString(buffer, "%s\n", js_s); - (void)MemBufferPrintToFPAsString(buffer, file_ctx->fp); - fflush(file_ctx->fp); + file_ctx->Write((const char *)MEMBUFFER_BUFFER(buffer), + MEMBUFFER_OFFSET(buffer), file_ctx); } SCMutexUnlock(&file_ctx->fp_mutex); free(js_s); @@ -411,6 +411,7 @@ OutputCtx *OutputJsonInitCtx(ConfNode *conf) SCFree(output_ctx); return NULL; } + OutputRegisterFileRotationFlag(&json_ctx->file_ctx->rotation_flag); const char *format_s = ConfNodeLookupChildValue(conf, "format"); if (format_s != NULL) {