6abd80cf10a80bb82a46cc3fa3f6b4540bff27ee
[citadel.git] / citadel / modules / mrtg / serv_mrtg.c
1 /*
2  * This module supplies statistics about the activity levels of your Citadel
3  * system.  We didn't bother writing a reporting module, because there is
4  * already an excellent tool called MRTG (Multi Router Traffic Grapher) which
5  * is available at http://www.mrtg.org that can fetch data using external
6  * scripts.  This module supplies data in the format expected by MRTG.
7  *
8  * Copyright (c) 1987-2012 by the citadel.org team
9  *
10  *  This program is open source software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License version 3.
12  *  
13  *  
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  
21  *  
22  *  
23  */
24
25 #include "sysdep.h"
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <stdio.h>
29 #include <fcntl.h>
30 #include <signal.h>
31 #include <pwd.h>
32 #include <errno.h>
33 #include <sys/types.h>
34
35 #if TIME_WITH_SYS_TIME
36 # include <sys/time.h>
37 # include <time.h>
38 #else
39 # if HAVE_SYS_TIME_H
40 #  include <sys/time.h>
41 # else
42 #  include <time.h>
43 # endif
44 #endif
45
46 #include <sys/wait.h>
47 #include <string.h>
48 #include <limits.h>
49 #include <libcitadel.h>
50 #include "citadel.h"
51 #include "server.h"
52 #include "citserver.h"
53 #include "support.h"
54 #include "config.h"
55 #include "control.h"
56 #include "user_ops.h"
57 #include "database.h"
58 #include "msgbase.h"
59
60
61 #include "ctdl_module.h"
62
63
64 /*
65  * Other functions call this one to output data in MRTG format
66  */
67 void mrtg_output(long value1, long value2) {
68         time_t uptime_t;
69         int uptime_days, uptime_hours, uptime_minutes;
70         
71         uptime_t = time(NULL) - server_startup_time;
72         uptime_days = (int) (uptime_t / 86400L);
73         uptime_hours = (int) ((uptime_t % 86400L) / 3600L);
74         uptime_minutes = (int) ((uptime_t % 3600L) / 60L);
75
76         cprintf("%d ok\n", LISTING_FOLLOWS);
77         cprintf("%ld\n", value1);
78         cprintf("%ld\n", value2);
79         cprintf("%d days, %d hours, %d minutes\n",
80                 uptime_days, uptime_hours, uptime_minutes);
81         cprintf("%s\n", config.c_humannode);
82         cprintf("000\n");
83 }
84
85
86
87
88 /*
89  * Tell us how many users are online
90  */
91 void mrtg_users(void) {
92         long connected_users = 0;
93         long active_users = 0;
94         
95         struct CitContext *cptr;
96
97         begin_critical_section(S_SESSION_TABLE);
98         for (cptr = ContextList; cptr != NULL; cptr = cptr->next) {
99
100                 if (cptr->internal_pgm == 0) {
101                         ++connected_users;
102
103                         if ( (time(NULL) - (cptr->lastidle)) < 900L) {
104                                 ++active_users;
105                         }
106                 }
107
108         }
109         end_critical_section(S_SESSION_TABLE);
110         
111         mrtg_output(connected_users, active_users);
112 }
113
114
115 /*
116  * Volume of messages submitted
117  */
118 void mrtg_messages(void) {
119         mrtg_output(CitControl.MMhighest, 0L);
120 }
121
122
123 struct num_accounts {
124         long total;
125         long active;
126 };
127
128 /*
129  * Helper function for mrtg_accounts()
130  */
131 void tally_account(struct ctdluser *EachUser, void *userdata)
132 {
133         struct num_accounts *n = (struct num_accounts *) userdata;
134
135         ++n->total;
136         if ( (time(NULL) - EachUser->lastcall) <= 2592000 ) ++n->active;
137 }
138
139
140 /*
141  * Number of accounts and active accounts
142  */
143 void mrtg_accounts(void) {
144         struct num_accounts n = {
145                 0,
146                 0
147         };
148
149         ForEachUser(tally_account, (void *)&n );
150         mrtg_output(n.total, n.active);
151 }
152
153
154 /*
155  * Fetch data for MRTG
156  */
157 void cmd_mrtg(char *argbuf) {
158         char which[32];
159
160         extract_token(which, argbuf, 0, '|', sizeof which);
161
162         if (!strcasecmp(which, "users")) {
163                 mrtg_users();
164         }
165         else if (!strcasecmp(which, "messages")) {
166                 mrtg_messages();
167         }
168         else if (!strcasecmp(which, "accounts")) {
169                 mrtg_accounts();
170         }
171         else {
172                 cprintf("%d Unrecognized keyword '%s'\n", ERROR + ILLEGAL_VALUE, which);
173         }
174 }
175
176
177 CTDL_MODULE_INIT(mrtg)
178 {
179         if (!threading)
180         {
181                 CtdlRegisterProtoHook(cmd_mrtg, "MRTG", "Supply stats to MRTG");
182         }
183         
184         /* return our module name for the log */
185         return "mrtg";
186 }