diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-10-11 00:12:43 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-10-11 12:22:57 +0300 |
commit | df83b714395d41b096f7ad8cc3a090c9341f7598 (patch) | |
tree | 1c3bcc412e633d3fc678e2cc083ea947e5dcd8e8 /src | |
download | vmod-binlog-df83b714395d41b096f7ad8cc3a090c9341f7598.tar.gz vmod-binlog-df83b714395d41b096f7ad8cc3a090c9341f7598.tar.bz2 |
Initial commit
Diffstat (limited to 'src')
-rw-r--r-- | src/.gitignore | 2 | ||||
-rw-r--r-- | src/Makefile.am | 41 | ||||
-rw-r--r-- | src/binlog.c | 516 | ||||
-rw-r--r-- | src/binlogcat.c | 134 | ||||
-rw-r--r-- | src/vmod-binlog.h | 71 | ||||
-rw-r--r-- | src/vmod.vcc | 7 |
6 files changed, 771 insertions, 0 deletions
diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 0000000..7f6e438 --- /dev/null +++ b/src/.gitignore | |||
@@ -0,0 +1,2 @@ | |||
1 | vcc_if.c | ||
2 | vcc_if.h | ||
diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..c9daf9a --- /dev/null +++ b/src/Makefile.am | |||
@@ -0,0 +1,41 @@ | |||
1 | # This file is part of vmod-binlog | ||
2 | # Copyright (C) 2013 Sergey Poznyakoff | ||
3 | # | ||
4 | # Vmod-binlog is free software; you can redistribute it and/or modify | ||
5 | # it under the terms of the GNU General Public License as published by | ||
6 | # the Free Software Foundation; either version 3, or (at your option) | ||
7 | # any later version. | ||
8 | # | ||
9 | # Vmod-binlog is distributed in the hope that it will be useful, | ||
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | # GNU General Public License for more details. | ||
13 | # | ||
14 | # You should have received a copy of the GNU General Public License | ||
15 | # along with vmod-binlog. If not, see <http://www.gnu.org/licenses/>. | ||
16 | |||
17 | AM_CPPFLAGS = -I$(VARNISHSRC)/include -I$(VARNISHSRC) | ||
18 | |||
19 | bin_PROGRAMS = binlogcat | ||
20 | binlogcat_SOURCES = binlogcat.c | ||
21 | |||
22 | vmoddir = $(VMODDIR) | ||
23 | vmod_LTLIBRARIES = libvmod_binlog.la | ||
24 | |||
25 | libvmod_binlog_la_LDFLAGS = -module -export-dynamic -avoid-version | ||
26 | libvmod_binlog_la_LIBADD= | ||
27 | |||
28 | libvmod_binlog_la_SOURCES = \ | ||
29 | binlog.c\ | ||
30 | vmod-binlog.h\ | ||
31 | vcc_if.c vcc_if.h | ||
32 | |||
33 | BUILT_SOURCES = vcc_if.c vcc_if.h | ||
34 | |||
35 | vcc_if.c vcc_if.h: $(VARNISHSRC)/lib/libvmod_std/vmod.py $(top_srcdir)/src/vmod.vcc | ||
36 | @PYTHON@ $(VARNISHSRC)/lib/libvmod_std/vmod.py $(top_srcdir)/src/vmod.vcc | ||
37 | |||
38 | EXTRA_DIST = vmod.vcc | ||
39 | |||
40 | CLEANFILES = $(builddir)/vcc_if.c $(builddir)/vcc_if.h | ||
41 | |||
diff --git a/src/binlog.c b/src/binlog.c new file mode 100644 index 0000000..f896803 --- /dev/null +++ b/src/binlog.c | |||
@@ -0,0 +1,516 @@ | |||
1 | /* This file is part of vmod-binlog | ||
2 | Copyright (C) 2013 Sergey Poznyakoff | ||
3 | |||
4 | Vmod-binlog is free software; you can redistribute it and/or modify | ||
5 | it under the terms of the GNU General Public License as published by | ||
6 | the Free Software Foundation; either version 3, or (at your option) | ||
7 | any later version. | ||
8 | |||
9 | Vmod-binlog is distributed in the hope that it will be useful, | ||
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | GNU General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with vmod-binlog. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | |||
18 | #include <config.h> | ||
19 | #include <sys/stat.h> | ||
20 | #include <sys/mman.h> | ||
21 | #include <fcntl.h> | ||
22 | #include <unistd.h> | ||
23 | #include <errno.h> | ||
24 | #include <syslog.h> | ||
25 | #include <stdlib.h> | ||
26 | #include <ctype.h> | ||
27 | #include <time.h> | ||
28 | #include "vrt.h" | ||
29 | #include "vcc_if.h" | ||
30 | #include "bin/varnishd/cache.h" | ||
31 | #include "vmod-binlog.h" | ||
32 | |||
33 | #ifndef O_SEARCH | ||
34 | # define O_SEARCH 0 | ||
35 | #endif | ||
36 | |||
37 | #define BLF_ROUNDTS 0x01 | ||
38 | |||
39 | struct binlog_config { | ||
40 | size_t size; /* maximum file size */ | ||
41 | unsigned interval; /* file rotation interval */ | ||
42 | char *pattern; /* file name pattern */ | ||
43 | int umask; /* umask for new files and directories */ | ||
44 | char *dir; /* root storage directory */ | ||
45 | int dd; /* directory descriptor */ | ||
46 | char *fname; /* current file name */ | ||
47 | int fd; /* current file descriptor */ | ||
48 | union binlog_header *base; /* mmap base */ | ||
49 | struct binlog_record *recbase; /* record base */ | ||
50 | size_t recnum; /* number of records in recbase */ | ||
51 | size_t recidx; /* index of the next free entry in recbase */ | ||
52 | time_t stoptime; /* when to rotate the current file */ | ||
53 | pthread_mutex_t mutex; | ||
54 | int debug; | ||
55 | int flags; | ||
56 | }; | ||
57 | |||
58 | static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; | ||
59 | |||
60 | void | ||
61 | binlog_error(const char *fmt, ...) | ||
62 | { | ||
63 | va_list ap; | ||
64 | va_start(ap, fmt); | ||
65 | vsyslog(LOG_DAEMON|LOG_ERR, fmt, ap); | ||
66 | va_end(ap); | ||
67 | } | ||
68 | |||
69 | void | ||
70 | binlog_debug(const char *fmt, ...) | ||
71 | { | ||
72 | va_list ap; | ||
73 | va_start(ap, fmt); | ||
74 | vsyslog(LOG_DAEMON|LOG_DEBUG, fmt, ap); | ||
75 | va_end(ap); | ||
76 | } | ||
77 | |||
78 | #define debug(c,l,s) do { if ((c)->debug>=(l)) binlog_debug s; } while(0) | ||
79 | |||
80 | int | ||
81 | module_init(struct vmod_priv *priv, const struct VCL_conf *vclconf) | ||
82 | { | ||
83 | struct binlog_config *conf = calloc(1, sizeof(*conf)); | ||
84 | AN(conf); | ||
85 | priv->priv = conf; | ||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | static char * | ||
90 | findparam(const char *param, char *name) | ||
91 | { | ||
92 | const char *p; | ||
93 | char *q; | ||
94 | |||
95 | while (*param) { | ||
96 | for (p = param, q = name; *p && *q && *p == *q; p++, q++); | ||
97 | for (param = p; *param && *param != ';'; param++); | ||
98 | if (*q == 0 && *p == '=') { | ||
99 | size_t len = param - p - 1; | ||
100 | q = malloc(len + 1); | ||
101 | AN(q); | ||
102 | memcpy(q, p + 1, len); | ||
103 | q[len] = 0; | ||
104 | return q; | ||
105 | } | ||
106 | if (*param) | ||
107 | ++param; | ||
108 | } | ||
109 | return NULL; | ||
110 | } | ||
111 | |||
112 | static unsigned long | ||
113 | getinterval(char *p, char **endp) | ||
114 | { | ||
115 | int n; | ||
116 | unsigned long hours = 0, minutes = 0, seconds = 0; | ||
117 | |||
118 | for (;;) { | ||
119 | n = 0; | ||
120 | while (*p && isdigit(*p)) { | ||
121 | n = 10*n + *p - '0'; | ||
122 | p++; | ||
123 | } | ||
124 | |||
125 | switch (*p) { | ||
126 | case 'h': | ||
127 | case 'H': | ||
128 | if (hours) { | ||
129 | *endp = p; | ||
130 | return -1; | ||
131 | } | ||
132 | hours = n; | ||
133 | break; | ||
134 | case 'm': | ||
135 | case 'M': | ||
136 | if (minutes) { | ||
137 | *endp = p; | ||
138 | return -1; | ||
139 | } | ||
140 | minutes = n; | ||
141 | break; | ||
142 | case 's': | ||
143 | case 'S': | ||
144 | if (seconds) { | ||
145 | *endp = p; | ||
146 | return -1; | ||
147 | } | ||
148 | seconds = n; | ||
149 | break; | ||
150 | default: | ||
151 | *endp = p; | ||
152 | if (!hours && !minutes && !seconds) | ||
153 | return n; | ||
154 | return (hours*60 + minutes)*60 + seconds; | ||
155 | } | ||
156 | p++; | ||
157 | } | ||
158 | } | ||
159 | |||
160 | void | ||
161 | vmod_init(struct sess *sp, struct vmod_priv *priv, const char *param) | ||
162 | { | ||
163 | struct binlog_config *conf = priv->priv; | ||
164 | struct stat st; | ||
165 | char *dir, *p, *q; | ||
166 | unsigned long n; | ||
167 | |||
168 | p = findparam(param, "debug"); | ||
169 | if (p) { | ||
170 | conf->debug = atoi(p); | ||
171 | free(p); | ||
172 | } | ||
173 | |||
174 | dir = findparam(param, "dir"); | ||
175 | if (!dir) { | ||
176 | binlog_error("parameter \"dir\" not set"); | ||
177 | abort(); | ||
178 | } | ||
179 | if (stat(dir, &st)) { | ||
180 | if (errno == ENOENT) | ||
181 | binlog_error("logging directory does not exist"); | ||
182 | else | ||
183 | binlog_error("cannot stat logging directory %s: %s", | ||
184 | dir, strerror(errno)); | ||
< |