From 24a32a060335f3ecddeb92601266e01cd6bc4cd6 Mon Sep 17 00:00:00 2001 From: Benjamin Sergeant Date: Wed, 15 May 2019 16:50:00 -0700 Subject: [PATCH] enum class HttpErrorCode derives from int --- ixwebsocket/IXHttpClient.h | 2 +- ixwebsocket/IXWebSocket.cpp | 2 +- ixwebsocket/IXWebSocketTransport.cpp | 12 +- ixwebsocket/IXWebSocketTransport.h | 2 +- ixwebsocket/LUrlParser.cpp | 10 +- ixwebsocket/LUrlParser.h | 10 +- test/IXWebSocketCloseTest.cpp | 22 +- third_party/spdlog/README.md | 638 +++++++++--------- .../include/spdlog/fmt/bundled/printf.h | 4 +- .../include/spdlog/fmt/bundled/ranges.h | 8 +- third_party/spdlog/include/spdlog/tweakme.h | 2 +- third_party/spdlog/tests/main.cpp | 2 +- third_party/spdlog/tests/test_mpmc_q.cpp | 2 +- third_party/spdlog/tests/utils.h | 2 +- 14 files changed, 359 insertions(+), 359 deletions(-) diff --git a/ixwebsocket/IXHttpClient.h b/ixwebsocket/IXHttpClient.h index 66f621cb..fe34ac0e 100644 --- a/ixwebsocket/IXHttpClient.h +++ b/ixwebsocket/IXHttpClient.h @@ -19,7 +19,7 @@ namespace ix { - enum class HttpErrorCode + enum class HttpErrorCode : int { Ok = 0, CannotConnect = 1, diff --git a/ixwebsocket/IXWebSocket.cpp b/ixwebsocket/IXWebSocket.cpp index c4a537ca..7617100a 100644 --- a/ixwebsocket/IXWebSocket.cpp +++ b/ixwebsocket/IXWebSocket.cpp @@ -263,7 +263,7 @@ namespace ix connectErr.wait_time = duration.count(); connectErr.retries = retries; } - + connectErr.reason = status.errorStr; connectErr.http_status = status.http_status; diff --git a/ixwebsocket/IXWebSocketTransport.cpp b/ixwebsocket/IXWebSocketTransport.cpp index 94c02591..f9a61adc 100644 --- a/ixwebsocket/IXWebSocketTransport.cpp +++ b/ixwebsocket/IXWebSocketTransport.cpp @@ -244,7 +244,7 @@ namespace ix { std::lock_guard lock(_lastSendPingTimePointMutex); _lastSendPingTimePoint = std::chrono::steady_clock::now(); - } + } { std::lock_guard lock(_lastReceivePongTimePointMutex); _lastReceivePongTimePoint = std::chrono::steady_clock::now(); @@ -303,7 +303,7 @@ namespace ix sendPing(ss.str()); } } - + // No timeout if state is not OPEN, otherwise computed // pingIntervalOrTimeoutGCD (equals to -1 if no ping and no ping timeout are set) int lastingTimeoutDelayInMs = (_readyState != ReadyState::OPEN) ? 0 : _pingIntervalOrTimeoutGCDSecs; @@ -316,10 +316,10 @@ namespace ix if (now >= _nextGCDTimePoint) { _nextGCDTimePoint = now + std::chrono::seconds(_pingIntervalOrTimeoutGCDSecs); - + lastingTimeoutDelayInMs = _pingIntervalOrTimeoutGCDSecs * 1000; } - else + else { lastingTimeoutDelayInMs = (int)std::chrono::duration_cast(_nextGCDTimePoint - now).count(); } @@ -368,7 +368,7 @@ namespace ix { // if there are received data pending to be processed, then delay the abnormal closure // to after dispatch (other close code/reason could be read from the buffer) - + closeSocket(); return PollResult::AbnormalClose; @@ -681,7 +681,7 @@ namespace ix closeSocket(); setReadyState(ReadyState::CLOSED); } - // if we weren't closing, then close using abnormal close code and message + // if we weren't closing, then close using abnormal close code and message else if (_readyState != ReadyState::CLOSED) { closeSocketAndSwitchToClosedState(kAbnormalCloseCode, kAbnormalCloseMessage, 0, false); diff --git a/ixwebsocket/IXWebSocketTransport.h b/ixwebsocket/IXWebSocketTransport.h index bae374ee..433d9e4a 100644 --- a/ixwebsocket/IXWebSocketTransport.h +++ b/ixwebsocket/IXWebSocketTransport.h @@ -173,7 +173,7 @@ namespace ix // Used to cancel dns lookup + socket connect + http upgrade std::atomic _requestInitCancellation; - + mutable std::mutex _closingTimePointMutex; std::chrono::time_point_closingTimePoint; static const int kClosingMaximumWaitingDelayInMs; diff --git a/ixwebsocket/LUrlParser.cpp b/ixwebsocket/LUrlParser.cpp index 926bf452..f7b82209 100644 --- a/ixwebsocket/LUrlParser.cpp +++ b/ixwebsocket/LUrlParser.cpp @@ -1,21 +1,21 @@ /* * Lightweight URL & URI parser (RFC 1738, RFC 3986) * https://github.com/corporateshark/LUrlParser - * + * * The MIT License (MIT) - * + * * Copyright (C) 2015 Sergey Kosarevsky (sk@linderdaum.com) - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/ixwebsocket/LUrlParser.h b/ixwebsocket/LUrlParser.h index e347b369..06bd3d20 100644 --- a/ixwebsocket/LUrlParser.h +++ b/ixwebsocket/LUrlParser.h @@ -1,21 +1,21 @@ /* * Lightweight URL & URI parser (RFC 1738, RFC 3986) * https://github.com/corporateshark/LUrlParser - * + * * The MIT License (MIT) - * + * * Copyright (C) 2015 Sergey Kosarevsky (sk@linderdaum.com) - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/test/IXWebSocketCloseTest.cpp b/test/IXWebSocketCloseTest.cpp index 1764b78a..ac286cda 100644 --- a/test/IXWebSocketCloseTest.cpp +++ b/test/IXWebSocketCloseTest.cpp @@ -61,7 +61,7 @@ namespace uint16_t WebSocketClient::getCloseCode() { std::lock_guard lck(_mutexCloseData); - + return _closeCode; } @@ -75,7 +75,7 @@ namespace bool WebSocketClient::getCloseRemote() { std::lock_guard lck(_mutexCloseData); - + return _closeRemote; } @@ -126,11 +126,11 @@ namespace log("client disconnected"); std::lock_guard lck(_mutexCloseData); - + _closeCode = closeInfo.code; _closeReason = std::string(closeInfo.reason); _closeRemote = closeInfo.remote; - + _webSocket.disableAutomaticReconnection(); } else if (messageType == ix::WebSocketMessageType::Error) @@ -209,7 +209,7 @@ namespace //Logger() << closeInfo.remote; std::lock_guard lck(mutexWrite); - + receivedCloseCode = closeInfo.code; receivedCloseReason = std::string(closeInfo.reason); receivedCloseRemote = closeInfo.remote; @@ -239,7 +239,7 @@ TEST_CASE("Websocket_client_close_default", "[close]") int port = getFreePort(); ix::WebSocketServer server(port); - + uint16_t serverReceivedCloseCode(0); bool serverReceivedCloseRemote(false); std::string serverReceivedCloseReason(""); @@ -274,7 +274,7 @@ TEST_CASE("Websocket_client_close_default", "[close]") { std::lock_guard lck(mutexWrite); - + // Here we read the code/reason received by the server, and ensure that remote is true REQUIRE(serverReceivedCloseCode == 1000); REQUIRE(serverReceivedCloseReason == "Normal closure"); @@ -297,7 +297,7 @@ TEST_CASE("Websocket_client_close_params_given", "[close]") int port = getFreePort(); ix::WebSocketServer server(port); - + uint16_t serverReceivedCloseCode(0); bool serverReceivedCloseRemote(false); std::string serverReceivedCloseReason(""); @@ -332,7 +332,7 @@ TEST_CASE("Websocket_client_close_params_given", "[close]") { std::lock_guard lck(mutexWrite); - + // Here we read the code/reason received by the server, and ensure that remote is true REQUIRE(serverReceivedCloseCode == 4000); REQUIRE(serverReceivedCloseReason == "My reason"); @@ -355,7 +355,7 @@ TEST_CASE("Websocket_server_close", "[close]") int port = getFreePort(); ix::WebSocketServer server(port); - + uint16_t serverReceivedCloseCode(0); bool serverReceivedCloseRemote(false); std::string serverReceivedCloseReason(""); @@ -390,7 +390,7 @@ TEST_CASE("Websocket_server_close", "[close]") { std::lock_guard lck(mutexWrite); - + // Here we read the code/reason received by the server, and ensure that remote is true REQUIRE(serverReceivedCloseCode == 1000); REQUIRE(serverReceivedCloseReason == "Normal closure"); diff --git a/third_party/spdlog/README.md b/third_party/spdlog/README.md index 48264324..1a2486f1 100644 --- a/third_party/spdlog/README.md +++ b/third_party/spdlog/README.md @@ -1,319 +1,319 @@ -# spdlog - -Very fast, header only, C++ logging library. [![Build Status](https://travis-ci.org/gabime/spdlog.svg?branch=master)](https://travis-ci.org/gabime/spdlog)  [![Build status](https://ci.appveyor.com/api/projects/status/d2jnxclg20vd0o50?svg=true)](https://ci.appveyor.com/project/gabime/spdlog) - - - -## Install -#### Just copy the headers: - -* Copy the source [folder](https://github.com/gabime/spdlog/tree/v1.x/include/spdlog) to your build tree and use a C++11 compiler. - -#### Or use your favorite package manager: - -* Ubuntu: `apt-get install libspdlog-dev` -* Homebrew: `brew install spdlog` -* FreeBSD: `cd /usr/ports/devel/spdlog/ && make install clean` -* Fedora: `yum install spdlog` -* Gentoo: `emerge dev-libs/spdlog` -* Arch Linux: `yaourt -S spdlog-git` -* vcpkg: `vcpkg install spdlog` - - -## Platforms - * Linux, FreeBSD, OpenBSD, Solaris, AIX - * Windows (msvc 2013+, cygwin) - * macOS (clang 3.5+) - * Android - -## Features -* Very fast (see [benchmarks](#benchmarks) below). -* Headers only, just copy and use. -* Feature rich formatting, using the excellent [fmt](https://github.com/fmtlib/fmt) library. -* Fast asynchronous mode (optional) -* [Custom](https://github.com/gabime/spdlog/wiki/3.-Custom-formatting) formatting. -* Multi/Single threaded loggers. -* Various log targets: - * Rotating log files. - * Daily log files. - * Console logging (colors supported). - * syslog. - * Windows debugger (```OutputDebugString(..)```) - * Easily extendable with custom log targets (just implement a single function in the [sink](include/spdlog/sinks/sink.h) interface). -* Severity based filtering - threshold levels can be modified in runtime as well as in compile time. -* Binary data logging. - - -## Benchmarks - -Below are some [benchmarks](https://github.com/gabime/spdlog/blob/v1.x/bench/bench.cpp) done in Ubuntu 64 bit, Intel i7-4770 CPU @ 3.40GHz - -#### Synchronous mode -``` -******************************************************************************* -Single thread, 1,000,000 iterations -******************************************************************************* -basic_st... Elapsed: 0.181652 5,505,042/sec -rotating_st... Elapsed: 0.181781 5,501,117/sec -daily_st... Elapsed: 0.187595 5,330,630/sec -null_st... Elapsed: 0.0504704 19,813,602/sec -******************************************************************************* -10 threads sharing same logger, 1,000,000 iterations -******************************************************************************* -basic_mt... Elapsed: 0.616035 1,623,284/sec -rotating_mt... Elapsed: 0.620344 1,612,008/sec -daily_mt... Elapsed: 0.648353 1,542,369/sec -null_mt... Elapsed: 0.151972 6,580,166/sec -``` -#### Asynchronous mode -``` -******************************************************************************* -10 threads sharing same logger, 1,000,000 iterations -******************************************************************************* -async... Elapsed: 0.350066 2,856,606/sec -async... Elapsed: 0.314865 3,175,960/sec -async... Elapsed: 0.349851 2,858,358/sec -``` - -## Usage samples - -#### Basic usage -```c++ -#include "spdlog/spdlog.h" -int main() -{ - spdlog::info("Welcome to spdlog!"); - spdlog::error("Some error message with arg: {}", 1); - - spdlog::warn("Easy padding in numbers like {:08d}", 12); - spdlog::critical("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42); - spdlog::info("Support for floats {:03.2f}", 1.23456); - spdlog::info("Positional args are {1} {0}..", "too", "supported"); - spdlog::info("{:<30}", "left aligned"); - - spdlog::set_level(spdlog::level::debug); // Set global log level to debug - spdlog::debug("This message should be displayed.."); - - // change log pattern - spdlog::set_pattern("[%H:%M:%S %z] [%n] [%^---%L---%$] [thread %t] %v"); - - // Compile time log levels - // define SPDLOG_ACTIVE_LEVEL to desired level - SPDLOG_TRACE("Some trace message with param {}", {}); - SPDLOG_DEBUG("Some debug message"); - -} -``` -#### create stdout/stderr logger object -```c++ -#include "spdlog/spdlog.h" -#include "spdlog/sinks/stdout_color_sinks.h" -void stdout_example() -{ - // create color multi threaded logger - auto console = spdlog::stdout_color_mt("console"); - auto err_logger = spdlog::stderr_color_mt("stderr"); - spdlog::get("console")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name)"); -} -``` ---- -#### Basic file logger -```c++ -#include "spdlog/sinks/basic_file_sink.h" -void basic_logfile_example() -{ - try - { - auto my_logger = spdlog::basic_logger_mt("basic_logger", "logs/basic-log.txt"); - } - catch (const spdlog::spdlog_ex &ex) - { - std::cout << "Log init failed: " << ex.what() << std::endl; - } -} -``` ---- -#### Rotating files -```c++ -#include "spdlog/sinks/rotating_file_sink.h" -void rotating_example() -{ - // Create a file rotating logger with 5mb size max and 3 rotated files - auto rotating_logger = spdlog::rotating_logger_mt("some_logger_name", "logs/rotating.txt", 1048576 * 5, 3); -} -``` - ---- -#### Daily files -```c++ - -#include "spdlog/sinks/daily_file_sink.h" -void daily_example() -{ - // Create a daily logger - a new file is created every day on 2:30am - auto daily_logger = spdlog::daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30); -} - -``` - ---- -#### Cloning loggers -```c++ -// clone a logger and give it new name. -// Useful for creating subsystem loggers from some "root" logger -void clone_example() -{ - auto network_logger = spdlog::get("root")->clone("network"); - network_logger->info("Logging network stuff.."); -} -``` - ---- -#### Periodic flush -```c++ -// periodically flush all *registered* loggers every 3 seconds: -// warning: only use if all your loggers are thread safe! -spdlog::flush_every(std::chrono::seconds(3)); - -``` - ---- -#### Binary logging -```c++ -// log binary data as hex. -// many types of std::container types can be used. -// ranges are supported too. -// format flags: -// {:X} - print in uppercase. -// {:s} - don't separate each byte with space. -// {:p} - don't print the position on each line start. -// {:n} - don't split the output to lines. - -#include "spdlog/fmt/bin_to_hex.h" - -void binary_example() -{ - auto console = spdlog::get("console"); - std::array buf; - console->info("Binary example: {}", spdlog::to_hex(buf)); - console->info("Another binary example:{:n}", spdlog::to_hex(std::begin(buf), std::begin(buf) + 10)); - // more examples: - // logger->info("uppercase: {:X}", spdlog::to_hex(buf)); - // logger->info("uppercase, no delimiters: {:Xs}", spdlog::to_hex(buf)); - // logger->info("uppercase, no delimiters, no position info: {:Xsp}", spdlog::to_hex(buf)); -} - -``` - ---- -#### Logger with multi sinks - each with different format and log level -```c++ - -// create logger with 2 targets with different log levels and formats. -// the console will show only warnings or errors, while the file will log all. -void multi_sink_example() -{ - auto console_sink = std::make_shared(); - console_sink->set_level(spdlog::level::warn); - console_sink->set_pattern("[multi_sink_example] [%^%l%$] %v"); - - auto file_sink = std::make_shared("logs/multisink.txt", true); - file_sink->set_level(spdlog::level::trace); - - spdlog::logger logger("multi_sink", {console_sink, file_sink}); - logger.set_level(spdlog::level::debug); - logger.warn("this should appear in both console and file"); - logger.info("this message should not appear in the console, only in the file"); -} -``` - ---- -#### Asynchronous logging -```c++ -#include "spdlog/async.h" -#include "spdlog/sinks/basic_file_sink.h" -void async_example() -{ - // default thread pool settings can be modified *before* creating the async logger: - // spdlog::init_thread_pool(8192, 1); // queue with 8k items and 1 backing thread. - auto async_file = spdlog::basic_logger_mt("async_file_logger", "logs/async_log.txt"); - // alternatively: - // auto async_file = spdlog::create_async("async_file_logger", "logs/async_log.txt"); -} - -``` - ---- -#### Asynchronous logger with multi sinks -```c++ -#include "spdlog/sinks/stdout_color_sinks.h" -#include "spdlog/sinks/rotating_file_sink.h" - -void multi_sink_example2() -{ - spdlog::init_thread_pool(8192, 1); - auto stdout_sink = std::make_shared(); - auto rotating_sink = std::make_shared("mylog.txt", 1024*1024*10, 3); - std::vector sinks {stdout_sink, rotating_sink}; - auto logger = std::make_shared("loggername", sinks.begin(), sinks.end(), spdlog::thread_pool(), spdlog::async_overflow_policy::block); - spdlog::register_logger(logger); -} -``` - ---- -#### User defined types -```c++ -// user defined types logging by implementing operator<< -#include "spdlog/fmt/ostr.h" // must be included -struct my_type -{ - int i; - template - friend OStream &operator<<(OStream &os, const my_type &c) - { - return os << "[my_type i=" << c.i << "]"; - } -}; - -void user_defined_example() -{ - spdlog::get("console")->info("user defined type: {}", my_type{14}); -} - -``` ---- -#### Custom error handler -```c++ -void err_handler_example() -{ - // can be set globally or per logger(logger->set_error_handler(..)) - spdlog::set_error_handler([](const std::string &msg) { spdlog::get("console")->error("*** LOGGER ERROR ***: {}", msg); }); - spdlog::get("console")->info("some invalid message to trigger an error {}{}{}{}", 3); -} - -``` ---- -#### syslog -```c++ -#include "spdlog/sinks/syslog_sink.h" -void syslog_example() -{ - std::string ident = "spdlog-example"; - auto syslog_logger = spdlog::syslog_logger_mt("syslog", ident, LOG_PID); - syslog_logger->warn("This is warning that will end up in syslog."); -} -``` ---- -#### Android example -```c++ -#include "spdlog/sinks/android_sink.h" -void android_example() -{ - std::string tag = "spdlog-android"; - auto android_logger = spdlog::android_logger("android", tag); - android_logger->critical("Use \"adb shell logcat\" to view this message."); -} -``` - -## Documentation -Documentation can be found in the [wiki](https://github.com/gabime/spdlog/wiki/1.-QuickStart) pages. +# spdlog + +Very fast, header only, C++ logging library. [![Build Status](https://travis-ci.org/gabime/spdlog.svg?branch=master)](https://travis-ci.org/gabime/spdlog)  [![Build status](https://ci.appveyor.com/api/projects/status/d2jnxclg20vd0o50?svg=true)](https://ci.appveyor.com/project/gabime/spdlog) + + + +## Install +#### Just copy the headers: + +* Copy the source [folder](https://github.com/gabime/spdlog/tree/v1.x/include/spdlog) to your build tree and use a C++11 compiler. + +#### Or use your favorite package manager: + +* Ubuntu: `apt-get install libspdlog-dev` +* Homebrew: `brew install spdlog` +* FreeBSD: `cd /usr/ports/devel/spdlog/ && make install clean` +* Fedora: `yum install spdlog` +* Gentoo: `emerge dev-libs/spdlog` +* Arch Linux: `yaourt -S spdlog-git` +* vcpkg: `vcpkg install spdlog` + + +## Platforms + * Linux, FreeBSD, OpenBSD, Solaris, AIX + * Windows (msvc 2013+, cygwin) + * macOS (clang 3.5+) + * Android + +## Features +* Very fast (see [benchmarks](#benchmarks) below). +* Headers only, just copy and use. +* Feature rich formatting, using the excellent [fmt](https://github.com/fmtlib/fmt) library. +* Fast asynchronous mode (optional) +* [Custom](https://github.com/gabime/spdlog/wiki/3.-Custom-formatting) formatting. +* Multi/Single threaded loggers. +* Various log targets: + * Rotating log files. + * Daily log files. + * Console logging (colors supported). + * syslog. + * Windows debugger (```OutputDebugString(..)```) + * Easily extendable with custom log targets (just implement a single function in the [sink](include/spdlog/sinks/sink.h) interface). +* Severity based filtering - threshold levels can be modified in runtime as well as in compile time. +* Binary data logging. + + +## Benchmarks + +Below are some [benchmarks](https://github.com/gabime/spdlog/blob/v1.x/bench/bench.cpp) done in Ubuntu 64 bit, Intel i7-4770 CPU @ 3.40GHz + +#### Synchronous mode +``` +******************************************************************************* +Single thread, 1,000,000 iterations +******************************************************************************* +basic_st... Elapsed: 0.181652 5,505,042/sec +rotating_st... Elapsed: 0.181781 5,501,117/sec +daily_st... Elapsed: 0.187595 5,330,630/sec +null_st... Elapsed: 0.0504704 19,813,602/sec +******************************************************************************* +10 threads sharing same logger, 1,000,000 iterations +******************************************************************************* +basic_mt... Elapsed: 0.616035 1,623,284/sec +rotating_mt... Elapsed: 0.620344 1,612,008/sec +daily_mt... Elapsed: 0.648353 1,542,369/sec +null_mt... Elapsed: 0.151972 6,580,166/sec +``` +#### Asynchronous mode +``` +******************************************************************************* +10 threads sharing same logger, 1,000,000 iterations +******************************************************************************* +async... Elapsed: 0.350066 2,856,606/sec +async... Elapsed: 0.314865 3,175,960/sec +async... Elapsed: 0.349851 2,858,358/sec +``` + +## Usage samples + +#### Basic usage +```c++ +#include "spdlog/spdlog.h" +int main() +{ + spdlog::info("Welcome to spdlog!"); + spdlog::error("Some error message with arg: {}", 1); + + spdlog::warn("Easy padding in numbers like {:08d}", 12); + spdlog::critical("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42); + spdlog::info("Support for floats {:03.2f}", 1.23456); + spdlog::info("Positional args are {1} {0}..", "too", "supported"); + spdlog::info("{:<30}", "left aligned"); + + spdlog::set_level(spdlog::level::debug); // Set global log level to debug + spdlog::debug("This message should be displayed.."); + + // change log pattern + spdlog::set_pattern("[%H:%M:%S %z] [%n] [%^---%L---%$] [thread %t] %v"); + + // Compile time log levels + // define SPDLOG_ACTIVE_LEVEL to desired level + SPDLOG_TRACE("Some trace message with param {}", {}); + SPDLOG_DEBUG("Some debug message"); + +} +``` +#### create stdout/stderr logger object +```c++ +#include "spdlog/spdlog.h" +#include "spdlog/sinks/stdout_color_sinks.h" +void stdout_example() +{ + // create color multi threaded logger + auto console = spdlog::stdout_color_mt("console"); + auto err_logger = spdlog::stderr_color_mt("stderr"); + spdlog::get("console")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name)"); +} +``` +--- +#### Basic file logger +```c++ +#include "spdlog/sinks/basic_file_sink.h" +void basic_logfile_example() +{ + try + { + auto my_logger = spdlog::basic_logger_mt("basic_logger", "logs/basic-log.txt"); + } + catch (const spdlog::spdlog_ex &ex) + { + std::cout << "Log init failed: " << ex.what() << std::endl; + } +} +``` +--- +#### Rotating files +```c++ +#include "spdlog/sinks/rotating_file_sink.h" +void rotating_example() +{ + // Create a file rotating logger with 5mb size max and 3 rotated files + auto rotating_logger = spdlog::rotating_logger_mt("some_logger_name", "logs/rotating.txt", 1048576 * 5, 3); +} +``` + +--- +#### Daily files +```c++ + +#include "spdlog/sinks/daily_file_sink.h" +void daily_example() +{ + // Create a daily logger - a new file is created every day on 2:30am + auto daily_logger = spdlog::daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30); +} + +``` + +--- +#### Cloning loggers +```c++ +// clone a logger and give it new name. +// Useful for creating subsystem loggers from some "root" logger +void clone_example() +{ + auto network_logger = spdlog::get("root")->clone("network"); + network_logger->info("Logging network stuff.."); +} +``` + +--- +#### Periodic flush +```c++ +// periodically flush all *registered* loggers every 3 seconds: +// warning: only use if all your loggers are thread safe! +spdlog::flush_every(std::chrono::seconds(3)); + +``` + +--- +#### Binary logging +```c++ +// log binary data as hex. +// many types of std::container types can be used. +// ranges are supported too. +// format flags: +// {:X} - print in uppercase. +// {:s} - don't separate each byte with space. +// {:p} - don't print the position on each line start. +// {:n} - don't split the output to lines. + +#include "spdlog/fmt/bin_to_hex.h" + +void binary_example() +{ + auto console = spdlog::get("console"); + std::array buf; + console->info("Binary example: {}", spdlog::to_hex(buf)); + console->info("Another binary example:{:n}", spdlog::to_hex(std::begin(buf), std::begin(buf) + 10)); + // more examples: + // logger->info("uppercase: {:X}", spdlog::to_hex(buf)); + // logger->info("uppercase, no delimiters: {:Xs}", spdlog::to_hex(buf)); + // logger->info("uppercase, no delimiters, no position info: {:Xsp}", spdlog::to_hex(buf)); +} + +``` + +--- +#### Logger with multi sinks - each with different format and log level +```c++ + +// create logger with 2 targets with different log levels and formats. +// the console will show only warnings or errors, while the file will log all. +void multi_sink_example() +{ + auto console_sink = std::make_shared(); + console_sink->set_level(spdlog::level::warn); + console_sink->set_pattern("[multi_sink_example] [%^%l%$] %v"); + + auto file_sink = std::make_shared("logs/multisink.txt", true); + file_sink->set_level(spdlog::level::trace); + + spdlog::logger logger("multi_sink", {console_sink, file_sink}); + logger.set_level(spdlog::level::debug); + logger.warn("this should appear in both console and file"); + logger.info("this message should not appear in the console, only in the file"); +} +``` + +--- +#### Asynchronous logging +```c++ +#include "spdlog/async.h" +#include "spdlog/sinks/basic_file_sink.h" +void async_example() +{ + // default thread pool settings can be modified *before* creating the async logger: + // spdlog::init_thread_pool(8192, 1); // queue with 8k items and 1 backing thread. + auto async_file = spdlog::basic_logger_mt("async_file_logger", "logs/async_log.txt"); + // alternatively: + // auto async_file = spdlog::create_async("async_file_logger", "logs/async_log.txt"); +} + +``` + +--- +#### Asynchronous logger with multi sinks +```c++ +#include "spdlog/sinks/stdout_color_sinks.h" +#include "spdlog/sinks/rotating_file_sink.h" + +void multi_sink_example2() +{ + spdlog::init_thread_pool(8192, 1); + auto stdout_sink = std::make_shared(); + auto rotating_sink = std::make_shared("mylog.txt", 1024*1024*10, 3); + std::vector sinks {stdout_sink, rotating_sink}; + auto logger = std::make_shared("loggername", sinks.begin(), sinks.end(), spdlog::thread_pool(), spdlog::async_overflow_policy::block); + spdlog::register_logger(logger); +} +``` + +--- +#### User defined types +```c++ +// user defined types logging by implementing operator<< +#include "spdlog/fmt/ostr.h" // must be included +struct my_type +{ + int i; + template + friend OStream &operator<<(OStream &os, const my_type &c) + { + return os << "[my_type i=" << c.i << "]"; + } +}; + +void user_defined_example() +{ + spdlog::get("console")->info("user defined type: {}", my_type{14}); +} + +``` +--- +#### Custom error handler +```c++ +void err_handler_example() +{ + // can be set globally or per logger(logger->set_error_handler(..)) + spdlog::set_error_handler([](const std::string &msg) { spdlog::get("console")->error("*** LOGGER ERROR ***: {}", msg); }); + spdlog::get("console")->info("some invalid message to trigger an error {}{}{}{}", 3); +} + +``` +--- +#### syslog +```c++ +#include "spdlog/sinks/syslog_sink.h" +void syslog_example() +{ + std::string ident = "spdlog-example"; + auto syslog_logger = spdlog::syslog_logger_mt("syslog", ident, LOG_PID); + syslog_logger->warn("This is warning that will end up in syslog."); +} +``` +--- +#### Android example +```c++ +#include "spdlog/sinks/android_sink.h" +void android_example() +{ + std::string tag = "spdlog-android"; + auto android_logger = spdlog::android_logger("android", tag); + android_logger->critical("Use \"adb shell logcat\" to view this message."); +} +``` + +## Documentation +Documentation can be found in the [wiki](https://github.com/gabime/spdlog/wiki/1.-QuickStart) pages. diff --git a/third_party/spdlog/include/spdlog/fmt/bundled/printf.h b/third_party/spdlog/include/spdlog/fmt/bundled/printf.h index 6f2715d9..c6088458 100644 --- a/third_party/spdlog/include/spdlog/fmt/bundled/printf.h +++ b/third_party/spdlog/include/spdlog/fmt/bundled/printf.h @@ -713,7 +713,7 @@ typedef basic_format_args wprintf_args; /** \rst Constructs an `~fmt::format_arg_store` object that contains references to - arguments and can be implicitly converted to `~fmt::printf_args`. + arguments and can be implicitly converted to `~fmt::printf_args`. \endrst */ template @@ -723,7 +723,7 @@ inline format_arg_store /** \rst Constructs an `~fmt::format_arg_store` object that contains references to - arguments and can be implicitly converted to `~fmt::wprintf_args`. + arguments and can be implicitly converted to `~fmt::wprintf_args`. \endrst */ template diff --git a/third_party/spdlog/include/spdlog/fmt/bundled/ranges.h b/third_party/spdlog/include/spdlog/fmt/bundled/ranges.h index 3672d4ca..59094100 100644 --- a/third_party/spdlog/include/spdlog/fmt/bundled/ranges.h +++ b/third_party/spdlog/include/spdlog/fmt/bundled/ranges.h @@ -159,7 +159,7 @@ void for_each(index_sequence, Tuple &&tup, F &&f) FMT_NOEXCEPT { } template -FMT_CONSTEXPR make_index_sequence::value> +FMT_CONSTEXPR make_index_sequence::value> get_indexes(T const &) { return {}; } template @@ -169,14 +169,14 @@ void for_each(Tuple &&tup, F &&f) { } template -FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const Arg&, +FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const Arg&, typename std::enable_if< !is_like_std_string::type>::value>::type* = nullptr) { return add_space ? " {}" : "{}"; } template -FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const Arg&, +FMT_CONSTEXPR const char* format_str_quoted(bool add_space, const Arg&, typename std::enable_if< is_like_std_string::type>::value>::type* = nullptr) { return add_space ? " \"{}\"" : "\"{}\""; @@ -205,7 +205,7 @@ struct is_tuple_like { }; template -struct formatter::value>::type> { private: // C++11 generic lambda for format() diff --git a/third_party/spdlog/include/spdlog/tweakme.h b/third_party/spdlog/include/spdlog/tweakme.h index b3b71e4f..d7db40ff 100644 --- a/third_party/spdlog/include/spdlog/tweakme.h +++ b/third_party/spdlog/include/spdlog/tweakme.h @@ -142,4 +142,4 @@ // Defaults to __FUNCTION__ (should work on all compilers) if not defined. // // #define SPDLOG_FUNCTION __PRETTY_FUNCTION__ -/////////////////////////////////////////////////////////////////////////////// \ No newline at end of file +/////////////////////////////////////////////////////////////////////////////// diff --git a/third_party/spdlog/tests/main.cpp b/third_party/spdlog/tests/main.cpp index 063e8787..0c7c351f 100644 --- a/third_party/spdlog/tests/main.cpp +++ b/third_party/spdlog/tests/main.cpp @@ -1,2 +1,2 @@ #define CATCH_CONFIG_MAIN -#include "catch.hpp" \ No newline at end of file +#include "catch.hpp" diff --git a/third_party/spdlog/tests/test_mpmc_q.cpp b/third_party/spdlog/tests/test_mpmc_q.cpp index 19a188d8..7959b10c 100644 --- a/third_party/spdlog/tests/test_mpmc_q.cpp +++ b/third_party/spdlog/tests/test_mpmc_q.cpp @@ -104,4 +104,4 @@ TEST_CASE("full_queue", "[mpmc_blocking_q]") int item = -1; q.dequeue_for(item, milliseconds(0)); REQUIRE(item == 123456); -} \ No newline at end of file +} diff --git a/third_party/spdlog/tests/utils.h b/third_party/spdlog/tests/utils.h index e788b507..e7ffc921 100644 --- a/third_party/spdlog/tests/utils.h +++ b/third_party/spdlog/tests/utils.h @@ -13,4 +13,4 @@ std::size_t count_lines(const std::string &filename); std::size_t get_filesize(const std::string &filename); -bool ends_with(std::string const &value, std::string const &ending); \ No newline at end of file +bool ends_with(std::string const &value, std::string const &ending);