Initial drop of dashboard instrumentation - enabled with
[privoxy.git] / src / stats.c
1 const char stats_rcs[] = "$Id: stats.c,v 2.3 2002/07/18 22:06:12 jongfoster Exp $";
2 /*********************************************************************
3  *
4  * File        :  $Source: /cvsroot/ijbswa/current/src/jcc.c,v $
5  *
6  * Purpose     :  
7  *                
8  *
9  * Copyright   :  Written by and Copyright (C) 2002, 2003 the SourceForge
10  *                Privoxy team. http://www.privoxy.org/
11  *
12  *                Based on the Internet Junkbuster originally written
13  *                by and Copyright (C) 1997 Anonymous Coders and
14  *                Junkbusters Corporation.  http://www.junkbusters.com
15  *
16  *                This program is free software; you can redistribute it
17  *                and/or modify it under the terms of the GNU General
18  *                Public License as published by the Free Software
19  *                Foundation; either version 2 of the License, or (at
20  *                your option) any later version.
21  *
22  *                This program is distributed in the hope that it will
23  *                be useful, but WITHOUT ANY WARRANTY; without even the
24  *                implied warranty of MERCHANTABILITY or FITNESS FOR A
25  *                PARTICULAR PURPOSE.  See the GNU General Public
26  *                License for more details.
27  *
28  *                The GNU General Public License should be included with
29  *                this file.  If not, you can view it at
30  *                http://www.gnu.org/copyleft/gpl.html
31  *                or write to the Free Software Foundation, Inc., 59
32  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
33  *
34  *********************************************************************/
35 \f
36
37 #ifdef unix
38 #include <sys/signal.h>
39 #endif
40 #include "project.h"
41 #include "errlog.h"
42 #include "stats.h"
43 #include "ipc.h"
44
45 const char stats_h_rcs[] = STATS_H_VERSION;
46 const char ipc_h_rcs[] = IPC_H_VERSION;
47 static IPC_MUTEX_LOCK stats_lock;
48
49 struct configuration_spec *latest_config;
50 int changed = 0,
51     stats_array[STATS_MAX_KEYS];
52
53 /*********************************************************************
54  *
55  * Function    :  init_stats_config
56  *
57  * Description :  Initializes the statistics array and spawns a thread
58  *                to transmit statistics to the listening party.
59  *
60  * Parameters  :
61  *          1  :  config = Privoxy configuration.
62  *
63  * Returns     :  N/A
64  *
65  *********************************************************************/
66 void init_stats_config(struct configuration_spec * config)
67 {
68   int i;
69 #if defined (_WIN32) || defined (__OS2__)
70   int child_id;
71 #else
72   pthread_attr_t attr;
73   pthread_t thread;
74 #endif /* def unix */
75
76   log_error(LOG_LEVEL_INFO, "init_stats_config hit.");
77   IPC_CREATE_MUTEX(stats_lock);
78   for (i=0; i < STATS_MAX_KEYS; i++)
79   {
80     stats_array[i] = 0;
81   }
82   latest_config = config;
83
84   /*
85    * Start the timing/sending thread - we'll need a lot of work here
86    * for each platform.  I imagine there is also a possibility of 
87    * doing this via fork() instead of threads.
88    */
89
90 #ifdef _WIN32
91     child_id = _beginthread(
92             (void (*)(void *))forward_stats,
93             64 * 1024,
94             NULL);
95 #elif __OS2__
96     child_id = _beginthread(
97             (void(* _Optlink)(void*))forward_stats,
98             NULL,
99             64 * 1024,
100             NULL);
101 #else
102     /* Generic unix processing */
103     signal(SIGALRM, null_routine);  /* Ignore the SIGALRM signal */
104     pthread_attr_init(&attr);
105     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
106     pthread_create(&thread, &attr, forward_stats, NULL);
107 #endif
108
109 }
110
111 /*********************************************************************
112  *
113  * Function    :  update_stats_config
114  *
115  * Description :  Updates the pointer to the most recent Privoxy
116  *                configuration changes.
117  *
118  * Parameters  :
119  *          1  :  config = Privoxy configuration.
120  *
121  * Returns     :  N/A
122  *
123  *********************************************************************/
124 void update_stats_config(struct configuration_spec * config)
125 {
126   latest_config = config;
127 }
128
129 /*********************************************************************
130  *
131  * Function    :  accumulate_stats
132  *
133  * Description :  Updates one element of the statistics array with a
134  *                single integer value.
135  *
136  * Parameters  :
137  *          1  :  key = the key into the stats array
138  *          2  :  value = the value to add to the current stats key
139  *
140  * Returns     :  N/A
141  *
142  *********************************************************************/
143 void accumulate_stats(int key, int value)
144 {
145   if (key < STATS_MAX_KEYS)
146   {
147     IPC_LOCK_MUTEX(stats_lock);
148     stats_array[key] += value;
149     changed = 1;
150     IPC_UNLOCK_MUTEX(stats_lock);
151   }
152   /* log_error(LOG_LEVEL_INFO, "Accumulate stats: key %d, value %d, total %d; send to: %s:%d", key, value, stats_array[key], latest_config->activity_address,latest_config->activity_port); */
153 }
154
155 /*********************************************************************
156  *
157  * Function    :  forward_stats
158  *
159  * Description :  Main routine for the statistics thread; loops and 
160  *                periodically checks if there's anything to send.  If
161  *                so, call send_stats() to do the work.
162  *
163  * Parameters  :  N/A
164  *
165  * Returns     :  N/A
166  *
167  *********************************************************************/
168 void *forward_stats()
169 {
170   int local_stats_array[STATS_MAX_KEYS];
171   
172   log_error(LOG_LEVEL_INFO, "forward_stats ready.");
173   for (;;)
174   {
175     IPC_SLEEP_SECONDS(latest_config->activity_freq);
176     if (changed == 1)
177     {
178       IPC_LOCK_MUTEX(stats_lock);
179       memcpy(local_stats_array,stats_array,sizeof(stats_array));
180       changed = 0;
181       IPC_UNLOCK_MUTEX(stats_lock);
182       send_stats(&local_stats_array);
183     }
184   }
185 }
186
187 /*********************************************************************
188  *
189  * Function    :  send_stats
190  *
191  * Description :  Attempt to send statistics to the listening console
192  *
193  * Parameters  :  N/A
194  *
195  * Returns     :  N/A
196  *
197  *********************************************************************/
198 void send_stats(int *local_stats_array[])
199 {
200   /* Here, we initiate the socket send to the console */
201   /*
202   log_error(LOG_LEVEL_INFO, "send_stats sending stats: %d %d %d %d %d %d %d %d %d %d",
203     local_stats_array[0],local_stats_array[1],local_stats_array[2],local_stats_array[3],local_stats_array[4],local_stats_array[5],local_stats_array[6],local_stats_array[7],local_stats_array[8],local_stats_array[9]);
204   */
205 }
206
207 /*********************************************************************
208  *
209  * Function    :  null_routine
210  *
211  * Description :  Called when hit by a signal in unix; do nothing.
212  *
213  * Parameters  :
214  *          1  :  sig - the integer signal
215  *
216  * Returns     :  N/A
217  *
218  *********************************************************************/
219 #ifdef unix
220 void null_routine(int sig)
221 {
222   /* sigignore(sig); */
223 }
224 #endif /* def unix */