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)
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;
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;
#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 *);
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;
+}
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__ */