From 5c4c0ca30911b5129b32142b430bb6be1baf0e47 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Mon, 7 May 2018 14:12:58 +0100 Subject: Adding all logging functionality in one file --- yage/core/logger.cpp | 144 +++++++++++++++++++++++++++++++++++++++++- yage/core/logger.h | 159 ++++++++++++++++++++++++++++++++++++++++++++--- yage/core/loglevel.h | 54 ---------------- yage/core/logmessage.cpp | 38 ----------- yage/core/logmessage.h | 70 --------------------- yage/core/logsink.cpp | 134 --------------------------------------- yage/core/logsink.h | 95 ---------------------------- 7 files changed, 293 insertions(+), 401 deletions(-) delete mode 100644 yage/core/loglevel.h delete mode 100644 yage/core/logmessage.cpp delete mode 100644 yage/core/logmessage.h delete mode 100644 yage/core/logsink.cpp delete mode 100644 yage/core/logsink.h (limited to 'yage/core') diff --git a/yage/core/logger.cpp b/yage/core/logger.cpp index 1ae04d0b..ac103a8b 100644 --- a/yage/core/logger.cpp +++ b/yage/core/logger.cpp @@ -7,18 +7,156 @@ */ #include "logger.h" -#include "logmessage.h" -#include "logsink.h" -#include +#include "../util/active.h" #include +#include +#include +#include +#include #include +#include #include namespace yage { +LogMessage::LogMessage(Logger *owner, LogLevel level, + const std::string &file_name, int line_num) + : owner_(owner), meta_({level, file_name, line_num}) +{ +} + +LogMessage::LogMessage(LogMessage &&msg) : owner_(std::move(msg.owner_)) {} + +LogMessage::~LogMessage() +{ + if (owner_ != nullptr) { + owner_->flush(this); + } +} + +LogMessage &LogMessage::operator<<(std::ostream &(*fn)(std::ostream &os)) +{ + fn(buffer_); + return *this; +} + +LogSink::LogSink(const LogSink &sink) : wrapper_(sink.wrapper_->clone()) {} + +LogSink::LogSink(LogSink &&sink) : wrapper_(std::move(sink.wrapper_)) {} + +LogSink &LogSink::operator=(const LogSink &sink) +{ + wrapper_.reset(sink.wrapper_->clone()); + return *this; +} + +LogSink &LogSink::operator=(LogSink &&sink) +{ + wrapper_ = std::move(sink.wrapper_); + return *this; +} + +bool LogSink::operator==(const LogSink &sink) +{ + return (wrapper_.get() == sink.wrapper_.get()); +} + +void LogSink::write(const LogMessage::Meta &meta, const std::string &msg) const +{ + wrapper_->write(meta, msg); +} + +LogSink makeConsoleSink() +{ + return [](const LogMessage::Meta &meta, const std::string &msg) { + std::cout << msg << "\n"; + }; +} + +namespace +{ + +class FileSink +{ +public: + FileSink(std::string &&filename) + : fileHandle_(std::make_shared(filename)) + { + if (!fileHandle_->good()) { + throw std::runtime_error("Could not open file: " + filename); + } + } + + FileSink(const std::string filename) + : fileHandle_(std::make_shared(filename)) + { + if (!fileHandle_->good()) { + throw std::runtime_error("Could not open file: " + filename); + } + } + + ~FileSink() = default; + + void operator()(const LogMessage::Meta &meta, const std::string &msg) const + { + using namespace std::chrono; + + auto now = system_clock::now(); + auto time_t = system_clock::to_time_t(now); + auto local_time = std::localtime(&time_t); + + std::string level; + + switch (meta.level) { + case LogLevel::DEBUG: + level = "DEBUG"; + break; + case LogLevel::INFO: + level = "INFO"; + break; + case LogLevel::WARNING: + level = "WARNING"; + break; + case LogLevel::ERROR: + level = "ERROR"; + break; + case LogLevel::FATAL: + level = "FATAL"; + break; + } + + (*fileHandle_) << std::put_time(local_time, "[%H:%M:%S] [") << level + << "] " << msg << "\n"; + if (meta.fileName != "") { + (*fileHandle_) << "(" << meta.fileName; + if (meta.line != -1) { + (*fileHandle_) << ":" << meta.line << ")"; + } else { + (*fileHandle_) << ")"; + } + } + (*fileHandle_) << "\n\n"; + } + +private: + std::shared_ptr fileHandle_; +}; + +} // namespace + +LogSink makeFileSink(const std::string &filename) +{ + return FileSink(filename); +} + +LogSink makeFileSink(std::string &&filename) +{ + return FileSink(filename); +} + Logger::Logger() : active_(Active::create()), min_level_(LogLevel::INFO) { add(makeConsoleSink()); diff --git a/yage/core/logger.h b/yage/core/logger.h index 2249f79c..cfec0307 100644 --- a/yage/core/logger.h +++ b/yage/core/logger.h @@ -6,21 +6,128 @@ * ---------------------------------------------------------------------------- */ -#ifndef YAGE_CORE_LOGGER_H -#define YAGE_CORE_LOGGER_H +#pragma once #include +#include #include #include #include "../util/active.h" -#include "loglevel.h" -#include "logmessage.h" -#include "logsink.h" namespace yage { +class Logger; + +/** + * Different log levels that can be assigned to each message sent to the Logger. + * The logger then outputs the message if it is above the minimum log level, or + * does not process it. + */ +enum class LogLevel { + /// Lowest log level. This is used by the game engine to output debugging + /// information but is turned off in the logger by default. + DEBUG, + + /// Information message. + INFO, + + /// Warning message. + WARNING, + +#ifdef _WIN32 +#ifdef ERROR +#define YAGE_ERROR_TMP ERROR +#undef ERROR +#endif +#endif + + /// Error message. + ERROR, + +#ifdef _WIN32 +#ifdef YAGE_ERROR_TMP +#define ERROR YAGE_ERROR_TMP +#undef YAGE_ERROR_TMP +#endif +#endif + + /// Fatal message that should be output when the game + /// crashes. + FATAL, +}; + +class LogMessage +{ +public: + ~LogMessage(); + + LogMessage(const LogMessage &msg) = delete; + + LogMessage &operator=(const LogMessage &msg) = delete; + LogMessage &operator=(LogMessage &&msg) = delete; + + template + LogMessage &operator<<(const T &value); + + LogMessage &operator<<(std::ostream &(*fn)(std::ostream &os)); + + struct Meta { + LogLevel level; + std::string fileName; + int line; + }; + +private: + friend class Logger; + + std::ostringstream buffer_; + Logger *owner_; + LogMessage::Meta meta_; + + LogMessage(Logger *owner, LogLevel level, const std::string &file_name, + int line_num); + LogMessage(LogMessage &&msg); +}; + +class LogSink +{ +public: + template + LogSink(T impl); + + LogSink(const LogSink &sink); + LogSink(LogSink &&sink); + + LogSink &operator=(const LogSink &sink); + LogSink &operator=(LogSink &&sink); + bool operator==(const LogSink &sink); + + void write(const LogMessage::Meta &meta, const std::string &msg) const; + +private: + struct Concept { + virtual ~Concept() = default; + + virtual Concept *clone() const = 0; + virtual void write(const LogMessage::Meta &meta, + const std::string &msg) const = 0; + }; + + template + struct Model : Concept { + Model(T impl_i); + virtual Concept *clone() const override; + virtual void write(const LogMessage::Meta &meta, + const std::string &msg) const override; + + T impl; + }; + + std::unique_ptr wrapper_; +}; + class Logger { public: @@ -48,6 +155,46 @@ private: LogLevel min_level_; }; +LogSink makeConsoleSink(); + +LogSink makeFileSink(const std::string &filename); +LogSink makeFileSink(std::string &&filename); + +/* ----------------------------------------------------------------------------- + * Template Implementation + * ----------------------------------------------------------------------------- + */ + +template +LogSink::LogSink(T impl) : wrapper_(new Model(std::move(impl))) +{ +} + +template +LogSink::Model::Model(T impl_i) : impl(impl_i) +{ +} + +template +LogSink::Concept *LogSink::Model::clone() const +{ + return new Model(impl); +} + +template +void LogSink::Model::write(const LogMessage::Meta &meta, + const std::string &msg) const +{ + impl(meta, msg); +} + +template +LogMessage &LogMessage::operator<<(const T &value) +{ + buffer_ << value; + return *this; +} + } // namespace yage #define yLogger (yage::Logger::instance()) @@ -66,5 +213,3 @@ private: #define yLogFatal \ (yage::Logger::instance()(yage::LogLevel::FATAL, __FILE__, __LINE__)) - -#endif diff --git a/yage/core/loglevel.h b/yage/core/loglevel.h deleted file mode 100644 index 51d28398..00000000 --- a/yage/core/loglevel.h +++ /dev/null @@ -1,54 +0,0 @@ -/** --------------------------------------------------------------------------- - * @file: loglevel.h - * - * Copyright (c) 2017 Yann Herklotz Grave - * MIT License, see LICENSE file for more details. - * ---------------------------------------------------------------------------- - */ - -#ifndef YAGE_CORE_LOGLEVEL_H -#define YAGE_CORE_LOGLEVEL_H - -#ifdef _WIN32 -#ifdef ERROR -#define YAGE_ERROR_TMP ERROR -#undef ERROR -#endif -#endif - -namespace yage -{ - -/** - * Different log levels that can be assigned to each message sent to the Logger. - * The logger then outputs the message if it is above the minimum log level, or - * does not process it. - */ -enum class LogLevel { - /// Lowest log level. This is used by the game engine to output debugging - /// information but is turned off in the logger by default. - DEBUG, - - /// Information message. - INFO, - - /// Warning message. - WARNING, - - /// Error message. - ERROR, - - /// Fatal message that should be output when the game - /// crashes. - FATAL, -}; -} - -#ifdef _WIN32 -#ifdef YAGE_ERROR_TMP -#define ERROR YAGE_ERROR_TMP -#undef YAGE_ERROR_TMP -#endif -#endif - -#endif diff --git a/yage/core/logmessage.cpp b/yage/core/logmessage.cpp deleted file mode 100644 index bda20fb0..00000000 --- a/yage/core/logmessage.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/** --------------------------------------------------------------------------- - * @file: logmessage.cpp - * - * Copyright (c) 2017 Yann Herklotz Grave - * MIT License, see LICENSE file for more details. - * ---------------------------------------------------------------------------- - */ - -#include "logmessage.h" -#include "logger.h" - -#include - -namespace yage -{ - -LogMessage::LogMessage(Logger *owner, LogLevel level, - const std::string &file_name, int line_num) - : owner_(owner), meta_({level, file_name, line_num}) -{ -} - -LogMessage::LogMessage(LogMessage &&msg) : owner_(std::move(msg.owner_)) {} - -LogMessage::~LogMessage() -{ - if (owner_ != nullptr) { - owner_->flush(this); - } -} - -LogMessage &LogMessage::operator<<(std::ostream &(*fn)(std::ostream &os)) -{ - fn(buffer_); - return *this; -} - -} // namespace yage diff --git a/yage/core/logmessage.h b/yage/core/logmessage.h deleted file mode 100644 index 5698e4c0..00000000 --- a/yage/core/logmessage.h +++ /dev/null @@ -1,70 +0,0 @@ -/** --------------------------------------------------------------------------- - * @file: logmessage.h - * - * Copyright (c) 2017 Yann Herklotz Grave - * MIT License, see LICENSE file for more details. - * ---------------------------------------------------------------------------- - */ - -#ifndef YAGE_CORE_LOGMESSAGE_H -#define YAGE_CORE_LOGMESSAGE_H - -#include -#include -#include - -#include "loglevel.h" - -namespace yage -{ - -class Logger; - -class LogMessage -{ -public: - ~LogMessage(); - - LogMessage(const LogMessage &msg) = delete; - - LogMessage &operator=(const LogMessage &msg) = delete; - LogMessage &operator=(LogMessage &&msg) = delete; - - template - LogMessage &operator<<(const T &value); - - LogMessage &operator<<(std::ostream &(*fn)(std::ostream &os)); - - struct Meta { - LogLevel level; - std::string fileName; - int line; - }; - -private: - friend class Logger; - - std::ostringstream buffer_; - Logger *owner_; - Meta meta_; - - LogMessage(Logger *owner, LogLevel level, const std::string &file_name, - int line_num); - LogMessage(LogMessage &&msg); -}; - -/* ----------------------------------------------------------------------------- - * Template definitions - * ----------------------------------------------------------------------------- - */ - -template -LogMessage &LogMessage::operator<<(const T &value) -{ - buffer_ << value; - return *this; -} - -} // namespace yage - -#endif diff --git a/yage/core/logsink.cpp b/yage/core/logsink.cpp deleted file mode 100644 index 1f026059..00000000 --- a/yage/core/logsink.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/** --------------------------------------------------------------------------- - * @file: logsink.cpp - * - * Copyright (c) 2017 Yann Herklotz Grave - * MIT License, see LICENSE file for more details. - * ---------------------------------------------------------------------------- - */ - -#include "logsink.h" - -#include -#include -#include -#include -#include - -namespace yage -{ - -LogSink::LogSink(const LogSink &sink) : wrapper_(sink.wrapper_->clone()) {} - -LogSink::LogSink(LogSink &&sink) : wrapper_(std::move(sink.wrapper_)) {} - -LogSink &LogSink::operator=(const LogSink &sink) -{ - wrapper_.reset(sink.wrapper_->clone()); - return *this; -} - -LogSink &LogSink::operator=(LogSink &&sink) -{ - wrapper_ = std::move(sink.wrapper_); - return *this; -} - -bool LogSink::operator==(const LogSink &sink) -{ - return (wrapper_.get() == sink.wrapper_.get()); -} - -void LogSink::write(const LogMessage::Meta &meta, const std::string &msg) const -{ - wrapper_->write(meta, msg); -} - -LogSink makeConsoleSink() -{ - return [](const LogMessage::Meta &meta, const std::string &msg) { - std::cout << msg << "\n"; - }; -} - -namespace -{ - -class FileSink -{ -public: - FileSink(std::string &&filename) - : fileHandle_(std::make_shared(filename)) - { - if (!fileHandle_->good()) { - throw std::runtime_error("Could not open file: " + filename); - } - } - - FileSink(const std::string filename) - : fileHandle_(std::make_shared(filename)) - { - if (!fileHandle_->good()) { - throw std::runtime_error("Could not open file: " + filename); - } - } - - ~FileSink() = default; - - void operator()(const LogMessage::Meta &meta, const std::string &msg) const - { - using namespace std::chrono; - - auto now = system_clock::now(); - auto time_t = system_clock::to_time_t(now); - auto local_time = std::localtime(&time_t); - - std::string level; - - switch (meta.level) { - case LogLevel::DEBUG: - level = "DEBUG"; - break; - case LogLevel::INFO: - level = "INFO"; - break; - case LogLevel::WARNING: - level = "WARNING"; - break; - case LogLevel::ERROR: - level = "ERROR"; - break; - case LogLevel::FATAL: - level = "FATAL"; - break; - } - - (*fileHandle_) << std::put_time(local_time, "[%H:%M:%S] [") << level - << "] " << msg << "\n"; - if (meta.fileName != "") { - (*fileHandle_) << "(" << meta.fileName; - if (meta.line != -1) { - (*fileHandle_) << ":" << meta.line << ")"; - } else { - (*fileHandle_) << ")"; - } - } - (*fileHandle_) << "\n\n"; - } - -private: - std::shared_ptr fileHandle_; -}; - -} // namespace - -LogSink makeFileSink(const std::string &filename) -{ - return FileSink(filename); -} - -LogSink makeFileSink(std::string &&filename) -{ - return FileSink(filename); -} - -} // namespace yage diff --git a/yage/core/logsink.h b/yage/core/logsink.h deleted file mode 100644 index 16812b16..00000000 --- a/yage/core/logsink.h +++ /dev/null @@ -1,95 +0,0 @@ -/** --------------------------------------------------------------------------- - * @file: logsink.h - * - * Copyright (c) 2017 Yann Herklotz Grave - * MIT License, see LICENSE file for more details. - * ---------------------------------------------------------------------------- - */ - -/// @file - -#ifndef YAGE_CORE_LOGSINK_H -#define YAGE_CORE_LOGSINK_H - -/// @todo remove the include to make compilation faster -#include "logmessage.h" - -#include -#include - -namespace yage -{ - -class LogSink -{ -public: - template - LogSink(T impl); - - LogSink(const LogSink &sink); - LogSink(LogSink &&sink); - - LogSink &operator=(const LogSink &sink); - LogSink &operator=(LogSink &&sink); - bool operator==(const LogSink &sink); - - void write(const LogMessage::Meta &meta, const std::string &msg) const; - -private: - struct Concept { - virtual ~Concept() = default; - - virtual Concept *clone() const = 0; - virtual void write(const LogMessage::Meta &meta, - const std::string &msg) const = 0; - }; - - template - struct Model : Concept { - Model(T impl_i); - virtual Concept *clone() const override; - virtual void write(const LogMessage::Meta &meta, - const std::string &msg) const override; - - T impl; - }; - - std::unique_ptr wrapper_; -}; - -LogSink makeConsoleSink(); - -LogSink makeFileSink(const std::string &filename); -LogSink makeFileSink(std::string &&filename); - -/* ----------------------------------------------------------------------------- - * Template Implementation - * ----------------------------------------------------------------------------- - */ - -template -LogSink::LogSink(T impl) : wrapper_(new Model(std::move(impl))) -{ -} - -template -LogSink::Model::Model(T impl_i) : impl(impl_i) -{ -} - -template -LogSink::Concept *LogSink::Model::clone() const -{ - return new Model(impl); -} - -template -void LogSink::Model::write(const LogMessage::Meta &meta, - const std::string &msg) const -{ - impl(meta, msg); -} - -} // namespace yage - -#endif -- cgit