diff options
author | Edward Rudd | 2008-10-25 16:44:17 +0000 |
---|---|---|
committer | Edward Rudd | 2008-10-25 16:44:17 +0000 |
commit | 19e09e15d96fa891d18fd07bb0f751faa0a7fc7a (patch) | |
tree | 77da4c55a5c91713184a1344cca6270ae8fd0afe /utility/logparse.c | |
parent | caae8dcfed1462cb19c82f99087e6fe2ba3d407c (diff) |
implement query arg extracter
"merge in" ap_unescape_url from HTTPD
updated logging statements
add per-line func data and per-func data
Diffstat (limited to 'utility/logparse.c')
-rw-r--r-- | utility/logparse.c | 105 |
1 files changed, 85 insertions, 20 deletions
diff --git a/utility/logparse.c b/utility/logparse.c index f4afb52..7ea6bc1 100644 --- a/utility/logparse.c +++ b/utility/logparse.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include "database.h" | 12 | #include "database.h" |
13 | 13 | ||
14 | apr_hash_t *g_parser_funcs; | 14 | apr_hash_t *g_parser_funcs; |
15 | void **g_parser_linedata; | ||
15 | 16 | ||
16 | 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, |
17 | config_output_field_t *field, const char *value, const char **ret) | 18 | config_output_field_t *field, const char *value, const char **ret) |
@@ -19,33 +20,34 @@ static apr_status_t parser_func_regexmatch(apr_pool_t *p, config_t *cfg, | |||
19 | struct { | 20 | struct { |
20 | ap_regex_t *rx; | 21 | ap_regex_t *rx; |
21 | const char *substr; | 22 | const char *substr; |
22 | }*data; | 23 | }*_data; |
23 | ap_regmatch_t regm[AP_MAX_REG_MATCH]; | 24 | ap_regmatch_t regm[AP_MAX_REG_MATCH]; |
24 | // Check if a regular expression configured | 25 | // Check if a regular expression configured |
25 | if (!field->args[0]) | 26 | if (!field->args[0]) |
26 | return APR_EINVAL; | 27 | return APR_EINVAL; |
27 | if (!field->data) { | 28 | if (!field->data) { |
28 | // pre compile the regex | 29 | // pre compile the regex |
29 | data = apr_palloc(cfg->pool, sizeof(ap_regex_t)+sizeof(const char *)); | 30 | _data = apr_palloc(cfg->pool, sizeof(ap_regex_t)+sizeof(const char *)); |
30 | data->rx = ap_pregcomp(cfg->pool, field->args[0], | 31 | _data->rx = ap_pregcomp(cfg->pool, field->args[0], |
31 | AP_REG_EXTENDED|AP_REG_ICASE); | 32 | AP_REG_EXTENDED|AP_REG_ICASE); |
32 | if (field->args[1]) { | 33 | if (field->args[1]) { |
33 | data->substr = field->args[1]; | 34 | _data->substr = field->args[1]; |
34 | } else { | 35 | } else { |
35 | data->substr = "$1"; | 36 | _data->substr = "$1"; |
36 | } | 37 | } |
37 | if (!data->rx) | 38 | if (!_data->rx) |
38 | return APR_EINVAL; | 39 | return APR_EINVAL; |
39 | field->data = data; | 40 | field->data = _data; |
40 | } else | 41 | } else |
41 | data = field->data; | 42 | _data = field->data; |
42 | 43 | ||
43 | if (!ap_regexec(data->rx, value, AP_MAX_REG_MATCH, regm, 0)) { | 44 | if (!ap_regexec(_data->rx, value, AP_MAX_REG_MATCH, regm, 0)) { |
44 | *ret = ap_pregsub(p, data->substr, value, AP_MAX_REG_MATCH, regm); | 45 | *ret = ap_pregsub(p, _data->substr, value, AP_MAX_REG_MATCH, regm); |
45 | } else { | 46 | } else { |
46 | *ret = field->def; | 47 | *ret = field->def; |
47 | } | 48 | } |
48 | //printf("We matched %s against %s to %s\n",value, field->args[0], *ret); | 49 | logging_log(cfg, LOGLEVEL_DEBUG, "REGEX: matched %s against %s to %s", value, |
50 | field->args[0], *ret); | ||
49 | return APR_SUCCESS; | 51 | return APR_SUCCESS; |
50 | } | 52 | } |
51 | 53 | ||
@@ -76,26 +78,87 @@ static apr_status_t parser_func_machineid(apr_pool_t *p, config_t *cfg, | |||
76 | } | 78 | } |
77 | 79 | ||
78 | /** @todo Implement Query arg ripping function */ | 80 | /** @todo Implement Query arg ripping function */ |
81 | static apr_status_t parser_func_queryarg(apr_pool_t *p, config_t *cfg, | ||
82 | config_output_field_t *field, const char *value, const char **ret) | ||
83 | { | ||
84 | apr_table_t *query = parser_get_linedata(field->func); | ||
85 | |||
86 | if (!field->args[0]) | ||
87 | return APR_EINVAL; | ||
88 | |||
89 | if (!query) { | ||
90 | char *query_beg; | ||
91 | |||
92 | query = apr_table_make(p,3); | ||
93 | |||
94 | query_beg = strchr(value, '?'); | ||
95 | // if we have a query string, rip it apart | ||
96 | if (query_beg) { | ||
97 | char *key; | ||
98 | char *value; | ||
99 | char *query_string; | ||
100 | char *strtok_state; | ||
101 | char *query_end = strrchr(++query_beg,' '); | ||
102 | |||
103 | query_string = apr_pstrndup(p, query_beg, query_end-query_beg); | ||
104 | logging_log(cfg, LOGLEVEL_DEBUG, "QUERY: Found String %pp, %pp, %s", | ||
105 | query_beg, query_end, query_string); | ||
106 | |||
107 | key = apr_strtok(query_string, "&", &strtok_state); | ||
108 | while (key) { | ||
109 | value = strchr(key, '='); | ||
110 | if (value) { | ||
111 | *value = '\0'; /* Split the string in two */ | ||
112 | value++; /* Skip past the = */ | ||
113 | } | ||
114 | else { | ||
115 | value = "1"; | ||
116 | } | ||
117 | ap_unescape_url(key); | ||
118 | ap_unescape_url(value); | ||
119 | apr_table_set(query, key, value); | ||
120 | |||
121 | logging_log(cfg, LOGLEVEL_DEBUG, | ||
122 | "QUERY: Found arg: %s = %s", key, value); | ||
79 | 123 | ||
80 | parser_func_t parser_get_func(const char *name) | 124 | key = apr_strtok(NULL, "&", &strtok_state); |
125 | } | ||
126 | } | ||
127 | parser_set_linedata(field->func,query); | ||
128 | } | ||
129 | *ret = apr_table_get(query, field->args[0]); | ||
130 | if (*ret == NULL) *ret = field->def; | ||
131 | return APR_SUCCESS; | ||
132 | } | ||
133 | |||
134 | parser_func_t *parser_get_func(const char *name) | ||
81 | { | 135 | { |
82 | return apr_hash_get(g_parser_funcs, name, APR_HASH_KEY_STRING); | 136 | return apr_hash_get(g_parser_funcs, name, APR_HASH_KEY_STRING); |
83 | } | 137 | } |
84 | 138 | ||
85 | static void parser_add_func(apr_pool_t *p, const char *const name, | 139 | static void parser_add_func(apr_pool_t *p, const char *const name, |
86 | parser_func_t func) | 140 | parser_func_f func, int id) |
87 | { | 141 | { |
142 | parser_func_t *s; | ||
88 | if (!g_parser_funcs) { | 143 | if (!g_parser_funcs) { |
89 | g_parser_funcs = apr_hash_make(p); | 144 | g_parser_funcs = apr_hash_make(p); |
90 | } | 145 | } |
91 | apr_hash_set(g_parser_funcs, lowerstr(p, name), APR_HASH_KEY_STRING, func); | 146 | s = apr_palloc(p, sizeof(parser_func_t)); |
147 | s->func = func; | ||
148 | s->pos = id; | ||
149 | s->linedata = &g_parser_linedata; | ||
150 | apr_hash_set(g_parser_funcs, lowerstr(p, name), APR_HASH_KEY_STRING, s); | ||
92 | } | 151 | } |
93 | 152 | ||
94 | void parser_init(apr_pool_t *p) | 153 | void parser_init(apr_pool_t *p) |
95 | { | 154 | { |
96 | parser_add_func(p, "regexmatch", parser_func_regexmatch); | 155 | int i = 0; |
97 | parser_add_func(p, "totimestamp", parser_func_totimestamp); | 156 | parser_add_func(p, "regexmatch", parser_func_regexmatch, ++i); |
98 | parser_add_func(p, "machineid", parser_func_machineid); | 157 | parser_add_func(p, "totimestamp", parser_func_totimestamp, ++i); |
158 | parser_add_func(p, "machineid", parser_func_machineid, ++i); | ||
159 | parser_add_func(p, "queryarg", parser_func_queryarg, ++i); | ||
160 | g_parser_linedata = apr_pcalloc(p, sizeof(void *) * (i+1)); | ||
161 | g_parser_linedata[0] = (void *)i; | ||
99 | } | 162 | } |
100 | 163 | ||
101 | void parser_find_logs(config_t *cfg) | 164 | void parser_find_logs(config_t *cfg) |
@@ -333,8 +396,10 @@ apr_status_t parse_processline(apr_pool_t *ptemp, config_t *cfg, char **argv, | |||
333 | } | 396 | } |
334 | /** @todo Run Pre Filters here */ | 397 | /** @todo Run Pre Filters here */ |
335 | 398 | ||
336 | // Convert input fields to output fields | ||
337 | ofields = (config_output_field_t *)cfg->output_fields->elts; | 399 | ofields = (config_output_field_t *)cfg->output_fields->elts; |
400 | // clear out ofield function per-line data | ||
401 | memset(&g_parser_linedata[1],0,sizeof(void *)*(int)g_parser_linedata[0]); | ||
402 | // Convert input fields to output fields | ||
338 | for (i=0; i<cfg->output_fields->nelts; i++) { | 403 | for (i=0; i<cfg->output_fields->nelts; i++) { |
339 | const char *val; | 404 | const char *val; |
340 | val = apr_table_get(datain, ofields[i].source); | 405 | val = apr_table_get(datain, ofields[i].source); |
@@ -347,8 +412,8 @@ apr_status_t parse_processline(apr_pool_t *ptemp, config_t *cfg, char **argv, | |||
347 | apr_table_setn(dataout, ofields[i].field, val); | 412 | apr_table_setn(dataout, ofields[i].field, val); |
348 | } else { | 413 | } else { |
349 | const char *ret= NULL; | 414 | const char *ret= NULL; |
350 | rv = ((parser_func_t)ofields[i].func)(ptemp, cfg, &ofields[i], val, | 415 | rv = ((parser_func_t *)ofields[i].func)->func(ptemp, cfg, |
351 | &ret); | 416 | &ofields[i], val, &ret); |
352 | if (rv) | 417 | if (rv) |
353 | return rv; | 418 | return rv; |
354 | apr_table_setn(dataout, ofields[i].field, ret); | 419 | apr_table_setn(dataout, ofields[i].field, ret); |