From 31971bf63b27eba2c2ae0ce7063ca73784ce67d2 Mon Sep 17 00:00:00 2001 From: gabi Date: Fri, 31 Oct 2014 03:17:40 +0200 Subject: [PATCH] updated example and added more creation functions --- c11logtest/c11logtest/ReadMe.txt | 14 +- c11logtest/c11logtest/c11logtest.vcxproj | 48 +++---- .../c11logtest/c11logtest.vcxproj.filters | 126 +++++++++--------- c11logtest/c11logtest/stdafx.cpp | 2 +- example/bench.cpp | 42 +++--- example/example.cpp | 52 +++++--- include/spdlog/common.h | 4 +- include/spdlog/details/file_helper.h | 4 +- include/spdlog/details/logger_impl.h | 10 +- include/spdlog/details/registry.h | 11 +- include/spdlog/details/spdlog_impl.h | 50 +++++++ include/spdlog/logger.h | 2 + include/spdlog/sinks/file_sinks.h | 6 +- include/spdlog/spdlog.h | 66 +++++---- 14 files changed, 272 insertions(+), 165 deletions(-) diff --git a/c11logtest/c11logtest/ReadMe.txt b/c11logtest/c11logtest/ReadMe.txt index 40735cf8..e6e0d568 100644 --- a/c11logtest/c11logtest/ReadMe.txt +++ b/c11logtest/c11logtest/ReadMe.txt @@ -1,27 +1,27 @@ ======================================================================== - CONSOLE APPLICATION : spitlogtest Project Overview + CONSOLE APPLICATION : spdlogtest Project Overview ======================================================================== -AppWizard has created this spitlogtest application for you. +AppWizard has created this spdlogtest application for you. This file contains a summary of what you will find in each of the files that -make up your spitlogtest application. +make up your spdlogtest application. -spitlogtest.vcxproj +spdlogtest.vcxproj This is the main project file for VC++ projects generated using an Application Wizard. It contains information about the version of Visual C++ that generated the file, and information about the platforms, configurations, and project features selected with the Application Wizard. -spitlogtest.vcxproj.filters +spdlogtest.vcxproj.filters This is the filters file for VC++ projects generated using an Application Wizard. It contains information about the association between the files in your project and the filters. This association is used in the IDE to show grouping of files with similar extensions under a specific node (for e.g. ".cpp" files are associated with the "Source Files" filter). -spitlogtest.cpp +spdlogtest.cpp This is the main application source file. ///////////////////////////////////////////////////////////////////////////// @@ -29,7 +29,7 @@ Other standard files: StdAfx.h, StdAfx.cpp These files are used to build a precompiled header (PCH) file - named spitlogtest.pch and a precompiled types file named StdAfx.obj. + named spdlogtest.pch and a precompiled types file named StdAfx.obj. ///////////////////////////////////////////////////////////////////////////// Other notes: diff --git a/c11logtest/c11logtest/c11logtest.vcxproj b/c11logtest/c11logtest/c11logtest.vcxproj index 440ac229..e3ab5c14 100644 --- a/c11logtest/c11logtest/c11logtest.vcxproj +++ b/c11logtest/c11logtest/c11logtest.vcxproj @@ -13,7 +13,7 @@ {DC7F2F3E-0D0E-4324-A278-410DBC4045AD} Win32Proj - spitlogtest + spdlogtest @@ -85,28 +85,30 @@ - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/c11logtest/c11logtest/c11logtest.vcxproj.filters b/c11logtest/c11logtest/c11logtest.vcxproj.filters index 6087b328..395bad14 100644 --- a/c11logtest/c11logtest/c11logtest.vcxproj.filters +++ b/c11logtest/c11logtest/c11logtest.vcxproj.filters @@ -13,13 +13,13 @@ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - + {bad4e9e3-82bd-4b02-9b4a-43198cc65844} - + {a4cc3c0e-8713-4146-98c7-1e7ab4ed95f8} - + {87170f3b-5292-49b8-8581-7db7cb9abd29} @@ -33,71 +33,77 @@ Header Files - + Header Files - + Header Files - + Header Files - + + Header Files\spdlog\sinks + + + Header Files\spdlog\sinks + + + Header Files\spdlog\sinks + + + Header Files\spdlog\sinks + + + Header Files\spdlog\sinks + + + Header Files\spdlog\sinks + + + Header Files\spdlog\details + + + Header Files\spdlog\details + + + Header Files\spdlog\details + + + Header Files\spdlog\details + + + Header Files\spdlog\sinks + + + Header Files\spdlog\details + + + Header Files\spdlog\details + + + Header Files\spdlog\details + + + Header Files\spdlog\details + + + Header Files\spdlog\details + + + Header Files\spdlog\details + + + Header Files\spdlog\details + + + Header Files\spdlog\details + + Header Files - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files + + Header Files\spdlog\details diff --git a/c11logtest/c11logtest/stdafx.cpp b/c11logtest/c11logtest/stdafx.cpp index 0661e975..b7d8a68c 100644 --- a/c11logtest/c11logtest/stdafx.cpp +++ b/c11logtest/c11logtest/stdafx.cpp @@ -1,5 +1,5 @@ // stdafx.cpp : source file that includes just the standard includes -// spitlogtest.pch will be the pre-compiled header +// spdlogtest.pch will be the pre-compiled header // stdafx.obj will contain the pre-compiled type information #include "stdafx.h" diff --git a/example/bench.cpp b/example/bench.cpp index 717313e1..c098ab7a 100644 --- a/example/bench.cpp +++ b/example/bench.cpp @@ -1,33 +1,39 @@ // example.cpp : Simple logger example // -#include "spitlog/logger.h" -#include "spitlog/sinks/async_sink.h" -#include "spitlog/sinks/file_sinks.h" -#include "spitlog/sinks/stdout_sinks.h" -#include "spitlog/sinks/null_sink.h" +#include "spdlog/spdlog.h" +#include "spdlog/sinks/file_sinks.h" +#include "spdlog/sinks/stdout_sinks.h" +#include "spdlog/sinks/null_sink.h" #include "utils.h" -#include "spitlog/details/registry.h" + +using namespace std; using namespace std::chrono; -using namespace spitlog; +using namespace spdlog; using namespace utils; -int main(int argc, char* argv[]) +int main_(int argc, char* argv[]) { try { + + using namespace spdlog::sinks; + spdlog::create("mylog", "dailylog", "txt"); const unsigned int howmany = argc <= 1 ? 1500000 : atoi(argv[1]); - //spitlog::set_format("%t"); - auto console = spitlog::create("reporter"); - //console->set_format("[%n %l] %t"); - console->set_level(spitlog::level::INFO); + spdlog::set_pattern("%Y-%m-%d %H:%M:%S.%e %l : %t"); + + + auto console = spdlog::create("reporter"); console->info("Starting bench with", howmany, "iterations.."); + console->log() << "Streams are also supprted: " << std::hex << 255; + spdlog::stop(); - auto bench = spitlog::create("bench", "myrotating", "txt", 1024 * 1024 * 1, 10, 0); + //return 0; + auto bench = spdlog::create("bench", "myrotating", "txt", 1024 * 1024 * 1, 10, 0); - //auto bench = spitlog::create("bench", "simplelog.txt", 1); - //auto bench = spitlog::create("bench"); + //auto bench = spdlog::create("bench", "simplelog.txt", 1); + //auto bench = spdlog::create("bench"); auto start = system_clock::now(); for (unsigned int i = 0; i < howmany; ++i) { @@ -37,9 +43,9 @@ int main(int argc, char* argv[]) auto delta = system_clock::now() - start; auto delta_d = duration_cast> (delta).count(); - console->info("Total:") << format(howmany); - console->info("Delta:") << format(delta_d); - console->info("Rate:") << format(howmany / delta_d) << "/sec"; + cout << "Total:" << format(howmany) << endl; + cout << "Delta:" << format(delta_d) << endl; + cout << "Rate:" << format(howmany / delta_d) << "/sec\n"; } catch (std::exception &ex) diff --git a/example/example.cpp b/example/example.cpp index e216552e..20e0b8bc 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -1,27 +1,45 @@ -// example.cpp : Simple logger example // -#define FFLOG_ENABLE_TRACE +// example.cpp : spdlog usage example +// #include -#include "spitlog/logger.h" -#include "spitlog/sinks/stdout_sinks.h" -#include "spitlog/sinks/file_sinks.h" -using namespace std; -using namespace spitlog; +#include "spdlog/spdlog.h" -details::fast_oss f(const std::string& what) -{ - details::fast_oss oss; - oss << what; - return oss; -} -int main_(int, char* []) +int main(int, char* []) { - auto foss = f("test2"); - foss.str(); + namespace spd = spdlog; + try + { + std::string filename = "spdlog_example"; + auto console = spd::stderr_logger_mt("console"); + console->info("Welcome to spdlog!"); + console->info() << "Creating file " << filename << ".."; + + auto file_logger = spd::rotating_logger_mt("file_logger", filename, 1024 * 1024 * 5, 3); + file_logger->info("Log file message number", 1); + + for (int i = 0; i < 100; ++i) + { + auto square = i*i; + file_logger->info() << i << '*' << i << '=' << square << " (" << "0x" << std::hex << square << ")"; + } + + + // Change log level to all loggers to warning and above + spd::set_level(spd::level::WARN); + console->info("This should not be displayed"); + console->warn("This should!"); + + // Change format pattern to all loggers + spd::set_pattern(" **** %Y-%m-%d %H:%M:%S.%e %l **** %t"); + spd::get("console")->warn("This is another message with different format"); + } + catch (const spd::spdlog_ex& ex) + { + std::cout << "Log failed: " << ex.what() << std::endl; + } - return 0; } diff --git a/include/spdlog/common.h b/include/spdlog/common.h index dd0dbe64..96118743 100644 --- a/include/spdlog/common.h +++ b/include/spdlog/common.h @@ -41,10 +41,10 @@ inline const char* to_str(spdlog::level::level_enum l) // // Log exception // -class fflog_exception : public std::exception +class spdlog_ex : public std::exception { public: - fflog_exception(const std::string& msg) :_msg(msg) {}; + spdlog_ex(const std::string& msg) :_msg(msg) {}; const char* what() const throw() override { return _msg.c_str(); } diff --git a/include/spdlog/details/file_helper.h b/include/spdlog/details/file_helper.h index fd5ee4a0..eae6c60e 100644 --- a/include/spdlog/details/file_helper.h +++ b/include/spdlog/details/file_helper.h @@ -54,7 +54,7 @@ public: std::this_thread::sleep_for(std::chrono::milliseconds(sleep_ms_bewteen_tries)); } - throw fflog_exception("Failed opening file " + filename + " for writing"); + throw spdlog_ex("Failed opening file " + filename + " for writing"); } void close() @@ -71,7 +71,7 @@ public: auto& buf = msg.formatted.buf(); size_t size = buf.size(); if(std::fwrite(buf.data(), sizeof(char), size, _fd) != size) - throw fflog_exception("Failed writing to file " + _filename); + throw spdlog_ex("Failed writing to file " + _filename); if(--_flush_countdown == 0) { diff --git a/include/spdlog/details/logger_impl.h b/include/spdlog/details/logger_impl.h index 32900093..53e7d59f 100644 --- a/include/spdlog/details/logger_impl.h +++ b/include/spdlog/details/logger_impl.h @@ -116,8 +116,16 @@ inline void spdlog::logger::stop_logging() inline void spdlog::logger::_variadic_log(spdlog::details::line_logger&) {} +template +inline void spdlog::logger::_variadic_log(spdlog::details::line_logger& l, const Last& last) +{ + l.write(last); +} + + + template -void spdlog::logger::_variadic_log(spdlog::details::line_logger& l, const First& first, const Rest&... rest) +inline void spdlog::logger::_variadic_log(spdlog::details::line_logger& l, const First& first, const Rest&... rest) { l.write(first); l.write(' '); diff --git a/include/spdlog/details/registry.h b/include/spdlog/details/registry.h index e75a17ec..ffdffff9 100644 --- a/include/spdlog/details/registry.h +++ b/include/spdlog/details/registry.h @@ -1,6 +1,6 @@ #pragma once // Loggers registy of unique name->logger pointer -// If 2 loggers with same name are added, the second will be overrun the first +// An attempt to create a logger with an alreasy existing name will be ignored // If user requests a non existing logger, nullptr will be returned // This class is thread safe @@ -16,10 +16,10 @@ namespace details { class registry { public: - std::shared_ptr get(const std::string& name) + std::shared_ptr get(const std::string& logger_name) { std::lock_guard lock(_mutex); - auto found = _loggers.find(name); + auto found = _loggers.find(logger_name); return found == _loggers.end() ? nullptr : found->second; } @@ -27,6 +27,11 @@ public: std::shared_ptr create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end) { std::lock_guard lock(_mutex); + //If already exists, just return it + auto found = _loggers.find(logger_name); + if (found != _loggers.end()) + return found->second; + auto new_logger = std::make_shared(logger_name, sinks_begin, sinks_end); new_logger->set_formatter(_formatter); new_logger->set_level(_level); diff --git a/include/spdlog/details/spdlog_impl.h b/include/spdlog/details/spdlog_impl.h index 05c1149a..3a088ba4 100644 --- a/include/spdlog/details/spdlog_impl.h +++ b/include/spdlog/details/spdlog_impl.h @@ -4,12 +4,62 @@ // Global registry functions // #include "registry.h" +#include "../sinks/file_sinks.h" +#include "../sinks/stdout_sinks.h" inline std::shared_ptr spdlog::get(const std::string& name) { return details::registry::instance().get(name); } + +// Create multi/single threaded rotating file logger +inline std::shared_ptr spdlog::rotating_logger_mt(const std::string& logger_name, const std::string& filename, size_t max_file_size, size_t max_files, size_t flush_inverval) +{ + return create(logger_name, filename, "txt", max_file_size, max_files, flush_inverval); +} + +inline std::shared_ptr spdlog::rotating_logger_st(const std::string& logger_name, const std::string& filename, size_t max_file_size, size_t max_files, size_t flush_inverval) +{ + return create(logger_name, filename, "txt", max_file_size, max_files, flush_inverval); +} + +// Create file logger which creates new file at midnight): +inline std::shared_ptr spdlog::daily_logger_mt(const std::string& logger_name, const std::string& filename, size_t flush_inverval) +{ + return create(logger_name, filename, "txt", flush_inverval); +} +inline std::shared_ptr spdlog::daily_logger_st(const std::string& logger_name, const std::string& filename, size_t flush_inverval) +{ + return create(logger_name, filename, "txt", flush_inverval); +} + + +// Create stdout/stderr loggers +inline std::shared_ptr spdlog::stdout_logger_mt(const std::string& logger_name) +{ + return create(logger_name); +} + +inline std::shared_ptr spdlog::stdout_logger_st(const std::string& logger_name) +{ + return create(logger_name); +} + +inline std::shared_ptr spdlog::stderr_logger_mt(const std::string& logger_name) +{ + return create(logger_name); +} + +inline std::shared_ptr spdlog::stderr_logger_st(const std::string& logger_name) +{ + return create(logger_name); +} + + + + + inline std::shared_ptr spdlog::create(const std::string& logger_name, spdlog::sinks_init_list sinks) { return details::registry::instance().create(logger_name, sinks); diff --git a/include/spdlog/logger.h b/include/spdlog/logger.h index a4008dc1..0789318b 100644 --- a/include/spdlog/logger.h +++ b/include/spdlog/logger.h @@ -64,6 +64,8 @@ private: std::vector _sinks; std::atomic_int _level; void _variadic_log(details::line_logger& l); + template + inline void _variadic_log(spdlog::details::line_logger& l, const Last& last); template void _variadic_log(details::line_logger&l, const First& first, const Rest&... rest); void _log_msg(details::log_msg& msg); diff --git a/include/spdlog/sinks/file_sinks.h b/include/spdlog/sinks/file_sinks.h index ae35d834..49b0ea44 100644 --- a/include/spdlog/sinks/file_sinks.h +++ b/include/spdlog/sinks/file_sinks.h @@ -48,8 +48,8 @@ class rotating_file_sink : public base_sink { public: rotating_file_sink(const std::string &base_filename, const std::string &extension, - const std::size_t max_size, const std::size_t max_files, - const std::size_t flush_inverval=0): + std::size_t max_size, std::size_t max_files, + std::size_t flush_inverval=0): _base_filename(base_filename), _extension(extension), _max_size(max_size), @@ -104,7 +104,7 @@ private: std::remove(target.c_str()); if (details::file_helper::file_exists(src) && std::rename(src.c_str(), target.c_str())) { - throw fflog_exception("rotating_file_sink: failed renaming " + src + " to " + target); + throw spdlog_ex("rotating_file_sink: failed renaming " + src + " to " + target); } } auto cur_name = _file_helper.filename(); diff --git a/include/spdlog/spdlog.h b/include/spdlog/spdlog.h index 44d13485..401a6e04 100644 --- a/include/spdlog/spdlog.h +++ b/include/spdlog/spdlog.h @@ -29,47 +29,57 @@ namespace spdlog std::shared_ptr get(const std::string& name); -// Example: -// auto logger = spdlog::create("mylog", {sink1, sink2}); -std::shared_ptr create(const std::string& logger_name, sinks_init_list sinks); - - -// Example (create a logger with daily rotating file): -// using namespace spdlog::sinks; -// spdlog::create("mylog", "dailylog_filename", "txt"); -template -std::shared_ptr create(const std::string& logger_name, const Args&... args); - -// Example: -// using namespace spdlog::sinks; -// std::vector mySinks; -// mySinks.push_back(std::make_shared("filename", "txt", 1024 * 1024 * 5, 10)); -// mySinks.push_back(std::make_shared()); -// spdlog::create("mylog", mySinks.begin(), mySinks.end()); -template -std::shared_ptr create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end); - - // Set global formatting -// Example: // spdlog::set_pattern("%Y-%m-%d %H:%M:%S.%e %l : %t"); void set_pattern(const std::string& format_string); -// Set global formatter object -void set_formatter(formatter_ptr f); - - -//Set global active logging level +//Set global logging level void set_level(level::level_enum log_level); +// Create multi/single threaded rotating file logger +std::shared_ptr rotating_logger_mt(const std::string& logger_name, const std::string& filename, size_t max_file_size, size_t max_files, size_t flush_inverval = 0); +std::shared_ptr rotating_logger_st(const std::string& logger_name, const std::string& filename, size_t max_file_size, size_t max_files, size_t flush_inverval = 0); + +// Create file logger which creates new file at midnight): +std::shared_ptr daily_logger_mt(const std::string& logger_name, const std::string& filename, size_t flush_inverval = 0); +std::shared_ptr daily_logger_st(const std::string& logger_name, const std::string& filename, size_t flush_inverval = 0); + + +// Create stdout/stderr loggers +std::shared_ptr stdout_logger_mt(const std::string& logger_name); +std::shared_ptr stdout_logger_st(const std::string& logger_name); +std::shared_ptr stderr_logger_mt(const std::string& logger_name); +std::shared_ptr stderr_logger_st(const std::string& logger_name); + + + +// +// Create a logger with multiple sinks +// +std::shared_ptr create(const std::string& logger_name, sinks_init_list sinks); + +template +std::shared_ptr create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end); + + +// Create a logger with templated sink type +// Example: spdlog::create("mylog", "dailylog_filename", "txt"); +template +std::shared_ptr create(const std::string& logger_name, const Args&... args); + + + +// Set global formatter object +void set_formatter(formatter_ptr f); + //Stop all loggers void stop(); // -// Trace macro to turn on/off at compile time +// Trace macro enabled only at debug compile // Example: SPDLOG_TRACE(my_logger, "Some trace message"); // #ifdef _DEBUG