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