diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-10-12 12:19:32 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-10-12 12:28:12 +0300 |
commit | b6678bb65fce1f64e82cc049aae3d7ba6f8aa19c (patch) | |
tree | 55c1959713e8f37f5958afb4c0cdb4d751406fe6 /src | |
parent | 791cdf412f5fb66a056aa28b27507fdc9af86507 (diff) | |
download | vmod-binlog-b6678bb65fce1f64e82cc049aae3d7ba6f8aa19c.tar.gz vmod-binlog-b6678bb65fce1f64e82cc049aae3d7ba6f8aa19c.tar.bz2 |
Rewrite using opaque record data.
Records can carry arbitrary data, whose format is defined using
teplate strings similar to those of Perl's pack() function. The
teplate string is stored in the logfile header and is used by
binlogcat to render a human-readable representation.
* src/.gitignore: New file.
* pack.c: New file.
* pack.h: New file.
* src/Makefile.am: Add pack.c, pack.h
* src/binlog.c: Rewrite. Use pack routines to construct each
record.
* src/binlogcat.c: Likewise. Use packout to unpack each record.
* src/vmod-binlog.h (struct binlog_record): Remove nid,aid.
(struct binlog_file_header): Add hdrsize.
(BINLOG_HEADER_SIZE,union binlog_header): Remove
(binlog_recnum): Remove.
(binlog_size): Rewrite.
* src/vmod.vcc (append,sappend): Remove.
(init): Change signature.
(start,commit,pack): New functions.
* tests/test01.at: Rewrite.
* tests/test02.at: Rewrite.
Diffstat (limited to 'src')
-rw-r--r-- | src/.gitignore | 1 | ||||
-rw-r--r-- | src/Makefile.am | 6 | ||||
-rw-r--r-- | src/binlog.c | 161 | ||||
-rw-r--r-- | src/binlogcat.c | 71 | ||||
-rw-r--r-- | src/pack.c | 588 | ||||
-rw-r--r-- | src/pack.h | 47 | ||||
-rw-r--r-- | src/vmod-binlog.h | 21 | ||||
-rw-r--r-- | src/vmod.vcc | 7 |
8 files changed, 831 insertions, 71 deletions
diff --git a/src/.gitignore b/src/.gitignore index 7f6e438..a75fe6d 100644 --- a/src/.gitignore +++ b/src/.gitignore | |||
@@ -1,2 +1,3 @@ | |||
1 | binlogcat | ||
1 | vcc_if.c | 2 | vcc_if.c |
2 | vcc_if.h | 3 | vcc_if.h |
diff --git a/src/Makefile.am b/src/Makefile.am index c9daf9a..9ce519f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am | |||
@@ -17,7 +17,8 @@ | |||
17 | AM_CPPFLAGS = -I$(VARNISHSRC)/include -I$(VARNISHSRC) | 17 | AM_CPPFLAGS = -I$(VARNISHSRC)/include -I$(VARNISHSRC) |
18 | 18 | ||
19 | bin_PROGRAMS = binlogcat | 19 | bin_PROGRAMS = binlogcat |
20 | binlogcat_SOURCES = binlogcat.c | 20 | binlogcat_SOURCES = binlogcat.c pack.c |
21 | binlogcat_CFLAGS = $(AM_CFLAGS) | ||
21 | 22 | ||
22 | vmoddir = $(VMODDIR) | 23 | vmoddir = $(VMODDIR) |
23 | vmod_LTLIBRARIES = libvmod_binlog.la | 24 | vmod_LTLIBRARIES = libvmod_binlog.la |
@@ -27,9 +28,12 @@ libvmod_binlog_la_LIBADD= | |||
27 | 28 | ||
28 | libvmod_binlog_la_SOURCES = \ | 29 | libvmod_binlog_la_SOURCES = \ |
29 | binlog.c\ | 30 | binlog.c\ |
31 | pack.c\ | ||
30 | vmod-binlog.h\ | 32 | vmod-binlog.h\ |
31 | vcc_if.c vcc_if.h | 33 | vcc_if.c vcc_if.h |
32 | 34 | ||
35 | noinst_HEADERS = pack.h | ||
36 | |||
33 | BUILT_SOURCES = vcc_if.c vcc_if.h | 37 | BUILT_SOURCES = vcc_if.c vcc_if.h |
34 | 38 | ||
35 | vcc_if.c vcc_if.h: $(VARNISHSRC)/lib/libvmod_std/vmod.py $(top_srcdir)/src/vmod.vcc | 39 | vcc_if.c vcc_if.h: $(VARNISHSRC)/lib/libvmod_std/vmod.py $(top_srcdir)/src/vmod.vcc |
diff --git a/src/binlog.c b/src/binlog.c index be32e10..6f438a8 100644 --- a/src/binlog.c +++ b/src/binlog.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <unistd.h> | 22 | #include <unistd.h> |
23 | #include <errno.h> | 23 | #include <errno.h> |
24 | #include <syslog.h> | 24 | #include <syslog.h> |
25 | #include <stddef.h> | ||
25 | #include <stdlib.h> | 26 | #include <stdlib.h> |
26 | #include <ctype.h> | 27 | #include <ctype.h> |
27 | #include <time.h> | 28 | #include <time.h> |
@@ -29,6 +30,7 @@ | |||
29 | #include "vcc_if.h" | 30 | #include "vcc_if.h" |
30 | #include "bin/varnishd/cache.h" | 31 | #include "bin/varnishd/cache.h" |
31 | #include "vmod-binlog.h" | 32 | #include "vmod-binlog.h" |
33 | #include "pack.h" | ||
32 | 34 | ||
33 | #ifndef O_SEARCH | 35 | #ifndef O_SEARCH |
34 | # define O_SEARCH 0 | 36 | # define O_SEARCH 0 |
@@ -36,6 +38,12 @@ | |||
36 | 38 | ||
37 | #define BLF_ROUNDTS 0x01 | 39 | #define BLF_ROUNDTS 0x01 |
38 | 40 | ||
41 | enum binlog_state { | ||
42 | state_init, | ||
43 | state_start, | ||
44 | state_pack | ||
45 | }; | ||
46 | |||
39 | struct binlog_config { | 47 | struct binlog_config { |
40 | size_t size; /* maximum file size */ | 48 | size_t size; /* maximum file size */ |
41 | unsigned interval; /* file rotation interval */ | 49 | unsigned interval; /* file rotation interval */ |
@@ -45,14 +53,21 @@ struct binlog_config { | |||
45 | int dd; /* directory descriptor */ | 53 | int dd; /* directory descriptor */ |
46 | char *fname; /* current file name */ | 54 | char *fname; /* current file name */ |
47 | int fd; /* current file descriptor */ | 55 | int fd; /* current file descriptor */ |
48 | union binlog_header *base; /* mmap base */ | 56 | struct binlog_file_header *base; /* mmap base */ |
49 | struct binlog_record *recbase; /* record base */ | 57 | char *recbase; /* record base */ |
50 | size_t recnum; /* number of records in recbase */ | 58 | size_t recnum; /* number of records in recbase */ |
51 | size_t recidx; /* index of the next free entry in recbase */ | 59 | size_t recsize; /* record size */ |
52 | time_t stoptime; /* when to rotate the current file */ | 60 | time_t stoptime; /* when to rotate the current file */ |
53 | pthread_mutex_t mutex; | 61 | pthread_mutex_t mutex; |
54 | int debug; | 62 | int debug; |
55 | int flags; | 63 | int flags; |
64 | |||
65 | char *dataspec; | ||
66 | struct packinst *inst_head; | ||
67 | struct packinst *inst_cur; | ||
68 | struct packenv *env; | ||
69 | enum binlog_state state; | ||
70 | time_t timestamp; | ||
56 | }; | 71 | }; |
57 | 72 | ||
58 | static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; | 73 | static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; |
@@ -158,11 +173,12 @@ getinterval(char *p, char **endp) | |||
158 | } | 173 | } |
159 | 174 | ||
160 | void | 175 | void |
161 | vmod_init(struct sess *sp, struct vmod_priv *priv, const char *param) | 176 | vmod_init(struct sess *sp, struct vmod_priv *priv, |
177 | const char *dir, const char *dataspec, const char *param) | ||
162 | { | 178 | { |
163 | struct binlog_config *conf = priv->priv; | 179 | struct binlog_config *conf = priv->priv; |
164 | struct stat st; | 180 | struct stat st; |
165 | char *dir, *p, *q; | 181 | char *p, *q; |
166 | unsigned long n; | 182 | unsigned long n; |
167 | 183 | ||
168 | p = findparam(param, "debug"); | 184 | p = findparam(param, "debug"); |
@@ -170,12 +186,7 @@ vmod_init(struct sess *sp, struct vmod_priv *priv, const char *param) | |||
170 | conf->debug = atoi(p); | 186 | conf->debug = atoi(p); |
171 | free(p); | 187 | free(p); |
172 | } | 188 | } |
173 | 189 | ||
174 | dir = findparam(param, "dir"); | ||
175 | if (!dir) { | ||
176 | binlog_error("parameter \"dir\" not set"); | ||
177 | abort(); | ||
178 | } | ||
179 | if (stat(dir, &st)) { | 190 | if (stat(dir, &st)) { |
180 | if (errno == ENOENT) | 191 | if (errno == ENOENT) |
181 | binlog_error("logging directory does not exist"); | 192 | binlog_error("logging directory does not exist"); |
@@ -194,8 +205,20 @@ vmod_init(struct sess *sp, struct vmod_priv *priv, const char *param) | |||
194 | dir, strerror(errno)); | 205 | dir, strerror(errno)); |
195 | abort(); | 206 | abort(); |
196 | } | 207 | } |
197 | conf->dir = dir; | 208 | conf->dir = strdup(dir); |
209 | AN(conf->dir); | ||
198 | 210 | ||
211 | conf->inst_head = packcomp(dataspec, &p); | ||
212 | if (*p) { | ||
213 | binlog_error("cannot compile data format near %s", p); | ||
214 | abort(); | ||
215 | } | ||
216 | conf->recsize = packsize(conf->inst_head); | ||
217 | conf->env = packenv_create(conf->recsize); | ||
218 | conf->recsize += offsetof(struct binlog_record,data); | ||
219 | conf->dataspec = strdup(dataspec); | ||
220 | AN(conf->dataspec); | ||
221 | |||
199 | p = findparam(param, "pattern"); | 222 | p = findparam(param, "pattern"); |
200 | if (!p) { | 223 | if (!p) { |
201 | p = strdup(BINLOG_PATTERN); | 224 | p = strdup(BINLOG_PATTERN); |
@@ -367,7 +390,6 @@ reset(struct binlog_config *conf) | |||
367 | conf->base = NULL; | 390 | conf->base = NULL; |
368 | conf->recbase = NULL; | 391 | conf->recbase = NULL; |
369 | conf->recnum = 0; | 392 | conf->recnum = 0; |
370 | conf->recidx = 0; | ||
371 | } | 393 | } |
372 | 394 | ||
373 | static int | 395 | static int |
@@ -379,11 +401,15 @@ setstoptime(struct binlog_config *conf) | |||
379 | conf->stoptime = ts - ts % conf->interval + conf->interval; | 401 | conf->stoptime = ts - ts % conf->interval + conf->interval; |
380 | } | 402 | } |
381 | 403 | ||
404 | #define binlog_recnum(conf) \ | ||
405 | (((conf)->size - (conf)->base->hdrsize) / (conf)->base->recsize) | ||
406 | |||
382 | static int | 407 | static int |
383 | newfile(struct sess *sp, struct binlog_config *conf) | 408 | newfile(struct sess *sp, struct binlog_config *conf) |
384 | { | 409 | { |
385 | int c; | 410 | int c; |
386 | void *base; | 411 | void *base; |
412 | size_t n; | ||
387 | 413 | ||
388 | setstoptime(conf); | 414 | setstoptime(conf); |
389 | 415 | ||
@@ -413,14 +439,18 @@ newfile(struct sess *sp, struct binlog_config *conf) | |||
413 | } | 439 | } |
414 | 440 | ||
415 | conf->base = base; | 441 | conf->base = base; |
416 | memcpy(conf->base->hdr.magic, BINLOG_MAGIC_STR, BINLOG_MAGIC_LEN); | 442 | memcpy(conf->base->magic, BINLOG_MAGIC_STR, BINLOG_MAGIC_LEN); |
417 | conf->base->hdr.version = BINLOG_VERSION; | 443 | conf->base->version = BINLOG_VERSION; |
418 | conf->base->hdr.recsize = sizeof(struct binlog_record); | 444 | conf->base->recsize = conf->recsize; |
419 | conf->base->hdr.recnum = 0; | 445 | conf->base->recnum = 0; |
446 | strcpy((char*)(conf->base + 1), conf->dataspec); | ||
420 | 447 | ||
421 | conf->recbase = (struct binlog_record *) (conf->base + 1); | 448 | n = (sizeof(struct binlog_file_header) + strlen(conf->dataspec) + |
449 | conf->recsize - 1) / conf->recsize; | ||
450 | conf->base->hdrsize = n * conf->recsize; | ||
451 | |||
452 | conf->recbase = (char *) conf->base + conf->base->hdrsize; | ||
422 | conf->recnum = binlog_recnum(conf); | 453 | conf->recnum = binlog_recnum(conf); |
423 | conf->recidx = 0; | ||
424 | 454 | ||
425 | debug(conf,1,("created new log file %s",conf->fname)); | 455 | debug(conf,1,("created new log file %s",conf->fname)); |
426 | return 0; | 456 | return 0; |
@@ -429,21 +459,23 @@ newfile(struct sess *sp, struct binlog_config *conf) |