Crossfire Server, Trunk  R20513
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 #ifdef DEBUG /* if we have a debug version, we want see ALL output */
86  fflush(logfile); /* so flush this! */
87 #endif
88  if (logfile != stderr) { /* if was it a logfile wrote it to screen too */
89  if (time_buf[0] != 0) {
90  fputs(time_buf, stderr);
91  fputs(" ", stderr);
92  }
93  fputs(loglevel_names[logLevel], stderr);
94  fputs(buf, stderr);
95  }
96 #else /* not WIN32 */
97  if (reopen_logfile) {
98  reopen_logfile = 0;
99  if (fclose(logfile) != 0) {
100  /* stderr has been closed if -detach was used, but it's better
101  * to try to report about this anyway. */
102  perror("tried to close log file after SIGHUP in logger.c:LOG()");
103  }
104  if ((logfile = fopen(settings.logfilename, "a")) == NULL) {
105  /* There's likely to be something very wrong with the OS anyway
106  * if reopening fails. */
107  perror("tried to open log file after SIGHUP in logger.c:LOG()");
108  emergency_save(0);
109  clean_tmp_files();
110  exit(1);
111  }
112  setvbuf(logfile, NULL, _IOLBF, 0);
113  LOG(llevInfo, "logfile reopened\n");
114  }
115 
116  if (time_buf[0] != 0) {
117  fputs(time_buf, logfile);
118  fputs(" ", logfile);
119  }
120  fputs(loglevel_names[logLevel], logfile);
121  fputs(buf, logfile);
122 #endif
123  }
124  if (!exiting
126  && logLevel == llevError
127  && ++nroferrors > MAX_ERRORS) {
128  exiting = 1;
130  emergency_save(0);
131  }
132  va_end(ap);
133 }
EXTERN FILE * logfile
Used by server/daemon.c.
Definition: global.h:144
Error, serious thing.
Definition: logger.h:11
void clean_tmp_files(void)
Remove temporary map files.
Definition: main.c:336
static const char *const loglevel_names[]
Human-readable name of log levels.
Definition: logger.c:31
Information.
Definition: logger.h:12
int reopen_logfile
Definition: logger.c:26
#define TRUE
Definition: compat.h:10
LogLevel debug
Default debugging level.
Definition: global.h:240
Global type definitions and header inclusions.
const char * logfilename
Logfile to use.
Definition: global.h:238
char * log_timestamp_format
Format for timestap, if log_timestamp is set.
Definition: global.h:317
EXTERN long nroferrors
If it exceeds MAX_ERRORS, call fatal()
Definition: global.h:136
void emergency_save(int flag)
Save all players.
Definition: main.c:333
LogLevel
Log levels for the LOG() function.
Definition: logger.h:10
int log_timestamp
If set, log will comport a timestamp.
Definition: global.h:316
#define vsnprintf
Definition: win32.h:61
EXTERN int exiting
True if the game is about to exit.
Definition: global.h:146
struct Settings settings
Server settings.
Definition: init.c:40
EXTERN long trying_emergency_save
True when emergency_save() is reached.
Definition: global.h:135
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.c:51
#define MAX_ERRORS
Bail out if more are received during tick.
Definition: config.h:572