--- config.c | 8 ++++++++ logrotate.8 | 8 ++++++++ logrotate.c | 49 +++++++++++++++++++++++++++++++++++++------------ logrotate.h | 1 + 4 files changed, 54 insertions(+), 12 deletions(-) Index: logrotate-3.7.1/logrotate.h =================================================================== --- logrotate-3.7.1.orig/logrotate.h +++ logrotate-3.7.1/logrotate.h @@ -16,6 +16,7 @@ #define LOG_FLAG_SHAREDSCRIPTS (1 << 7) #define LOG_FLAG_COPY (1 << 8) #define LOG_FLAG_DATEEXT (1 << 9) +#define LOG_FLAG_TIMEEXT (1 << 10) #define NO_FORCE_ROTATE 0 #define FORCE_ROTATE 1 Index: logrotate-3.7.1/config.c =================================================================== --- logrotate-3.7.1.orig/config.c +++ logrotate-3.7.1/config.c @@ -521,6 +521,14 @@ static int readConfigFile(const char * c newlog->flags &= ~LOG_FLAG_DATEEXT; *endtag = oldchar, start = endtag; + } else if (!strcmp(start, "timeext")) { + newlog->flags |= (LOG_FLAG_TIMEEXT); + + *endtag = oldchar, start = endtag; + } else if (!strcmp(start, "notimeext")) { + newlog->flags &= ~LOG_FLAG_TIMEEXT; + + *endtag = oldchar, start = endtag; } else if (!strcmp(start, "noolddir")) { newlog->oldDir = NULL; Index: logrotate-3.7.1/logrotate.8 =================================================================== --- logrotate-3.7.1.orig/logrotate.8 +++ logrotate-3.7.1/logrotate.8 @@ -216,6 +216,14 @@ Archive old versions of log files adding instead of simply adding a number. .TP +\fBtimeext\fR +Archive old versions of log files adding a timestamp extension like +YYYYMMDDThhmmssZ instead of simply adding a number. +The timestamp conforms to International Standard ISO 8601. +20060307T114252Z -> 2006/03/07 11:42:52 Zulu (UTC) + + +.TP \fBdelaycompress\fR Postpone compression of the previous log file to the next rotation cycle. This only has effect when used in combination with \fBcompress\fR. Index: logrotate-3.7.1/logrotate.c =================================================================== --- logrotate-3.7.1.orig/logrotate.c +++ logrotate-3.7.1/logrotate.c @@ -542,7 +542,7 @@ int rotateSingleLog(logInfo * log, int l alloc_size = strlen(dirName) + strlen(baseName) + strlen(log->files[logNum]) + strlen(fileext) + - strlen(compext) + 18; + strlen(compext) + 18 + 8; oldName = alloca(alloc_size); newName = alloca(alloc_size); @@ -564,13 +564,17 @@ int rotateSingleLog(logInfo * log, int l /* First compress the previous log when necessary */ if (log->flags & LOG_FLAG_COMPRESS && log->flags & LOG_FLAG_DELAYCOMPRESS) { - if (log->flags & LOG_FLAG_DATEEXT) { + if (log->flags & LOG_FLAG_DATEEXT || + log->flags & LOG_FLAG_TIMEEXT) { /* glob for uncompressed files with our pattern */ glob_pattern = malloc(strlen(dirName) + strlen(baseName) - + strlen(fileext) + 44 ); + + strlen(fileext) + 44 + 32); sprintf(glob_pattern, - "%s/%s-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%s", - dirName, baseName, fileext); + "%s/%s%s%s", + dirName, baseName, log->flags & LOG_FLAG_TIMEEXT ? + "-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]T[0-9][0-9][0-9][0-9][0-9][0-9]Z" : + "-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]", + fileext); rc = glob(glob_pattern, 0, globerr, &globResult); if (!rc && globResult.gl_pathc > 0) { for (i = 0; i < globResult.gl_pathc && !hasErrors; i++) { @@ -605,16 +609,20 @@ int rotateSingleLog(logInfo * log, int l } firstRotated = alloca(strlen(dirName) + strlen(baseName) + - strlen(fileext) + strlen(compext) + 30); + strlen(fileext) + strlen(compext) + 30 + 8); - if(log->flags & LOG_FLAG_DATEEXT) { + if(log->flags & LOG_FLAG_DATEEXT || + log->flags & LOG_FLAG_TIMEEXT) { /* glob for compressed files with our pattern * and compress ext */ glob_pattern = malloc(strlen(dirName)+strlen(baseName) - +strlen(fileext)+strlen(compext)+44); + +strlen(fileext)+strlen(compext)+44+32); sprintf(glob_pattern, - "%s/%s-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%s%s", - dirName, baseName, fileext, compext); + "%s/%s%s%s%s", + dirName, baseName, log->flags & LOG_FLAG_TIMEEXT ? + "-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]T[0-9][0-9][0-9][0-9][0-9][0-9]Z" : + "-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]", + fileext, compext); rc = glob(glob_pattern, 0, globerr, &globResult); if (!rc) { /* search for files to drop, if we find one remember it, @@ -654,9 +662,17 @@ int rotateSingleLog(logInfo * log, int l disposeName = NULL; } /* firstRotated is most recently created/compressed rotated log */ + if(log->flags & LOG_FLAG_TIMEEXT) + sprintf(firstRotated, "%s/%s-%04d%02d%02dT%02d%02d%02dZ%s%s", + dirName, baseName, now.tm_year+1900, + now.tm_mon+1, now.tm_mday, + now.tm_hour, now.tm_min, now.tm_sec, + fileext, compext); + else sprintf(firstRotated, "%s/%s-%04d%02d%02d%s%s", dirName, baseName, now.tm_year+1900, now.tm_mon+1, now.tm_mday, fileext, compext); + globfree(&globResult); free(glob_pattern); } else { @@ -743,13 +759,22 @@ int rotateSingleLog(logInfo * log, int l finalName = oldName; - if(log->flags & LOG_FLAG_DATEEXT) { + if(log->flags & LOG_FLAG_DATEEXT || + log->flags & LOG_FLAG_TIMEEXT) { char * destFile = alloca(strlen(dirName) + strlen(baseName) + - strlen(fileext) + strlen(compext) + 30); + strlen(fileext) + strlen(compext) + 30 + 8); struct stat fst_buf; + if(log->flags & LOG_FLAG_TIMEEXT) + sprintf(finalName, "%s/%s-%04d%02d%02dT%02d%02d%02dZ%s", + dirName, baseName, now.tm_year+1900, + now.tm_mon+1, now.tm_mday, + now.tm_hour, now.tm_min, now.tm_sec, + fileext); + else sprintf(finalName, "%s/%s-%04d%02d%02d%s", dirName, baseName, now.tm_year+1900, now.tm_mon+1, now.tm_mday, fileext); + sprintf(destFile, "%s%s", finalName, compext); if(!stat(destFile,&fst_buf)) { message (MESS_DEBUG, "destination %s already exists, skipping rotation\n", firstRotated);