more logging improvements.

do_exit function, replace all exits and execve calls, so we can clean up (and flush log files)
This commit is contained in:
fishwaldo 2003-04-10 15:26:58 +00:00
parent 7a0159d72b
commit 9eb2b6914c
16 changed files with 211 additions and 67 deletions

View file

@ -15,6 +15,7 @@ NeoStats ChangeLog - Anything we add/remove/fix/change is in here (even our rant
debug level: what level to write debug messages.
help and version info
- Started the new logging function, nlog
- Added a function, do_exit, that should be called when exiting NeoStats to flush and close the logs and perform any cleanup that should be done. Hopefully one day we can get rid of the execve code!
* NeoStats * Fish * Version 2.5.1
- ConnectServ's username was too long for NeoIRCd, fixed

21
TODO
View file

@ -1,30 +1,18 @@
NeoStats - TODO Log:
--------------------
Shmad:
------
Fish:
-----
Bind sockets to a IP address
fnmatch is Baaaad news... find a good ircmatch function and port it over...
unkline on Hybrid7
2.6.0 Series - Yep, I'm already thinking about this....
2.6.0 Series -
------------
Channel (Not IRC Channels, Event Channels) Based Logging... Means we can get rid of the #ifdef DEBUG, log(...
stuff, and define what gets logged when.
Module Config File Support improvements. (I got ideas - Find Keeper Config libary for more info:)
Re-Do the send/recv code... Its Horrible.. (Backup Server links etc can
then be implemented)
@ -32,9 +20,6 @@ Move all the stuff in ircd.c into relevent ircd support files. ircd.c is
getting just way to hard to manage now and will get worse as
we add aditional IRCd support.
"Driver" modules??? (eg, Unreal, Ultimate are drivers. So is DB/SQL
or WebServer)
Redo Config files. I pretty much got Bison/Flex figured out...
libwebserver module :)
@ -44,4 +29,6 @@ modules
DCC chat interface???
Language File support
Language File support
do some nice cleanups of code in do_exit...

View file

@ -20,7 +20,7 @@
** USA
**
** NeoStats CVS Identification
** $Id: Ultimate.c,v 1.41 2003/02/14 13:10:38 fishwaldo Exp $
** $Id: Ultimate.c,v 1.42 2003/04/10 15:26:55 fishwaldo Exp $
*/
#include "stats.h"
@ -424,7 +424,7 @@ void sts(char *fmt,...)
sent = write (servsock, buf, strlen (buf));
if (sent == -1) {
log("Write error.");
exit(0);
do_exit(0);
}
me.SendM++;
me.SendBytes = me.SendBytes + sent;
@ -451,7 +451,7 @@ void chanalert(char *who, char *buf,...)
if (sent == -1) {
me.onchan = 0;
log("Write error.");
exit(0);
do_exit(0);
}
me.SendM++;
me.SendBytes = me.SendBytes + sent;

View file

@ -20,7 +20,7 @@
** USA
**
** NeoStats CVS Identification
** $Id: Unreal.c,v 1.36 2003/02/14 13:10:38 fishwaldo Exp $
** $Id: Unreal.c,v 1.37 2003/04/10 15:26:55 fishwaldo Exp $
*/
#include "stats.h"
@ -345,7 +345,7 @@ void sts(char *fmt,...)
sent = write (servsock, buf, strlen (buf));
if (sent == -1) {
log("Write error.");
exit(0);
do_exit(0);
}
me.SendM++;
me.SendBytes = me.SendBytes + sent;
@ -372,7 +372,7 @@ void chanalert(char *who, char *buf,...)
if (sent == -1) {
me.onchan = 0;
log("Write error.");
exit(0);
do_exit(0);
}
me.SendM++;
me.SendBytes = me.SendBytes + sent;

3
conf.c
View file

@ -20,7 +20,7 @@
** USA
**
** NeoStats CVS Identification
** $Id: conf.c,v 1.20 2003/04/10 09:32:01 fishwaldo Exp $
** $Id: conf.c,v 1.21 2003/04/10 15:26:56 fishwaldo Exp $
*/
#include "stats.h"
@ -107,6 +107,7 @@ void ConfLoad() {
printf("* *\n");
printf("* NeoStats NOT Started *\n");
printf("***************************************************\n");
/* no need to call do_exit, we havn't even started! */
exit(0);
}
printf("Sucessfully Loaded Config File, Now Booting NeoStats\n");

