jabberd2  2.6.1
log.c
Go to the documentation of this file.
1 /*
2  * jabberd - Jabber Open Source Server
3  * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney,
4  * Ryan Eatmon, Robert Norris
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
19  */
20 
21 #include "util.h"
22 
23 #define MAX_LOG_LINE (1024)
24 
25 #ifdef DEBUG
26 static int debug_flag;
27 static FILE *debug_log_target = 0;
28 #endif
29 
30 static const char *_log_level[] =
31 {
32  "emergency",
33  "alert",
34  "critical",
35  "error",
36  "warning",
37  "notice",
38  "info",
39  "debug"
40 };
41 
43  { "local0", LOG_LOCAL0 },
44  { "local1", LOG_LOCAL1 },
45  { "local2", LOG_LOCAL2 },
46  { "local3", LOG_LOCAL3 },
47  { "local4", LOG_LOCAL4 },
48  { "local5", LOG_LOCAL5 },
49  { "local6", LOG_LOCAL6 },
50  { "local7", LOG_LOCAL7 },
51  { "log_user", LOG_USER },
52  { NULL, -1 }
53 };
54 
55 static int _log_facility(const char *facility) {
56  log_facility_t *lp;
57 
58  if (facility == NULL) {
59  return -1;
60  }
61  for (lp = _log_facilities; lp->facility; lp++) {
62  if (!strcasecmp(lp->facility, facility)) {
63  break;
64  }
65  }
66  return lp->number;
67 }
68 
69 log_t log_new(log_type_t type, const char *ident, const char *facility)
70 {
71  log_t log;
72  int fnum = 0;
73 
74  log = (log_t) calloc(1, sizeof(struct log_st));
75 
76  log->type = type;
77 
78  if(type == log_SYSLOG) {
79  fnum = _log_facility(facility);
80  if (fnum < 0)
81  fnum = LOG_LOCAL7;
82  openlog(ident, LOG_PID, fnum);
83  return log;
84  }
85 
86  else if(type == log_STDOUT) {
87  log->file = stdout;
88  return log;
89  }
90 
91  log->file = fopen(ident, "a+");
92  if(log->file == NULL)
93  {
94  fprintf(stderr,
95  "ERROR: couldn't open logfile: %s\n"
96  " logging will go to stdout instead\n", strerror(errno));
97  log->type = log_STDOUT;
98  log->file = stdout;
99  }
100 
101  return log;
102 }
103 
104 void log_write(log_t log, int level, const char *msgfmt, ...)
105 {
106  va_list ap;
107  char *pos, message[MAX_LOG_LINE+1];
108  int sz, len;
109  time_t t;
110 
111  if(log && log->type == log_SYSLOG) {
112  va_start(ap, msgfmt);
113 #ifdef HAVE_VSYSLOG
114  vsyslog(level, msgfmt, ap);
115 #else
116  len = vsnprintf(message, MAX_LOG_LINE, msgfmt, ap);
117  if (len > MAX_LOG_LINE)
118  message[MAX_LOG_LINE] = '\0';
119  else
120  message[len] = '\0';
121  syslog(level, "%s", message);
122 #endif
123  va_end(ap);
124 
125 #ifndef DEBUG
126  return;
127 #endif
128  }
129 
130  /* timestamp */
131  t = time(NULL);
132  pos = ctime(&t);
133  sz = strlen(pos);
134  /* chop off the \n */
135  pos[sz-1]=' ';
136 
137  /* insert the header */
138  len = snprintf(message, MAX_LOG_LINE, "%s[%s] ", pos, _log_level[level]);
139  if (len > MAX_LOG_LINE)
140  message[MAX_LOG_LINE] = '\0';
141  else
142  message[len] = '\0';
143 
144  /* find the end and attach the rest of the msg */
145  for (pos = message; *pos != '\0'; pos++); /*empty statement */
146  sz = pos - message;
147  va_start(ap, msgfmt);
148  vsnprintf(pos, MAX_LOG_LINE - sz, msgfmt, ap);
149  va_end(ap);
150 #ifndef DEBUG
151  if(log && log->type != log_SYSLOG) {
152 #endif
153  if(log && log->file) {
154  fprintf(log->file,"%s", message);
155  fprintf(log->file, "\n");
156  fflush(log->file);
157  }
158 #ifndef DEBUG
159  }
160 #endif
161 
162 #ifdef DEBUG
163  if (!debug_log_target) {
164  debug_log_target = stderr;
165  }
166  /* If we are in debug mode we want everything copied to the stdout */
167  if ((log == 0) || (get_debug_flag() && log->type != log_STDOUT)) {
168  fprintf(debug_log_target, "%s\n", message);
169  fflush(debug_log_target);
170  }
171 #endif /*DEBUG*/
172 }
173 
174 void log_free(log_t log) {
175  if(log->type == log_SYSLOG)
176  closelog();
177  else if(log->type == log_FILE)
178  fclose(log->file);
179 
180  free(log);
181 }
182 
183 #ifdef DEBUG
184 
185 void debug_log(const char *file, int line, const char *msgfmt, ...)
186 {
187  va_list ap;
188  char *pos, message[MAX_DEBUG];
189  int sz;
190  time_t t;
191 
192  if (!debug_log_target) {
193  debug_log_target = stderr;
194  }
195  /* timestamp */
196  t = time(NULL);
197  pos = ctime(&t);
198  sz = strlen(pos);
199  /* chop off the \n */
200  pos[sz-1]=' ';
201 
202  /* insert the header */
203  snprintf(message, MAX_DEBUG, "%s%s:%d ", pos, file, line);
204 
205  /* find the end and attach the rest of the msg */
206  for (pos = message; *pos != '\0'; pos++); /*empty statement */
207  sz = pos - message;
208  va_start(ap, msgfmt);
209  vsnprintf(pos, MAX_DEBUG - sz, msgfmt, ap);
210  va_end(ap);
211  fprintf(debug_log_target,"%s", message);
212  fprintf(debug_log_target, "\n");
213  fflush(debug_log_target);
214 }
215 
216 int get_debug_flag(void)
217 {
218  return debug_flag;
219 }
220 
221 void set_debug_flag(int v)
222 {
223  debug_flag = v;
224 }
225 
227 {
228  return set_debug_file(config_get_one(c, "log.debug", 0));
229 }
230 
231 JABBERD2_API void set_debug_file(const char *filename)
232 {
233  // Close debug output file but not stderr
234  if (debug_log_target != 0 &&
235  debug_log_target != stderr)
236  {
237  fprintf(debug_log_target, "Closing log\n");
238  fclose(debug_log_target);
239 
240  debug_log_target = stderr;
241  }
242 
243  // Setup new log target
244  if (filename) {
245  log_debug(ZONE, "Openning debug log file %s", filename);
246  debug_log_target = fopen(filename, "a+");
247 
248  if (debug_log_target) {
249  log_debug(ZONE, "Staring debug log");
250  } else {
251  debug_log_target = stderr;
252  log_debug(ZONE, "Failed to open debug output file %s. Fallback to stderr", filename);
253  }
254  } else {
255  // set stderr
256  debug_log_target = stderr;
257  }
258 }
259 
260 #else /* DEBUG */
261 void debug_log(const char *file, int line, const char *msgfmt, ...)
262 { }
263 
264 void set_debug_flag(int v)
265 { }
266 
268 { }
269 #endif
JABBERD2_API void set_debug_file(const char *filename)
#define JABBERD2_API
Definition: mio.h:39
void log_write(log_t log, int level, const char *msgfmt,...)
Definition: log.c:104
static const char * _log_level[]
Definition: log.c:30
#define MAX_LOG_LINE
Definition: log.c:23
holder for the config hash and nad
Definition: util.h:200
int number
Definition: util.h:188
void log_free(log_t log)
Definition: log.c:174
JABBERD2_API int get_debug_flag(void)
Definition: log.h:42
const char * facility
Definition: util.h:187
struct _log_st * log_t
Definition: log.h:48
void set_debug_log_from_config(config_t c)
Definition: log.c:267
log_type_t
Definition: log.h:41
static log_facility_t _log_facilities[]
Definition: log.c:42
void debug_log(const char *file, int line, const char *msgfmt,...)
Definition: log.c:261
#define log_debug(...)
Definition: log.h:65
Definition: util.h:179
static int _log_facility(const char *facility)
Definition: log.c:55
void set_debug_flag(int v)
Definition: log.c:264
Definition: log.h:43
Definition: log.h:44
log_t log_new(log_type_t type, const char *ident, const char *facility)
Definition: log.c:69
#define ZONE
Definition: mio_impl.h:76
const char * config_get_one(config_t c, const char *key, int num)
get config value n for this key
Definition: config.c:278
#define MAX_DEBUG
Definition: util.h:422