Crossfire Server, Trunk
logger.cpp
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 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  if (settings.log_callback) {
63  settings.log_callback(logLevel, format, ap);
64  va_end(ap);
65  return;
66  }
67 
68  buf[0] = '\0';
69  if (logLevel <= settings.debug) {
70  time_buf[0] = '\0';
71  if (settings.log_timestamp == TRUE) {
72  struct tm *time_tmp;
73  time_t now = time((time_t *)NULL);
74 
75  time_tmp = localtime(&now);
76  if (time_tmp != NULL) {
77  if (strftime(time_buf, sizeof(time_buf), settings.log_timestamp_format, time_tmp) == 0) {
78  time_buf[0] = '\0';
79  }
80  }
81  }
82 
83  vsnprintf(buf, sizeof(buf), format, ap);
84 #ifdef WIN32 /* ---win32 change log handling for win32 */
85  if (time_buf[0] != 0) {
86  fputs(time_buf, logfile);
87  fputs(" ", logfile);
88  }
89  fputs(loglevel_names[logLevel], logfile); /* wrote to file or stdout */
90  fputs(buf, logfile); /* wrote to file or stdout */
91  fflush(logfile); /* always force flushing! */
92  if (logfile != stderr) { /* if was it a logfile wrote it to screen too */
93  if (time_buf[0] != 0) {
94  fputs(time_buf, stderr);
95  fputs(" ", stderr);
96  }
97  fputs(loglevel_names[logLevel], stderr);
98  fputs(buf, stderr);
99  fflush(stderr);
100  }
101 #else /* not WIN32 */
102  if (reopen_logfile) {
103  reopen_logfile = 0;
104  if (fclose(logfile) != 0) {
105  /* stderr has been closed if -detach was used, but it's better
106  * to try to report about this anyway. */
107  perror("tried to close log file after SIGHUP in logger.c:LOG()");
108  }
109  if ((logfile = fopen(settings.logfilename, "a")) == NULL) {
110  /* There's likely to be something very wrong with the OS anyway
111  * if reopening fails. */
112  perror("tried to open log file after SIGHUP in logger.c:LOG()");
113  emergency_save(0);
114  clean_tmp_files();
115  exit(1);
116  }
117  setvbuf(logfile, NULL, _IOLBF, 0);
118  LOG(llevInfo, "logfile reopened\n");
119  }
120 
121  if (time_buf[0] != 0) {
122  fputs(time_buf, logfile);
123  fputs(" ", logfile);
124  }
125  fputs(loglevel_names[logLevel], logfile);
126  fputs(buf, logfile);
127 #endif
128  }
129  if (!exiting
131  && logLevel == llevError
132  && ++nroferrors > MAX_ERRORS) {
133  exiting = 1;
135  emergency_save(0);
136  }
137  va_end(ap);
138 }
global.h
settings
struct Settings settings
Definition: init.cpp:139
emergency_save
void emergency_save(int flag)
Definition: main.cpp:347
llevError
@ llevError
Definition: logger.h:11
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.cpp:51
Settings::log_timestamp_format
char * log_timestamp_format
Definition: global.h:319
MAX_ERRORS
#define MAX_ERRORS
Definition: config.h:514
buf
StringBuffer * buf
Definition: readable.cpp:1611
Settings::log_callback
logHook log_callback
Definition: global.h:244
Settings::debug
LogLevel debug
Definition: global.h:243
Settings::logfilename
const char * logfilename
Definition: global.h:241
trying_emergency_save
long trying_emergency_save
Definition: init.cpp:111
nroferrors
long nroferrors
Definition: init.cpp:112
sproto.h
logfile
FILE * logfile
Definition: init.cpp:114
reopen_logfile
int reopen_logfile
Definition: logger.cpp:26
llevInfo
@ llevInfo
Definition: logger.h:12
clean_tmp_files
void clean_tmp_files(void)
Definition: main.cpp:351
loglevel_names
const char *const loglevel_names[]
Definition: logger.cpp:31
LogLevel
LogLevel
Definition: logger.h:10
TRUE
#define TRUE
Definition: compat.h:11
Settings::log_timestamp
int log_timestamp
Definition: global.h:318
exiting
int exiting
Definition: init.cpp:115