6
hash.c
View file

@ -39,7 +39,7 @@
* into proprietary software; there is no requirement for such software to
* contain a copyright notice related to this source.
*
* $Id: hash.c,v 1.6 2002/09/04 08:40:26 fishwaldo Exp $
* $Id: hash.c,v 1.7 2003/04/10 15:26:57 fishwaldo Exp $
* $Name: $
*/
@ -51,8 +51,10 @@
#define HASH_IMPLEMENTATION
#include "hash.h"
#ifdef KAZLIB_RCSID
static const char rcsid[] = "$Id: hash.c,v 1.6 2002/09/04 08:40:26 fishwaldo Exp $";
static const char rcsid[] = "$Id: hash.c,v 1.7 2003/04/10 15:26:57 fishwaldo Exp $";
#endif
#define INIT_BITS 6

View file

@ -18,7 +18,7 @@
** USA
**
** NeoStats CVS Identification
** $Id: hybrid7.c,v 1.10 2003/02/14 13:10:38 fishwaldo Exp $
** $Id: hybrid7.c,v 1.11 2003/04/10 15:26:57 fishwaldo Exp $
*/
#include "stats.h"
@ -300,7 +300,7 @@ void sts(char *fmt,...)
sent = write (servsock, buf, strlen (buf));
if (sent == -1) {
log("Write error.");
exit(0);
do_exit(0);
}
me.SendM++;
me.SendBytes = me.SendBytes + sent;
@ -327,7 +327,7 @@ void chanalert(char *who, char *buf,...)
if (sent == -1) {
me.onchan = 0;
log("Write error.");
exit(0);
do_exit(0);
}
me.SendM++;
me.SendBytes = me.SendBytes + sent;

106
log.c
View file

@ -20,11 +20,13 @@
** USA
**
** NeoStats CVS Identification
** $Id: log.c,v 1.1 2003/04/10 09:32:01 fishwaldo Exp $
** $Id: log.c,v 1.2 2003/04/10 15:26:57 fishwaldo Exp $
*/
#include "stats.h"
#include "conf.h"
#include "hash.h"
#include "log.h"
const char *loglevels[10] = {
"CRITICAL",
@ -38,29 +40,117 @@ const char *loglevels[10] = {
"DEBUG3",
"INSANE"
};
struct logs_ {
FILE *logfile;
char name[30];
unsigned int flush : 1;
} ;
hash_t *logs;
void *close_logs();
/** @brief Initilize the logging functions
*/
void init_logs() {
logs = hash_create(NUM_MODULES+1, 0, 0);
if (!logs) {
printf("ERROR: Can't Initilize Log SubSystem. Exiting!");
/* if this fails, no need to call do_exit, as this is the first thing that runs... so nothing to do! */
exit(-1);
}
config.debug = 5;
}
/** @brief Occasionally flush log files out
*/
void *close_logs() {
hscan_t hs;
hnode_t *hn;
struct logs_ *logentry;
hash_scan_begin(&hs, logs);
while ((hn = hash_scan_next(&hs)) != NULL) {
logentry = hnode_get(hn);
if (logentry->flush > 0) {
fflush(logentry->logfile);
logentry->flush = 0;
}
#ifdef DEBUG
printf("Closing Logfile %s\n", logentry->name);
#endif
fclose(logentry->logfile);
hash_scan_delete(logs, hn);
hnode_destroy(hn);
free(logentry);
}
return NULL;
}
/** @Configurable logging function
*/
void nlog(int level, int scope, char *fmt, ...) {
va_list ap;
static FILE *logfile;
char buf[512], fmttime[80];
int gotlog;
hnode_t *hn;
struct logs_ *logentry;
time_t ts = time(NULL);
if (level <= config.debug) {
if (!logfile)
if ((logfile = fopen("logs/neostats.log", "a")) == NULL) return;
/* if scope is > 0, then log to a diff file */
if (scope > 0) {
if (strlen(segvinmodule) > 1) {
hn = hash_lookup(logs, segvinmodule);
} else {
nlog(LOG_ERROR, LOG_CORE, "Warning, nlog called with LOG_MOD, but segvinmodule is blank! Logging to Core");
hn = hash_lookup(logs, "core");
}
} else {
hn = hash_lookup(logs, "core");
}
if (hn) {
/* we found our log entry */
logentry = hnode_get(hn);
gotlog = 1;
} else {
/* log file not found */
if ((strlen(segvinmodule) <= 1) && (scope > 0)) {
#ifdef DEBUG
printf("segvinmodule is blank, but scope is for Modules!\n");
#endif
/* bad, but hey !*/
scope = 0;
}
logentry = malloc(sizeof(struct logs_));
strncpy(logentry->name, scope ? segvinmodule : "core", 30);
snprintf(buf, 40, "logs/%s.log", scope ? segvinmodule : "NeoStats");
logentry->logfile = fopen(buf, "a");
logentry->flush = 0;
hn = hnode_create(logentry);
hash_insert(logs, hn, scope ? segvinmodule : "core");
}
if (!logentry->logfile) {
#ifdef DEBUG
printf("%s\n", strerror(errno));
do_exit(0);
#endif
}
strftime(fmttime, 80, "%d/%m/%Y[%H:%M]", localtime(&ts));
va_start(ap, fmt);
vsnprintf(buf, 512, fmt, ap);
fprintf(logfile, "(%s) %s %s - %s\n", fmttime, loglevels[level-1], scope ? "core" : segvinmodule, buf);
fprintf(logentry->logfile, "(%s) %s %s - %s\n", fmttime, loglevels[level-1], segvinmodule ? "core" : segvinmodule, buf);
logentry->flush = 1;
#ifndef DEBUG
if (config.foreground)
printf("%s %s - %s\n", loglevels[level-1], scope ? "core" : segvinmodule, buf);
#endif
printf("%s %s - %s\n", loglevels[level-1], segvinmodule ? "core" : segvinmodule, buf);
va_end(ap);
}
}
}

10
log.h
View file

@ -20,7 +20,7 @@
** USA
**
** NeoStats CVS Identification
** $Id: log.h,v 1.1 2003/04/10 09:32:01 fishwaldo Exp $
** $Id: log.h,v 1.2 2003/04/10 15:26:57 fishwaldo Exp $
*/
@ -56,6 +56,14 @@
#define LOG_DEBUG4 10
/* Scope of Logging Defines: */
#define LOG_CORE 0
#define LOG_MOD 1
extern void nlog(int level, int scope, char *fmt, ...);
void *close_logs();
void init_logs();
#endif

82
main.c
View file

@ -22,18 +22,19 @@
** USA
**
** NeoStats CVS Identification
** $Id: main.c,v 1.84 2003/04/10 09:32:01 fishwaldo Exp $
** $Id: main.c,v 1.85 2003/04/10 15:26:57 fishwaldo Exp $
*/
#include <setjmp.h>
#include <stdio.h>
#include "stats.h"
#include "signal.h"
#include "dl.h"
#include "conf.h"
#ifdef HAVE_BACKTRACE
#include <execinfo.h>
#endif
#include "signal.h"
#include "dl.h"
#include "conf.h"
#include "log.h"
/*! this is the name of the services bot */
@ -81,9 +82,9 @@ int forked = 0;
int main(int argc, char *argv[])
{
FILE *fp;
#if 0
char *test;
int i;
#if 0
/* testing of keeper database */
SetConf("test", 1, "testconf");
SetConf((void *)12, 2, "this");
@ -96,11 +97,19 @@ int main(int argc, char *argv[])
printf("%d\n", i);
free(test);
#endif
/* get our commandline options */
get_options(argc, argv);
/* before we do anything, make sure logging is setup */
init_logs();
/* our crash trace variables */
strcpy(segv_location, "main");
strcpy(segvinmodule, "");
/* for modules, let them know we are not ready */
me.onchan = 0;
get_options(argc, argv);
/* keep quiet if we are told to :) */
if (!config.quiet) {
printf("NeoStats %d.%d.%d%s Loading...\n", MAJOR, MINOR, REV, version);
printf("-----------------------------------------------\n");
@ -110,6 +119,7 @@ int main(int argc, char *argv[])
printf("^Enigma^ (enigma@neostats.net)\n");
printf("-----------------------------------------------\n\n");
}
/* set some defaults before we parse the config file */
me.t_start = time(NULL);
me.want_privmsg = 0;
me.enable_spam = 0;
@ -128,11 +138,18 @@ int main(int argc, char *argv[])
me.client = 0;
#endif
strcpy(me.modpath,"dl");
#ifdef RECVLOG
remove("logs/recv.log");
#endif
/* if we are doing recv.log, remove the previous version */
if (config.recvlog)
remove("logs/recv.log");
/* initilze our Module subsystem */
__init_mod_list();
/* prepare to catch errors */
setup_signals();
/* load the config files */
ConfLoad();
if (me.die) {
printf("\n-----> ERROR: Read the README file then edit neostats.cfg! <-----\n\n");
@ -140,13 +157,17 @@ int main(int argc, char *argv[])
sleep(1);
close(servsock);
remove("neostats.pid");
/* we are exiting the parent, not the program, don't call do_exit() */
exit(0);
}
/* initilize the rest of the subsystems */
TimerReset();
init_dns();
init_server_hash();
init_user_hash();
init_chan_hash();
/** This section ALWAYS craps out so we ignore it-- for now */
if (init_modules()) {
/* printf("WARNING: Some Modules Failed to Load"); */
@ -154,10 +175,12 @@ int main(int argc, char *argv[])
#ifndef DEBUG
/* if we are compiled with debug, or forground switch was specified, DONT FORK */
if (!config.foreground) {
forked=fork();
#endif
if (forked) {
/* write out our PID */
fp = fopen("neostats.pid", "w");
fprintf(fp, "%i", forked);
fclose(fp);
@ -169,6 +192,7 @@ int main(int argc, char *argv[])
return 0;
}
#ifndef DEBUG
/* detach from parent process */
if (setpgid(0, 0) < 0) {
log("setpgid() failed");
}
@ -176,6 +200,7 @@ int main(int argc, char *argv[])
#endif
log("Statistics Started (NeoStats %d.%d.%d%s).", MAJOR, MINOR, REV, version);
/* we are ready to start now Duh! */
start();
return 1;
@ -361,8 +386,8 @@ RETSIGTYPE serv_segv() {
sleep(2);
kill(forked, 3);
kill(forked, 9);
exit(-1);
ssquit_cmd(me.name);
/* clean up */
do_exit(1);
}
}
@ -448,7 +473,7 @@ void start()
unload_module(mod_ptr->info->module_name, finduser(s_Services));
}
sleep(5);
execve("./neostats", NULL, NULL);
do_exit(2);
}
/** @brief Login to IRC
*
@ -489,7 +514,7 @@ void *smalloc(long size)
buf = malloc(size);
if (!buf) {
log("smalloc(): out of memory.");
exit(0);
do_exit(1);
}
return buf;
}
@ -510,7 +535,7 @@ char *sstrdup(const char *s)
char *t = strdup(s);
if (!t) {
log("sstrdup(): out of memory.");
exit(0);
do_exit(1);
}
return t;
}
@ -597,3 +622,32 @@ for (i = 0; i== C; i++)
C = 0;
}
/** @brief before exiting call this function. It flushes log files and tidy's up.
*
* Cleans up before exiting
* @parm segv 1 = we are exiting because of a segv fault, 0, we are not.
* if 1, we don't prompt to save data
*/
void do_exit(int segv) {
switch (segv) {
case 0:
nlog(LOG_NORMAL, LOG_CORE, "Normal shut down SubSystems");
break;
case 2:
nlog(LOG_NORMAL, LOG_CORE, "Restarting NeoStats SubSystems");
break;
case 1:
nlog(LOG_NORMAL, LOG_CORE, "Shutting Down SubSystems without saving data due to core");
break;
}
close_logs();
if (segv == 1) {
exit(-1);
} else if (segv == 2) {
execve("./neostats", NULL, NULL);
} else {
exit(1);
}
}

View file

@ -18,7 +18,7 @@
** USA
**
** NeoStats CVS Identification
** $Id: neoircd.c,v 1.5 2003/03/06 11:18:12 fishwaldo Exp $
** $Id: neoircd.c,v 1.6 2003/04/10 15:26:57 fishwaldo Exp $
*/
#include "stats.h"
@ -307,7 +307,7 @@ void sts(char *fmt,...)
sent = write (servsock, buf, strlen (buf));
if (sent == -1) {
log("Write error.");
exit(0);
do_exit(0);
}
me.SendM++;
me.SendBytes = me.SendBytes + sent;
@ -334,7 +334,7 @@ void chanalert(char *who, char *buf,...)
if (sent == -1) {
me.onchan = 0;
log("Write error.");
exit(0);
do_exit(0);
}
me.SendM++;
me.SendBytes = me.SendBytes + sent;

View file

@ -22,7 +22,7 @@
** USA
**
** NeoStats CVS Identification
** $Id: server.c,v 1.13 2002/09/04 08:40:27 fishwaldo Exp $
** $Id: server.c,v 1.14 2003/04/10 15:26:57 fishwaldo Exp $
*/
#include <fnmatch.h>
@ -141,7 +141,7 @@ void init_server_hash()
sh = hash_create(S_TABLE_SIZE, 0, 0);
if (!sh) {
log("Create Server Hash Failed\n");
exit(-1);
do_exit(1);
}
AddServer(me.name,NULL, 0);
}

View file

@ -22,7 +22,7 @@
** USA
**
** NeoStats CVS Identification
** $Id: services.c,v 1.50 2003/04/03 14:36:36 fishwaldo Exp $
** $Id: services.c,v 1.51 2003/04/10 15:26:57 fishwaldo Exp $
*/
#include "stats.h"
@ -307,7 +307,7 @@ extern void ns_shutdown(User *u, char *reason)
remove("neostats.pid");
log("%s [%s](%s) requested SHUTDOWN.", u->nick, u->username,
u->hostname);
exit(0);
do_exit(0);
}
static void ns_reload(User *u, char *reason)
@ -329,7 +329,7 @@ static void ns_reload(User *u, char *reason)
squit_cmd(s_Services, quitmsg);
ssquit_cmd(me.name);
sleep(5);
execve("./neostats", NULL, NULL);
do_exit(2);
}
@ -399,7 +399,7 @@ static void ns_raw(User *u, char *message)
sent = write (servsock, message, strlen (message));
if (sent == -1) {
log("Write error.");
exit(0);
do_exit(0);
}
me.SendM++;
me.SendBytes = me.SendBytes + sent;

4
sock.c
View file

@ -22,7 +22,7 @@
** USA
**
** NeoStats CVS Identification
** $Id: sock.c,v 1.31 2003/04/10 09:32:01 fishwaldo Exp $
** $Id: sock.c,v 1.32 2003/04/10 15:26:57 fishwaldo Exp $
*/
#include <fcntl.h>
@ -194,7 +194,7 @@ void read_loop()
close(servsock);
sleep(5);
log("Eeek, Zombie Server, Reconnecting");
execve("./neostats", NULL, NULL);
do_exit(2);
}
} else if (SelectResult == -1) {
if (errno != EINTR)

View file

@ -20,7 +20,7 @@
** USA
**
** NeoStats CVS Identification
** $Id: stats.h,v 1.71 2003/04/10 06:06:10 fishwaldo Exp $
** $Id: stats.h,v 1.72 2003/04/10 15:26:57 fishwaldo Exp $
*/
#ifndef STATS_H
@ -265,6 +265,7 @@ extern unsigned long HASH(const unsigned char *, int);
extern char *strlower(char *);
extern void AddStringToList(char ***List,char S[],int *C);
void FreeList(char **List,int C);
void do_exit(int);
/* ircd.c */
extern void parse();

View file

@ -20,7 +20,7 @@
** USA
**
** NeoStats CVS Identification
** $Id: timer.c,v 1.19 2002/09/04 08:50:48 fishwaldo Exp $
** $Id: timer.c,v 1.20 2003/04/10 15:26:58 fishwaldo Exp $
*/
#include "stats.h"
@ -77,8 +77,8 @@ void chk()
if (hash_verify(th) == 0) {
log("Eeeek, Corruption of the Timer hash");
}
/* flush log files */
fflush(NULL);
}
if (is_midnight() == 1 && midnight == 0) {
TimerMidnight();