summaryrefslogtreecommitdiffstats
path: root/utility
diff options
context:
space:
mode:
authorGravatar Edward Rudd 2008-10-24 13:55:48 +0000
committerGravatar Edward Rudd 2008-10-24 13:55:48 +0000
commit19bbdd68a491721dd4aeff7cacea51148ce3a9b9 (patch)
tree4e143a77f879f7baf65797c08a4e3a489b4ac755 /utility
parent50af087b9f3831285869dc8d8bf91cc3e6d5169a (diff)
add logging function
added @todo tags for what needs to be finished
Diffstat (limited to 'utility')
-rw-r--r--utility/config.c31
-rw-r--r--utility/config.h6
-rw-r--r--utility/database.c102
-rw-r--r--utility/logparse.c28
-rw-r--r--utility/logparse.h2
-rw-r--r--utility/shell.c20
-rw-r--r--utility/util.c39
-rw-r--r--utility/util.h7
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
26static apr_status_t config_set_int(config_t *cfg, config_opt_t *opt, int argc,
27 const char **argv) __attribute__ ((__unused__));
28static 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
39static apr_status_t config_set_flag(config_t *cfg, config_opt_t *opt, int argc, 26static 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
319apr_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
332static int config_merge(void *rec, const char *key, const char *value) 337static 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);
135void config_dump(config_t *cfg); 136void config_dump(config_t *cfg);
136 137
137/** 138/**
139 * Checks the configuration to ensure all the required settings are set
140 */
141apr_status_t config_check(config_t *cfg);
142
143/**
138 * Creates the default configuration 144 * Creates the default configuration
139 */ 145 */
140config_t *config_create(apr_pool_t *p); 146config_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
6struct config_dbd_t { 8struct 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)
18apr_status_t database_connect(config_t *cfg) 20apr_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
52static 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}
41apr_status_t database_insert(config_t *cfg, apr_pool_t *p, apr_table_t *data) 102apr_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 @@
15apr_hash_t *g_parser_funcs; 15apr_hash_t *g_parser_funcs;
16 16
17static apr_status_t parser_func_regexmatch(apr_pool_t *p, config_t *cfg, 17static 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
50static apr_status_t parser_func_totimestamp(apr_pool_t *p, config_t *cfg, 50static 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
65static apr_status_t parser_func_machineid(apr_pool_t *p, config_t *cfg, 65static 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
72parser_func_t parser_get_func(const char *name) 78parser_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
6typedef apr_status_t (*parser_func_t)(apr_pool_t *p, config_t *cfg, 6typedef 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
9parser_func_t parser_get_func(const char *name); 9parser_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
14const apr_getopt_option_t _opt_config[] = { 15const 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
6char *lowerstr(apr_pool_t *pool, const char *input) 10char *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
34void 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 */
48void 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
6char *lowerstr(apr_pool_t *pool, const char *input); 8char *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 */
11void line_chomp(char *str); 13void line_chomp(char *str);
12 14
15void logging_init(config_t *cfg);
16
17void 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_*/