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 #include "stats.h"
26 
27 int reopen_logfile = 0; /* May be set in SIGHUP handler */
28 
32 const char *const loglevel_names[] = {
33  "[EE] ",
34  "[II] ",
35  "[DD] ",
36  "[MM] ",
37 };
38 
42 
43 int log_total = 0;
44 
58 void LOG(LogLevel logLevel, const char *format, ...) {
59  char buf[20480]; /* This needs to be really really big - larger
60  * than any other buffer, since that buffer may
61  * need to be put in this one.
62  */
63 
64  char time_buf[2048];
65 
66  va_list ap;
67  va_start(ap, format);
68 
69  if (settings.log_callback) {
70  settings.log_callback(logLevel, format, ap);
71  va_end(ap);
72  return;
73  }
74 
75  buf[0] = '\0';
76  if (logLevel <= settings.debug) {
77  time_buf[0] = '\0';
78  if (settings.log_timestamp == TRUE) {
79  struct tm *time_tmp;
80  time_t now = time((time_t *)NULL);
81 
82  time_tmp = localtime(&now);
83  if (time_tmp != NULL) {
84  if (strftime(time_buf, sizeof(time_buf), settings.log_timestamp_format, time_tmp) == 0) {
85  time_buf[0] = '\0';
86  }
87  }
88  }
89 
90  vsnprintf(buf, sizeof(buf), format, ap);
91 #ifdef WIN32 /* ---win32 change log handling for win32 */
92  if (time_buf[0] != 0) {
93  fputs(time_buf, logfile);
94  fputs(" ", logfile);
95  }
96  fputs(loglevel_names[logLevel], logfile); /* wrote to file or stdout */
97  fputs(buf, logfile); /* wrote to file or stdout */
98  fflush(logfile); /* always force flushing! */
99  if (logfile != stderr) { /* if was it a logfile wrote it to screen too */
100  if (time_buf[0] != 0) {
101  fputs(time_buf, stderr);
102  fputs(" ", stderr);
103  }
104  fputs(loglevel_names[logLevel], stderr);
105  fputs(buf, stderr);
106  fflush(stderr);
107  }
108 #else /* not WIN32 */
109  if (reopen_logfile) {
110  reopen_logfile = 0;
111  if (fclose(logfile) != 0) {
112  /* stderr has been closed if -detach was used, but it's better
113  * to try to report about this anyway. */
114  perror("tried to close log file after SIGHUP in logger.c:LOG()");
115  }
116  if ((logfile = fopen(settings.logfilename, "a")) == NULL) {
117  /* There's likely to be something very wrong with the OS anyway
118  * if reopening fails. */
119  perror("tried to open log file after SIGHUP in logger.c:LOG()");
120  emergency_save(0);
121  clean_tmp_files();
122  exit(1);
123  }
124  setvbuf(logfile, NULL, _IOLBF, 0);
125  LOG(llevInfo, "logfile reopened\n");
126  }
127 
128  if (time_buf[0] != 0) {
129  fputs(time_buf, logfile);
130  fputs(" ", logfile);
131  }
132  fputs(loglevel_names[logLevel], logfile);
133  fputs(buf, logfile);
134 #endif
135  log_total++;
136  }
137  if (!exiting
139  && logLevel == llevError
140  && ++nroferrors > MAX_ERRORS) {
141  exiting = 1;
143  emergency_save(0);
144  }
145  va_end(ap);
146 }
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:58
Settings::log_timestamp_format
char * log_timestamp_format
Definition: global.h:319
maps_saved_total
int maps_saved_total
Definition: logger.cpp:40
maps_swapped_total
int maps_swapped_total
Definition: logger.cpp:41
MAX_ERRORS
#define MAX_ERRORS
Definition: config.h:522
buf
StringBuffer * buf
Definition: readable.cpp:1565
Settings::log_callback
logHook log_callback
Definition: global.h:244
log_total
int log_total
Definition: logger.cpp:43
Settings::debug
LogLevel debug
Definition: global.h:243
stats.h
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
maps_loaded_total
int maps_loaded_total
Definition: logger.cpp:39
reopen_logfile
int reopen_logfile
Definition: logger.cpp:27
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:32
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