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:355
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:321
time
same as sound ncom command like but with extra the client want tick commands so it knows animation timing the client wants to be informed of pickup mode changes Mode will be sent when the player successfully logs and afterward any time the value is but over time
Definition: protocol.txt:416
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:521
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:359
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:320
exiting
int exiting
True if the game is about to exit.
Definition: init.cpp:115
NRLOGLEVELS
@ NRLOGLEVELS
Definition: logger.h:17