diff options
| author | 2008-10-25 16:44:17 +0000 | |
|---|---|---|
| committer | 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); |
