From: Fabian Keil Date: Fri, 7 Aug 2020 09:08:23 +0000 (+0200) Subject: Gather statistics for block reasons X-Git-Tag: v_3_0_29~228 X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=commitdiff_plain;h=92d54bfa51701a0b2b96a1b929bd9b7279b89fab Gather statistics for block reasons ... if FEATURE_EXTENDED_STATISTICS is enabled. Sponsored by: Robert Klemme --- diff --git a/actions.c b/actions.c index a1c00f98..087f59db 100644 --- a/actions.c +++ b/actions.c @@ -547,6 +547,12 @@ jb_err get_actions(char *line, return JB_ERR_PARSE; } } +#ifdef FEATURE_EXTENDED_STATISTICS + if (0 == strcmpic(action->name, "+block")) + { + register_block_reason_for_statistics(value); + } +#endif /* FIXME: should validate option string here */ freez (cur_action->string[action->index]); cur_action->string[action->index] = strdup(value); diff --git a/cgisimple.c b/cgisimple.c index 3428d81e..e738a605 100644 --- a/cgisimple.c +++ b/cgisimple.c @@ -1032,6 +1032,76 @@ jb_err cgi_send_user_manual(struct client_state *csp, #ifdef FEATURE_EXTENDED_STATISTICS +/********************************************************************* + * + * Function : get_block_reason_statistics_table + * + * Description : Produces the block reason statistic table content. + * + * Parameters : + * 1 : csp = Current client state (buffers, headers, etc...) + * + * Returns : Pointer to the HTML statistic table content or + * NULL on out of memory + * + *********************************************************************/ +static char *get_block_reason_statistics_table(const struct client_state *csp) +{ + char buf[BUFFER_SIZE]; + char *statistics; + int i; + struct file_list *fl; + jb_err err = JB_ERR_OK; + + statistics = strdup_or_die(""); + + /* Run through all action files. */ + for (i = 0; i < MAX_AF_FILES; i++) + { + struct url_actions *b; + struct action_spec *last_action = NULL; + + if (((fl = csp->actions_list[i]) == NULL) || ((b = fl->f) == NULL)) + { + /* Skip empty files */ + continue; + } + + /* Go through all the actions. */ + for (b = b->next; NULL != b; b = b->next) + { + if (last_action == b->action) + { + continue; + } + if ((b->action->add & ACTION_BLOCK)) + { + unsigned long long count; + const char *block_reason = b->action->string[ACTION_STRING_BLOCK]; + const char *encoded_block_reason = html_encode(block_reason); + + if (encoded_block_reason == NULL) + { + freez(statistics); + return NULL; + } + get_block_reason_count(block_reason, &count); + snprintf(buf, sizeof(buf), + "%s%llu", + encoded_block_reason, count); + freez(encoded_block_reason); + + if (!err) err = string_append(&statistics, buf); + } + last_action = b->action; + } + } + + return statistics; + +} + + /********************************************************************* * * Function : get_filter_statistics_table @@ -1094,7 +1164,7 @@ static char *get_filter_statistics_table(const struct client_state *csp) return statistics; } -#endif +#endif /* def FEATURE_EXTENDED_STATISTICS */ /********************************************************************* @@ -1210,6 +1280,17 @@ jb_err cgi_show_status(struct client_state *csp, #endif /* ndef FEATURE_STATISTICS */ #ifdef FEATURE_EXTENDED_STATISTICS + { + char *block_reason_statistics = get_block_reason_statistics_table(csp); + if (block_reason_statistics != NULL) + { + if (!err) err = map(exports, "block-reason-statistics", 1, block_reason_statistics, 0); + } + else + { + if (!err) err = map_block_killer(exports, "extended-statistics"); + } + } { char *filter_statistics = get_filter_statistics_table(csp); if (filter_statistics != NULL) diff --git a/filters.c b/filters.c index 82f79db4..0c338907 100644 --- a/filters.c +++ b/filters.c @@ -87,6 +87,10 @@ static void apply_url_actions(struct current_action_spec *action, #endif struct url_actions *b); +#ifdef FEATURE_EXTENDED_STATISTICS +static void increment_block_reason_counter(const char *block_reason); +#endif + #ifdef FEATURE_ACL #ifdef HAVE_RFC2553 /********************************************************************* @@ -557,6 +561,13 @@ struct http_response *block_url(struct client_state *csp) return cgi_error_memory(); } +#ifdef FEATURE_EXTENDED_STATISTICS + if (csp->action->string[ACTION_STRING_BLOCK] != NULL) + { + increment_block_reason_counter(csp->action->string[ACTION_STRING_BLOCK]); + } +#endif + /* * If it's an image-url, send back an image or redirect * as specified by the relevant +image action @@ -2897,6 +2908,136 @@ void get_filter_statistics(const char *filter, unsigned long long *executions, } + +struct block_statistics_entry +{ + char *block_reason; + unsigned long long count; + + struct block_statistics_entry *next; +}; + +static struct block_statistics_entry *block_statistics = NULL; + +/********************************************************************* + * + * Function : register_block_reason_for_statistics + * + * Description : Registers a block reason so we can gather statistics + * for it unless the block reason has already been + * registered before. + * + * Parameters : + * 1 : block_reason = Block reason to register + * + * Returns : void + * + *********************************************************************/ +void register_block_reason_for_statistics(const char *block_reason) +{ + struct block_statistics_entry *entry; + + privoxy_mutex_lock(&block_statistics_mutex); + + if (block_statistics == NULL) + { + block_statistics = zalloc_or_die(sizeof(struct block_statistics_entry)); + entry = block_statistics; + entry->block_reason = strdup_or_die(block_reason); + privoxy_mutex_unlock(&block_statistics_mutex); + return; + } + entry = block_statistics; + while (entry != NULL) + { + if (!strcmp(entry->block_reason, block_reason)) + { + /* Already registered, nothing to do. */ + break; + } + if (entry->next == NULL) + { + entry->next = zalloc_or_die(sizeof(struct block_statistics_entry)); + entry->next->block_reason = strdup_or_die(block_reason); + break; + } + entry = entry->next; + } + + privoxy_mutex_unlock(&block_statistics_mutex); + +} + + +/********************************************************************* + * + * Function : increment_block_reason_counter + * + * Description : Updates the counter for a block reason. + * + * Parameters : + * 1 : block_reason = Block reason to count + * + * Returns : void + * + *********************************************************************/ +static void increment_block_reason_counter(const char *block_reason) +{ + struct block_statistics_entry *entry; + + privoxy_mutex_lock(&block_statistics_mutex); + + entry = block_statistics; + while (entry != NULL) + { + if (!strcmp(entry->block_reason, block_reason)) + { + entry->count++; + break; + } + entry = entry->next; + } + + privoxy_mutex_unlock(&block_statistics_mutex); + +} + + +/********************************************************************* + * + * Function : get_block_reason_count + * + * Description : Gets number of times a block reason was used. + * + * Parameters : + * 1 : block_reason = Block reason to get statistics for. + * 2 : count = Storage for the number of times the block + * reason was used. + * + * Returns : void + * + *********************************************************************/ +void get_block_reason_count(const char *block_reason, unsigned long long *count) +{ + struct block_statistics_entry *entry; + + privoxy_mutex_lock(&block_statistics_mutex); + + entry = block_statistics; + while (entry != NULL) + { + if (!strcmp(entry->block_reason, block_reason)) + { + *count = entry->count; + break; + } + entry = entry->next; + } + + privoxy_mutex_unlock(&block_statistics_mutex); + +} + #endif /* def FEATURE_EXTENDED_STATISTICS */ /* diff --git a/filters.h b/filters.h index dcd58e21..b8004fec 100644 --- a/filters.h +++ b/filters.h @@ -111,6 +111,10 @@ extern void get_filter_statistics(const char *filter, unsigned long long *executions, unsigned long long *pages_modified, unsigned long long *hits); + +extern void register_block_reason_for_statistics(const char *block_reason); +extern void get_block_reason_count(const char *block_reason, + unsigned long long *count); #endif #endif /* ndef FILTERS_H_INCLUDED */ diff --git a/jcc.c b/jcc.c index 5846f8a2..1380100a 100644 --- a/jcc.c +++ b/jcc.c @@ -206,6 +206,7 @@ privoxy_mutex_t client_tags_mutex; #endif #ifdef FEATURE_EXTENDED_STATISTICS privoxy_mutex_t filter_statistics_mutex; +privoxy_mutex_t block_statistics_mutex; #endif #if !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_GETHOSTBYNAME_R) @@ -4572,6 +4573,7 @@ static void initialize_mutexes(void) #endif #ifdef FEATURE_EXTENDED_STATISTICS privoxy_mutex_init(&filter_statistics_mutex); + privoxy_mutex_init(&block_statistics_mutex); #endif /* diff --git a/jcc.h b/jcc.h index 3412ab29..ad68f42f 100644 --- a/jcc.h +++ b/jcc.h @@ -88,6 +88,7 @@ extern privoxy_mutex_t client_tags_mutex; #ifdef FEATURE_EXTENDED_STATISTICS extern privoxy_mutex_t filter_statistics_mutex; +extern privoxy_mutex_t block_statistics_mutex; #endif #ifndef HAVE_GMTIME_R diff --git a/templates/show-status b/templates/show-status index 39f906bd..fe34b4f9 100644 --- a/templates/show-status +++ b/templates/show-status @@ -93,7 +93,9 @@ # There haven't any statistics been collected yet # extended-statistics: # Privoxy was compiled with extended statistiscs support. -# In this case the following symbol is available: +# In this case the following symbols are available: +# block-reason-statistics: +# Table content of block reasons and how often they were used. # filter-statistics: # Table content of content filter statistics. # pcrs-support: @@ -220,6 +222,14 @@ + + +

Block Reason Statistics:

+ + +@block-reason-statistics@
Block reasonCount
+ +

Content Filter Statistics: