Crossfire Server, Trunk
logger.c
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
19 #include "global.h"
20 
21 #include <stdarg.h>
22 #include <stdlib.h>
23 
24 #include "sproto.h"
25 
26 int reopen_logfile = 0; /* May be set in SIGHUP handler */
27 
31 static const char *const loglevel_names[] = {
32  "[EE] ",
33  "[II] ",
34  "[DD] ",
35  "[MM] ",
36 };
37 
51 void LOG(LogLevel logLevel, const char *format, ...) {
52  char buf[20480]; /* This needs to be really really big - larger
53  * than any other buffer, since that buffer may
54  * need to be put in this one.
55  */
56 
57  char time_buf[2048];
58 
59  va_list ap;
60  va_start(ap, format);
61 
62  buf[0] = '\0';
63  if (logLevel <= settings.debug) {
64  time_buf[0] = '\0';
65  if (settings.log_timestamp == TRUE) {
66  struct tm *time_tmp;
67  time_t now = time((time_t *)NULL);
68 
69  time_tmp = localtime(&now);
70  if (time_tmp != NULL) {
71  if (strftime(time_buf, sizeof(time_buf), settings.log_timestamp_format, time_tmp) == 0) {
72  time_buf[0] = '\0';
73  }
74  }
75  }
76 
77  vsnprintf(buf, sizeof(buf), format, ap);
78 #ifdef WIN32 /* ---win32 change log handling for win32 */
79  if (time_buf[0] != 0) {
80  fputs(time_buf, logfile);
81  fputs(" ", logfile);
82  }
83  fputs(loglevel_names[logLevel], logfile); /* wrote to file or stdout */
84  fputs(buf, logfile); /* wrote to file or stdout */
85  fflush(logfile); /* always force flushing! */
86  if (logfile != stderr) { /* if was it a logfile wrote it to screen too */
87  if (time_buf[0] != 0) {
88  fputs(time_buf, stderr);
89  fputs(" ", stderr);
90  }
91  fputs(loglevel_names[logLevel], stderr);
92  fputs(buf, stderr);
93  fflush(stderr);
94  }
95 #else /* not WIN32 */
96  if (reopen_logfile) {
97  reopen_logfile = 0;
98  if (fclose(logfile) != 0) {
99  /* stderr has been closed if -detach was used, but it's better
100  * to try to report about this anyway. */
101  perror("tried to close log file after SIGHUP in logger.c:LOG()");
102  }
103  if ((logfile = fopen(settings.logfilename, "a")) == NULL) {
104  /* There's likely to be something very wrong with the OS anyway
105  * if reopening fails. */
106  perror("tried to open log file after SIGHUP in logger.c:LOG()");
107  emergency_save(0);
108  clean_tmp_files();
109  exit(1);
110  }
111  setvbuf(logfile, NULL, _IOLBF, 0);
112  LOG(llevInfo, "logfile reopened\n");
113  }
114 
115  if (time_buf[0] != 0) {
116  fputs(time_buf, logfile);
117  fputs(" ", logfile);
118  }
119  fputs(loglevel_names[logLevel], logfile);
120  fputs(buf, logfile);
121 #endif
122  }
123  if (!exiting
125  && logLevel == llevError
126  && ++nroferrors > MAX_ERRORS) {
127  exiting = 1;
129  emergency_save(0);
130  }
131  va_end(ap);
132 }
global.h
emergency_save
void emergency_save(int flag)
Definition: main.c:348
llevError
@ llevError
Definition: logger.h:11
Settings::log_timestamp_format
char * log_timestamp_format
Definition: global.h:314
MAX_ERRORS
#define MAX_ERRORS
Definition: config.h:514
settings
struct Settings settings
Definition: init.c:39
reopen_logfile
int reopen_logfile
Definition: logger.c:26
Settings::debug
LogLevel debug
Definition: global.h:239
Settings::logfilename
const char * logfilename
Definition: global.h:237
sproto.h
nroferrors
EXTERN long nroferrors
Definition: global.h:126
logfile
EXTERN FILE * logfile
Definition: global.h:134
llevInfo
@ llevInfo
Definition: logger.h:12
clean_tmp_files
void clean_tmp_files(void)
Definition: main.c:352
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:51
buf
StringBuffer * buf
Definition: readable.c:1610
loglevel_names
static const char *const loglevel_names[]
Definition: logger.c:31
trying_emergency_save
EXTERN long trying_emergency_save
Definition: global.h:125
exiting
EXTERN int exiting
Definition: global.h:136
LogLevel
LogLevel
Definition: logger.h:10
TRUE
#define TRUE
Definition: compat.h:11
Settings::log_timestamp
int log_timestamp
Definition: global.h:313