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.
20 #include <sys/types.h>
22 #if TIME_WITH_SYS_TIME
23 # include <sys/time.h>
27 # include <sys/time.h>
36 #include <libcitadel.h>
39 #include "citserver.h"
50 #include "ctdl_module.h"
54 * Other functions call this one to output data in MRTG format
56 void mrtg_output(long value1
, long value2
) {
58 int uptime_days
, uptime_hours
, uptime_minutes
;
60 uptime_t
= time(NULL
) - server_startup_time
;
61 uptime_days
= (int) (uptime_t
/ 86400L);
62 uptime_hours
= (int) ((uptime_t
% 86400L) / 3600L);
63 uptime_minutes
= (int) ((uptime_t
% 3600L) / 60L);
65 cprintf("%d ok\n", LISTING_FOLLOWS
);
66 cprintf("%ld\n", value1
);
67 cprintf("%ld\n", value2
);
68 cprintf("%d days, %d hours, %d minutes\n",
69 uptime_days
, uptime_hours
, uptime_minutes
);
70 cprintf("%s\n", config
.c_humannode
);
78 * Tell us how many users are online
80 void mrtg_users(void) {
81 long connected_users
= 0;
82 long active_users
= 0;
84 struct CitContext
*cptr
;
86 begin_critical_section(S_SESSION_TABLE
);
87 for (cptr
= ContextList
; cptr
!= NULL
; cptr
= cptr
->next
) {
89 if (cptr
->internal_pgm
== 0) {
92 if ( (time(NULL
) - (cptr
->lastidle
)) < 900L) {
98 end_critical_section(S_SESSION_TABLE
);
100 mrtg_output(connected_users
, active_users
);
105 * Volume of messages submitted
107 void mrtg_messages(void) {
108 mrtg_output(CitControl
.MMhighest
, 0L);
112 struct num_accounts
{
118 * Helper function for mrtg_accounts()
120 void tally_account(struct ctdluser
*EachUser
, void *userdata
)
122 struct num_accounts
*n
= (struct num_accounts
*) userdata
;
125 if ( (time(NULL
) - EachUser
->lastcall
) <= 2592000 ) ++n
->active
;
130 * Number of accounts and active accounts
132 void mrtg_accounts(void) {
133 struct num_accounts n
= {
138 ForEachUser(tally_account
, (void *)&n
);
139 mrtg_output(n
.total
, n
.active
);
144 * Fetch data for MRTG
146 void cmd_mrtg(char *argbuf
) {
149 extract_token(which
, argbuf
, 0, '|', sizeof which
);
151 if (!strcasecmp(which
, "users")) {
154 else if (!strcasecmp(which
, "messages")) {
157 else if (!strcasecmp(which
, "accounts")) {
161 cprintf("%d Unrecognized keyword '%s'\n", ERROR
+ ILLEGAL_VALUE
, which
);
166 CTDL_MODULE_INIT(mrtg
)
170 CtdlRegisterProtoHook(cmd_mrtg
, "MRTG", "Supply stats to MRTG");
173 /* return our Subversion id for the Log */