/* tinyproxy - A fast light-weight HTTP proxy * Copyright (C) 2000 Robert James Kaes * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* This module handles the statistics for tinyproxy. There are only two * public API functions. The reason for the functions, rather than just a * external structure is that tinyproxy is now multi-threaded and we can * not allow more than one child to access the statistics at the same * time. This is prevented by a mutex. If there is a need for more * statistics in the future, just add to the structure, enum (in the header), * and the switch statement in update_stats(). */ #include "tinyproxy.h" #include "log.h" #include "heap.h" #include "html-error.h" #include "stats.h" #include "utils.h" struct stat_s { unsigned long int num_reqs; unsigned long int num_badcons; unsigned long int num_open; unsigned long int num_refused; unsigned long int num_denied; }; static struct stat_s *stats; /* * Initialize the statistics information to zero. */ void init_stats(void) { stats = malloc_shared_memory(sizeof(struct stat_s)); if (stats == MAP_FAILED) return; memset(stats, 0, sizeof(struct stat_s)); } /* * Display the statics of the tinyproxy server. */ int showstats(struct conn_s *connptr) { static char *msg = "\n" "\n" "\n" "%s version %s run-time statistics\n" "\n" "

%s version %s run-time statistics

\n" "

\n" "Number of open connections: %lu
\n" "Number of requests: %lu
\n" "Number of bad connections: %lu
\n" "Number of denied connections: %lu
\n" "Number of refused connections due to high load: %lu\n" "

\n" "
\n" "

Generated by %s version %s.

\n" "\n" "\n"; char *message_buffer; char opens[16], reqs[16], badconns[16], denied[16], refused[16]; FILE *statfile; snprintf(opens, sizeof(opens), "%lu", stats->num_open); snprintf(reqs, sizeof(reqs), "%lu", stats->num_reqs); snprintf(badconns, sizeof(badconns), "%lu", stats->num_badcons); snprintf(denied, sizeof(denied), "%lu", stats->num_denied); snprintf(refused, sizeof(refused), "%lu", stats->num_refused); if (!config.statpage || (!(statfile = fopen(config.statpage, "r")))) { message_buffer = safemalloc(MAXBUFFSIZE); if (!message_buffer) return -1; snprintf(message_buffer, MAXBUFFSIZE, msg, PACKAGE, VERSION, PACKAGE, VERSION, stats->num_open, stats->num_reqs, stats->num_badcons, stats->num_denied, stats->num_refused, PACKAGE, VERSION); if (send_http_message(connptr, 200, "OK", message_buffer) < 0) { safefree(message_buffer); return -1; } safefree(message_buffer); return 0; } add_error_variable(connptr, "opens", opens); add_error_variable(connptr, "reqs", reqs); add_error_variable(connptr, "badconns", badconns); add_error_variable(connptr, "denied", denied); add_error_variable(connptr, "refused", refused); add_standard_vars(connptr); send_http_headers(connptr, 200, "Statistic requested"); send_html_file(statfile, connptr); fclose(statfile); return 0; } /* * Update the value of the statistics. The update_level is defined in * stats.h */ int update_stats(status_t update_level) { switch (update_level) { case STAT_BADCONN: ++stats->num_badcons; break; case STAT_OPEN: ++stats->num_open; ++stats->num_reqs; break; case STAT_CLOSE: --stats->num_open; break; case STAT_REFUSE: ++stats->num_refused; break; case STAT_DENIED: ++stats->num_denied; break; default: return -1; } return 0; }