/usr/include/kea/log/logger.h is in kea-dev 1.1.0-1build2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 | // Copyright (C) 2011-2015 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_H
#define LOGGER_H
#include <cassert>
#include <cstdlib>
#include <string>
#include <cstring>
#include <boost/static_assert.hpp>
#include <exceptions/exceptions.h>
#include <log/logger_level.h>
#include <log/message_types.h>
#include <log/log_formatter.h>
namespace isc {
namespace log {
namespace interprocess {
// Forward declaration to hide implementation details from normal
// applications.
class InterprocessSync;
}
/// \page LoggingApi Logging API
/// \section LoggingApiOverview Overview
/// Kea logging uses the concepts of the widely-used Java logging
/// package log4j (http://logging.apache.log/log4j), albeit implemented
/// in C++ using an open-source port. Features of the system are:
///
/// - Within the code objects - known as loggers - can be created and
/// used to log messages. These loggers have names; those with the
/// same name share characteristics (such as output destination).
/// - Loggers have a hierarchical relationship, with each logger being
/// the child of another logger, except for the top of the hierarchy, the
/// root logger. If a logger does not log a message, it is passed to the
/// parent logger.
/// - Messages can be logged at severity levels of FATAL, ERROR, WARN, INFO
/// or DEBUG. The DEBUG level has further sub-levels numbered 0 (least
/// informative) to 99 (most informative).
/// - Each logger has a severity level set associated with it. When a
/// message is logged, it is output only if it is logged at a level equal
/// to the logger severity level or greater, e.g. if the logger's severity
/// is WARN, only messages logged at WARN, ERROR or FATAL will be output.
///
/// \section LoggingApiLoggerNames Kea Logger Names
/// Within Kea, the root logger root logger is given the name of the
/// program (via the stand-alone function setRootLoggerName()). Other loggers
/// are children of the root logger and are named "<program>.<sublogger>".
/// This name appears in logging output, allowing users to identify both
/// the Kea program and the component within the program that generated
/// the message.
///
/// When creating a logger, the abbreviated name "<sublogger>" can be used;
/// the program name will be prepended to it when the logger is created.
/// In this way, individual libraries can have their own loggers without
/// worrying about the program in which they are used, but:
/// - The origin of the message will be clearly identified.
/// - The same component can have different options (e.g. logging severity)
/// in different programs at the same time.
///
/// \section LoggingApiLoggingMessages Logging Messages
/// Instead of embedding the text of messages within the code, each message
/// is referred to using a symbolic name. The logging code uses this name as
/// a key in a dictionary from which the message text is obtained. Such a
/// system allows for the optional replacement of message text at run time.
/// More details about the message dictionary (and the compiler used to create
/// the symbol definitions) can be found in other modules in the src/lib/log
/// directory.
///
/// \section LoggingApiImplementationIssues Implementation Issues
/// Owing to the way that the logging is implemented, notably that loggers can
/// be declared as static external objects, there is a restriction on the
/// length of the name of a logger component (i.e. the length of
/// the string passed to the Logger constructor) to a maximum of 31 characters.
/// There is no reason for this particular value other than limiting the amount
/// of memory used. It is defined by the constant Logger::MAX_LOGGER_NAME_SIZE,
/// and can be made larger (or smaller) if so desired. Note however, using a
/// logger name larger than this limit will cause an assertion failure.
class LoggerImpl; // Forward declaration of the implementation class
/// \brief Bad Interprocess Sync
///
/// Exception thrown if a bad InterprocessSync object (such as NULL) is
/// used.
class BadInterprocessSync : public isc::Exception {
public:
BadInterprocessSync(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what)
{}
};
/// \brief Logger Name Error
///
/// Exception thrown if a logger name is too short or too long.
class LoggerNameError : public isc::Exception {
public:
LoggerNameError(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what)
{}
};
/// \brief Logger Name is Null
///
/// Exception thrown if a logger name is null
class LoggerNameNull : public isc::Exception {
public:
LoggerNameNull(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what)
{}
};
/// \brief Logging Not Initialized
///
/// Exception thrown if an attempt is made to access a logging function
/// if the logging system has not been initialized.
class LoggingNotInitialized : public isc::Exception {
public:
LoggingNotInitialized(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what)
{}
};
/// \brief Logger Class
///
/// This class is the main class used for logging. Use comprises:
///
/// 1. Constructing a logger by instantiating it with a specific name. (If the
/// same logger is in multiple functions within a file, overhead can be
/// minimized by declaring it as a file-wide static variable.)
/// 2. Using the error(), info() etc. methods to log an error. (However, it is
/// recommended to use the LOG_ERROR, LOG_INFO etc. macros defined in macros.h.
/// These will avoid the potentially-expensive evaluation of arguments if the
/// severity is such that the message will be suppressed.)
class Logger {
public:
/// Maximum size of a logger name
static const size_t MAX_LOGGER_NAME_SIZE = 31;
/// \brief Constructor
///
/// Creates/attaches to a logger of a specific name.
///
/// \param name Name of the logger. If the name is that of the root name,
/// this creates an instance of the root logger; otherwise it creates a
/// child of the root logger.
///
/// \note The name of the logger may be no longer than MAX_LOGGER_NAME_SIZE
/// else the program will throw an exception. This restriction allows
/// loggers to be declared statically: the name is stored in a fixed-size
/// array to avoid the need to allocate heap storage during program
/// initialization (which causes problems on some operating systems).
///
/// \note Note also that there is no constructor taking a std::string. This
/// minimizes the possibility of initializing a static logger with a
/// string, so leading to problems mentioned above.
Logger(const char* name) : loggerptr_(NULL) {
// Validate the name of the logger.
if (name == NULL) {
isc_throw(LoggerNameNull, "logger names may not be null");
} else {
// Name not null, is it too short or too long?
size_t namelen = std::strlen(name);
if ((namelen == 0) || (namelen > MAX_LOGGER_NAME_SIZE)) {
isc_throw(LoggerNameError, "'" << name << "' is not a valid "
<< "name for a logger: valid names must be between 1 "
<< "and " << MAX_LOGGER_NAME_SIZE << " characters in "
<< "length");
}
}
// The checks above and the assertion below ensure that the contents of
// "name" plus a trailing null will fit into the space allocated for
// "name_".
BOOST_STATIC_ASSERT(MAX_LOGGER_NAME_SIZE < sizeof(name_));
// Do the copy, ensuring a trailing NULL in all cases.
std::strncpy(name_, name, MAX_LOGGER_NAME_SIZE);
name_[MAX_LOGGER_NAME_SIZE] = '\0';
}
/// \brief Destructor
virtual ~Logger();
/// \brief Version
static std::string getVersion();
/// \brief The formatter used to replace placeholders
typedef isc::log::Formatter<Logger> Formatter;
/// \brief Get Name of Logger
///
/// \return The full name of the logger (including the root name)
virtual std::string getName();
/// \brief Set Severity Level for Logger
///
/// Sets the level at which this logger will log messages. If none is set,
/// the level is inherited from the parent.
///
/// \param severity Severity level to log
/// \param dbglevel If the severity is DEBUG, this is the debug level.
/// This can be in the range 1 to 100 and controls the verbosity. A value
/// outside these limits is silently coerced to the nearest boundary.
virtual void setSeverity(isc::log::Severity severity, int dbglevel = 1);
/// \brief Get Severity Level for Logger
///
/// \return The current logging level of this logger. In most cases though,
/// the effective logging level is what is required.
virtual isc::log::Severity getSeverity();
/// \brief Get Effective Severity Level for Logger
///
/// \return The effective severity level of the logger. This is the same
/// as getSeverity() if the logger has a severity level set, but otherwise
/// is the severity of the parent.
virtual isc::log::Severity getEffectiveSeverity();
/// \brief Return DEBUG Level
///
/// \return Current setting of debug level. This is returned regardless of
/// whether the severity is set to debug.
virtual int getDebugLevel();
/// \brief Get Effective Debug Level for Logger
///
/// \return The effective debug level of the logger. This is the same
/// as getDebugLevel() if the logger has a debug level set, but otherwise
/// is the debug level of the parent.
virtual int getEffectiveDebugLevel();
/// \brief Returns if Debug Message Should Be Output
///
/// \param dbglevel Level for which debugging is checked. Debugging is
/// enabled only if the logger has DEBUG enabled and if the dbglevel
/// checked is less than or equal to the debug level set for the logger.
virtual bool isDebugEnabled(int dbglevel = MIN_DEBUG_LEVEL);
/// \brief Is INFO Enabled?
virtual bool isInfoEnabled();
/// \brief Is WARNING Enabled?
virtual bool isWarnEnabled();
/// \brief Is ERROR Enabled?
virtual bool isErrorEnabled();
/// \brief Is FATAL Enabled?
virtual bool isFatalEnabled();
/// \brief Output Debug Message
///
/// \param dbglevel Debug level, ranging between 0 and 99. Higher numbers
/// are used for more verbose output.
/// \param ident Message identification.
Formatter debug(int dbglevel, const MessageID& ident);
/// \brief Output Informational Message
///
/// \param ident Message identification.
Formatter info(const MessageID& ident);
/// \brief Output Warning Message
///
/// \param ident Message identification.
Formatter warn(const MessageID& ident);
/// \brief Output Error Message
///
/// \param ident Message identification.
Formatter error(const MessageID& ident);
/// \brief Output Fatal Message
///
/// \param ident Message identification.
Formatter fatal(const MessageID& ident);
/// \brief Replace the interprocess synchronization object
///
/// If this method is called with NULL as the argument, it throws a
/// BadInterprocessSync exception.
///
/// \note This method is intended to be used only within this log library
/// and its tests. Normal application shouldn't use it (in fact,
/// normal application shouldn't even be able to instantiate
/// InterprocessSync objects).
///
/// \param sync The logger uses this synchronization object for
/// synchronizing output of log messages. It should be deletable and
/// the ownership is transferred to the logger. If NULL is passed,
/// a BadInterprocessSync exception is thrown.
void setInterprocessSync(isc::log::interprocess::InterprocessSync* sync);
/// \brief Equality
///
/// Check if two instances of this logger refer to the same stream.
///
/// \return true if the logger objects are instances of the same logger.
bool operator==(Logger& other);
private:
friend class isc::log::Formatter<Logger>;
/// \brief Raw output function
///
/// This is used by the formatter to output formatted output.
///
/// \param severity Severity of the message being output.
/// \param message Text of the message to be output.
void output(const Severity& severity, const std::string& message);
/// \brief Copy Constructor
///
/// Disabled (marked private) as it makes no sense to copy the logger -
/// just create another one of the same name.
Logger(const Logger&);
/// \brief Assignment Operator
///
/// Disabled (marked private) as it makes no sense to copy the logger -
/// just create another one of the same name.
Logger& operator=(const Logger&);
/// \brief Initialize Implementation
///
/// Returns the logger pointer. If not yet set, the implementation class is
/// initialized.
///
/// The main reason for this is to allow loggers to be declared statically
/// before the underlying logging system is initialized. However, any
/// attempt to access a logging method on any logger before initialization -
/// regardless of whether is is statically or automatically declared - will
/// cause a "LoggingNotInitialized" exception to be thrown.
///
/// \return Returns pointer to implementation
LoggerImpl* getLoggerPtr() {
if (!loggerptr_) {
initLoggerImpl();
}
return (loggerptr_);
}
/// \brief Initialize Underlying Implementation and Set loggerptr_
void initLoggerImpl();
LoggerImpl* loggerptr_; ///< Pointer to underlying logger
char name_[MAX_LOGGER_NAME_SIZE + 1]; ///< Copy of the logger name
};
} // namespace log
} // namespace isc
#endif // LOGGER_H
|