Back to index

citadel  8.12
serv_mrtg.c
Go to the documentation of this file.
00001 /*
00002  * This module supplies statistics about the activity levels of your Citadel
00003  * system.  We didn't bother writing a reporting module, because there is
00004  * already an excellent tool called MRTG (Multi Router Traffic Grapher) which
00005  * is available at http://www.mrtg.org that can fetch data using external
00006  * scripts.  This module supplies data in the format expected by MRTG.
00007  *
00008  * Copyright (c) 1987-2012 by the citadel.org team
00009  *
00010  *  This program is open source software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License version 3.
00012  *  
00013  *  
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU General Public License for more details.
00019  *
00020  *  
00021  *  
00022  *  
00023  */
00024 
00025 #include "sysdep.h"
00026 #include <stdlib.h>
00027 #include <unistd.h>
00028 #include <stdio.h>
00029 #include <fcntl.h>
00030 #include <signal.h>
00031 #include <pwd.h>
00032 #include <errno.h>
00033 #include <sys/types.h>
00034 
00035 #if TIME_WITH_SYS_TIME
00036 # include <sys/time.h>
00037 # include <time.h>
00038 #else
00039 # if HAVE_SYS_TIME_H
00040 #  include <sys/time.h>
00041 # else
00042 #  include <time.h>
00043 # endif
00044 #endif
00045 
00046 #include <sys/wait.h>
00047 #include <string.h>
00048 #include <limits.h>
00049 #include <libcitadel.h>
00050 #include "citadel.h"
00051 #include "server.h"
00052 #include "citserver.h"
00053 #include "support.h"
00054 #include "config.h"
00055 #include "control.h"
00056 #include "user_ops.h"
00057 #include "database.h"
00058 #include "msgbase.h"
00059 
00060 
00061 #include "ctdl_module.h"
00062 
00063 
00064 /*
00065  * Other functions call this one to output data in MRTG format
00066  */
00067 void mrtg_output(long value1, long value2) {
00068        time_t uptime_t;
00069        int uptime_days, uptime_hours, uptime_minutes;
00070        
00071        uptime_t = time(NULL) - server_startup_time;
00072        uptime_days = (int) (uptime_t / 86400L);
00073        uptime_hours = (int) ((uptime_t % 86400L) / 3600L);
00074        uptime_minutes = (int) ((uptime_t % 3600L) / 60L);
00075 
00076        cprintf("%d ok\n", LISTING_FOLLOWS);
00077        cprintf("%ld\n", value1);
00078        cprintf("%ld\n", value2);
00079        cprintf("%d days, %d hours, %d minutes\n",
00080               uptime_days, uptime_hours, uptime_minutes);
00081        cprintf("%s\n", config.c_humannode);
00082        cprintf("000\n");
00083 }
00084 
00085 
00086 
00087 
00088 /*
00089  * Tell us how many users are online
00090  */
00091 void mrtg_users(void) {
00092        long connected_users = 0;
00093        long active_users = 0;
00094        
00095        struct CitContext *cptr;
00096 
00097        begin_critical_section(S_SESSION_TABLE);
00098         for (cptr = ContextList; cptr != NULL; cptr = cptr->next) {
00099 
00100               if (cptr->internal_pgm == 0) {
00101                      ++connected_users;
00102 
00103                      if ( (time(NULL) - (cptr->lastidle)) < 900L) {
00104                             ++active_users;
00105                      }
00106               }
00107 
00108        }
00109        end_critical_section(S_SESSION_TABLE);
00110        
00111        mrtg_output(connected_users, active_users);
00112 }
00113 
00114 
00115 /*
00116  * Volume of messages submitted
00117  */
00118 void mrtg_messages(void) {
00119        mrtg_output(CitControl.MMhighest, 0L);
00120 }
00121 
00122 
00123 struct num_accounts {
00124        long total;
00125        long active;
00126 };
00127 
00128 /*
00129  * Helper function for mrtg_accounts()
00130  */
00131 void tally_account(struct ctdluser *EachUser, void *userdata)
00132 {
00133        struct num_accounts *n = (struct num_accounts *) userdata;
00134 
00135        ++n->total;
00136        if ( (time(NULL) - EachUser->lastcall) <= 2592000 ) ++n->active;
00137 }
00138 
00139 
00140 /*
00141  * Number of accounts and active accounts
00142  */
00143 void mrtg_accounts(void) {
00144        struct num_accounts n = {
00145               0,
00146               0
00147        };
00148 
00149        ForEachUser(tally_account, (void *)&n );
00150        mrtg_output(n.total, n.active);
00151 }
00152 
00153 
00154 /*
00155  * Fetch data for MRTG
00156  */
00157 void cmd_mrtg(char *argbuf) {
00158        char which[32];
00159 
00160        extract_token(which, argbuf, 0, '|', sizeof which);
00161 
00162        if (!strcasecmp(which, "users")) {
00163               mrtg_users();
00164        }
00165        else if (!strcasecmp(which, "messages")) {
00166               mrtg_messages();
00167        }
00168        else if (!strcasecmp(which, "accounts")) {
00169               mrtg_accounts();
00170        }
00171        else {
00172               cprintf("%d Unrecognized keyword '%s'\n", ERROR + ILLEGAL_VALUE, which);
00173        }
00174 }
00175 
00176 
00177 CTDL_MODULE_INIT(mrtg)
00178 {
00179        if (!threading)
00180        {
00181                CtdlRegisterProtoHook(cmd_mrtg, "MRTG", "Supply stats to MRTG");
00182        }
00183        
00184        /* return our module name for the log */
00185         return "mrtg";
00186 }