00001 00002 /*************************************************************************** 00003 * factory.cpp - Logger factory 00004 * 00005 * Created: Mon Jun 04 10:57:21 2007 00006 * Copyright 2007 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. A runtime exception applies to 00014 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Library General Public License for more details. 00020 * 00021 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00022 */ 00023 00024 #include <utils/logging/factory.h> 00025 #include <utils/logging/console.h> 00026 #include <utils/logging/file.h> 00027 #include <utils/logging/multi.h> 00028 00029 #include <cstring> 00030 #include <cstdlib> 00031 00032 namespace fawkes { 00033 00034 /** @class UnknownLoggerTypeException factory.h <utils/logging/factory.h> 00035 * Unknown logger type exception. 00036 * Thrown if the requested logger has not been recognized 00037 */ 00038 00039 /** Constructor. 00040 * @param msg optional explanation 00041 */ 00042 UnknownLoggerTypeException::UnknownLoggerTypeException(const char *msg) 00043 : Exception("Unknown logger type") 00044 { 00045 append(msg); 00046 } 00047 00048 00049 /** @class LoggerFactory factory.h <utils/logging/factory.h> 00050 * Logger factory. 00051 * This logging factory provides access to all loggers in a unified way. You just 00052 * supply a logger argument string and depending on the logger type an instance of 00053 * the desired logger is returned or otherwise 00054 * an exception is thrown. See instance() for a list of supported logger types. 00055 * 00056 * @author Tim Niemueller 00057 */ 00058 00059 /** Get logger instance. 00060 * Get an instance of a logger of the given type. The argument string is used for 00061 * logger arguments. 00062 * Supported logger types: 00063 * - console, ConsoleLogger 00064 * - file, FileLogger 00065 * NOT supported: 00066 * - NetworkLogger, needs a FawkesNetworkHub which cannot be passed by parameter 00067 * @param type logger type 00068 * @param as logger argument string 00069 * @return logger instance of requested type 00070 * @exception UnknownLoggerTypeException thrown, if the desired logger could 00071 * not be instantiated. This could be a misspelled logger type. 00072 */ 00073 Logger * 00074 LoggerFactory::instance(const char *type, const char *as) 00075 { 00076 Logger *l = NULL; 00077 00078 if ( strcmp(type, "console") == 0 ) { 00079 // no supported arguments 00080 l = new ConsoleLogger(); 00081 } else if ( strcmp(type, "file") == 0 ) { 00082 char *tmp = strdup(as); 00083 char *saveptr; 00084 char *r = strtok_r(tmp, ":", &saveptr); 00085 const char *file_name; 00086 r = strtok_r(tmp, ":", &saveptr); 00087 if ( r == NULL ) { 00088 file_name = "unnamed.log"; 00089 } else { 00090 file_name = r; 00091 } 00092 l = new FileLogger(file_name); 00093 free(tmp); 00094 } 00095 00096 if ( l == NULL ) throw UnknownLoggerTypeException(); 00097 return l; 00098 } 00099 00100 00101 /** Create MultiLogger instance. 00102 * This creates a multi logger instance based on the supplied argument string. 00103 * The argument string is of the form 00104 * @code 00105 * ltype:largs[;ltype2:largs2[;...]] 00106 * @endcode 00107 * So it is a list of logger type/argument tuples separated by columns concatenated 00108 * to one list with exclamation marks. The list is not pre-processed, so if you 00109 * mention a logger twice this logger is added twice. 00110 * @param as logger argument string 00111 * @return multi logger instance with requested loggers 00112 * @exception UnknownLoggerTypeException thrown if any of the loggers was unknown. 00113 */ 00114 MultiLogger * 00115 LoggerFactory::multilogger_instance(const char *as) 00116 { 00117 MultiLogger *m = new MultiLogger(); 00118 00119 char *logger_string = strdup(as); 00120 char *str = logger_string; 00121 char *saveptr, *r; 00122 const char *type, *args; 00123 char *typeargs_saveptr; 00124 const char *logger_delim = ";"; 00125 const char *logger_typeargs_delim = ":"; 00126 while ((r = strtok_r(str, logger_delim, &saveptr)) != NULL ) { 00127 type = strtok_r(r, logger_typeargs_delim, &typeargs_saveptr); 00128 args = strtok_r(NULL, logger_typeargs_delim, &typeargs_saveptr); 00129 if ( type == NULL ) { 00130 throw UnknownLoggerTypeException(); 00131 } 00132 if ( args == NULL ) { 00133 args = ""; 00134 } 00135 00136 try { 00137 Logger *l = instance(type, args); 00138 m->add_logger(l); 00139 } catch (Exception &e) { 00140 e.append("Could not open logger '%s:%s'", type, args); 00141 free(logger_string); 00142 delete m; 00143 throw; 00144 } 00145 str = NULL; 00146 } 00147 00148 free(logger_string); 00149 00150 return m; 00151 } 00152 00153 00154 } // end namespace fawkes