LCOV - code coverage report
Current view: top level - log - logger_manager_impl.cc (source / functions) Hit Total Coverage
Test: report.info Lines: 52 64 81.2 %
Date: 2012-05-15 Functions: 9 11 81.8 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 38 94 40.4 %

           Branch data     Line data    Source code
       1                 :            : // Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
       2                 :            : //
       3                 :            : // Permission to use, copy, modify, and/or distribute this software for any
       4                 :            : // purpose with or without fee is hereby granted, provided that the above
       5                 :            : // copyright notice and this permission notice appear in all copies.
       6                 :            : //
       7                 :            : // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
       8                 :            : // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
       9                 :            : // AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
      10                 :            : // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
      11                 :            : // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
      12                 :            : // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
      13                 :            : // PERFORMANCE OF THIS SOFTWARE.
      14                 :            : 
      15                 :            : #include <algorithm>
      16                 :            : #include <iostream>
      17                 :            : 
      18                 :            : #include <log4cplus/logger.h>
      19                 :            : #include <log4cplus/configurator.h>
      20                 :            : #include <log4cplus/consoleappender.h>
      21                 :            : #include <log4cplus/fileappender.h>
      22                 :            : #include <log4cplus/syslogappender.h>
      23                 :            : 
      24                 :            : #include <log/logger.h>
      25                 :            : #include <log/logger_level_impl.h>
      26                 :            : #include <log/logger_manager.h>
      27                 :            : #include <log/logger_manager_impl.h>
      28                 :            : #include <log/log_messages.h>
      29                 :            : #include <log/logger_name.h>
      30                 :            : #include <log/logger_specification.h>
      31                 :            : 
      32                 :            : using namespace std;
      33                 :            : 
      34                 :            : namespace isc {
      35                 :            : namespace log {
      36                 :            : 
      37                 :            : // Reset hierarchy of loggers back to default settings.  This removes all
      38                 :            : // appenders from loggers, sets their severity to NOT_SET (so that events are
      39                 :            : // passed back to the parent) and resets the root logger to logging
      40                 :            : // informational messages.  (This last is not a log4cplus default, so we have to
      41                 :            : // explicitly reset the logging severity.)
      42                 :            : 
      43                 :            : void
      44                 :        200 : LoggerManagerImpl::processInit() {
      45                 :        200 :     log4cplus::Logger::getDefaultHierarchy().resetConfiguration();
      46                 :        200 :     initRootLogger();
      47                 :        200 : }
      48                 :            : 
      49                 :            : // Process logging specification.  Set up the common states then dispatch to
      50                 :            : // add output specifications.
      51                 :            : 
      52                 :            : void
      53                 :         62 : LoggerManagerImpl::processSpecification(const LoggerSpecification& spec) {
      54                 :            : 
      55                 :            :     log4cplus::Logger logger = log4cplus::Logger::getInstance(
      56 [ +  - ][ +  - ]:        124 :                                    expandLoggerName(spec.getName()));
      57                 :            : 
      58                 :            :     // Set severity level according to specification entry.
      59                 :            :     logger.setLogLevel(LoggerLevelImpl::convertFromBindLevel(
      60 [ +  - ][ +  - ]:         62 :                        Level(spec.getSeverity(), spec.getDbglevel())));
      61                 :            : 
      62                 :            :     // Set the additive flag.
      63         [ +  - ]:         62 :     logger.setAdditivity(spec.getAdditive());
      64                 :            : 
      65                 :            :     // Output options given?
      66         [ +  - ]:         62 :     if (spec.optionCount() > 0) {
      67                 :            : 
      68                 :            :         // Yes, so replace all appenders for this logger.
      69         [ +  - ]:         62 :         logger.removeAllAppenders();
      70                 :            : 
      71                 :            :         // Now process output specifications.
      72         [ +  + ]:        125 :         for (LoggerSpecification::const_iterator i = spec.begin();
      73                 :        125 :              i != spec.end(); ++i) {
      74   [ +  +  -  - ]:         63 :             switch (i->destination) {
      75                 :            :             case OutputOption::DEST_CONSOLE:
      76         [ +  - ]:         14 :                 createConsoleAppender(logger, *i);
      77                 :            :                 break;
      78                 :            : 
      79                 :            :             case OutputOption::DEST_FILE:
      80         [ +  - ]:         49 :                 createFileAppender(logger, *i);
      81                 :            :                 break;
      82                 :            : 
      83                 :            :             case OutputOption::DEST_SYSLOG:
      84         [ #  # ]:          0 :                 createSyslogAppender(logger, *i);
      85                 :            :                 break;
      86                 :            : 
      87                 :            :             default:
      88                 :            :                 // Not a valid destination.  As we are in the middle of updating
      89                 :            :                 // logging destinations, we could be in the situation where
      90                 :            :                 // there are no valid appenders.  For this reason, throw an
      91                 :            :                 // exception.
      92 [ #  # ][ #  # ]:          0 :                 isc_throw(UnknownLoggingDestination,
                 [ #  # ]
      93                 :            :                           "Unknown logging destination, code = " <<
      94                 :            :                           i->destination);
      95                 :            :             }
      96                 :            :         }
      97                 :            :     }
      98                 :         62 : }
      99                 :            : 
     100                 :            : // Console appender - log to either stdout or stderr.
     101                 :            : void
     102                 :        364 : LoggerManagerImpl::createConsoleAppender(log4cplus::Logger& logger,
     103                 :            :                                          const OutputOption& opt)
     104                 :            : {
     105                 :            :     log4cplus::SharedAppenderPtr console(
     106                 :            :         new log4cplus::ConsoleAppender(
     107         [ +  - ]:        728 :             (opt.stream == OutputOption::STR_STDERR), opt.flush));
     108         [ +  - ]:        364 :     setConsoleAppenderLayout(console);
     109 [ +  - ][ +  - ]:        364 :     logger.addAppender(console);
     110                 :        364 : }
     111                 :            : 
     112                 :            : // File appender.  Depending on whether a maximum size is given, either
     113                 :            : // a standard file appender or a rolling file appender will be created.
     114                 :            : void
     115                 :         49 : LoggerManagerImpl::createFileAppender(log4cplus::Logger& logger,
     116                 :            :                                          const OutputOption& opt)
     117                 :            : {
     118                 :            :     // Append to existing file
     119                 :         49 :     std::ios::openmode mode = std::ios::app;
     120                 :            : 
     121                 :         49 :     log4cplus::SharedAppenderPtr fileapp;
     122         [ +  + ]:         49 :     if (opt.maxsize == 0) {
     123                 :            :         fileapp = log4cplus::SharedAppenderPtr(new log4cplus::FileAppender(
     124 [ +  - ][ +  - ]:         94 :             opt.filename, mode, opt.flush));
                 [ +  - ]
     125                 :            :     } else {
     126                 :            :         fileapp = log4cplus::SharedAppenderPtr(
     127                 :            :             new log4cplus::RollingFileAppender(opt.filename, opt.maxsize,
     128 [ +  - ][ +  - ]:          4 :                                                opt.maxver, opt.flush));
                 [ +  - ]
     129                 :            :     }
     130                 :            : 
     131                 :            :     // use the same console layout for the files.
     132         [ +  - ]:         49 :     setConsoleAppenderLayout(fileapp);
     133 [ +  - ][ +  - ]:         49 :     logger.addAppender(fileapp);
     134                 :         49 : }
     135                 :            : 
     136                 :            : // Syslog appender. 
     137                 :            : void
     138                 :          0 : LoggerManagerImpl::createSyslogAppender(log4cplus::Logger& logger,
     139                 :            :                                          const OutputOption& opt)
     140                 :            : {
     141                 :            :     log4cplus::SharedAppenderPtr syslogapp(
     142         [ #  # ]:          0 :         new log4cplus::SysLogAppender(opt.facility));
     143         [ #  # ]:          0 :     setSyslogAppenderLayout(syslogapp);
     144 [ #  # ][ #  # ]:          0 :     logger.addAppender(syslogapp);
     145                 :          0 : }
     146                 :            : 
     147                 :            : 
     148                 :            : // One-time initialization of the log4cplus system
     149                 :            : 
     150                 :            : void
     151                 :        120 : LoggerManagerImpl::init(isc::log::Severity severity, int dbglevel) {
     152                 :            : 
     153                 :            :     // Set up basic configurator.  This attaches a ConsoleAppender to the
     154                 :            :     // root logger with suitable output.  This is used until we we have
     155                 :            :     // actually read the logging configuration, in which case the output
     156                 :            :     // may well be changed.
     157                 :        240 :     log4cplus::BasicConfigurator config;
     158         [ +  - ]:        120 :     config.configure();
     159                 :            : 
     160                 :            :     // Add the additional debug levels
     161         [ +  - ]:        120 :     LoggerLevelImpl::init();
     162                 :            : 
     163         [ +  - ]:        120 :     reset(severity, dbglevel);
     164                 :        120 : }
     165                 :            : 
     166                 :            : // Reset logging to default configuration.  This closes all appenders
     167                 :            : // and resets the root logger to output INFO messages to the console.
     168                 :            : // It is principally used in testing.
     169                 :            : void
     170                 :        150 : LoggerManagerImpl::reset(isc::log::Severity severity, int dbglevel) {
     171                 :            : 
     172                 :            :     // Initialize the root logger
     173                 :        150 :     initRootLogger(severity, dbglevel);
     174                 :        150 : }
     175                 :            : 
     176                 :            : // Initialize the root logger
     177                 :        350 : void LoggerManagerImpl::initRootLogger(isc::log::Severity severity,
     178                 :            :                                        int dbglevel)
     179                 :            : {
     180                 :        350 :     log4cplus::Logger::getDefaultHierarchy().resetConfiguration();
     181                 :            : 
     182                 :            :     // Set the log4cplus root to not output anything - effectively we are
     183                 :            :     // ignoring it.
     184         [ +  - ]:        350 :     log4cplus::Logger::getRoot().setLogLevel(log4cplus::OFF_LOG_LEVEL);
     185                 :            : 
     186                 :            :     // Set the level for the BIND 10 root logger to the given severity and
     187                 :            :     // debug level.
     188                 :            :     log4cplus::Logger b10root = log4cplus::Logger::getInstance(
     189                 :        700 :                                                     getRootLoggerName());
     190                 :            :     b10root.setLogLevel(LoggerLevelImpl::convertFromBindLevel(
     191 [ +  - ][ +  - ]:        350 :                                                     Level(severity, dbglevel)));
     192                 :            : 
     193                 :            :     // Set the BIND 10 root to use a console logger.
     194                 :            :     OutputOption opt;
     195         [ +  - ]:        350 :     createConsoleAppender(b10root, opt);
     196                 :        350 : }
     197                 :            : 
     198                 :            : // Set the the "console" layout for the given appenders.  This layout includes
     199                 :            : // a date/time and the name of the logger.
     200                 :            : 
     201                 :        413 : void LoggerManagerImpl::setConsoleAppenderLayout(
     202                 :            :         log4cplus::SharedAppenderPtr& appender)
     203                 :            : {
     204                 :            :     // Create the pattern we want for the output - local time.
     205                 :        826 :     string pattern = "%D{%Y-%m-%d %H:%M:%S.%q} %-5p [%c] %m\n";
     206                 :            : 
     207                 :            :     // Finally the text of the message
     208 [ +  - ][ +  - ]:        413 :     auto_ptr<log4cplus::Layout> layout(new log4cplus::PatternLayout(pattern));
     209         [ +  - ]:        413 :     appender->setLayout(layout);
     210                 :        413 : }
     211                 :            : 
     212                 :            : // Set the the "syslog" layout for the given appenders.  This is the same
     213                 :            : // as the console, but without the timestamp (which is expected to be
     214                 :            : // set by syslogd).
     215                 :            : 
     216                 :          0 : void LoggerManagerImpl::setSyslogAppenderLayout(
     217                 :            :         log4cplus::SharedAppenderPtr& appender)
     218                 :            : {
     219                 :            :     // Create the pattern we want for the output - local time.
     220                 :          0 :     string pattern = "%-5p [%c] %m\n";
     221                 :            : 
     222                 :            :     // Finally the text of the message
     223 [ #  # ][ #  # ]:          0 :     auto_ptr<log4cplus::Layout> layout(new log4cplus::PatternLayout(pattern));
     224         [ #  # ]:          0 :     appender->setLayout(layout);
     225                 :          0 : }
     226                 :            : 
     227                 :            : } // namespace log
     228                 :        141 : } // namespace isc

Generated by: LCOV version 1.9