1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
// Copyright (C) 2011-2022 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef LOGGER_MANAGER_IMPL_H
#define LOGGER_MANAGER_IMPL_H

#include <string><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <log4cplus/appender.h><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <log/logger_level.h>
#include <log/logger_specification.h>

// Forward declaration to avoid need to include log4cplus header file here.
namespace log4cplus {
class Logger;
class Appender;
}

namespace isc {
namespace log {

// Forward declarations
struct OutputOption;

/// \brief Logger Manager Implementation
///
/// This is the implementation of the logger manager for the log4cplus
/// underlying logger.
///
/// As noted in logger_manager.h, the logger manager class exists to set up the
/// logging given a set of specifications.  This class handles the processing
/// of those specifications.
///
/// Note: the logging has been implemented using a "pimpl" idiom to conceal
/// the underlying implementation (log4cplus) from the Kea interface.
/// This requires that there be an implementation class, even though in this
/// case, all the implementation class methods can be declared static.

class LoggerManagerImpl {
public:

    /// \brief Constructor
    LoggerManagerImpl() {}

    /// \brief Initialize Processing
    ///
    /// This resets the hierarchy of loggers back to their defaults.  This means
    /// that all non-root loggers (if they exist) are set to NOT_SET, and the
    /// root logger reset to logging informational messages.
    void processInit();

    /// \brief Process Specification
    ///
    /// Processes the specification for a single logger.
    ///
    /// \param spec Logging specification for this logger
    void processSpecification(const LoggerSpecification& spec);

    /// \brief End Processing
    ///
    /// Terminates the processing of the logging specifications.
    void processEnd();

    /// \brief Implementation-specific initialization
    ///
    /// Sets the basic configuration for logging (the root logger has INFO and
    /// more severe messages routed to stdout).  Unless this function (or
    /// process() with a valid specification for all loggers that will log
    /// messages) is called before a message is logged, log4cplus will output
    /// a message to stderr noting that logging has not been initialized.
    ///
    /// It is assumed here that the name of the Kea root logger can be
    /// obtained from the global function getRootLoggerName().
    ///
    /// \param severity Severity to be associated with this logger
    /// \param dbglevel Debug level associated with the root logger
    /// \param buffer If true, all log messages will be buffered until one of
    ///        the \c process() methods is called. If false, initial logging
    ///        shall go to the default output (i.e. stdout)
    static void init(isc::log::Severity severity = isc::log::INFO,
                     int dbglevel = 0, bool buffer = false);

    /// \brief Reset logging
    ///
    /// Resets to default configuration (root logger logging to the console
    /// with INFO severity).
    ///
    /// \param severity Severity to be associated with this logger
    /// \param dbglevel Debug level associated with the root logger
    static void reset(isc::log::Severity severity = isc::log::INFO,
                      int dbglevel = 0);

private:
    /// @brief Decides what appender to create.
    ///
    /// Delegates to the other functions that create appenders based on what's
    /// in spec.
    ///
    /// @param logger log4cplus logger to which the appender must be attached
    /// @param spec the configured specification consisting of output options
    static void appenderFactory(log4cplus::Logger& logger,
                                LoggerSpecification const& spec);

    /// \brief Create console appender
    ///
    /// Creates an object that, when attached to a logger, will log to one
    /// of the output streams (stdout or stderr).
    ///
    /// \param logger Log4cplus logger to which the appender must be attached.
    /// \param opt Output options for this appender.
    static void createConsoleAppender(log4cplus::Logger& logger,
                                      const OutputOption& opt);

    /// \brief Create file appender
    ///
    /// Creates an object that, when attached to a logger, will log to a
    /// specified file.  This also includes the ability to "roll" files when
    /// they reach a specified size.
    ///
    /// \param logger Log4cplus logger to which the appender must be attached.
    /// \param opt Output options for this appender.
    static void createFileAppender(log4cplus::Logger& logger,
                                   const OutputOption& opt);

    /// \brief Create syslog appender
    ///
    /// Creates an object that, when attached to a logger, will log to the
    /// syslog file.
    ///
    /// \param logger Log4cplus logger to which the appender must be attached.
    /// \param opt Output options for this appender.
    static void createSyslogAppender(log4cplus::Logger& logger,
                                     const OutputOption& opt);

    /// \brief Create buffered appender
    ///
    /// Appends an object to the logger that will store the log events sent
    /// to the logger. These log messages are replayed to the logger in
    /// processEnd().
    ///
    /// \param logger Log4cplus logger to which the appender must be attached.
    static void createBufferAppender(log4cplus::Logger& logger);

    /// \brief Set default layout and severity for root logger
    ///
    /// Initializes the root logger to Kea defaults - console or buffered
    /// output and the passed severity/debug level.
    ///
    /// \param severity Severity of messages that the logger should output.
    /// \param dbglevel Debug level if severity = DEBUG
    /// \param buffer If true, all log messages will be buffered until one of
    ///        the \c process() methods is called. If false, initial logging
    ///        shall go to the default output (i.e. stdout)
    static void initRootLogger(isc::log::Severity severity = isc::log::INFO,
                               int dbglevel = 0, bool buffer = false);

    /// \brief Set layout for an appender
    ///
    /// Sets the layout of the specified appender to one suitable for file
    /// or console output:
    ///
    /// \param appender Appender for which this pattern is to be set.
    /// \param pattern  Log message format pattern
    static void setAppenderLayout(log4cplus::SharedAppenderPtr& appender,
                                  std::string pattern);

    /// \brief Store all buffer appenders
    ///
    /// When processing a new specification, this method can be used
    /// to keep a list of the buffer appenders; the caller can then
    /// process the specification, and call \c flushBufferAppenders()
    /// to flush and clear the list
    void storeBufferAppenders();

    /// \brief Flush the stored buffer appenders
    ///
    /// This flushes the list of buffer appenders stored in
    /// \c storeBufferAppenders(), and clears it
    void flushBufferAppenders();

    /// @brief Only used between processInit() and processEnd(), to temporarily
    /// store the buffer appenders in order to flush them after
    /// processSpecification() calls have been completed
    std::vector<log4cplus::SharedAppenderPtr> buffer_appender_store_;

    /// @brief A hard copy of the specification for the root logger used for
    /// inheritance by child loggers.
    LoggerSpecification root_spec_;
};

} // namespace log
} // namespace isc

#endif // LOGGER_MANAGER_IMPL_H