]> git.pld-linux.org Git - packages/syslog-ng.git/blame - log-file-size-limit.patch
fix build without tests
[packages/syslog-ng.git] / log-file-size-limit.patch
CommitLineData
ee13f759
ER
1
2https://lists.balabit.hu/pipermail/syslog-ng/2009-August/013325.html
3
4
5 [syslog-ng] PATCH: Log file size limit (was: Logfile Rotation)
6
7Balazs Scheidler wrote:
8>>
9>> Personally I prefer to arrange log rotation based on the file size
10>> rather than some fixed time interval, so I have added that feature
11>> to syslog-ng. If anyone is interested I can explain in more details
12>> and post the patch.
13>
14> Please do. That's what open source is about.
15>
16
17The following patch introduces two new configuration options:
18'file_size_limit' to be used inside global 'options' and 'size_limit' to
19be used inside 'file' destination. Each option specifies log file size
20limit in bytes. If the global option is set to a value greater than zero
21it applies to all 'file' destinations. A particular file destination can
22remove the limit by setting it to zero. For example:
23
24# set the global file size limit
25options { file_size_limit(123456); };
26
27# set a different size limit for a particular file destination
28destination log1 { file("/var/log/log1.log" size_limit(456789)); };
29
30# remove size limit for a particular file destination
31# (only useful if there is a global size limit set)
32destination log2 { file("/var/log/log2.log" size_limit(0)); };
33
34The file size is checked after writing each log message and if the file
35has grown up to or above the size limit the file is renamed and a new
36empty file is created to continue logging to. The name format the
37"overgrown" log file is renamed to is "<p>-<s>.<m>-<r>", where <p> - the
38full path and name of the original log file, <s> - current time in UNIX
39format (seconds since Jan 1, 1970), <m> - fractional part of the current
40time (microseconds, 6 digits), <r> - a random number (10 digits).
41
42The intended use is to have incrond or another similar mechanism to
43detect when there is a new "renamed" log file and to process it in
44whatever way necessary (gzip it, parse it, send it my email, etc.).
45
46*********** BEGIN PATCH ***********
47diff -U5 -rb syslog-ng-3.0.4-orig/src/affile.c syslog-ng-3.0.4/src/affile.c
48--- syslog-ng-3.0.4-orig/src/affile.c 2009-07-31 11:41:20.000000000 +0200
49+++ syslog-ng-3.0.4/src/affile.c 2009-08-17 11:02:41.000000000 +0200
50@@ -428,14 +428,72 @@
51 {
52 return log_queue_get_length(((LogWriter *) self->writer)->queue) == 0;
53 }
54
55 static gboolean
56+affile_dw_open_file(AFFileDestWriter *self, int *fd)
57+{
58+ return affile_open_file(self->filename->str, (self->owner->flags & AFFILE_PIPE)?
59+ (O_RDWR | O_NOCTTY | O_NONBLOCK | O_LARGEFILE):
60+ (O_WRONLY | O_CREAT | O_NOCTTY | O_NONBLOCK | O_LARGEFILE),
61+ self->owner->file_uid, self->owner->file_gid, self->owner->file_perm,
62+ self->owner->dir_uid, self->owner->dir_gid, self->owner->dir_perm,
63+ !!(self->owner->flags & AFFILE_CREATE_DIRS), FALSE, !!(self->owner->flags & AFFILE_PIPE), fd);
64+}
65+
66+static void
67+affile_dw_transport_callback(gint fd, void *context)
68+{
69+ static const size_t extra_length = 32;
70+ AFFileDestWriter *self = (AFFileDestWriter *) context;
71+ off_t size = lseek(fd, 0, SEEK_CUR);
72+ GTimeVal time;
73+ GString *name;
74+ int reopen_fd;
75+ if ((size > 0) && (size >= self->owner->size_limit))
76+ {
77+ /* TODO: use g_file_read_link() */
78+ g_get_current_time(&time);
79+ name = g_string_sized_new(self->filename->len + extra_length);
80+ g_string_printf(name, "%s-%lu.%06lu-%010lu", self->filename->str, (gulong)time.tv_sec, (gulong)time.tv_usec, (gulong)g_random_int());
81+ if (rename(self->filename->str, name->str) == 0)
82+ {
83+ if (affile_dw_open_file(self, &reopen_fd))
84+ {
85+ if (dup2(reopen_fd, fd) < 0)
86+ {
87+ msg_error("Error swithing to new log file",
88+ evt_tag_str("filename", self->filename->str),
89+ evt_tag_errno(EVT_TAG_OSERROR, errno),
90+ NULL);
91+ }
92+ close(reopen_fd);
93+ }
94+ else
95+ {
96+ msg_error("Error opening file for writing",
97+ evt_tag_str("filename", self->filename->str),
98+ evt_tag_errno(EVT_TAG_OSERROR, errno),
99+ NULL);
100+ }
101+ }
102+ else
103+ {
104+ msg_error("Error renaming overgrown file",
105+ evt_tag_str("filename", self->filename->str),
106+ evt_tag_errno(EVT_TAG_OSERROR, errno),
107+ NULL);
108+ }
109+ g_string_free(name, TRUE);
110+ }
111+}
112+
113+static gboolean
114 affile_dw_init(LogPipe *s)
115 {
116 AFFileDestWriter *self = (AFFileDestWriter *) s;
117- int fd, flags;
118+ int fd;
119 struct stat st;
120 GlobalConfig *cfg = log_pipe_get_config(s);
121
122 if (cfg)
123 self->time_reopen = cfg->time_reopen;
124@@ -454,20 +512,12 @@
125 evt_tag_int("overwrite_if_older", self->owner->overwrite_if_older),
126 NULL);
127 unlink(self->filename->str);
128 }
129
130- if (self->owner->flags & AFFILE_PIPE)
131- flags = O_RDWR | O_NOCTTY | O_NONBLOCK | O_LARGEFILE;
132- else
133- flags = O_WRONLY | O_CREAT | O_NOCTTY | O_NONBLOCK | O_LARGEFILE;
134-
135 self->last_open_stamp = time(NULL);
136- if (affile_open_file(self->filename->str, flags,
137- self->owner->file_uid, self->owner->file_gid, self->owner->file_perm,
138- self->owner->dir_uid, self->owner->dir_gid, self->owner->dir_perm,
139- !!(self->owner->flags & AFFILE_CREATE_DIRS), FALSE, !!(self->owner->flags & AFFILE_PIPE), &fd))
140+ if (affile_dw_open_file(self, &fd))
141 {
142 guint write_flags;
143
144 if (!self->writer)
145 {
146@@ -482,11 +532,11 @@
147 self->writer = NULL;
148 close(fd);
149 return FALSE;
150 }
151 write_flags = ((self->owner->flags & AFFILE_FSYNC) ? LTF_FSYNC : 0) | LTF_APPEND;
152- log_writer_reopen(self->writer, log_proto_plain_new_client(log_transport_plain_new(fd, write_flags)));
153+ log_writer_reopen(self->writer, log_proto_plain_new_client(((self->owner->size_limit > 0) && !(self->owner->flags & AFFILE_PIPE))? log_transport_plain_new_with_callback(fd, write_flags, affile_dw_transport_callback, self): log_transport_plain_new(fd, write_flags)));
154 }
155 else
156 {
157 msg_error("Error opening file for writing",
158 evt_tag_str("filename", self->filename->str),
159@@ -678,10 +728,18 @@
160 AFFileDestDriver *self = (AFFileDestDriver *) s;
161
162 self->local_time_zone = g_strdup(local_time_zone);
163 }
164
165+void
166+affile_dd_set_file_size_limit(LogDriver *s, off_t file_size_limit)
167+{
168+ AFFileDestDriver *self = (AFFileDestDriver *) s;
169+
170+ self->size_limit = file_size_limit;
171+}
172+
173 static inline gchar *
174 affile_dd_format_persist_name(AFFileDestDriver *self)
175 {
176 static gchar persist_name[1024];
177
178@@ -766,10 +824,12 @@
179 self->dir_gid = cfg->dir_gid;
180 if (self->dir_perm == (mode_t) -1)
181 self->dir_perm = cfg->dir_perm;
182 if (self->time_reap == -1)
183 self->time_reap = cfg->time_reap;
184+ if (self->size_limit == -1)
185+ self->size_limit = cfg->file_size_limit;
186
187 self->use_time_recvd = cfg->use_time_recvd;
188
189 if (self->local_time_zone_info)
190 time_zone_info_free(self->local_time_zone_info);
191@@ -973,7 +1033,8 @@
192 if (strchr(filename, '$') == NULL)
193 {
194 self->flags |= AFFILE_NO_EXPAND;
195 }
196 self->time_reap = -1;
197+ self->size_limit = -1;
198 return &self->super;
199 }
200diff -U5 -rb syslog-ng-3.0.4-orig/src/affile.h syslog-ng-3.0.4/src/affile.h
201--- syslog-ng-3.0.4-orig/src/affile.h 2009-04-30 12:22:53.000000000 +0200
202+++ syslog-ng-3.0.4/src/affile.h 2009-08-17 10:10:39.000000000 +0200
203@@ -72,10 +72,11 @@
204
205 gint overwrite_if_older;
206 gboolean use_time_recvd;
207 gint time_reap;
208 guint reap_timer;
209+ off_t size_limit;
210 } AFFileDestDriver;
211
212 LogDriver *affile_dd_new(gchar *filename, guint32 flags);
213
214 void affile_dd_set_compress(LogDriver *s, gboolean compress);
215@@ -88,7 +89,8 @@
216 void affile_dd_set_dir_perm(LogDriver *s, mode_t dir_perm);
217 void affile_dd_set_create_dirs(LogDriver *s, gboolean create_dirs);
218 void affile_dd_set_fsync(LogDriver *s, gboolean enable);
219 void affile_dd_set_overwrite_if_older(LogDriver *s, gint overwrite_if_older);
220 void affile_dd_set_local_time_zone(LogDriver *s, const gchar *local_time_zone);
221+void affile_dd_set_file_size_limit(LogDriver *s, off_t file_size_limit);
222
223 #endif
224diff -U5 -rb syslog-ng-3.0.4-orig/src/cfg-grammar.y syslog-ng-3.0.4/src/cfg-grammar.y
225--- syslog-ng-3.0.4-orig/src/cfg-grammar.y 2009-08-05 12:34:18.000000000 +0200
226+++ syslog-ng-3.0.4/src/cfg-grammar.y 2009-08-17 10:10:39.000000000 +0200
227@@ -154,10 +154,11 @@
228 %token KW_DIR_OWNER KW_DIR_GROUP KW_DIR_PERM
229 %token KW_TEMPLATE KW_TEMPLATE_ESCAPE
230 %token KW_FOLLOW_FREQ
231 %token KW_OVERWRITE_IF_OLDER
232 %token KW_DEFAULT_FACILITY KW_DEFAULT_LEVEL
233+%token KW_FILE_SIZE_LIMIT KW_SIZE_LIMIT
234
235 /* socket related options */
236 %token KW_KEEP_ALIVE KW_MAX_CONNECTIONS
237 %token KW_LOCALIP KW_IP KW_LOCALPORT KW_PORT KW_DESTPORT
238 %token KW_IP_TTL KW_SO_BROADCAST KW_IP_TOS KW_SO_SNDBUF KW_SO_RCVBUF KW_SO_KEEPALIVE KW_SPOOF_SOURCE
239@@ -799,10 +800,11 @@
240 | KW_DIR_PERM '(' LL_NUMBER ')' { affile_dd_set_dir_perm(last_driver, $3); }
241 | KW_CREATE_DIRS '(' yesno ')' { affile_dd_set_create_dirs(last_driver, $3); }
242 | KW_OVERWRITE_IF_OLDER '(' LL_NUMBER ')' { affile_dd_set_overwrite_if_older(last_driver, $3); }
243 | KW_FSYNC '(' yesno ')' { affile_dd_set_fsync(last_driver, $3); }
244 | KW_LOCAL_TIME_ZONE '(' string ')' { affile_dd_set_local_time_zone(last_driver, $3); free($3); }
245+ | KW_SIZE_LIMIT '(' LL_NUMBER ')' { affile_dd_set_file_size_limit(last_driver, $3); }
246 ;
247
248 dest_afpipe
249 : KW_PIPE '(' dest_afpipe_params ')' { $$ = $3; }
250 ;
251@@ -1141,10 +1143,11 @@
252 | KW_FILE_TEMPLATE '(' string ')' { configuration->file_template_name = g_strdup($3); free($3); }
253 | KW_PROTO_TEMPLATE '(' string ')' { configuration->proto_template_name = g_strdup($3); free($3); }
254 | KW_RECV_TIME_ZONE '(' string ')' { configuration->recv_time_zone = g_strdup($3); free($3); }
255 | KW_SEND_TIME_ZONE '(' string ')' { configuration->send_time_zone = g_strdup($3); free($3); }
256 | KW_LOCAL_TIME_ZONE '(' string ')' { configuration->local_time_zone = g_strdup($3); free($3); }
257+ | KW_FILE_SIZE_LIMIT '(' LL_NUMBER ')' { configuration->file_size_limit = $3; }
258 ;
259
260 /* BEGIN MARK: tls */
261 tls_options
262 : tls_option tls_options
263diff -U5 -rb syslog-ng-3.0.4-orig/src/cfg-lex.l syslog-ng-3.0.4/src/cfg-lex.l
264--- syslog-ng-3.0.4-orig/src/cfg-lex.l 2009-05-06 11:20:22.000000000 +0200
265+++ syslog-ng-3.0.4/src/cfg-lex.l 2009-08-17 10:10:39.000000000 +0200
266@@ -126,10 +126,12 @@
267 { "recv_time_zone", KW_RECV_TIME_ZONE },
268 { "send_time_zone", KW_SEND_TIME_ZONE },
269 { "local_time_zone", KW_LOCAL_TIME_ZONE },
270 { "use_time_recvd", KW_USE_TIME_RECVD, KWS_OBSOLETE, "Use R_ or S_ prefixed macros in templates" },
271 { "use_fqdn", KW_USE_FQDN },
272+ { "size_limit", KW_SIZE_LIMIT },
273+ { "file_size_limit", KW_FILE_SIZE_LIMIT },
274 { "use_dns", KW_USE_DNS },
275 { "gc_threshold", KW_GC_BUSY_THRESHOLD },
276 { "gc_busy_threshold", KW_GC_BUSY_THRESHOLD },
277 { "gc_idle_threshold", KW_GC_IDLE_THRESHOLD },
278 { "time_reopen", KW_TIME_REOPEN },
279diff -U5 -rb syslog-ng-3.0.4-orig/src/cfg.c syslog-ng-3.0.4/src/cfg.c
280--- syslog-ng-3.0.4-orig/src/cfg.c 2009-04-30 12:00:54.000000000 +0200
281+++ syslog-ng-3.0.4/src/cfg.c 2009-08-17 10:10:39.000000000 +0200
282@@ -298,10 +298,11 @@
283
284 self->follow_freq = -1;
285 self->file_uid = 0;
286 self->file_gid = 0;
287 self->file_perm = 0600;
288+ self->file_size_limit = 0;
289 self->dir_uid = 0;
290 self->dir_gid = 0;
291 self->dir_perm = 0700;
292
293 self->use_dns_cache = 1;
294diff -U5 -rb syslog-ng-3.0.4-orig/src/cfg.h syslog-ng-3.0.4/src/cfg.h
295--- syslog-ng-3.0.4-orig/src/cfg.h 2009-06-03 13:08:27.000000000 +0200
296+++ syslog-ng-3.0.4/src/cfg.h 2009-08-17 10:10:39.000000000 +0200
297@@ -78,10 +78,11 @@
298 gint follow_freq;
299 gboolean create_dirs;
300 uid_t file_uid;
301 gid_t file_gid;
302 mode_t file_perm;
303+ off_t file_size_limit;
304
305 uid_t dir_uid;
306 gid_t dir_gid;
307 mode_t dir_perm;
308
309diff -U5 -rb syslog-ng-3.0.4-orig/src/logtransport.c syslog-ng-3.0.4/src/logtransport.c
310--- syslog-ng-3.0.4-orig/src/logtransport.c 2009-04-30 10:53:22.000000000 +0200
311+++ syslog-ng-3.0.4/src/logtransport.c 2009-08-17 11:01:33.000000000 +0200
312@@ -53,10 +53,12 @@
313 typedef struct _LogTransportPlain LogTransportPlain;
314
315 struct _LogTransportPlain
316 {
317 LogTransport super;
318+ LogTransportCallback callback;
319+ void *context;
320 };
321
322 static gssize
323 log_transport_plain_read_method(LogTransport *s, gpointer buf, gsize buflen, GSockAddr **sa)
324 {
325@@ -138,24 +140,32 @@
326 alarm_cancel();
327 if (self->super.flags & LTF_FSYNC)
328 fsync(self->super.fd);
329 }
330 while (rc == -1 && errno == EINTR);
331+ if ((self->callback != NULL) && (rc > 0))
332+ self->callback(self->super.fd, self->context);
333 return rc;
334 }
335
336
337 LogTransport *
338-log_transport_plain_new(gint fd, guint flags)
339+log_transport_plain_new_with_callback(gint fd, guint flags, LogTransportCallback callback, void *context)
340 {
341 LogTransportPlain *self = g_new0(LogTransportPlain, 1);
342
343 self->super.fd = fd;
344 self->super.cond = 0;
345 self->super.flags = flags;
346 self->super.read = log_transport_plain_read_method;
347 self->super.write = log_transport_plain_write_method;
348 self->super.free_fn = log_transport_free_method;
349+ self->callback = callback;
350+ self->context = context;
351 return &self->super;
352 }
353
354-
355+LogTransport *
356+log_transport_plain_new(gint fd, guint flags)
357+{
358+ return log_transport_plain_new_with_callback(fd, flags, NULL, NULL);
359+}
360diff -U5 -rb syslog-ng-3.0.4-orig/src/logtransport.h syslog-ng-3.0.4/src/logtransport.h
361--- syslog-ng-3.0.4-orig/src/logtransport.h 2009-04-30 10:46:55.000000000 +0200
362+++ syslog-ng-3.0.4/src/logtransport.h 2009-08-17 11:00:58.000000000 +0200
363@@ -57,10 +57,12 @@
364 log_transport_read(LogTransport *self, gpointer buf, gsize count, GSockAddr **sa)
365 {
366 return self->read(self, buf, count, sa);
367 }
368
369+typedef void (*LogTransportCallback)(gint fd, void *context);
370+LogTransport *log_transport_plain_new_with_callback(gint fd, guint flags, LogTransportCallback callback, void *context);
371 LogTransport *log_transport_plain_new(gint fd, guint flags);
372 void log_transport_free(LogTransport *s);
373 void log_transport_free_method(LogTransport *s);
374
375
376
This page took 0.131453 seconds and 4 git commands to generate.