Fawkes API  Fawkes Development Version
factory.cpp
1 
2 /***************************************************************************
3  * factory.cpp - Logger factory
4  *
5  * Created: Mon Jun 04 10:57:21 2007
6  * Copyright 2007-2011 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version. A runtime exception applies to
14  * this software (see LICENSE.GPL_WRE file mentioned below for details).
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22  */
23 
24 #include <logging/factory.h>
25 #include <logging/console.h>
26 #include <logging/file.h>
27 #include <logging/syslog.h>
28 #include <logging/multi.h>
29 
30 #include <cstring>
31 #include <cstdlib>
32 
33 namespace fawkes {
34 
35 /** @class UnknownLoggerTypeException <logging/factory.h>
36  * Unknown logger type exception.
37  * Thrown if the requested logger has not been recognized.
38  * @author Tim Niemueller
39  */
40 
41 /** Constructor.
42  * @param msg optional explanation
43  */
45  : Exception("Unknown logger type")
46 {
47  append(msg);
48 }
49 
50 
51 /** @class LoggerFactory <logging/factory.h>
52  * Logger factory.
53  * This logging factory provides access to all loggers in a unified
54  * way. You just supply a logger argument string and depending on the
55  * logger type an instance of the desired logger is returned or
56  * otherwise an exception is thrown. See instance() for a list of
57  * supported logger types.
58  *
59  * @author Tim Niemueller
60  */
61 
62 /** Get logger instance.
63  * Get an instance of a logger of the given type. The argument string is used for
64  * logger arguments.
65  * Supported logger types:
66  * - console, ConsoleLogger
67  * - file, FileLogger
68  * - syslog, SyslogLogger
69  * NOT supported:
70  * - NetworkLogger, needs a FawkesNetworkHub which cannot be passed by parameter
71  * @param type logger type
72  * @param as logger argument string
73  * @return logger instance of requested type
74  * @exception UnknownLoggerTypeException thrown, if the desired logger could
75  * not be instantiated. This could be a misspelled logger type.
76  */
77 Logger *
78 LoggerFactory::instance(const char *type, const char *as)
79 {
80  Logger *l = NULL;
81 
82  if ( strcmp(type, "console") == 0 ) {
83  // no supported arguments
84  l = new ConsoleLogger();
85  } else if ( strcmp(type, "file") == 0 ) {
86  char *tmp = strdup(as);
87  char *saveptr;
88  char *r = strtok_r(tmp, ":", &saveptr);
89  const char *file_name;
90  r = strtok_r(tmp, ":", &saveptr);
91  if ( r == NULL ) {
92  file_name = "unnamed.log";
93  } else {
94  file_name = r;
95  }
96  l = new FileLogger(file_name);
97  free(tmp);
98  } else if ( strcmp(type, "syslog") == 0 ) {
99  l = new SyslogLogger(as);
100  }
101 
102  if ( l == NULL ) throw UnknownLoggerTypeException();
103  return l;
104 }
105 
106 
107 /** Create MultiLogger instance.
108  * This creates a multi logger instance based on the supplied argument string.
109  * The argument string is of the form
110  * @code
111  * ltype:largs[;ltype2:largs2[;...]]
112  * @endcode
113  * So it is a list of logger type/argument tuples separated by columns concatenated
114  * to one list with exclamation marks. The list is not pre-processed, so if you
115  * mention a logger twice this logger is added twice.
116  * @param as logger argument string
117  * @return multi logger instance with requested loggers
118  * @exception UnknownLoggerTypeException thrown if any of the loggers was unknown.
119  */
120 MultiLogger *
122 {
123  MultiLogger *m = new MultiLogger();
124 
125  char *logger_string = strdup(as);
126  char *str = logger_string;
127  char *saveptr, *r;
128  const char *type, *args;
129  char *typeargs_saveptr;
130  const char *logger_delim = ";";
131  const char *logger_typeargs_delim = ":";
132  while ((r = strtok_r(str, logger_delim, &saveptr)) != NULL ) {
133  type = strtok_r(r, logger_typeargs_delim, &typeargs_saveptr);
134  args = strtok_r(NULL, logger_typeargs_delim, &typeargs_saveptr);
135  if ( type == NULL ) {
137  }
138  if ( args == NULL ) {
139  args = "";
140  }
141 
142  try {
143  Logger *l = instance(type, args);
144  m->add_logger(l);
145  } catch (Exception &e) {
146  e.append("Could not open logger '%s:%s'", type, args);
147  free(logger_string);
148  delete m;
149  throw;
150  }
151  str = NULL;
152  }
153 
154  free(logger_string);
155 
156  return m;
157 }
158 
159 
160 } // end namespace fawkes
static MultiLogger * multilogger_instance(const char *as)
Create MultiLogger instance.
Definition: factory.cpp:121
Interface for logging to a specified file.
Definition: file.h:36
Interface for logging to stderr.
Definition: console.h:35
Fawkes library namespace.
static Logger * instance(const char *type, const char *as)
Get logger instance.
Definition: factory.cpp:78
Unknown logger type exception.
Definition: factory.h:35
Log through multiple loggers.
Definition: multi.h:35
Base class for exceptions in Fawkes.
Definition: exception.h:36
void add_logger(Logger *logger)
Add a logger.
Definition: multi.cpp:115
Interface for logging to syslog.
Definition: syslog.h:35
UnknownLoggerTypeException(const char *msg=NULL)
Constructor.
Definition: factory.cpp:44
void append(const char *format,...)
Append messages to the message list.
Definition: exception.cpp:341
Interface for logging.
Definition: logger.h:34