output-json: rotate log file based on time

Rotate log file based on time. Support both rotating based on a timer (XXs,
XXm, XXd, XXw) and rotating based on a absolute time, like each minute,
hour or day.
pull/2655/head
Mats Klepsland 8 years ago committed by Victor Julien
parent db6c80fd8e
commit 47a5b493d7

@ -136,6 +136,14 @@ static int SCLogFileWrite(const char *buffer, int buffer_len, LogFileCtx *log_ct
SCConfLogReopen(log_ctx);
}
if (log_ctx->flags & LOGFILE_ROTATE_INTERVAL) {
time_t now = time(NULL);
if (now >= log_ctx->rotate_time) {
SCConfLogReopen(log_ctx);
log_ctx->rotate_time = now + log_ctx->rotate_interval;
}
}
int ret = 0;
if (log_ctx->fp == NULL && log_ctx->is_sock)
@ -290,6 +298,36 @@ SCConfLogOpenGeneric(ConfNode *conf,
snprintf(log_path, PATH_MAX, "%s/%s", log_dir, filename);
}
/* Rotate log file based on time */
const char *rotate_int = ConfNodeLookupChildValue(conf, "rotate-interval");
if (rotate_int != NULL) {
time_t now = time(NULL);
log_ctx->flags |= LOGFILE_ROTATE_INTERVAL;
/* Use a specific time */
if (strcmp(rotate_int, "minute") == 0) {
log_ctx->rotate_time = now + SCGetSecondsUntil(rotate_int, now);
log_ctx->rotate_interval = 60;
} else if (strcmp(rotate_int, "hour") == 0) {
log_ctx->rotate_time = now + SCGetSecondsUntil(rotate_int, now);
log_ctx->rotate_interval = 3600;
} else if (strcmp(rotate_int, "day") == 0) {
log_ctx->rotate_time = now + SCGetSecondsUntil(rotate_int, now);
log_ctx->rotate_interval = 86400;
}
/* Use a timer */
else {
log_ctx->rotate_interval = SCParseTimeSizeString(rotate_int);
if (log_ctx->rotate_interval == 0) {
SCLogError(SC_ERR_INVALID_NUMERIC_VALUE,
"invalid rotate-interval value");
exit(EXIT_FAILURE);
}
log_ctx->rotate_time = now + log_ctx->rotate_interval;
}
}
filetype = ConfNodeLookupChildValue(conf, "filetype");
if (filetype == NULL)
filetype = DEFAULT_LOG_FILETYPE;

@ -102,6 +102,13 @@ typedef struct LogFileCtx_ {
int sock_type;
uint64_t reconn_timer;
/** The next time to rotate log file, if rotate interval is
specified. */
time_t rotate_time;
/** The interval to rotate the log file */
uint64_t rotate_interval;
/**< Used by some alert loggers like the unified ones that append
* the date onto the end of files. */
char *prefix;
@ -133,8 +140,9 @@ typedef struct LogFileCtx_ {
#define LOGFILE_RECONN_MIN_TIME 500
/* flags for LogFileCtx */
#define LOGFILE_HEADER_WRITTEN 0x01
#define LOGFILE_ALERTS_PRINTED 0x02
#define LOGFILE_HEADER_WRITTEN 0x01
#define LOGFILE_ALERTS_PRINTED 0x02
#define LOGFILE_ROTATE_INTERVAL 0x04
LogFileCtx *LogFileNewCtx(void);
int LogFileFreeCtx(LogFileCtx *);

@ -512,3 +512,80 @@ int SCTimeToStringPattern (time_t epoch, const char *pattern, char *str, size_t
return 0;
}
/**
* \brief Parse string containing time size (1m, 1h, etc).
*
* \param str String to parse.
*
* \retval size on success.
* \retval 0 on failure.
*/
uint64_t SCParseTimeSizeString (const char *str)
{
uint64_t size = 0;
uint64_t modifier = 1;
char last = str[strlen(str)-1];
switch (last)
{
case '0' ... '9':
break;
/* seconds */
case 's':
break;
/* minutes */
case 'm':
modifier = 60;
break;
/* hours */
case 'h':
modifier = 60 * 60;
break;
/* days */
case 'd':
modifier = 60 * 60 * 24;
break;
/* weeks */
case 'w':
modifier = 60 * 60 * 24 * 7;
break;
/* invalid */
default:
return 0;
}
errno = 0;
size = strtoumax(str, NULL, 10);
if (errno) {
return 0;
}
return (size * modifier);
}
/**
* \brief Get seconds until a time unit changes.
*
* \param str String containing time type (minute, hour, etc).
* \param epoch Epoch time.
*
* \retval seconds.
*/
uint64_t SCGetSecondsUntil (const char *str, time_t epoch)
{
uint64_t seconds = 0;
struct tm tm;
memset(&tm, 0, sizeof(tm));
struct tm *tp = (struct tm *)SCLocalTime(epoch, &tm);
if (strcmp(str, "minute") == 0)
seconds = 60 - tp->tm_sec;
else if (strcmp(str, "hour") == 0)
seconds = (60 * (60 - tp->tm_min)) + (60 - tp->tm_sec);
else if (strcmp(str, "day") == 0)
seconds = (3600 * (24 - tp->tm_hour)) + (60 * (60 - tp->tm_min)) +
(60 - tp->tm_sec);
return seconds;
}

@ -60,6 +60,8 @@ int SCStringPatternToTime(char *string, char **patterns,
int num_patterns, struct tm *time);
int SCTimeToStringPattern (time_t epoch, const char *pattern, char *str,
size_t size);
uint64_t SCParseTimeSizeString (const char *str);
uint64_t SCGetSecondsUntil (const char *str, time_t epoch);
#endif /* __UTIL_TIME_H__ */

Loading…
Cancel
Save