Fawkes API  Fawkes Development Version
factory.cpp
00001 
00002 /***************************************************************************
00003  *  factory.cpp - Logger factory
00004  *
00005  *  Created: Mon Jun 04 10:57:21 2007
00006  *  Copyright  2007-2011  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 <logging/factory.h>
00025 #include <logging/console.h>
00026 #include <logging/file.h>
00027 #include <logging/syslog.h>
00028 #include <logging/multi.h>
00029 
00030 #include <cstring>
00031 #include <cstdlib>
00032 
00033 namespace fawkes {
00034 
00035 /** @class UnknownLoggerTypeException <logging/factory.h>
00036  * Unknown logger type exception.
00037  * Thrown if the requested logger has not been recognized.
00038  * @author Tim Niemueller
00039  */
00040 
00041 /** Constructor.
00042  * @param msg optional explanation
00043  */
00044 UnknownLoggerTypeException::UnknownLoggerTypeException(const char *msg)
00045   : Exception("Unknown logger type")
00046 {
00047   append(msg);
00048 }
00049 
00050 
00051 /** @class LoggerFactory <logging/factory.h>
00052  * Logger factory.
00053  * This logging factory provides access to all loggers in a unified
00054  * way. You just supply a logger argument string and depending on the
00055  * logger type an instance of the desired logger is returned or
00056  * otherwise an exception is thrown. See instance() for a list of
00057  * supported logger types.
00058  *
00059  * @author Tim Niemueller
00060  */
00061 
00062 /** Get logger instance.
00063  * Get an instance of a logger of the given type. The argument string is used for
00064  * logger arguments.
00065  * Supported logger types:
00066  * - console, ConsoleLogger
00067  * - file, FileLogger
00068  * - syslog, SyslogLogger
00069  * NOT supported:
00070  * - NetworkLogger, needs a FawkesNetworkHub which cannot be passed by parameter
00071  * @param type logger type
00072  * @param as logger argument string
00073  * @return logger instance of requested type
00074  * @exception UnknownLoggerTypeException thrown, if the desired logger could
00075  * not be instantiated. This could be a misspelled logger type.
00076  */
00077 Logger *
00078 LoggerFactory::instance(const char *type, const char *as)
00079 {
00080   Logger *l = NULL;
00081 
00082   if ( strcmp(type, "console") == 0 ) {
00083     // no supported arguments
00084     l = new ConsoleLogger();
00085   } else if ( strcmp(type, "file") == 0 ) {
00086     char *tmp = strdup(as);
00087     char *saveptr;
00088     char *r = strtok_r(tmp, ":", &saveptr);
00089     const char *file_name;
00090     r = strtok_r(tmp, ":", &saveptr);
00091     if ( r == NULL ) {
00092       file_name = "unnamed.log";
00093     } else {
00094       file_name = r;
00095     }
00096     l = new FileLogger(file_name);
00097     free(tmp);
00098   } else if ( strcmp(type, "syslog") == 0 ) {
00099     l = new SyslogLogger(as);
00100   }
00101 
00102   if ( l == NULL )  throw UnknownLoggerTypeException();
00103   return l;
00104 }
00105 
00106 
00107 /** Create MultiLogger instance.
00108  * This creates a multi logger instance based on the supplied argument string.
00109  * The argument string is of the form
00110  * @code
00111  *  ltype:largs[;ltype2:largs2[;...]]
00112  * @endcode
00113  * So it is a list of logger type/argument tuples separated by columns concatenated
00114  * to one list with exclamation marks. The list is not pre-processed, so if you
00115  * mention a logger twice this logger is added twice.
00116  * @param as logger argument string
00117  * @return multi logger instance with requested loggers
00118  * @exception UnknownLoggerTypeException thrown if any of the loggers was unknown.
00119  */
00120 MultiLogger *
00121 LoggerFactory::multilogger_instance(const char *as)
00122 {
00123   MultiLogger *m = new MultiLogger();
00124 
00125   char *logger_string = strdup(as);
00126   char *str = logger_string;
00127   char *saveptr, *r;
00128   const char *type, *args;
00129   char *typeargs_saveptr;
00130   const char *logger_delim = ";";
00131   const char *logger_typeargs_delim = ":";
00132   while ((r = strtok_r(str, logger_delim, &saveptr)) != NULL ) {
00133     type = strtok_r(r, logger_typeargs_delim, &typeargs_saveptr);
00134     args = strtok_r(NULL, logger_typeargs_delim, &typeargs_saveptr);
00135     if ( type == NULL ) {
00136       throw UnknownLoggerTypeException();
00137     }
00138     if ( args == NULL ) {
00139       args = "";
00140     }
00141 
00142     try {
00143       Logger *l = instance(type, args);
00144       m->add_logger(l);
00145     } catch (Exception &e) {
00146       e.append("Could not open logger '%s:%s'", type, args);
00147       free(logger_string);
00148       delete m;
00149       throw;
00150     }
00151     str = NULL;
00152   }
00153 
00154   free(logger_string);
00155 
00156   return m;
00157 }
00158 
00159 
00160 } // end namespace fawkes