Commit cf46f370 authored by Michal 'vorner' Vaner's avatar Michal 'vorner' Vaner
Browse files

[trac901] The formatter interface

But it's mostly empty for now.
parent 50ebc839
......@@ -21,6 +21,7 @@ liblog_la_SOURCES += message_initializer.cc message_initializer.h
liblog_la_SOURCES += message_reader.cc message_reader.h
liblog_la_SOURCES += message_types.h
liblog_la_SOURCES += root_logger_name.cc root_logger_name.h
liblog_la_SOURCES += log_formatter.h
EXTRA_DIST = README
EXTRA_DIST += messagedef.mes
......
// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef __LOG_FORMATTER_H
#define __LOG_FORMMATER_H
#include <string>
namespace isc {
namespace log {
///
/// \brief The log message formatter
///
/// This class allows us to format logging messages conveniently. We
/// call something like logger.warn(WARN_MSG).arg(15).arg(dnsMsg). This
/// outputs some text with placeholders replaced by the arguments, if
/// the logging verbosity is at WARN level or more.
///
/// To make this work, we use the Formatter. The warn (or whatever logging
/// function) returns a Formatter object. That one holds the string to be
/// output with the placeholders. It also remembers if there should be any
/// output at all (eg. if the logging is enabled for this level). When there's
/// no .arg call on the object, it is destroyed right away and we use the
/// destructor to output the text (but only in case we should output anything).
///
/// If there's an .arg call, it replaces a placeholder with the argument
/// converted to string and produces another Formatter. We mark the current
/// Formatter so it won't output anything in it's destructor and the task
/// to do the output is moved onto the new object. Again, the last one in
/// the chain is destroyed without any modification and does the real output.
///
/// Of course, if the logging is turned off, we don't bother with any replacing
/// and just return new empty Formatter. As everything here is in the header
/// file, compiler should be able to easily optimise most of the work with
/// creating and destroying objects and simply do the replacing only.
///
/// User of logging code should not really care much about this class, only
/// call the .arg method to generate the correct output.
template<class Logger> class Formatter {
private:
/// \brief The logger we will use to output the final message
Logger& logger_;
/// \brief Prefix (eg. "ERROR", "DEBUG" or like that)
const char* prefix_;
/// \brief The messages with %1, %2... placeholders
const std::string message_;
/// \brief Which will be the next placeholder to replace
const unsigned nextPlaceholder_;
/// \brief Should we do output?
bool active_;
public:
/// \brief Constructor of "active" formatter
///
/// This will create a formatter in active mode -- the one when it
/// will generate output.
///
/// \param prefix The prefix, like "ERROR" or "DEBUG"
/// \param message The message with placeholders
/// \param nextPlaceholder It is the number of next placeholder which
/// should be replaced. It should be called with 1, higher numbers
/// are used internally in the chain.
/// \param logger The logger where the final output will go.
Formatter(const char* prefix, const std::string& message,
const unsigned& nextPlaceholder, Logger& logger) :
prefix_(prefix), message_(message),
nextPlaceholder_(nextPlaceholder), logger_(logger),
active_(true)
{
}
/// \brief Constructor of "inactive" formatter
///
/// This will create a formatter that produces no output.
Formatter() :
active_(false)
{
}
/// \brief Destructor.
//
/// This is the place where output happens if the formatter is active.
~ Formatter() {
}
/// \brief Replaces another placeholder
///
/// Replaces another placeholder and returns a new formatter with it.
/// Deactivates the current formatter. In case the formatter is not active,
/// only produces another inactive formatter.
template<class Arg> Formatter arg(const Arg& arg) {
}
};
}
}
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment