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/console.h>
25#include <logging/factory.h>
26#include <logging/file.h>
27#include <logging/multi.h>
28#include <logging/syslog.h>
29
30#include <cstdlib>
31#include <cstring>
32#include <string>
33
34namespace fawkes {
35
36/** @class UnknownLoggerTypeException <logging/factory.h>
37 * Unknown logger type exception.
38 * Thrown if the requested logger has not been recognized.
39 * @author Tim Niemueller
40 */
41
42/** Constructor.
43 * @param msg optional explanation
44 */
46: Exception("Unknown logger type")
47{
48 append(msg);
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/** Convert a string to a log level.
63 * @param log_level log level as string
64 * @return log level
65 */
67LoggerFactory::string_to_loglevel(const char *log_level)
68{
69 std::string ll = log_level;
70
71 if (ll == "info" || ll == "INFO") {
72 return Logger::LL_INFO;
73 } else if (ll == "warn" || ll == "WARN") {
74 return Logger::LL_WARN;
75 } else if (ll == "error" || ll == "ERROR") {
76 return Logger::LL_ERROR;
77 } else {
78 return Logger::LL_DEBUG;
79 }
80}
81
82/** Get logger instance.
83 * Get an instance of a logger of the given type. The argument string is used for
84 * logger arguments.
85 * Supported logger types:
86 * - console, ConsoleLogger
87 * - file, FileLogger
88 * - syslog, SyslogLogger
89 * NOT supported:
90 * - NetworkLogger, needs a FawkesNetworkHub which cannot be passed by parameter
91 * @param type logger type
92 * @param as logger argument string
93 * @return logger instance of requested type
94 * @exception UnknownLoggerTypeException thrown, if the desired logger could
95 * not be instantiated. This could be a misspelled logger type.
96 */
97Logger *
98LoggerFactory::instance(const char *type, const char *as)
99{
100 Logger *l = NULL;
101
102 if (strcmp(type, "console") == 0) {
103 // no supported arguments
104 l = new ConsoleLogger();
105 } else if (strcmp(type, "file") == 0) {
106 char * tmp = strdup(as);
107 char * saveptr;
108 char * r = strtok_r(tmp, ":", &saveptr);
109 const char *file_name;
110 r = strtok_r(tmp, ":", &saveptr);
111 if (r == NULL) {
112 file_name = "unnamed.log";
113 } else {
114 file_name = r;
115 }
116 l = new FileLogger(file_name);
117 free(tmp);
118 } else if (strcmp(type, "syslog") == 0) {
119 l = new SyslogLogger(as);
120 }
121
122 if (l == NULL)
124 return l;
125}
126
127/** Create MultiLogger instance.
128 * This creates a multi logger instance based on the supplied argument string.
129 * The argument string is of the form
130 * @code
131 * ltype:largs[;ltype2:largs2[;...]]
132 * @endcode
133 * So it is a list of logger type/argument tuples separated by columns concatenated
134 * to one list with exclamation marks. The list is not pre-processed, so if you
135 * mention a logger twice this logger is added twice.
136 * @param as logger argument string
137 * @param default_ll default log level for multi logger
138 * @return multi logger instance with requested loggers
139 * @exception UnknownLoggerTypeException thrown if any of the loggers was unknown.
140 */
143{
144 MultiLogger *m = new MultiLogger();
145 m->set_loglevel(default_ll);
146
147 char * logger_string = strdup(as);
148 char * str = logger_string;
149 char * saveptr, *r;
150 const char *type, *args, *level;
151 char * typeargs_saveptr, *level_saveptr, *type_str;
152 const char *logger_delim = ";";
153 const char *logger_typeargs_delim = ":";
154 const char *logger_level_delim = "/";
155 while ((r = strtok_r(str, logger_delim, &saveptr)) != NULL) {
156 type = strtok_r(r, logger_typeargs_delim, &typeargs_saveptr);
157 args = strtok_r(NULL, logger_typeargs_delim, &typeargs_saveptr);
158
159 type_str = strdup(type);
160
161 type = strtok_r(type_str, logger_level_delim, &level_saveptr);
162 level = strtok_r(NULL, logger_level_delim, &level_saveptr);
163
164 if (type == NULL) {
166 }
167 if (args == NULL) {
168 args = "";
169 }
170
171 try {
172 Logger *l = instance(type, args);
173 m->add_logger(l);
174 if (level) {
175 Logger::LogLevel ll = string_to_loglevel(level);
176 l->set_loglevel(ll);
177 }
178 } catch (Exception &e) {
179 e.append("Could not open logger '%s:%s'", type, args);
180 free(type_str);
181 free(logger_string);
182 delete m;
183 throw;
184 }
185 str = NULL;
186
187 free(type_str);
188 }
189
190 free(logger_string);
191
192 return m;
193}
194
195} // end namespace fawkes
Interface for logging to stderr.
Definition: console.h:37
Base class for exceptions in Fawkes.
Definition: exception.h:36
void append(const char *format,...) noexcept
Append messages to the message list.
Definition: exception.cpp:333
Interface for logging to a specified file.
Definition: file.h:38
static MultiLogger * multilogger_instance(const char *as, Logger::LogLevel default_ll=Logger::LL_DEBUG)
Create MultiLogger instance.
Definition: factory.cpp:142
static Logger * instance(const char *type, const char *as)
Get logger instance.
Definition: factory.cpp:98
Interface for logging.
Definition: logger.h:42
LogLevel
Log level.
Definition: logger.h:51
@ LL_INFO
informational output about normal procedures
Definition: logger.h:53
@ LL_WARN
warning, should be investigated but software still functions, an example is that something was reques...
Definition: logger.h:54
@ LL_ERROR
error, may be recoverable (software still running) or not (software has to terminate).
Definition: logger.h:57
@ LL_DEBUG
debug output, relevant only when tracking down problems
Definition: logger.h:52
virtual void set_loglevel(LogLevel level)
Sets the log level.
Definition: logger.cpp:258
Log through multiple loggers.
Definition: multi.h:35
virtual void set_loglevel(LogLevel level)
Sets the log level.
Definition: multi.cpp:139
void add_logger(Logger *logger)
Add a logger.
Definition: multi.cpp:110
Interface for logging to syslog.
Definition: syslog.h:36
Unknown logger type exception.
Definition: factory.h:36
UnknownLoggerTypeException(const char *msg=NULL)
Constructor.
Definition: factory.cpp:45
Fawkes library namespace.