Page MenuHomePhorge

log.h
No OneTemporary

Size
9 KB
Referenced Files
None
Subscribers
None
//===-- rosa/support/log.h --------------------------------------*- C++ -*-===//
//
// The RoSA Framework
//
// Distributed under the terms and conditions of the Boost Software License 1.0.
// See accompanying file LICENSE.
//
// If you did not receive a copy of the license file, see
// http://www.boost.org/LICENSE_1_0.txt.
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/support/log.h
///
/// \author David Juhasz (david.juhasz@tuwien.ac.at)
///
/// \date 2017-2019
///
/// \brief Facility for logging.
///
/// \note One call for the various logging macros is supposed to be used
/// for registering one log entry. That goes natural with the non-stream
/// implementations, which accept one string as argument. A more flexible way
/// for printing log entries, for example for colorizing text, is to use macros
/// providing a log stream. It is important to note, however, that the stream
/// obtained from one macro evaluation fits for printing one log entry, without
/// nested/overlapping log entry emissions and the entry being closed with a
/// newline. Should this simple recommendation not being followed, the result
/// becomes hard to read due to missing line breaks and overlapping entries.
///
/// \todo Thread-safety is another issue, which need to be addressed for proper
/// logging.
///
//===----------------------------------------------------------------------===//
#ifndef ROSA_SUPPORT_LOG_H
#define ROSA_SUPPORT_LOG_H
#include "rosa/config/config.h"
#include "rosa/support/terminal_colors.h"
#include <ostream>
#include <string>
/* ****************************************************************************
* Log Levels *
* ****************************************************************************/
namespace rosa {
/// Type-safe definition of log levels, use this in code.
/// \note Keep values in sync with the corresponding preprocessor definitions.
enum class LogLevel {
Error, ///< Log errors only
Warning, ///< Like \c rosa::LogLevel::Error and also log warnings
Info, ///< Like \c rosa::LogLevel::Warning and also log general infos
Debug, ///< Like \c rosa::LogLevel::Info and also log debug infos
Trace, ///< Like \c rosa::LogLevel::Debug and also log trace infos
NumLogLevels ///< Number of log levels
};
/// Converts a \c rosa::LogLevel to its textual representation.
///
/// \param logLevel \c rosa::LogLevel to convert
///
/// \return \c std::string representing \p logLevel
///
/// \pre `logLevel` is valid:\code
/// logLevel != LogLevel::NumLogLevels
/// \endcode
std::string logLevelToString(const LogLevel logLevel);
/// Prints colorized tag for the given \c rosa::LogLevel.
///
/// \param [in,out] OS \c std::ostream to print to
/// \param logLevel \c rosa::LogLevel to print tag for
///
/// \return \p OS after printing a tag for \p logLevel
///
/// \pre \p logLevel is valid:\code
/// logLevel != LogLevel::NumLogLevels
/// \endcode
std::ostream &operator<<(std::ostream &OS, const LogLevel logLevel);
} // End namespace rosa
/// \name Valid log level constants
/// \note Only for preprocessor definitions in this file.
/// \note Keep the defintions in sync with the values of \c rosa::LogLevel.
///@{
#define ROSA_LOG_LEVEL_ERROR \
0 ///< Value corresponding to \c rosa::LogLevel::Error
#define ROSA_LOG_LEVEL_WARNING \
1 ///< Value corresponding to \c rosa::LogLevel::Warning
#define ROSA_LOG_LEVEL_INFO \
2 ///< Value corresponding to \c rosa::LogLevel::Info
#define ROSA_LOG_LEVEL_DEBUG \
3 ///< Value corresponding to \c rosa::LogLevel::Debug
#define ROSA_LOG_LEVEL_TRACE \
4 ///< Value corresponding to \c rosa::LogLevel::Trace
///@}
/* ****************************************************************************
* Logger Implementation *
* ****************************************************************************/
/// Stream to print logs to
///
/// \todo Make it configurable, e.g. printing into a file.
#define ROSA_LOG_OSTREAM std::clog
/// Prints a log message to \c ROSA_LOG_OSTREAM.
///
/// \param level \c rosa::LogLevel of the log entry
/// \param output message to print
#define ROSA_LOG_IMPL(level, output) \
do { \
ROSA_LOG_OSTREAM << (level) << " " << __func__ << "@" << __FILENAME__ \
<< ":" << __LINE__ << ": " << (output) << '\n'; \
} while (false)
/// Returns a stream to print a log message to.
///
/// \param level \c rosa::LogLevel of the log entry that is about to be printed
#define ROSA_LOG_STREAM_IMPL(level) \
([](void) -> std::ostream & { \
return ROSA_LOG_OSTREAM << (level) << " " << __func__ << "@" \
<< __FILENAME__ << ":" << __LINE__ << ": "; \
}())
namespace rosa {
/// Dummy \c std::ostream printing to nowhere.
extern std::ostream LogSink;
} // End namespace rosa
/// An output stream ignoring all its input.
#define ROSA_LOG_STREAM_IGNORE rosa::LogSink
/* ****************************************************************************
* Logging Interface *
* ****************************************************************************/
/// \name Logging interface
///
/// Preprocesser macros for convenience.
///@{
/// \def LOG_ERROR_STREAM
/// \brief Returns a stream to print a log entry of level
/// \c rosa::LogLevel::Error.
/// \note Takes effect only if RoSA is built with a log level not smaller than
/// \c rosa::LogLevel::Error.
/// \def LOG_ERROR(output)
/// \brief Prints a log entry of level \c rosa::LogLevel::Error.
/// \param output the message to print
/// \note Takes effect only if RoSA is built with a log level not smaller than
/// \c rosa::LogLevel::Error.
/// \def LOG_WARNING_STREAM
/// \brief Returns a stream to print a log entry of level
/// \c rosa::LogLevel::Warning.
/// \note Takes effect only if RoSA is built with a log level not smaller than
/// \c rosa::LogLevel::Warning.
/// \def LOG_WARNING(output)
/// \brief Prints a log entry of level \c rosa::LogLevel::Warning.
/// \param output the message to print
/// \note Takes effect only if RoSA is built with a log level not smaller than
/// \c rosa::LogLevel::Warning.
/// \def LOG_INFO_STREAM
/// \brief Returns a stream to print a log entry of level
/// \c rosa::LogLevel::Info.
/// \note Takes effect only if RoSA is built with a log level not smaller than
/// \c rosa::LogLevel::Info.
/// \def LOG_INFO(output)
/// \brief Prints a log entry of level \c rosa::LogLevel::Info.
/// \param output the message to print
/// \note Takes effect only if RoSA is built with a log level not smaller than
/// \c rosa::LogLevel::Info.
/// \def LOG_DEBUG_STREAM
/// \brief Returns a stream to print a log entry of level
/// \c rosa::LogLevel::Debug.
/// \note Takes effect only if RoSA is built with a log level not smaller than
/// \c rosa::LogLevel::Debug.
/// \def LOG_DEBUG(output)
/// \brief Prints a log entry of level \c rosa::LogLevel::Debug.
/// \param output the message to print
/// \note Takes effect only if RoSA is built with a log level not smaller than
/// \c rosa::LogLevel::Debug.
/// \def LOG_TRACE_STREAM
/// \brief Returns a stream to print a log entry of level
/// \c rosa::LogLevel::Trace.
/// \note Takes effect only if RoSA is built with a log level not smaller than
/// \c rosa::LogLevel::Trace.
/// \def LOG_TRACE(output)
/// \brief Prints a log entry of level \c rosa::LogLevel::Trace.
/// \param output the message to print
/// \note Takes effect only if RoSA is built with a log level not smaller than
/// \c rosa::LogLevel::Trace.
///@}
// Define logging macros if logging is enabled.
#ifdef ROSA_LOG_LEVEL
#define LOG_ERROR_STREAM ROSA_LOG_STREAM_IMPL(rosa::LogLevel::Error)
#define LOG_ERROR(output) ROSA_LOG_IMPL(rosa::LogLevel::Error, output)
#if ROSA_LOG_LEVEL >= ROSA_LOG_LEVEL_WARNING
#define LOG_WARNING_STREAM ROSA_LOG_STREAM_IMPL(rosa::LogLevel::Warning)
#define LOG_WARNING(output) ROSA_LOG_IMPL(rosa::LogLevel::Warning, output)
#endif
#if ROSA_LOG_LEVEL >= ROSA_LOG_LEVEL_INFO
#define LOG_INFO_STREAM ROSA_LOG_STREAM_IMPL(rosa::LogLevel::Info)
#define LOG_INFO(output) ROSA_LOG_IMPL(rosa::LogLevel::Info, output)
#endif
#if ROSA_LOG_LEVEL >= ROSA_LOG_LEVEL_DEBUG
#define LOG_DEBUG_STREAM ROSA_LOG_STREAM_IMPL(rosa::LogLevel::Debug)
#define LOG_DEBUG(output) ROSA_LOG_IMPL(rosa::LogLevel::Debug, output)
#endif
#if ROSA_LOG_LEVEL >= ROSA_LOG_LEVEL_TRACE
#define LOG_TRACE_STREAM ROSA_LOG_STREAM_IMPL(rosa::LogLevel::Trace)
#define LOG_TRACE(output) ROSA_LOG_IMPL(rosa::LogLevel::Trace, output)
#endif
#endif // defined ROSA_LOG_LEVEL
// Define all disabled logging features as void.
#ifndef LOG_ERROR
#define LOG_ERROR_STREAM ROSA_LOG_STREAM_IGNORE
#define LOG_ERROR(output) ROSA_IGNORE_UNUSED_EXPR(output)
#endif
#ifndef LOG_WARNING
#define LOG_WARNING_STREAM ROSA_LOG_STREAM_IGNORE
#define LOG_WARNING(output) ROSA_IGNORE_UNUSED_EXPR(output)
#endif
#ifndef LOG_INFO
#define LOG_INFO_STREAM ROSA_LOG_STREAM_IGNORE
#define LOG_INFO(output) ROSA_IGNORE_UNUSED_EXPR(output)
#endif
#ifndef LOG_DEBUG
#define LOG_DEBUG_STREAM ROSA_LOG_STREAM_IGNORE
#define LOG_DEBUG(output) ROSA_IGNORE_UNUSED_EXPR(output)
#endif
#ifndef LOG_TRACE
#define LOG_TRACE_STREAM ROSA_LOG_STREAM_IGNORE
#define LOG_TRACE(output) ROSA_IGNORE_UNUSED_EXPR(output)
#endif
#endif // ROSA_SUPPORT_LOG_H

File Metadata

Mime Type
text/x-c++
Expires
Sun, Jun 8, 7:34 PM (19 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
150510
Default Alt Text
log.h (9 KB)

Event Timeline