[squid-dev] [PATCH] support rotate=N option on access_log

Amos Jeffries squid3 at treenet.co.nz
Mon Dec 29 12:25:15 UTC 2014


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

This adds a rotate=N option to access_log directive to set per-log
what the retained log count will be. At present it is only used by the
stdio: logging module, which is also the only one to use
logfile_rotate directive.

If this option is absent (as will be the common case) the log rotation
defaults to using the value of logfile_rotate directive.

Also, add missing dump output of other access_log options if they
differ from the default.

The use-cases for this are:

1) Unix fifo logging requires all the stdio: module operations except
that the normal rotate/rename operation is NOT performed on the fifo
socket. It makes more sense to add this option whih can also meet ase
#2 than to create a whole new module just for fifo.

2) managing only some access_log files with a third-party log manager.
Those specific logs need rotate=0, but the Squid managed logs may
require non-0 values.

Amos
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (MingW32)

iQEcBAEBAgAGBQJUoUgqAAoJELJo5wb/XPRjJMAH+wTIHGx0L0QGFLzKf/CMUdtm
k2/qFN08Pr7tGvfEaKWMhYx7NqUrAULwWyWyjV18IqTM51zl9ANkoPRvgDzTCTOi
/krb5EPv/q7KfHGkBWh/asJ8echxvL5Xs7ub2vYXN8MQpkQteL1wWIVd6aJgJwJb
Uo0GxRgrDl8T59CcCbEDsf9JKzTfeSVAabxjvv01iPVRhXcBQ7WgujoInDBvboD2
ufNDsFBSMoLD4qLrFoE62X+JwpyYteniPKYTzCG08cdVTHCbdEx9xhRskACvaUot
Q/CuxAtV23jnmtWMT/M9rBjzDFcwFJc0MXzbADa/Z48O2ItVagZuoZ6KkWczNDg=
=8Lvv
-----END PGP SIGNATURE-----
-------------- next part --------------
=== modified file 'src/adaptation/icap/icap_log.cc'
--- src/adaptation/icap/icap_log.cc	2014-12-20 12:12:02 +0000
+++ src/adaptation/icap/icap_log.cc	2014-12-29 02:37:06 +0000
@@ -35,37 +35,37 @@
 }
 
 void
 icapLogClose()
 {
     CustomLog *log;
 
     for (log = Config.Log.icaplogs; log; log = log->next) {
         if (log->logfile) {
             logfileClose(log->logfile);
             log->logfile = NULL;
         }
     }
 }
 
 void
 icapLogRotate()
 {
     for (CustomLog* log = Config.Log.icaplogs; log; log = log->next) {
         if (log->logfile) {
-            logfileRotate(log->logfile);
+            logfileRotate(log->logfile, Config.Log.rotateNumber);
         }
     }
 }
 
 void icapLogLog(AccessLogEntry::Pointer &al)
 {
     if (IcapLogfileStatus == LOG_ENABLE) {
         ACLFilledChecklist checklist(NULL, al->adapted_request, NULL);
         if (al->reply) {
             checklist.reply = al->reply;
             HTTPMSGLOCK(checklist.reply);
         }
         accessLogLogTo(Config.Log.icaplogs, al, &checklist);
     }
 }
 

=== modified file 'src/cache_cf.cc'
--- src/cache_cf.cc	2014-12-20 12:12:02 +0000
+++ src/cache_cf.cc	2014-12-29 05:46:09 +0000
@@ -4079,63 +4079,66 @@
 
     /* determine configuration style */
 
     const char *filename = ConfigParser::NextToken();
     if (!filename) {
         self_destruct();
         return;
     }
 
     if (strcmp(filename, "none") == 0) {
         cl->type = Log::Format::CLF_NONE;
         aclParseAclList(LegacyParser, &cl->aclList, filename);
         while (*logs)
             logs = &(*logs)->next;
         *logs = cl;
         return;
     }
 
     cl->filename = xstrdup(filename);
     cl->type = Log::Format::CLF_UNKNOWN;
+    cl->rotateCount = -1; // default: use global logfile_rotate setting.
 
     const char *token = ConfigParser::PeekAtToken();
     if (!token) { // style #1
         // no options to deal with
     } else if (!strchr(token, '=')) { // style #3
         // if logformat name is recognized,
         // pop the previewed token; Else it must be an ACL name
         if (setLogformat(cl, token, false))
             (void)ConfigParser::NextToken();
     } else { // style #4
         do {
             if (strncasecmp(token, "on-error=", 9) == 0) {
                 if (strncasecmp(token+9, "die", 3) == 0) {
                     cl->fatal = true;
                 } else if (strncasecmp(token+9, "drop", 4) == 0) {
                     cl->fatal = false;
                 } else {
                     debugs(3, DBG_CRITICAL, "Unknown value for on-error '" <<
                            token << "' expected 'drop' or 'die'");
                     self_destruct();
                 }
             } else if (strncasecmp(token, "buffer-size=", 12) == 0) {
                 parseBytesOptionValue(&cl->bufferSize, B_BYTES_STR, token+12);
+            } else if (strncasecmp(token, "rotate=", 7) == 0) {
+                cl->rotateCount = xatoi(token + 7);
             } else if (strncasecmp(token, "logformat=", 10) == 0) {
                 setLogformat(cl, token+10, true);
             } else if (!strchr(token, '=')) {
                 // Do not pop the token; it must be an ACL name
                 break; // done with name=value options, now to ACLs
             } else {
                 debugs(3, DBG_CRITICAL, "Unknown access_log option " << token);
                 self_destruct();
             }
             // Pop the token, it was a valid "name=value" option
             (void)ConfigParser::NextToken();
             // Get next with preview ConfigParser::NextToken call.
         } while ((token = ConfigParser::PeekAtToken()) != NULL);
     }
 
     // set format if it has not been specified explicitly
     if (cl->type == Log::Format::CLF_UNKNOWN)
         setLogformat(cl, "squid", true);
 
     aclParseAclList(LegacyParser, &cl->aclList, cl->filename);
@@ -4206,76 +4209,87 @@
     return true;
 }
 
 static int
 check_null_access_log(CustomLog *customlog_definitions)
 {
     return customlog_definitions == NULL;
 }
 
 static void
 dump_access_log(StoreEntry * entry, const char *name, CustomLog * logs)
 {
     CustomLog *log;
 
     for (log = logs; log; log = log->next) {
         storeAppendPrintf(entry, "%s ", name);
 
         switch (log->type) {
 
         case Log::Format::CLF_CUSTOM:
-            storeAppendPrintf(entry, "%s %s", log->filename, log->logFormat->name);
+            storeAppendPrintf(entry, "%s logformat=%s", log->filename, log->logFormat->name);
             break;
 
         case Log::Format::CLF_NONE:
-            storeAppendPrintf(entry, "none");
+            storeAppendPrintf(entry, "logformat=none");
             break;
 
         case Log::Format::CLF_SQUID:
-            storeAppendPrintf(entry, "%s squid", log->filename);
+            storeAppendPrintf(entry, "%s logformat=squid", log->filename);
             break;
 
         case Log::Format::CLF_COMBINED:
-            storeAppendPrintf(entry, "%s combined", log->filename);
+            storeAppendPrintf(entry, "%s logformat=combined", log->filename);
             break;
 
         case Log::Format::CLF_COMMON:
-            storeAppendPrintf(entry, "%s common", log->filename);
+            storeAppendPrintf(entry, "%s logformat=common", log->filename);
             break;
 
 #if ICAP_CLIENT
         case Log::Format::CLF_ICAP_SQUID:
-            storeAppendPrintf(entry, "%s icap_squid", log->filename);
+            storeAppendPrintf(entry, "%s logformat=icap_squid", log->filename);
             break;
 #endif
         case Log::Format::CLF_USERAGENT:
-            storeAppendPrintf(entry, "%s useragent", log->filename);
+            storeAppendPrintf(entry, "%s logformat=useragent", log->filename);
             break;
 
         case Log::Format::CLF_REFERER:
-            storeAppendPrintf(entry, "%s referrer", log->filename);
+            storeAppendPrintf(entry, "%s logformat=referrer", log->filename);
             break;
 
         case Log::Format::CLF_UNKNOWN:
             break;
         }
 
+        // default is on-error=die
+        if (!log->fatal)
+            storeAppendPrintf(entry, " on-error=drop");
+
+        // default: 64KB
+        if (log->bufferSize != 64*1024)
+            storeAppendPrintf(entry, " buffer-size=%d", log->bufferSize);
+
+        if (log->rotateCount >= 0)
+            storeAppendPrintf(entry, " rotate=%d", log->rotateCount);
+
         if (log->aclList)
             dump_acl_list(entry, log->aclList);
 
         storeAppendPrintf(entry, "\n");
     }
 }
 
 static void
 free_access_log(CustomLog ** definitions)
 {
     while (*definitions) {
         CustomLog *log = *definitions;
         *definitions = log->next;
 
         log->logFormat = NULL;
         log->type = Log::Format::CLF_UNKNOWN;
 
         if (log->aclList)
             aclDestroyAclList(&log->aclList);
 

=== modified file 'src/cf.data.pre'
--- src/cf.data.pre	2014-12-24 09:20:52 +0000
+++ src/cf.data.pre	2014-12-29 05:37:59 +0000
@@ -4208,40 +4208,49 @@
 	logformat=name		Names log line format (either built-in or
 				defined by a logformat directive). Defaults
 				to 'squid'.
 
 	buffer-size=64KB	Defines approximate buffering limit for log
 				records (see buffered_logs).  Squid should not
 				keep more than the specified size and, hence,
 				should flush records before the buffer becomes
 				full to avoid overflows under normal
 				conditions (the exact flushing algorithm is
 				module-dependent though).  The on-error option
 				controls overflow handling.
 
 	on-error=die|drop	Defines action on unrecoverable errors. The
 				'drop' action ignores (i.e., does not log)
 				affected log records. The default 'die' action
 				kills the affected worker. The drop action 
 				support has not been tested for modules other
 				than tcp.
 
+	rotate=N		Specifies the number of log file rotations to
+				make when you run 'squid -k rotate'. The default
+				is to obey the logfile_rotate diretive. Setting
+				rotate=0 will disable the file name rotation,
+				but the log files are still closed and re-opened.
+				This will enable you to rename the logfiles
+				yourself just before sending the rotate signal.
+				Only supported by the stdio module.
+
 	===== Modules Currently available =====
 	
 	none	Do not log any requests matching these ACL.
 		Do not specify Place or logformat name.
 	
 	stdio	Write each log line to disk immediately at the completion of
 		each request.
 		Place: the filename and path to be written.
 	
 	daemon	Very similar to stdio. But instead of writing to disk the log
 		line is passed to a daemon helper for asychronous handling instead.
 		Place: varies depending on the daemon.
 		
 		log_file_daemon Place: the file name and path to be written.
 	
 	syslog	To log each request via syslog facility.
 		Place: The syslog facility and priority level for these entries.
 		Place Format:  facility.priority
 
 		where facility could be any of:
@@ -4428,56 +4437,61 @@
 	these swap logs will have names such as:
 
 		cache_swap_log.00
 		cache_swap_log.01
 		cache_swap_log.02
 
 	The numbered extension (which is added automatically)
 	corresponds to the order of the 'cache_dir' lines in this
 	configuration file.  If you change the order of the 'cache_dir'
 	lines in this file, these index files will NOT correspond to
 	the correct 'cache_dir' entry (unless you manually rename
 	them).  We recommend you do NOT use this option.  It is
 	better to keep these index files in each 'cache_dir' directory.
 DOC_END
 
 NAME: logfile_rotate
 TYPE: int
 DEFAULT: 10
 LOC: Config.Log.rotateNumber
 DOC_START
-	Specifies the number of logfile rotations to make when you
+	Specifies the default number of logfile rotations to make when you
 	type 'squid -k rotate'. The default is 10, which will rotate
 	with extensions 0 through 9. Setting logfile_rotate to 0 will
 	disable the file name rotation, but the logfiles are still closed
 	and re-opened. This will enable you to rename the logfiles
 	yourself just before sending the rotate signal.
 
+	Note, from Squid-3.1 this option is only a default for cache.log,
+	that log can be rotated separately by using debug_options.
+
+	Note, from Squid-3.6 this option is only a default for access.log
+	recrded by stdio: module. Those logs can be rotated separately by
+	using the rotate=N option on their access_log directive.
+
 	Note, the 'squid -k rotate' command normally sends a USR1
 	signal to the running squid process.  In certain situations
 	(e.g. on Linux with Async I/O), USR1 is used for other
 	purposes, so -k rotate uses another signal.  It is best to get
 	in the habit of using 'squid -k rotate' instead of 'kill -USR1
 	<pid>'.
 
-	Note, from Squid-3.1 this option is only a default for cache.log,
-	that log can be rotated separately by using debug_options.
 DOC_END
 
 NAME: mime_table
 TYPE: string
 DEFAULT: @DEFAULT_MIME_TABLE@
 LOC: Config.mimeTablePathname
 DOC_START
 	Path to Squid's icon configuration file.
 
 	You shouldn't need to change this, but the default file contains
 	examples and formatting information if you do.
 DOC_END
 
 NAME: log_mime_hdrs
 COMMENT: on|off
 TYPE: onoff
 LOC: Config.onoff.log_mime_hdrs
 DEFAULT: off
 DOC_START
 	The Cache can record both the request and the response MIME

=== modified file 'src/log/CustomLog.h'
--- src/log/CustomLog.h	2014-12-20 12:12:02 +0000
+++ src/log/CustomLog.h	2014-12-29 01:45:14 +0000
@@ -2,38 +2,40 @@
  * Copyright (C) 1996-2014 The Squid Software Foundation and contributors
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
  * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
 #ifndef SQUID_CUSTOMLOG_H_
 #define SQUID_CUSTOMLOG_H_
 
 //#include "format/Format.h"
 #include "acl/forward.h"
 #include "log/Formats.h"
 
 class Logfile;
 namespace Format
 {
 class Format;
 }
 
-/// representaiton of a custom log directive. Currently a POD.
+/// representation of a custom log directive.
 class CustomLog
 {
 public:
     char *filename;
     ACLList *aclList;
     Format::Format *logFormat;
     Logfile *logfile;
     CustomLog *next;
     Log::Format::log_type type;
     /// how much to buffer before dropping or dying (access_log buffer-size)
     size_t bufferSize;
     /// whether unrecoverable errors (e.g., dropping a log record) kill worker
     bool fatal;
+    /// How many log files to retain when rotating. Default: obey logfile_rotate
+    int16_t rotateCount;
 };
 
 #endif /* SQUID_CUSTOMLOG_H_ */
 

=== modified file 'src/log/File.cc'
--- src/log/File.cc	2014-12-20 12:12:02 +0000
+++ src/log/File.cc	2014-12-29 02:34:49 +0000
@@ -67,44 +67,44 @@
     assert(lf->data != NULL);
 
     if (fatal_flag)
         lf->flags.fatal = 1;
 
     lf->sequence_number = 0;
 
     return lf;
 }
 
 void
 logfileClose(Logfile * lf)
 {
     debugs(50, DBG_IMPORTANT, "Logfile: closing log " << lf->path);
     lf->f_flush(lf);
     lf->f_close(lf);
     cbdataFree(lf);
 }
 
 void
-logfileRotate(Logfile * lf)
+logfileRotate(Logfile * lf, int16_t rotateCount)
 {
     debugs(50, DBG_IMPORTANT, "logfileRotate: " << lf->path);
-    lf->f_rotate(lf);
+    lf->f_rotate(lf, rotateCount);
 }
 
 void
 logfileWrite(Logfile * lf, char *buf, size_t len)
 {
     lf->f_linewrite(lf, buf, len);
 }
 
 void
 logfilePrintf(Logfile * lf, const char *fmt,...)
 {
     va_list args;
     char buf[8192];
     int s;
 
     va_start(args, fmt);
 
     s = vsnprintf(buf, 8192, fmt, args);
 
     if (s > 8192) {

=== modified file 'src/log/File.h'
--- src/log/File.h	2014-12-20 12:12:02 +0000
+++ src/log/File.h	2014-12-29 02:47:39 +0000
@@ -14,58 +14,58 @@
 #if HAVE_SYS_PARAM_H
 #include <sys/param.h>
 #endif
 
 class logfile_buffer_t
 {
 public:
     char *buf;
     int size;
     int len;
     int written_len;
     dlink_node node;
 };
 
 class Logfile;
 
 typedef void LOGLINESTART(Logfile *);
 typedef void LOGWRITE(Logfile *, const char *, size_t len);
 typedef void LOGLINEEND(Logfile *);
 typedef void LOGFLUSH(Logfile *);
-typedef void LOGROTATE(Logfile *);
+typedef void LOGROTATE(Logfile *, const int16_t);
 typedef void LOGCLOSE(Logfile *);
 
 class Logfile
 {
 
 public:
     char path[MAXPATHLEN];
 
     struct {
         unsigned int fatal;
     } flags;
 
     int64_t sequence_number;  ///< Unique sequence number per log line.
 
 public:
     void *data;
 
     LOGLINESTART *f_linestart;
     LOGWRITE *f_linewrite;
     LOGLINEEND *f_lineend;
     LOGFLUSH *f_flush;
     LOGROTATE *f_rotate;
     LOGCLOSE *f_close;
 };
 
 /* Legacy API */
 Logfile *logfileOpen(const char *path, size_t bufsz, int);
 void logfileClose(Logfile * lf);
-void logfileRotate(Logfile * lf);
+void logfileRotate(Logfile * lf, int16_t rotateCount);
 void logfileWrite(Logfile * lf, char *buf, size_t len);
 void logfileFlush(Logfile * lf);
 void logfilePrintf(Logfile * lf, const char *fmt,...) PRINTF_FORMAT_ARG2;
 void logfileLineStart(Logfile * lf);
 void logfileLineEnd(Logfile * lf);
 
 #endif /* SQUID_SRC_LOG_FILE_H */
 

=== modified file 'src/log/ModDaemon.cc'
--- src/log/ModDaemon.cc	2014-12-20 12:12:02 +0000
+++ src/log/ModDaemon.cc	2014-12-29 02:38:40 +0000
@@ -252,41 +252,41 @@
 static void
 logfile_mod_daemon_close(Logfile * lf)
 {
     l_daemon_t *ll = static_cast<l_daemon_t *>(lf->data);
     debugs(50, DBG_IMPORTANT, "Logfile Daemon: closing log " << lf->path);
     logfileFlush(lf);
     if (ll->rfd == ll->wfd)
         comm_close(ll->rfd);
     else {
         comm_close(ll->rfd);
         comm_close(ll->wfd);
     }
     kill(ll->pid, SIGTERM);
     eventDelete(logfileFlushEvent, lf);
     xfree(ll);
     lf->data = NULL;
     cbdataInternalUnlock(lf); // WTF??
 }
 
 static void
-logfile_mod_daemon_rotate(Logfile * lf)
+logfile_mod_daemon_rotate(Logfile * lf, const int16_t)
 {
     char tb[3];
     debugs(50, DBG_IMPORTANT, "logfileRotate: " << lf->path);
     tb[0] = 'R';
     tb[1] = '\n';
     tb[2] = '\0';
     logfile_mod_daemon_append(lf, tb, 2);
 }
 
 /*
  * This routine assumes that up to one line is written. Don't try to
  * call this routine with more than one line or subsequent lines
  * won't be prefixed with the command type and confuse the logging
  * daemon somewhat.
  */
 static void
 logfile_mod_daemon_writeline(Logfile * lf, const char *buf, size_t len)
 {
     l_daemon_t *ll = static_cast<l_daemon_t *>(lf->data);
     /* Make sure the logfile buffer isn't too large */

=== modified file 'src/log/ModStdio.cc'
--- src/log/ModStdio.cc	2014-12-20 12:12:02 +0000
+++ src/log/ModStdio.cc	2014-12-29 02:58:02 +0000
@@ -81,79 +81,78 @@
 {
 }
 
 static void
 logfile_mod_stdio_lineend(Logfile * lf)
 {
     lf->f_flush(lf);
 }
 
 static void
 logfile_mod_stdio_flush(Logfile * lf)
 {
     l_stdio_t *ll = (l_stdio_t *) lf->data;
     if (0 == ll->offset)
         return;
     logfileWriteWrapper(lf, ll->buf, (size_t) ll->offset);
     ll->offset = 0;
 }
 
 static void
-logfile_mod_stdio_rotate(Logfile * lf)
+logfile_mod_stdio_rotate(Logfile * lf, const int16_t nRotate)
 {
 #ifdef S_ISREG
 
     struct stat sb;
 #endif
 
-    int i;
     char from[MAXPATHLEN];
     char to[MAXPATHLEN];
     l_stdio_t *ll = (l_stdio_t *) lf->data;
     assert(lf->path);
     const char *realpath = lf->path+6; // skip 'stdio:' prefix.
     assert(realpath);
 
 #ifdef S_ISREG
 
     if (stat(realpath, &sb) == 0)
         if (S_ISREG(sb.st_mode) == 0)
             return;
 
 #endif
 
     debugs(0, DBG_IMPORTANT, "Rotate log file " << lf->path);
 
     /* Rotate numbers 0 through N up one */
-    for (i = Config.Log.rotateNumber; i > 1;) {
+    for (int16_t i = nRotate; i > 1;) {
         --i;
         snprintf(from, MAXPATHLEN, "%s.%d", realpath, i - 1);
         snprintf(to, MAXPATHLEN, "%s.%d", realpath, i);
         xrename(from, to);
     }
 
     /* Rotate the current log to .0 */
     logfileFlush(lf);
 
     file_close(ll->fd);     /* always close */
 
-    if (Config.Log.rotateNumber > 0) {
+    if (nRotate > 0) {
         snprintf(to, MAXPATHLEN, "%s.%d", realpath, 0);
         xrename(realpath, to);
     }
     /* Reopen the log.  It may have been renamed "manually" */
     ll->fd = file_open(realpath, O_WRONLY | O_CREAT | O_TEXT);
 
     if (DISK_ERROR == ll->fd && lf->flags.fatal) {
         debugs(50, DBG_CRITICAL, "ERROR: logfileRotate: " << lf->path << ": " << xstrerror());
         fatalf("Cannot open %s: %s", lf->path, xstrerror());
     }
 }
 
 static void
 logfile_mod_stdio_close(Logfile * lf)
 {
     l_stdio_t *ll = (l_stdio_t *) lf->data;
     lf->f_flush(lf);
 
     if (ll->fd >= 0)
         file_close(ll->fd);

=== modified file 'src/log/ModSyslog.cc'
--- src/log/ModSyslog.cc	2014-12-20 12:12:02 +0000
+++ src/log/ModSyslog.cc	2014-12-29 02:39:00 +0000
@@ -103,41 +103,41 @@
     l_syslog_t *ll = (l_syslog_t *) lf->data;
     syslog(ll->syslog_priority, "%s", (char *) buf);
 }
 
 static void
 logfile_mod_syslog_linestart(Logfile * lf)
 {
 }
 
 static void
 logfile_mod_syslog_lineend(Logfile * lf)
 {
 }
 
 static void
 logfile_mod_syslog_flush(Logfile * lf)
 {
 }
 
 static void
-logfile_mod_syslog_rotate(Logfile * lf)
+logfile_mod_syslog_rotate(Logfile *, const int16_t)
 {
 }
 
 static void
 logfile_mod_syslog_close(Logfile * lf)
 {
     xfree(lf->data);
     lf->data = NULL;
 }
 
 /*
  * This code expects the path to be syslog:<priority>
  */
 int
 logfile_mod_syslog_open(Logfile * lf, const char *path, size_t bufsz, int fatal_flag)
 {
     lf->f_close = logfile_mod_syslog_close;
     lf->f_linewrite = logfile_mod_syslog_writeline;
     lf->f_linestart = logfile_mod_syslog_linestart;
     lf->f_lineend = logfile_mod_syslog_lineend;

=== modified file 'src/log/ModUdp.cc'
--- src/log/ModUdp.cc	2014-12-20 12:12:02 +0000
+++ src/log/ModUdp.cc	2014-12-29 02:39:16 +0000
@@ -87,43 +87,42 @@
     memcpy(ll->buf + ll->offset, buf, len);
 
     ll->offset += len;
 
     assert(ll->offset >= 0);
 
     assert((size_t) ll->offset <= ll->bufsz);
 }
 
 static void
 logfile_mod_udp_linestart(Logfile * lf)
 {
 }
 
 static void
 logfile_mod_udp_lineend(Logfile * lf)
 {
 }
 
 static void
-logfile_mod_udp_rotate(Logfile * lf)
+logfile_mod_udp_rotate(Logfile *, const int16_t)
 {
-    return;
 }
 
 static void
 logfile_mod_udp_close(Logfile * lf)
 {
     l_udp_t *ll = (l_udp_t *) lf->data;
     lf->f_flush(lf);
 
     if (ll->fd >= 0)
         file_close(ll->fd);
 
     if (ll->buf)
         xfree(ll->buf);
 
     xfree(lf->data);
     lf->data = NULL;
 }
 
 /*
  * This code expects the path to be //host:port

=== modified file 'src/log/TcpLogger.cc'
--- src/log/TcpLogger.cc	2014-12-20 12:12:02 +0000
+++ src/log/TcpLogger.cc	2014-12-29 02:39:38 +0000
@@ -406,41 +406,41 @@
 void
 Log::TcpLogger::WriteLine(Logfile * lf, const char *buf, size_t len)
 {
     if (TcpLogger *logger = StillLogging(lf))
         logger->logRecord(buf, len);
 }
 
 void
 Log::TcpLogger::StartLine(Logfile * lf)
 {
 }
 
 void
 Log::TcpLogger::EndLine(Logfile * lf)
 {
     if (!Config.onoff.buffered_logs)
         Flush(lf);
 }
 
 void
-Log::TcpLogger::Rotate(Logfile * lf)
+Log::TcpLogger::Rotate(Logfile *, const int16_t)
 {
 }
 
 void
 Log::TcpLogger::Close(Logfile * lf)
 {
     if (TcpLogger *logger = StillLogging(lf)) {
         debugs(50, 3, "Closing " << logger);
         typedef NullaryMemFunT<TcpLogger> Dialer;
         Dialer dialer(logger, &Log::TcpLogger::endGracefully);
         AsyncCall::Pointer call = asyncCall(50, 3, "Log::TcpLogger::endGracefully", dialer);
         ScheduleCallHere(call);
     }
     delete static_cast<Pointer*>(lf->data);
     lf->data = NULL;
 }
 
 /*
  * This code expects the path to be //host:port
  */

=== modified file 'src/log/TcpLogger.h'
--- src/log/TcpLogger.h	2014-12-20 12:12:02 +0000
+++ src/log/TcpLogger.h	2014-12-29 02:59:37 +0000
@@ -44,41 +44,41 @@
     /// will result in [eventual] job termination.
     void endGracefully();
 
     /// buffers record and possibly writes it to the remote logger
     void logRecord(const char *buf, size_t len);
 
     /// write all currently buffered records ASAP
     void flush();
 
     /* AsyncJob API */
     virtual void start();
     virtual bool doneAll() const;
     virtual void swanSong();
 
 private:
     /* Logfile API. Map c-style Logfile calls to TcpLogger method calls. */
     static void Flush(Logfile *lf);
     static void WriteLine(Logfile *lf, const char *buf, size_t len);
     static void StartLine(Logfile *lf);
     static void EndLine(Logfile *lf);
-    static void Rotate(Logfile *lf);
+    static void Rotate(Logfile *lf, const int16_t);
     static void Close(Logfile *lf);
 
     static TcpLogger *StillLogging(Logfile *lf);
 
     static void DelayedReconnect(void *data);
     void delayedReconnect();
 
     bool canFit(const size_t len) const;
     void appendRecord(const char *buf, size_t len);
     void appendChunk(const char *chunk, const size_t len);
     void writeIfNeeded();
     void writeIfPossible();
     void doConnect();
     void disconnect();
 
     /* comm callbacks */
     void connectDone(const CommConnectCbParams &conn);
     void writeDone(const CommIoCbParams &io);
     void handleClosure(const CommCloseCbParams &io);
 

=== modified file 'src/log/access_log.cc'
--- src/log/access_log.cc	2014-12-20 12:12:02 +0000
+++ src/log/access_log.cc	2014-12-29 02:37:18 +0000
@@ -177,47 +177,48 @@
 
         comm_udp_sendto(mcast_miss_fd,
                         &mcast_miss_to, sizeof(mcast_miss_to),
                         ibuf, isize * sizeof(int));
     }
 
 #endif
 }
 
 void
 accessLogRotate(void)
 {
     CustomLog *log;
 #if USE_FORW_VIA_DB
 
     fvdbClear();
 #endif
 
     for (log = Config.Log.accesslogs; log; log = log->next) {
         if (log->logfile) {
-            logfileRotate(log->logfile);
+            int16_t rc = (log->rotateCount >= 0 ? log->rotateCount : Config.Log.rotateNumber);
+            logfileRotate(log->logfile, rc);
         }
     }
 
 #if HEADERS_LOG
 
-    logfileRotate(headerslog);
+    logfileRotate(headerslog, Config.Log.rotateNumber);
 
 #endif
 }
 
 void
 accessLogClose(void)
 {
     CustomLog *log;
 
     for (log = Config.Log.accesslogs; log; log = log->next) {
         if (log->logfile) {
             logfileClose(log->logfile);
             log->logfile = NULL;
         }
     }
 
 #if HEADERS_LOG
 
     logfileClose(headerslog);
 

=== modified file 'src/store_log.cc'
--- src/store_log.cc	2014-12-20 12:12:02 +0000
+++ src/store_log.cc	2014-12-29 02:36:59 +0000
@@ -78,41 +78,41 @@
     } else {
         /* no mem object. Most RELEASE cases */
         logfileLineStart(storelog);
         logfilePrintf(storelog, "%9d.%03d %-7s %02d %08X %s   ?         ?         ?         ? ?/? ?/? ? ?\n",
                       (int) current_time.tv_sec,
                       (int) current_time.tv_usec / 1000,
                       storeLogTags[tag],
                       e->swap_dirn,
                       e->swap_filen,
                       e->getMD5Text());
         logfileLineEnd(storelog);
     }
 }
 
 void
 storeLogRotate(void)
 {
     if (NULL == storelog)
         return;
 
-    logfileRotate(storelog);
+    logfileRotate(storelog, Config.Log.rotateNumber);
 }
 
 void
 storeLogClose(void)
 {
     if (NULL == storelog)
         return;
 
     logfileClose(storelog);
 
     storelog = NULL;
 }
 
 static void
 storeLogRegisterWithCacheManager(void)
 {
     Mgr::RegisterAction("store_log_tags", "Histogram of store.log tags",
                         storeLogTagsHist, 0, 1);
 }
 

-------------- next part --------------
A non-text attachment was scrubbed...
Name: accesslog_rotateN_mk1.patch.sig
Type: application/octet-stream
Size: 287 bytes
Desc: not available
URL: <http://lists.squid-cache.org/pipermail/squid-dev/attachments/20141230/16aad44e/attachment-0001.obj>


More information about the squid-dev mailing list