Crossfire Server, Trunk  1.75.0
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 #ifdef HAVE_SYSLOG_H
25 #include <syslog.h>
26 #endif
27 
28 #include "sproto.h"
29 #include "stats.h"
30 
31 int reopen_logfile = 0; /* May be set in SIGHUP handler */
32 
36 const char *const loglevel_names[NRLOGLEVELS] = {
37  "[EE] ",
38  "[WW] ",
39  "[NN] ",
40  "[II] ",
41  "[DD] ",
42  "[MM] ",
43 };
44 
45 #ifdef HAVE_SYSLOG_H
46 const int syslog_pri_map[NRLOGLEVELS] = {
47  LOG_ERR,
48  LOG_WARNING,
49  LOG_NOTICE,
50  LOG_INFO,
51  LOG_DEBUG,
52  LOG_DEBUG,
53 };
54 #endif
55 
59 
60 int log_total = 0;
61 
62 void init_log() {
63 #ifdef HAVE_SYSLOG_H
64  // disable syslog, then only re-enable it if configured
65  setlogmask(0);
66 #endif
67 }
68 
82 void LOG(LogLevel logLevel, const char *format, ...) {
83  char buf[20480]; /* This needs to be really really big - larger
84  * than any other buffer, since that buffer may
85  * need to be put in this one.
86  */
87 
88  char time_buf[2048];
89 
90  va_list ap;
91  va_start(ap, format);
92 
93  if (settings.log_callback) {
94  settings.log_callback(logLevel, format, ap);
95  va_end(ap);
96  return;
97  }
98 
99  buf[0] = '\0';
100  if (logLevel <= settings.debug) {
101  time_buf[0] = '\0';
102  if (settings.log_timestamp == TRUE) {
103  struct tm *time_tmp;
104  time_t now = time((time_t *)NULL);
105 
106  time_tmp = localtime(&now);
107  if (time_tmp != NULL) {
108  if (strftime(time_buf, sizeof(time_buf), settings.log_timestamp_format, time_tmp) == 0) {
109  time_buf[0] = '\0';
110  }
111  }
112  }
113 
114  vsnprintf(buf, sizeof(buf), format, ap);
115 #ifdef HAVE_SYSLOG_H
116  syslog(syslog_pri_map[logLevel], "%s", buf);
117 #endif
118 #ifdef WIN32 /* ---win32 change log handling for win32 */
119  if (time_buf[0] != 0) {
120  fputs(time_buf, logfile);
121  fputs(" ", logfile);
122  }
123  fputs(loglevel_names[logLevel], logfile); /* wrote to file or stdout */
124  fputs(buf, logfile); /* wrote to file or stdout */
125  fflush(logfile); /* always force flushing! */
126  if (logfile != stderr) { /* if was it a logfile wrote it to screen too */
127  if (time_buf[0] != 0) {
128  fputs(time_buf, stderr);
129  fputs(" ", stderr);
130  }
131  fputs(loglevel_names[logLevel], stderr);
132  fputs(buf, stderr);
133  fflush(stderr);
134  }
135 #else /* not WIN32 */
136  if (reopen_logfile) {
137  reopen_logfile = 0;
138  if (fclose(logfile) != 0) {
139  /* stderr has been closed if -detach was used, but it's better
140  * to try to report about this anyway. */
141  perror("tried to close log file after SIGHUP in logger.c:LOG()");
142  }
143  if ((logfile = fopen(settings.logfilename, "a")) == NULL) {
144  /* There's likely to be something very wrong with the OS anyway
145  * if reopening fails. */
146  perror("tried to open log file after SIGHUP in logger.c:LOG()");
147  emergency_save(0);
148  clean_tmp_files();
149  exit(1);
150  }
151  setvbuf(logfile, NULL, _IOLBF, 0);
152  LOG(llevInfo, "logfile reopened\n");
153  }
154 
155  if (time_buf[0] != 0) {
156  fputs(time_buf, logfile);
157  fputs(" ", logfile);
158  }
159  fputs(loglevel_names[logLevel], logfile);
160  fputs(buf, logfile);
161 #endif
162  log_total++;
163  }
164  if (!exiting
166  && logLevel == llevError
167  && ++nroferrors > MAX_ERRORS) {
168  exiting = 1;
170  emergency_save(0);
171  }
172  va_end(ap);
173 }
global.h
settings
struct Settings settings
Global settings.
Definition: init.cpp:139
emergency_save
void emergency_save(int flag)
Save all players.
Definition: main.cpp:347
llevError
@ llevError
Problems requiring server admin to fix.
Definition: logger.h:11
LOG
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Definition: logger.cpp:82
Settings::log_timestamp_format
char * log_timestamp_format
Format for timestap, if log_timestamp is set.
Definition: global.h:322
maps_saved_total
int maps_saved_total
Definition: logger.cpp:57
maps_swapped_total
int maps_swapped_total
Definition: logger.cpp:58
MAX_ERRORS
#define MAX_ERRORS
Bail out if more are received during tick.
Definition: config.h:522
time
non standard information is not specified or uptime this means how long since the executable has been started A particular host may have been running a server for quite a long time
Definition: arch-handbook.txt:206
buf
StringBuffer * buf
Definition: readable.cpp:1564
Settings::log_callback
logHook log_callback
Log hook, to intercept log messages.
Definition: global.h:249
log_total
int log_total
Definition: logger.cpp:60
Settings::debug
LogLevel debug
Default debugging level.
Definition: global.h:248
stats.h
Settings::logfilename
const char * logfilename
Logfile to use.
Definition: global.h:246
init_log
void init_log()
Definition: logger.cpp:62
trying_emergency_save
long trying_emergency_save
True when emergency_save() is reached.
Definition: init.cpp:111
nroferrors
long nroferrors
If it exceeds MAX_ERRORS, call fatal()
Definition: init.cpp:112
sproto.h
logfile
FILE * logfile
Used by server/daemon.c.
Definition: init.cpp:114
maps_loaded_total
int maps_loaded_total
Definition: logger.cpp:56
llevInfo
@ llevInfo
Information.
Definition: logger.h:14
clean_tmp_files
void clean_tmp_files(void)
Save unique maps and clean up temporary map files unless recycling temporary maps.
Definition: main.cpp:351
reopen_logfile
int reopen_logfile
Definition: logger.cpp:31
LogLevel
LogLevel
Log levels for the LOG() function.
Definition: logger.h:10
TRUE
#define TRUE
Definition: compat.h:11
loglevel_names
const char *const loglevel_names[NRLOGLEVELS]
Human-readable name of log levels.
Definition: logger.cpp:36
Settings::log_timestamp
int log_timestamp
If set, log will comport a timestamp.
Definition: global.h:321
exiting
int exiting
True if the game is about to exit.
Definition: init.cpp:115
NRLOGLEVELS
@ NRLOGLEVELS
Definition: logger.h:17