aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2013-10-12 12:19:32 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2013-10-12 12:28:12 +0300
commitb6678bb65fce1f64e82cc049aae3d7ba6f8aa19c (patch)
tree55c1959713e8f37f5958afb4c0cdb4d751406fe6 /src
parent791cdf412f5fb66a056aa28b27507fdc9af86507 (diff)
downloadvmod-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/.gitignore1
-rw-r--r--src/Makefile.am6
-rw-r--r--src/binlog.c161
-rw-r--r--src/binlogcat.c71
-rw-r--r--src/pack.c588
-rw-r--r--src/pack.h47
-rw-r--r--src/vmod-binlog.h21
-rw-r--r--src/vmod.vcc7
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 @@
1binlogcat
1vcc_if.c 2vcc_if.c
2vcc_if.h 3vcc_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 @@
17AM_CPPFLAGS = -I$(VARNISHSRC)/include -I$(VARNISHSRC) 17AM_CPPFLAGS = -I$(VARNISHSRC)/include -I$(VARNISHSRC)
18 18
19bin_PROGRAMS = binlogcat 19bin_PROGRAMS = binlogcat
20binlogcat_SOURCES = binlogcat.c 20binlogcat_SOURCES = binlogcat.c pack.c
21binlogcat_CFLAGS = $(AM_CFLAGS)
21 22
22vmoddir = $(VMODDIR) 23vmoddir = $(VMODDIR)
23vmod_LTLIBRARIES = libvmod_binlog.la 24vmod_LTLIBRARIES = libvmod_binlog.la
@@ -27,9 +28,12 @@ libvmod_binlog_la_LIBADD=
27 28
28libvmod_binlog_la_SOURCES = \ 29libvmod_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
35noinst_HEADERS = pack.h
36
33BUILT_SOURCES = vcc_if.c vcc_if.h 37BUILT_SOURCES = vcc_if.c vcc_if.h
34 38
35vcc_if.c vcc_if.h: $(VARNISHSRC)/lib/libvmod_std/vmod.py $(top_srcdir)/src/vmod.vcc 39vcc_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
41enum binlog_state {
42 state_init,
43 state_start,
44 state_pack
45};
46
39struct binlog_config { 47struct 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
58static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 73static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -158,11 +173,12 @@ getinterval(char *p, char **endp)
158} 173}
159 174
160void 175void
161vmod_init(struct sess *sp, struct vmod_priv *priv, const char *param) 176vmod_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
373static int 395static 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
382static int 407static int
383newfile(struct sess *sp, struct binlog_config *conf) 408newfile(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)