diff options
Diffstat (limited to 'utility')
-rw-r--r-- | utility/config.c | 31 | ||||
-rw-r--r-- | utility/config.h | 6 | ||||
-rw-r--r-- | utility/database.c | 102 | ||||
-rw-r--r-- | utility/logparse.c | 28 | ||||
-rw-r--r-- | utility/logparse.h | 2 | ||||
-rw-r--r-- | utility/shell.c | 20 | ||||
-rw-r--r-- | utility/util.c | 39 | ||||
-rw-r--r-- | utility/util.h | 7 |
8 files changed, 170 insertions, 65 deletions
diff --git a/utility/config.c b/utility/config.c index d3a6ca5..ccdc6e5 100644 --- a/utility/config.c +++ b/utility/config.c | |||
@@ -23,19 +23,6 @@ static apr_status_t config_set_string(config_t *cfg, config_opt_t *opt, | |||
23 | return APR_SUCCESS; | 23 | return APR_SUCCESS; |
24 | } | 24 | } |
25 | 25 | ||
26 | static apr_status_t config_set_int(config_t *cfg, config_opt_t *opt, int argc, | ||
27 | const char **argv) __attribute__ ((__unused__)); | ||
28 | static apr_status_t config_set_int(config_t *cfg, config_opt_t *opt, int argc, | ||
29 | const char **argv) | ||
30 | { | ||
31 | int offset = (int)(long)opt->data; | ||
32 | int *data = (int *)((void *)cfg + offset); | ||
33 | if (argc != 2) | ||
34 | return APR_EINVAL; | ||
35 | *data = apr_atoi64(argv[1]); | ||
36 | return APR_SUCCESS; | ||
37 | } | ||
38 | |||
39 | static apr_status_t config_set_flag(config_t *cfg, config_opt_t *opt, int argc, | 26 | static apr_status_t config_set_flag(config_t *cfg, config_opt_t *opt, int argc, |
40 | const char **argv) | 27 | const char **argv) |
41 | { | 28 | { |
@@ -329,6 +316,24 @@ config_t *config_create(apr_pool_t *p) | |||
329 | return cfg; | 316 | return cfg; |
330 | } | 317 | } |
331 | 318 | ||
319 | apr_status_t config_check(config_t *cfg) | ||
320 | { | ||
321 | apr_status_t ret = APR_SUCCESS; | ||
322 | if (!cfg->dbdriver || !cfg->dbparams) { | ||
323 | printf("Database configuration is missing\n"); | ||
324 | ret = APR_EINVAL; | ||
325 | } | ||
326 | if (!cfg->table) { | ||
327 | printf("No Log Table defined\n"); | ||
328 | ret = APR_EINVAL; | ||
329 | } | ||
330 | if (apr_is_empty_array(cfg->output_fields)) { | ||
331 | printf("No Output Fields Defined\n"); | ||
332 | ret = APR_EINVAL; | ||
333 | } | ||
334 | return ret; | ||
335 | } | ||
336 | |||
332 | static int config_merge(void *rec, const char *key, const char *value) | 337 | static int config_merge(void *rec, const char *key, const char *value) |
333 | { | 338 | { |
334 | config_t *cfg = (config_t *)rec; | 339 | config_t *cfg = (config_t *)rec; |
diff --git a/utility/config.h b/utility/config.h index 0e80856..611e9de 100644 --- a/utility/config.h +++ b/utility/config.h | |||
@@ -25,6 +25,7 @@ struct config_t { | |||
25 | loglevel_e loglevel; | 25 | loglevel_e loglevel; |
26 | /** error_log */ | 26 | /** error_log */ |
27 | apr_file_t *errorlog_fp; | 27 | apr_file_t *errorlog_fp; |
28 | apr_pool_t *errorlog_p; | ||
28 | 29 | ||
29 | /** input directory of log files */ | 30 | /** input directory of log files */ |
30 | const char *input_dir; | 31 | const char *input_dir; |
@@ -135,6 +136,11 @@ void config_init(apr_pool_t *p); | |||
135 | void config_dump(config_t *cfg); | 136 | void config_dump(config_t *cfg); |
136 | 137 | ||
137 | /** | 138 | /** |
139 | * Checks the configuration to ensure all the required settings are set | ||
140 | */ | ||
141 | apr_status_t config_check(config_t *cfg); | ||
142 | |||
143 | /** | ||
138 | * Creates the default configuration | 144 | * Creates the default configuration |
139 | */ | 145 | */ |
140 | config_t *config_create(apr_pool_t *p); | 146 | config_t *config_create(apr_pool_t *p); |
diff --git a/utility/database.c b/utility/database.c index a979268..45022da 100644 --- a/utility/database.c +++ b/utility/database.c | |||
@@ -3,6 +3,8 @@ | |||
3 | #include "apr_dbd.h" | 3 | #include "apr_dbd.h" |
4 | #include "apr_strings.h" | 4 | #include "apr_strings.h" |
5 | 5 | ||
6 | #include "util.h" | ||
7 | |||
6 | struct config_dbd_t { | 8 | struct config_dbd_t { |
7 | const apr_dbd_driver_t *driver; | 9 | const apr_dbd_driver_t *driver; |
8 | apr_dbd_t *dbd; | 10 | apr_dbd_t *dbd; |
@@ -18,17 +20,26 @@ void database_init(apr_pool_t *p) | |||
18 | apr_status_t database_connect(config_t *cfg) | 20 | apr_status_t database_connect(config_t *cfg) |
19 | { | 21 | { |
20 | apr_status_t rv; | 22 | apr_status_t rv; |
23 | if (!cfg->dbdriver || !cfg->dbparams) | ||
24 | return APR_EINVAL; | ||
21 | if (!cfg->dbconn) { | 25 | if (!cfg->dbconn) { |
22 | cfg->dbconn = apr_pcalloc(cfg->pool, sizeof(config_dbd_t)); | 26 | cfg->dbconn = apr_pcalloc(cfg->pool, sizeof(config_dbd_t)); |
23 | } | 27 | } |
24 | rv = apr_dbd_get_driver(cfg->pool, cfg->dbdriver, &(cfg->dbconn->driver)); | 28 | rv = apr_dbd_get_driver(cfg->pool, cfg->dbdriver, &(cfg->dbconn->driver)); |
25 | if (rv) | 29 | if (rv) { |
30 | logging_log(cfg, LOGLEVEL_ERROR, | ||
31 | "Could not load database driver %s. Error %d", cfg->dbdriver, | ||
32 | rv); | ||
26 | return rv; | 33 | return rv; |
34 | } | ||
27 | 35 | ||
28 | rv = apr_dbd_open(cfg->dbconn->driver, cfg->pool, cfg->dbparams, | 36 | rv = apr_dbd_open(cfg->dbconn->driver, cfg->pool, cfg->dbparams, |
29 | &(cfg->dbconn->dbd)); | 37 | &(cfg->dbconn->dbd)); |
30 | if (rv) | 38 | if (rv) { |
39 | logging_log(cfg, LOGLEVEL_ERROR, | ||
40 | "Could not connect to database. Error %d", rv); | ||
31 | return rv; | 41 | return rv; |
42 | } | ||
32 | 43 | ||
33 | return APR_SUCCESS; | 44 | return APR_SUCCESS; |
34 | } | 45 | } |
@@ -38,6 +49,56 @@ apr_status_t database_disconnect(config_t *cfg) | |||
38 | return apr_dbd_close(cfg->dbconn->driver, cfg->dbconn->dbd); | 49 | return apr_dbd_close(cfg->dbconn->driver, cfg->dbconn->dbd); |
39 | } | 50 | } |
40 | 51 | ||
52 | static apr_dbd_prepared_t *database_prepare_insert(config_t *cfg, apr_pool_t *p) | ||
53 | { | ||
54 | apr_status_t rv; | ||
55 | char *sql; | ||
56 | int i, f; | ||
57 | struct iovec *vec; | ||
58 | apr_dbd_prepared_t *stmt; | ||
59 | int nfs = cfg->output_fields->nelts; | ||
60 | config_output_field_t *ofields; | ||
61 | |||
62 | ofields = (config_output_field_t *)cfg->output_fields->elts; | ||
63 | |||
64 | vec = apr_palloc(p, (nfs*2 + 5) * sizeof(struct iovec)); | ||
65 | sql = apr_palloc(p, (nfs*3)); | ||
66 | |||
67 | vec[0].iov_base = "INSERT INTO "; | ||
68 | vec[0].iov_len = 12; | ||
69 | vec[1].iov_base = (void *)cfg->table; | ||
70 | vec[1].iov_len = strlen(cfg->table); | ||
71 | vec[2].iov_base = " ("; | ||
72 | vec[2].iov_len = 2; | ||
73 | for (i=3, f=0; f<nfs; f++, i+=2) { | ||
74 | vec[i].iov_base = (void *)ofields[f].field; | ||
75 | vec[i].iov_len = strlen(vec[i].iov_base); | ||
76 | vec[i+1].iov_base = ","; | ||
77 | vec[i+1].iov_len = 1; | ||
78 | memcpy(&sql[f*3], "%s,", 3); | ||
79 | } | ||
80 | sql[nfs*3-1] = '\0'; | ||
81 | vec[i-1].iov_base = ") VALUES ("; | ||
82 | vec[i-1].iov_len = 10; | ||
83 | vec[i].iov_base = sql; | ||
84 | vec[i].iov_len = nfs*3-1; | ||
85 | vec[i+1].iov_base = ")"; | ||
86 | vec[i+1].iov_len = 1; | ||
87 | |||
88 | sql = apr_pstrcatv(p, vec, i+2, NULL); | ||
89 | |||
90 | printf("SQL: %s\n", sql); | ||
91 | |||
92 | rv = apr_dbd_prepare(cfg->dbconn->driver, cfg->pool, cfg->dbconn->dbd, sql, | ||
93 | "INSERT", &stmt); | ||
94 | |||
95 | if (rv) { | ||
96 | printf("DB Error: %s\n", apr_dbd_error(cfg->dbconn->driver, | ||
97 | cfg->dbconn->dbd, rv)); | ||
98 | return NULL; | ||
99 | } | ||
100 | return stmt; | ||
101 | } | ||
41 | apr_status_t database_insert(config_t *cfg, apr_pool_t *p, apr_table_t *data) | 102 | apr_status_t database_insert(config_t *cfg, apr_pool_t *p, apr_table_t *data) |
42 | { | 103 | { |
43 | apr_status_t rv; | 104 | apr_status_t rv; |
@@ -47,41 +108,8 @@ apr_status_t database_insert(config_t *cfg, apr_pool_t *p, apr_table_t *data) | |||
47 | nfs = cfg->output_fields->nelts; | 108 | nfs = cfg->output_fields->nelts; |
48 | // Prepare statement | 109 | // Prepare statement |
49 | if (!cfg->dbconn->stmt) { | 110 | if (!cfg->dbconn->stmt) { |
50 | char *sql; | 111 | cfg->dbconn->stmt = database_prepare_insert(cfg, p); |
51 | int i; | ||
52 | struct iovec *vec; | ||
53 | vec = apr_palloc(p, (nfs*2 + 5) * sizeof(struct iovec)); | ||
54 | sql = apr_palloc(p, (nfs*3)); | ||
55 | vec[0].iov_base = "INSERT INTO "; | ||
56 | vec[0].iov_len = 12; | ||
57 | vec[1].iov_base = (void *)cfg->table; | ||
58 | vec[1].iov_len = strlen(cfg->table); | ||
59 | vec[2].iov_base = " ("; | ||
60 | vec[2].iov_len = 2; | ||
61 | for (i=3, f=0; f<nfs; f++, i+=2) { | ||
62 | vec[i].iov_base = (void *)ofields[f].field; | ||
63 | vec[i].iov_len = strlen(vec[i].iov_base); | ||
64 | vec[i+1].iov_base = ","; | ||
65 | vec[i+1].iov_len = 1; | ||
66 | memcpy(&sql[f*3], "%s,", 3); | ||
67 | } | ||
68 | sql[nfs*3-1] = '\0'; | ||
69 | vec[i-1].iov_base = ") VALUES ("; | ||
70 | vec[i-1].iov_len = 10; | ||
71 | vec[i].iov_base = sql; | ||
72 | vec[i].iov_len = nfs*3-1; | ||
73 | vec[i+1].iov_base = ")"; | ||
74 | vec[i+1].iov_len = 1; | ||
75 | sql = apr_pstrcatv(p, vec, i+2, NULL); | ||
76 | printf("SQL: %s\n", sql); | ||
77 | cfg->dbconn->args = apr_palloc(cfg->pool, nfs * sizeof(char *)); | 112 | cfg->dbconn->args = apr_palloc(cfg->pool, nfs * sizeof(char *)); |
78 | rv = apr_dbd_prepare(cfg->dbconn->driver, cfg->pool, cfg->dbconn->dbd, | ||
79 | sql, "INSERT", &(cfg->dbconn->stmt)); | ||
80 | if (rv) { | ||
81 | printf("DB Error: %s\n", apr_dbd_error(cfg->dbconn->driver, | ||
82 | cfg->dbconn->dbd, rv)); | ||
83 | return rv; | ||
84 | } | ||
85 | } | 113 | } |
86 | for (f=0; f<nfs; f++) { | 114 | for (f=0; f<nfs; f++) { |
87 | cfg->dbconn->args[f] = apr_table_get(data, ofields[f].field); | 115 | cfg->dbconn->args[f] = apr_table_get(data, ofields[f].field); |
@@ -95,3 +123,5 @@ apr_status_t database_insert(config_t *cfg, apr_pool_t *p, apr_table_t *data) | |||
95 | } | 123 | } |
96 | return APR_SUCCESS; | 124 | return APR_SUCCESS; |
97 | } | 125 | } |
126 | |||
127 | /** @todo implement transactions */ | ||
diff --git a/utility/logparse.c b/utility/logparse.c index dfe2e9b..4b5ab40 100644 --- a/utility/logparse.c +++ b/utility/logparse.c | |||
@@ -15,7 +15,7 @@ | |||
15 | apr_hash_t *g_parser_funcs; | 15 | apr_hash_t *g_parser_funcs; |
16 | 16 | ||
17 | static apr_status_t parser_func_regexmatch(apr_pool_t *p, config_t *cfg, | 17 | static apr_status_t parser_func_regexmatch(apr_pool_t *p, config_t *cfg, |
18 | config_output_field_t *field, const char *value, char **ret) | 18 | config_output_field_t *field, const char *value, const char **ret) |
19 | { | 19 | { |
20 | struct { | 20 | struct { |
21 | ap_regex_t *rx; | 21 | ap_regex_t *rx; |
@@ -48,7 +48,7 @@ static apr_status_t parser_func_regexmatch(apr_pool_t *p, config_t *cfg, | |||
48 | } | 48 | } |
49 | 49 | ||
50 | static apr_status_t parser_func_totimestamp(apr_pool_t *p, config_t *cfg, | 50 | static apr_status_t parser_func_totimestamp(apr_pool_t *p, config_t *cfg, |
51 | config_output_field_t *field, const char *value, char **ret) | 51 | config_output_field_t *field, const char *value, const char **ret) |
52 | { | 52 | { |
53 | time_t time; | 53 | time_t time; |
54 | struct tm ts; | 54 | struct tm ts; |
@@ -63,12 +63,18 @@ static apr_status_t parser_func_totimestamp(apr_pool_t *p, config_t *cfg, | |||
63 | } | 63 | } |
64 | 64 | ||
65 | static apr_status_t parser_func_machineid(apr_pool_t *p, config_t *cfg, | 65 | static apr_status_t parser_func_machineid(apr_pool_t *p, config_t *cfg, |
66 | config_output_field_t *field, const char *value, char **ret) | 66 | config_output_field_t *field, const char *value, const char **ret) |
67 | { | 67 | { |
68 | *ret = apr_pstrdup(p,cfg->machineid); | 68 | if (cfg->machineid) { |
69 | *ret = apr_pstrdup(p,cfg->machineid); | ||
70 | } else { | ||
71 | *ret = field->def; | ||
72 | } | ||
69 | return APR_SUCCESS; | 73 | return APR_SUCCESS; |
70 | } | 74 | } |
71 | 75 | ||
76 | /** @todo Implement Query arg ripping function */ | ||
77 | |||
72 | parser_func_t parser_get_func(const char *name) | 78 | parser_func_t parser_get_func(const char *name) |
73 | { | 79 | { |
74 | return apr_hash_get(g_parser_funcs, name, APR_HASH_KEY_STRING); | 80 | return apr_hash_get(g_parser_funcs, name, APR_HASH_KEY_STRING); |
@@ -258,6 +264,7 @@ apr_status_t parse_logfile(config_t *cfg, const char *filename) | |||
258 | rv = apr_file_open(&file, filename, APR_FOPEN_READ | APR_BUFFERED, | 264 | rv = apr_file_open(&file, filename, APR_FOPEN_READ | APR_BUFFERED, |
259 | APR_OS_DEFAULT, tp); | 265 | APR_OS_DEFAULT, tp); |
260 | if (rv != APR_SUCCESS) { | 266 | if (rv != APR_SUCCESS) { |
267 | logging_log(cfg, LOGLEVEL_ERROR, "Could not open %s",filename); | ||
261 | printf("Could not open %s\n", filename); | 268 | printf("Could not open %s\n", filename); |
262 | return rv; | 269 | return rv; |
263 | } | 270 | } |
@@ -298,7 +305,7 @@ apr_status_t parse_processline(apr_pool_t *ptemp, config_t *cfg, char **argv, in | |||
298 | config_output_field_t *ofields; | 305 | config_output_field_t *ofields; |
299 | apr_table_t *datain; | 306 | apr_table_t *datain; |
300 | apr_table_t *dataout; | 307 | apr_table_t *dataout; |
301 | apr_status_t rv; | 308 | apr_status_t rv = APR_SUCCESS; |
302 | int i; | 309 | int i; |
303 | 310 | ||
304 | fmt = apr_hash_get(cfg->log_formats, cfg->logformat, APR_HASH_KEY_STRING); | 311 | fmt = apr_hash_get(cfg->log_formats, cfg->logformat, APR_HASH_KEY_STRING); |
@@ -326,21 +333,20 @@ apr_status_t parse_processline(apr_pool_t *ptemp, config_t *cfg, char **argv, in | |||
326 | } | 333 | } |
327 | if (!ofields[i].func) { | 334 | if (!ofields[i].func) { |
328 | apr_table_setn(dataout,ofields[i].field, val); | 335 | apr_table_setn(dataout,ofields[i].field, val); |
329 | //printf("S: %s = %s\n",ofields[i].field, val); | ||
330 | } else { | 336 | } else { |
331 | char *ret = NULL; | 337 | const char *ret = NULL; |
332 | rv = ((parser_func_t)ofields[i].func)(ptemp, cfg, &ofields[i], val, | 338 | rv = ((parser_func_t)ofields[i].func)(ptemp, cfg, &ofields[i], val, |
333 | &ret); | 339 | &ret); |
334 | if (rv) return rv; | 340 | if (rv) return rv; |
335 | apr_table_setn(dataout, ofields[i].field, ret); | 341 | apr_table_setn(dataout, ofields[i].field, ret); |
336 | //printf("S: %s = %s\n",ofields[i].field, ret); | ||
337 | } | 342 | } |
338 | } | 343 | } |
339 | 344 | ||
340 | /** @todo Run Post Filters here */ | 345 | /** @todo Run Post Filters here */ |
341 | 346 | ||
342 | // Process DB Query | 347 | // Process DB Query |
343 | rv = database_insert(cfg, ptemp, dataout); | 348 | if (!cfg->dryrun) { |
344 | if (rv) return rv; | 349 | rv = database_insert(cfg, ptemp, dataout); |
345 | return APR_SUCCESS; | 350 | } |
351 | return rv; | ||
346 | } | 352 | } |
diff --git a/utility/logparse.h b/utility/logparse.h index 53b376b..816624a 100644 --- a/utility/logparse.h +++ b/utility/logparse.h | |||
@@ -4,7 +4,7 @@ | |||
4 | #include "config.h" | 4 | #include "config.h" |
5 | 5 | ||
6 | typedef apr_status_t (*parser_func_t)(apr_pool_t *p, config_t *cfg, | 6 | typedef apr_status_t (*parser_func_t)(apr_pool_t *p, config_t *cfg, |
7 | config_output_field_t *field, const char *value, char **ret); | 7 | config_output_field_t *field, const char *value, const char **ret); |
8 | 8 | ||
9 | parser_func_t parser_get_func(const char *name); | 9 | parser_func_t parser_get_func(const char *name); |
10 | 10 | ||
diff --git a/utility/shell.c b/utility/shell.c index 94cca35..b289bce 100644 --- a/utility/shell.c +++ b/utility/shell.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include "config.h" | 10 | #include "config.h" |
11 | #include "logparse.h" | 11 | #include "logparse.h" |
12 | #include "database.h" | 12 | #include "database.h" |
13 | #include "util.h" | ||
13 | 14 | ||
14 | const apr_getopt_option_t _opt_config[] = { | 15 | const apr_getopt_option_t _opt_config[] = { |
15 | {"machineid", 'm', 1, "Machine ID for the log file"}, | 16 | {"machineid", 'm', 1, "Machine ID for the log file"}, |
@@ -127,6 +128,7 @@ int main(int argc, const char *const argv[]) | |||
127 | parser_init(pool); | 128 | parser_init(pool); |
128 | config_init(pool); | 129 | config_init(pool); |
129 | database_init(pool); | 130 | database_init(pool); |
131 | logging_init(pool); | ||
130 | // Process configuration file | 132 | // Process configuration file |
131 | base = config_create(pool); | 133 | base = config_create(pool); |
132 | rv = config_read(base, apr_table_get(args,"Config"), args); | 134 | rv = config_read(base, apr_table_get(args,"Config"), args); |
@@ -139,11 +141,18 @@ int main(int argc, const char *const argv[]) | |||
139 | } | 141 | } |
140 | config_dump(base); | 142 | config_dump(base); |
141 | 143 | ||
144 | if (config_check(base)) { | ||
145 | printf("Please correct the configuration\n"); | ||
146 | exit(1); | ||
147 | } | ||
148 | |||
142 | // Find files and parse | 149 | // Find files and parse |
143 | parser_find_logs(base); | 150 | parser_find_logs(base); |
144 | if ((rv = database_connect(base))) { | 151 | if (!base->dryrun) { |
145 | printf("Error Connecting to Database: %d\n",rv); | 152 | if ((rv = database_connect(base))) { |
146 | exit(1); | 153 | printf("Error Connecting to Database: %d\n",rv); |
154 | exit(1); | ||
155 | } | ||
147 | } | 156 | } |
148 | if (!apr_is_empty_array(base->input_files)) { | 157 | if (!apr_is_empty_array(base->input_files)) { |
149 | char **filelist; | 158 | char **filelist; |
@@ -156,6 +165,9 @@ int main(int argc, const char *const argv[]) | |||
156 | } else { | 165 | } else { |
157 | printf("No input files\n"); | 166 | printf("No input files\n"); |
158 | } | 167 | } |
159 | database_disconnect(base); | 168 | if (!base->dryrun) { |
169 | database_disconnect(base); | ||
170 | } | ||
171 | /** @todo summary goes here */ | ||
160 | return 0; | 172 | return 0; |
161 | } | 173 | } |
diff --git a/utility/util.c b/utility/util.c index ef3ea68..cb6898d 100644 --- a/utility/util.c +++ b/utility/util.c | |||
@@ -1,7 +1,11 @@ | |||
1 | #include "util.h" | 1 | #include "util.h" |
2 | #include "apr_strings.h" | 2 | #include "apr_strings.h" |
3 | #include "apr_lib.h" | 3 | #include "apr_lib.h" |
4 | #include "apr_file_io.h" | ||
4 | 5 | ||
6 | #include "config.h" | ||
7 | |||
8 | #include <stdarg.h> | ||
5 | 9 | ||
6 | char *lowerstr(apr_pool_t *pool, const char *input) | 10 | char *lowerstr(apr_pool_t *pool, const char *input) |
7 | { | 11 | { |
@@ -26,3 +30,38 @@ void line_chomp(char *str) | |||
26 | } | 30 | } |
27 | } | 31 | } |
28 | } | 32 | } |
33 | |||
34 | void logging_init(config_t *cfg) | ||
35 | { | ||
36 | if (cfg->errorlog) { | ||
37 | apr_file_open(&cfg->errorlog_fp, cfg->errorlog, | ||
38 | APR_FOPEN_CREATE | APR_FOPEN_WRITE | APR_BUFFERED, | ||
39 | APR_OS_DEFAULT, | ||
40 | cfg->pool); | ||
41 | apr_pool_create(&cfg->errorlog_p, cfg->pool); | ||
42 | } | ||
43 | } | ||
44 | |||
45 | /** | ||
46 | * @todo implement logging | ||
47 | */ | ||
48 | void logging_log(config_t *cfg, loglevel_e level, const char *fmt, ...) | ||
49 | { | ||
50 | va_list ap; | ||
51 | struct iovec vec[2]; | ||
52 | apr_size_t blen; | ||
53 | |||
54 | if (!cfg->errorlog_fp || cfg->loglevel < level) return; | ||
55 | |||
56 | va_start(ap, fmt); | ||
57 | apr_pool_clear(cfg->errorlog_p); | ||
58 | |||
59 | vec[0].iov_base = apr_pvsprintf(cfg->errorlog_p, fmt, ap); | ||
60 | vec[0].iov_len = strlen(vec[0].iov_base); | ||
61 | vec[1].iov_base = "\n"; | ||
62 | vec[1].iov_len = 1; | ||
63 | |||
64 | apr_file_writev(cfg->errorlog_fp,vec,2,&blen); | ||
65 | |||
66 | va_end(ap); | ||
67 | } | ||
diff --git a/utility/util.h b/utility/util.h index 8c48474..9e3aed3 100644 --- a/utility/util.h +++ b/utility/util.h | |||
@@ -3,6 +3,8 @@ | |||
3 | 3 | ||
4 | #include "apr_pools.h" | 4 | #include "apr_pools.h" |
5 | 5 | ||
6 | #include "config.h" | ||
7 | |||
6 | char *lowerstr(apr_pool_t *pool, const char *input); | 8 | char *lowerstr(apr_pool_t *pool, const char *input); |
7 | 9 | ||
8 | /** | 10 | /** |
@@ -10,4 +12,9 @@ char *lowerstr(apr_pool_t *pool, const char *input); | |||
10 | */ | 12 | */ |
11 | void line_chomp(char *str); | 13 | void line_chomp(char *str); |
12 | 14 | ||
15 | void logging_init(config_t *cfg); | ||
16 | |||
17 | void logging_log(config_t *cfg, loglevel_e level, const char *fmt, ...) | ||
18 | __attribute__((format(printf, 3, 4))); | ||
19 | |||
13 | #endif /*UTIL_H_*/ | 20 | #endif /*UTIL_H_*/ |