(third_party deps) fix #177, update bundled spdlog to 1.6.0
This commit is contained in:
parent
2eb5c9480e
commit
f1c106728b
@ -5,7 +5,7 @@ include(FindPackageHandleStandardArgs)
|
|||||||
find_path(JSONCPP_INCLUDE_DIRS json/json.h)
|
find_path(JSONCPP_INCLUDE_DIRS json/json.h)
|
||||||
find_library(JSONCPP_LIBRARY jsoncpp)
|
find_library(JSONCPP_LIBRARY jsoncpp)
|
||||||
|
|
||||||
find_package_handle_standard_args(JSONCPP
|
find_package_handle_standard_args(JsonCpp
|
||||||
FOUND_VAR
|
FOUND_VAR
|
||||||
JSONCPP_FOUND
|
JSONCPP_FOUND
|
||||||
REQUIRED_VARS
|
REQUIRED_VARS
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
All changes to this project will be documented in this file.
|
All changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [9.2.2] - 2020-04-04
|
||||||
|
|
||||||
|
(third_party deps) fix #177, update bundled spdlog to 1.6.0
|
||||||
|
|
||||||
## [9.2.1] - 2020-04-04
|
## [9.2.1] - 2020-04-04
|
||||||
|
|
||||||
(windows) when using OpenSSL, the system store is used to populate the cacert. No need to ship a cacert.pem file with your app.
|
(windows) when using OpenSSL, the system store is used to populate the cacert. No need to ship a cacert.pem file with your app.
|
||||||
|
@ -6,4 +6,4 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define IX_WEBSOCKET_VERSION "9.2.1"
|
#define IX_WEBSOCKET_VERSION "9.2.2"
|
||||||
|
@ -1,19 +1,32 @@
|
|||||||
Checks: '\
|
Checks: 'cppcoreguidelines-*,
|
||||||
cppcoreguidelines-*,\
|
performance-*,
|
||||||
performance-*,\
|
modernize-*,
|
||||||
-performance-unnecessary-value-param,\
|
google-*,
|
||||||
modernize-*,\
|
misc-*,
|
||||||
-modernize-use-trailing-return-type,\
|
cert-*,
|
||||||
google-*,\
|
readability-*,
|
||||||
-google-runtime-references,\
|
clang-analyzer-*,
|
||||||
misc-*,\
|
-performance-unnecessary-value-param,
|
||||||
-misc-non-private-member-variables-in-classes,\
|
-modernize-use-trailing-return-type,
|
||||||
cert-*,\
|
-google-runtime-references,
|
||||||
readability-*,\
|
-misc-non-private-member-variables-in-classes,
|
||||||
clang-analyzer-*'
|
-readability-braces-around-statements,
|
||||||
|
-google-readability-braces-around-statements,
|
||||||
|
-cppcoreguidelines-avoid-magic-numbers,
|
||||||
|
-readability-magic-numbers,
|
||||||
|
-readability-magic-numbers,
|
||||||
|
-cppcoreguidelines-pro-type-vararg,
|
||||||
|
-cppcoreguidelines-pro-bounds-pointer-arithmetic,
|
||||||
|
-cppcoreguidelines-avoid-c-arrays,
|
||||||
|
-modernize-avoid-c-arrays,
|
||||||
|
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
|
||||||
|
-readability-named-parameter,
|
||||||
|
-cert-env33-c
|
||||||
|
'
|
||||||
|
|
||||||
|
|
||||||
WarningsAsErrors: ''
|
WarningsAsErrors: ''
|
||||||
HeaderFilterRegex: 'async.h|async_logger.h|common.h|details|formatter.h|logger.h|sinks|spdlog.h|tweakme.h|version.h'
|
HeaderFilterRegex: '*spdlog/[^f].*'
|
||||||
AnalyzeTemporaryDtors: false
|
AnalyzeTemporaryDtors: false
|
||||||
FormatStyle: none
|
FormatStyle: none
|
||||||
|
|
1
third_party/spdlog/.travis.yml
vendored
1
third_party/spdlog/.travis.yml
vendored
@ -97,6 +97,7 @@ script:
|
|||||||
-DCMAKE_CXX_STANDARD=$CPP \
|
-DCMAKE_CXX_STANDARD=$CPP \
|
||||||
-DSPDLOG_BUILD_EXAMPLE=ON \
|
-DSPDLOG_BUILD_EXAMPLE=ON \
|
||||||
-DSPDLOG_BUILD_EXAMPLE_HO=ON \
|
-DSPDLOG_BUILD_EXAMPLE_HO=ON \
|
||||||
|
-DSPDLOG_ENABLE_WARNINGS=ON \
|
||||||
-DSPDLOG_BUILD_BENCH=OFF \
|
-DSPDLOG_BUILD_BENCH=OFF \
|
||||||
-DSPDLOG_BUILD_TESTS=ON \
|
-DSPDLOG_BUILD_TESTS=ON \
|
||||||
-DSPDLOG_BUILD_TESTS_HO=OFf \
|
-DSPDLOG_BUILD_TESTS_HO=OFf \
|
||||||
|
81
third_party/spdlog/CMakeLists.txt
vendored
81
third_party/spdlog/CMakeLists.txt
vendored
@ -3,15 +3,27 @@
|
|||||||
|
|
||||||
cmake_minimum_required(VERSION 3.2)
|
cmake_minimum_required(VERSION 3.2)
|
||||||
|
|
||||||
|
if(${CMAKE_VERSION} VERSION_LESS 3.11)
|
||||||
|
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
|
||||||
|
else()
|
||||||
|
cmake_policy(VERSION 3.11)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
ENABLE_LANGUAGE(C)
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------------
|
||||||
# Start spdlog project
|
# Start spdlog project
|
||||||
#---------------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------------
|
||||||
include(GNUInstallDirs)
|
|
||||||
include(cmake/utils.cmake)
|
include(cmake/utils.cmake)
|
||||||
include(cmake/ide.cmake)
|
include(cmake/ide.cmake)
|
||||||
|
|
||||||
spdlog_extract_version()
|
spdlog_extract_version()
|
||||||
|
|
||||||
|
project(spdlog VERSION ${SPDLOG_VERSION} LANGUAGES CXX)
|
||||||
|
message(STATUS "Build spdlog: ${SPDLOG_VERSION}")
|
||||||
|
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------------
|
||||||
# Set default build to release
|
# Set default build to release
|
||||||
#---------------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------------
|
||||||
@ -19,16 +31,22 @@ if(NOT CMAKE_BUILD_TYPE)
|
|||||||
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose Release or Debug" FORCE)
|
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose Release or Debug" FORCE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
project(spdlog VERSION ${SPDLOG_VERSION} LANGUAGES CXX)
|
|
||||||
message(STATUS "Build spdlog: ${SPDLOG_VERSION}")
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------------
|
||||||
# Compiler config
|
# Compiler config
|
||||||
#---------------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------------
|
||||||
|
if (NOT CMAKE_CXX_STANDARD)
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
|
||||||
|
if(CMAKE_SYSTEM_NAME MATCHES "CYGWIN")
|
||||||
|
set(CMAKE_CXX_EXTENSIONS ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------------
|
||||||
# Set SPDLOG_MASTER_PROJECT to ON if we are building spdlog
|
# Set SPDLOG_MASTER_PROJECT to ON if we are building spdlog
|
||||||
#---------------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------------
|
||||||
@ -42,16 +60,17 @@ if (NOT DEFINED SPDLOG_MASTER_PROJECT)
|
|||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
# build shared option
|
# build shared option
|
||||||
if(NOT WIN32)
|
|
||||||
option(SPDLOG_BUILD_SHARED "Build shared library" OFF)
|
option(SPDLOG_BUILD_SHARED "Build shared library" OFF)
|
||||||
endif()
|
|
||||||
|
# precompiled headers option
|
||||||
|
option(SPDLOG_ENABLE_PCH "Build static or shared library using precompiled header to speed up compilation time" OFF)
|
||||||
|
|
||||||
# example options
|
# example options
|
||||||
option(SPDLOG_BUILD_EXAMPLE "Build example" ${SPDLOG_MASTER_PROJECT})
|
option(SPDLOG_BUILD_EXAMPLE "Build example" ${SPDLOG_MASTER_PROJECT})
|
||||||
option(SPDLOG_BUILD_EXAMPLE_HO "Build header only example" OFF)
|
option(SPDLOG_BUILD_EXAMPLE_HO "Build header only example" OFF)
|
||||||
|
|
||||||
# testing options
|
# testing options
|
||||||
option(SPDLOG_BUILD_TESTS "Build tests" ${SPDLOG_MASTER_PROJECT})
|
option(SPDLOG_BUILD_TESTS "Build tests" OFF)
|
||||||
option(SPDLOG_BUILD_TESTS_HO "Build tests using the header only version" OFF)
|
option(SPDLOG_BUILD_TESTS_HO "Build tests using the header only version" OFF)
|
||||||
|
|
||||||
# bench options
|
# bench options
|
||||||
@ -60,6 +79,9 @@ option(SPDLOG_BUILD_BENCH "Build benchmarks (Requires https://github.com/google/
|
|||||||
# sanitizer options
|
# sanitizer options
|
||||||
option(SPDLOG_SANITIZE_ADDRESS "Enable address sanitizer in tests" OFF)
|
option(SPDLOG_SANITIZE_ADDRESS "Enable address sanitizer in tests" OFF)
|
||||||
|
|
||||||
|
# warning options
|
||||||
|
option(SPDLOG_BUILD_WARNINGS "Enable compiler warnings" OFF)
|
||||||
|
|
||||||
# install options
|
# install options
|
||||||
option(SPDLOG_INSTALL "Generate the install target" ${SPDLOG_MASTER_PROJECT})
|
option(SPDLOG_INSTALL "Generate the install target" ${SPDLOG_MASTER_PROJECT})
|
||||||
option(SPDLOG_FMT_EXTERNAL "Use external fmt library instead of bundled" OFF)
|
option(SPDLOG_FMT_EXTERNAL "Use external fmt library instead of bundled" OFF)
|
||||||
@ -84,6 +106,17 @@ option(SPDLOG_NO_THREAD_ID "prevent spdlog from querying the thread id on each l
|
|||||||
option(SPDLOG_NO_TLS "prevent spdlog from using thread local storage" OFF)
|
option(SPDLOG_NO_TLS "prevent spdlog from using thread local storage" OFF)
|
||||||
option(SPDLOG_NO_ATOMIC_LEVELS "prevent spdlog from using of std::atomic log levels (use only if your code never modifies log levels concurrently" OFF)
|
option(SPDLOG_NO_ATOMIC_LEVELS "prevent spdlog from using of std::atomic log levels (use only if your code never modifies log levels concurrently" OFF)
|
||||||
|
|
||||||
|
# clang-tidy
|
||||||
|
if(${CMAKE_VERSION} VERSION_GREATER "3.5")
|
||||||
|
option(SPDLOG_TIDY "run clang-tidy" OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(SPDLOG_TIDY)
|
||||||
|
set(CMAKE_CXX_CLANG_TIDY "clang-tidy")
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
message(STATUS "Enabled clang-tidy")
|
||||||
|
endif()
|
||||||
|
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
message(STATUS "Build type: " ${CMAKE_BUILD_TYPE})
|
message(STATUS "Build type: " ${CMAKE_BUILD_TYPE})
|
||||||
#---------------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------------
|
||||||
@ -94,18 +127,27 @@ set(SPDLOG_SRCS
|
|||||||
src/stdout_sinks.cpp
|
src/stdout_sinks.cpp
|
||||||
src/color_sinks.cpp
|
src/color_sinks.cpp
|
||||||
src/file_sinks.cpp
|
src/file_sinks.cpp
|
||||||
src/async.cpp)
|
src/async.cpp
|
||||||
|
src/cfg.cpp)
|
||||||
|
|
||||||
if(NOT SPDLOG_FMT_EXTERNAL AND NOT SPDLOG_FMT_EXTERNAL_HO)
|
if(NOT SPDLOG_FMT_EXTERNAL AND NOT SPDLOG_FMT_EXTERNAL_HO)
|
||||||
list(APPEND SPDLOG_SRCS src/fmt.cpp)
|
list(APPEND SPDLOG_SRCS src/fmt.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (SPDLOG_BUILD_SHARED)
|
if(WIN32 AND SPDLOG_BUILD_SHARED)
|
||||||
if(WIN32)
|
list(APPEND SPDLOG_SRCS ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
|
||||||
message(FATAL_ERROR "spdlog shared lib is not yet supported under windows")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (SPDLOG_BUILD_SHARED)
|
||||||
add_library(spdlog SHARED ${SPDLOG_SRCS} ${SPDLOG_ALL_HEADERS})
|
add_library(spdlog SHARED ${SPDLOG_SRCS} ${SPDLOG_ALL_HEADERS})
|
||||||
|
target_compile_definitions(spdlog PUBLIC SPDLOG_SHARED_LIB)
|
||||||
|
if(WIN32)
|
||||||
|
target_compile_options(spdlog PUBLIC /wd4251 /wd4275)
|
||||||
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/version.rc.in ${CMAKE_CURRENT_BINARY_DIR}/version.rc @ONLY)
|
||||||
|
endif()
|
||||||
|
if(NOT SPDLOG_FMT_EXTERNAL AND NOT SPDLOG_FMT_EXTERNAL_HO)
|
||||||
|
target_compile_definitions(spdlog PRIVATE FMT_EXPORT PUBLIC FMT_SHARED)
|
||||||
|
endif()
|
||||||
else()
|
else()
|
||||||
add_library(spdlog STATIC ${SPDLOG_SRCS} ${SPDLOG_ALL_HEADERS})
|
add_library(spdlog STATIC ${SPDLOG_SRCS} ${SPDLOG_ALL_HEADERS})
|
||||||
endif()
|
endif()
|
||||||
@ -122,6 +164,11 @@ spdlog_enable_warnings(spdlog)
|
|||||||
set_target_properties(spdlog PROPERTIES VERSION ${SPDLOG_VERSION} SOVERSION ${SPDLOG_VERSION_MAJOR})
|
set_target_properties(spdlog PROPERTIES VERSION ${SPDLOG_VERSION} SOVERSION ${SPDLOG_VERSION_MAJOR})
|
||||||
set_target_properties(spdlog PROPERTIES DEBUG_POSTFIX d)
|
set_target_properties(spdlog PROPERTIES DEBUG_POSTFIX d)
|
||||||
|
|
||||||
|
if(COMMAND target_precompile_headers AND SPDLOG_ENABLE_PCH)
|
||||||
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/pch.h.in ${PROJECT_BINARY_DIR}/spdlog_pch.h @ONLY)
|
||||||
|
target_precompile_headers(spdlog PRIVATE ${PROJECT_BINARY_DIR}/spdlog_pch.h)
|
||||||
|
endif()
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------------
|
||||||
# Header only version
|
# Header only version
|
||||||
#---------------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------------
|
||||||
@ -209,8 +256,12 @@ endif()
|
|||||||
# Build binaries
|
# Build binaries
|
||||||
#---------------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------------
|
||||||
if(SPDLOG_BUILD_EXAMPLE OR SPDLOG_BUILD_EXAMPLE_HO)
|
if(SPDLOG_BUILD_EXAMPLE OR SPDLOG_BUILD_EXAMPLE_HO)
|
||||||
message(STATUS "Generating examples")
|
message(STATUS "Generating example(s)")
|
||||||
add_subdirectory(example)
|
add_subdirectory(example)
|
||||||
|
spdlog_enable_warnings(example)
|
||||||
|
if(SPDLOG_BUILD_EXAMPLE_HO)
|
||||||
|
spdlog_enable_warnings(example_header_only)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(SPDLOG_BUILD_TESTS OR SPDLOG_BUILD_TESTS_HO)
|
if(SPDLOG_BUILD_TESTS OR SPDLOG_BUILD_TESTS_HO)
|
||||||
@ -241,7 +292,10 @@ if (SPDLOG_INSTALL)
|
|||||||
# Include files
|
# Include files
|
||||||
#---------------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------------
|
||||||
install(DIRECTORY include/ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" PATTERN "fmt/bundled" EXCLUDE)
|
install(DIRECTORY include/ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" PATTERN "fmt/bundled" EXCLUDE)
|
||||||
install(TARGETS spdlog spdlog_header_only EXPORT spdlog DESTINATION "${CMAKE_INSTALL_LIBDIR}")
|
install(TARGETS spdlog spdlog_header_only EXPORT spdlog
|
||||||
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
|
|
||||||
if(NOT SPDLOG_FMT_EXTERNAL AND NOT SPDLOG_FMT_EXTERNAL_HO)
|
if(NOT SPDLOG_FMT_EXTERNAL AND NOT SPDLOG_FMT_EXTERNAL_HO)
|
||||||
install(DIRECTORY include/${PROJECT_NAME}/fmt/bundled/
|
install(DIRECTORY include/${PROJECT_NAME}/fmt/bundled/
|
||||||
@ -277,6 +331,5 @@ if (SPDLOG_INSTALL)
|
|||||||
# Support creation of installable packages
|
# Support creation of installable packages
|
||||||
#---------------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------------
|
||||||
include(cmake/spdlogCPack.cmake)
|
include(cmake/spdlogCPack.cmake)
|
||||||
|
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
4
third_party/spdlog/LICENSE
vendored
4
third_party/spdlog/LICENSE
vendored
@ -20,3 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
-- NOTE: Third party dependecy used by this sofware --
|
||||||
|
This software depends on the fmt lib (MIT License),
|
||||||
|
and users must comply to its license: https://github.com/fmtlib/fmt/blob/master/LICENSE.rst
|
||||||
|
|
||||||
|
76
third_party/spdlog/README.md
vendored
76
third_party/spdlog/README.md
vendored
@ -1,8 +1,6 @@
|
|||||||
# spdlog
|
# spdlog
|
||||||
|
|
||||||
Very fast, header-only/compiled, C++ logging library. [](https://travis-ci.org/gabime/spdlog) [](https://ci.appveyor.com/project/gabime/spdlog)
|
Very fast, header-only/compiled, C++ logging library. [](https://travis-ci.org/gabime/spdlog) [](https://ci.appveyor.com/project/gabime/spdlog) [](https://github.com/gabime/spdlog/releases/latest)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
#### Header only version
|
#### Header only version
|
||||||
@ -25,20 +23,22 @@ $ cmake .. && make -j
|
|||||||
|
|
||||||
## Package managers:
|
## Package managers:
|
||||||
* Homebrew: `brew install spdlog`
|
* Homebrew: `brew install spdlog`
|
||||||
|
* MacPorts: `sudo port install spdlog`
|
||||||
* FreeBSD: `cd /usr/ports/devel/spdlog/ && make install clean`
|
* FreeBSD: `cd /usr/ports/devel/spdlog/ && make install clean`
|
||||||
* Fedora: `yum install spdlog`
|
* Fedora: `yum install spdlog`
|
||||||
* Gentoo: `emerge dev-libs/spdlog`
|
* Gentoo: `emerge dev-libs/spdlog`
|
||||||
* Arch Linux: `yaourt -S spdlog-git`
|
* Arch Linux: `pacman -S spdlog`
|
||||||
* vcpkg: `vcpkg install spdlog`
|
* vcpkg: `vcpkg install spdlog`
|
||||||
* conan: `spdlog/[>=1.4.1]@bincrafters/stable`
|
* conan: `spdlog/[>=1.4.1]`
|
||||||
|
* conda: `conda install -c conda-forge spdlog`
|
||||||
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
* Very fast (see [benchmarks](#benchmarks) below).
|
* Very fast (see [benchmarks](#benchmarks) below).
|
||||||
* Headers only, just copy and use. Or use as a compiled library.
|
* Headers only or compiled version
|
||||||
* Feature rich formatting, using the excellent [fmt](https://github.com/fmtlib/fmt) library.
|
* Feature rich formatting, using the excellent [fmt](https://github.com/fmtlib/fmt) library.
|
||||||
* **New!** [Backtrace](#backtrace-support) support - store debug or other messages in a ring buffer and display later on demand.
|
* **New!** [Backtrace](#backtrace-support) support - store debug messages in a ring buffer and display later on demand.
|
||||||
* Fast asynchronous mode (optional)
|
* Asynchronous mode (optional)
|
||||||
* [Custom](https://github.com/gabime/spdlog/wiki/3.-Custom-formatting) formatting.
|
* [Custom](https://github.com/gabime/spdlog/wiki/3.-Custom-formatting) formatting.
|
||||||
* Multi/Single threaded loggers.
|
* Multi/Single threaded loggers.
|
||||||
* Various log targets:
|
* Various log targets:
|
||||||
@ -48,7 +48,8 @@ $ cmake .. && make -j
|
|||||||
* syslog.
|
* syslog.
|
||||||
* Windows debugger (```OutputDebugString(..)```)
|
* Windows debugger (```OutputDebugString(..)```)
|
||||||
* Easily extendable with custom log targets (just implement a single function in the [sink](include/spdlog/sinks/sink.h) interface).
|
* 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.
|
* Log filtering - log levels can be modified in runtime as well as in compile time.
|
||||||
|
* Support for loading log levels from argv or from environment var.
|
||||||
|
|
||||||
|
|
||||||
## Usage samples
|
## Usage samples
|
||||||
@ -77,15 +78,30 @@ int main()
|
|||||||
|
|
||||||
// Compile time log levels
|
// Compile time log levels
|
||||||
// define SPDLOG_ACTIVE_LEVEL to desired level
|
// define SPDLOG_ACTIVE_LEVEL to desired level
|
||||||
SPDLOG_TRACE("Some trace message with param {}", {});
|
SPDLOG_TRACE("Some trace message with param {}", 42);
|
||||||
SPDLOG_DEBUG("Some debug message");
|
SPDLOG_DEBUG("Some debug message");
|
||||||
|
|
||||||
// Set the default logger to file logger
|
// Set the default logger to file logger
|
||||||
auto file_logger = spdlog::basic_logger_mt("basic_logger", "logs/basic.txt");
|
auto file_logger = spdlog::basic_logger_mt("basic_logger", "logs/basic.txt");
|
||||||
spdlog::set_default_logger(file_logger);
|
spdlog::set_default_logger(file_logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
#### create stdout/stderr logger object
|
#### Load log levels from env variable or from argv
|
||||||
|
```c++
|
||||||
|
#include "spdlog/cfg/env.h"
|
||||||
|
void load_levels_example()
|
||||||
|
{
|
||||||
|
// Set the log level to "info" and mylogger to to "trace":
|
||||||
|
// SPDLOG_LEVEL=info,mylogger=trace && ./example
|
||||||
|
spdlog::cfg::load_env_levels();
|
||||||
|
// or from command line:
|
||||||
|
// ./example SPDLOG_LEVEL=info,mylogger=trace
|
||||||
|
// #include "spdlog/cfg/argv.h" // for loading levels from argv
|
||||||
|
// spdlog::cfg::load_argv_levels(args, argv);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
#### Create stdout/stderr logger object
|
||||||
```c++
|
```c++
|
||||||
#include "spdlog/spdlog.h"
|
#include "spdlog/spdlog.h"
|
||||||
#include "spdlog/sinks/stdout_color_sinks.h"
|
#include "spdlog/sinks/stdout_color_sinks.h"
|
||||||
@ -158,7 +174,7 @@ spdlog::dump_backtrace(); // log them now! show the last 32 messages
|
|||||||
#### Periodic flush
|
#### Periodic flush
|
||||||
```c++
|
```c++
|
||||||
// periodically flush all *registered* loggers every 3 seconds:
|
// periodically flush all *registered* loggers every 3 seconds:
|
||||||
// warning: only use if all your loggers are thread safe!
|
// warning: only use if all your loggers are thread safe ("_mt" loggers)
|
||||||
spdlog::flush_every(std::chrono::seconds(3));
|
spdlog::flush_every(std::chrono::seconds(3));
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -266,6 +282,37 @@ void user_defined_example()
|
|||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
#### User defined flags in the log pattern
|
||||||
|
```c++
|
||||||
|
// Log patterns can contain custom flags.
|
||||||
|
// the following example will add new flag '%*' - which will be bound to a <my_formatter_flag> instance.
|
||||||
|
#include "spdlog/pattern_formatter.h"
|
||||||
|
class my_formatter_flag : public spdlog::custom_flag_formatter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void format(const spdlog::details::log_msg &, const std::tm &, spdlog::memory_buf_t &dest) override
|
||||||
|
{
|
||||||
|
std::string some_txt = "custom-flag";
|
||||||
|
dest.append(some_txt.data(), some_txt.data() + some_txt.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<custom_flag_formatter> clone() const override
|
||||||
|
{
|
||||||
|
return spdlog::details::make_unique<my_formatter_flag>();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void custom_flags_example()
|
||||||
|
{
|
||||||
|
auto formatter = std::make_unique<spdlog::pattern_formatter>();
|
||||||
|
formatter->add_flag<my_formatter_flag>('*').set_pattern("[%n] [%*] [%^%l%$] %v");
|
||||||
|
spdlog::set_formatter(std::move(formatter));
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
#### Custom error handler
|
#### Custom error handler
|
||||||
```c++
|
```c++
|
||||||
@ -277,6 +324,8 @@ void err_handler_example()
|
|||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
#### syslog
|
#### syslog
|
||||||
```c++
|
```c++
|
||||||
@ -321,7 +370,7 @@ Below are some [benchmarks](https://github.com/gabime/spdlog/blob/v1.x/bench/ben
|
|||||||
[info] daily_st Elapsed: 0.42 secs 2,393,298/sec
|
[info] daily_st Elapsed: 0.42 secs 2,393,298/sec
|
||||||
[info] null_st Elapsed: 0.04 secs 27,446,957/sec
|
[info] null_st Elapsed: 0.04 secs 27,446,957/sec
|
||||||
[info] **************************************************************
|
[info] **************************************************************
|
||||||
[info] 10 threads sharing same logger, 1,000,000 iterations
|
[info] 10 threads, competing over the same logger object, 1,000,000 iterations
|
||||||
[info] **************************************************************
|
[info] **************************************************************
|
||||||
[info] basic_mt Elapsed: 0.60 secs 1,659,613/sec
|
[info] basic_mt Elapsed: 0.60 secs 1,659,613/sec
|
||||||
[info] rotating_mt Elapsed: 0.62 secs 1,612,493/sec
|
[info] rotating_mt Elapsed: 0.62 secs 1,612,493/sec
|
||||||
@ -335,7 +384,6 @@ Below are some [benchmarks](https://github.com/gabime/spdlog/blob/v1.x/bench/ben
|
|||||||
[info] Threads : 10
|
[info] Threads : 10
|
||||||
[info] Queue : 8,192 slots
|
[info] Queue : 8,192 slots
|
||||||
[info] Queue memory : 8,192 x 272 = 2,176 KB
|
[info] Queue memory : 8,192 x 272 = 2,176 KB
|
||||||
[info] Total iters : 3
|
|
||||||
[info] -------------------------------------------------
|
[info] -------------------------------------------------
|
||||||
[info]
|
[info]
|
||||||
[info] *********************************
|
[info] *********************************
|
||||||
|
2
third_party/spdlog/appveyor.yml
vendored
2
third_party/spdlog/appveyor.yml
vendored
@ -30,7 +30,7 @@ build_script:
|
|||||||
|
|
||||||
set PATH=%PATH%:C:\Program Files\Git\usr\bin
|
set PATH=%PATH%:C:\Program Files\Git\usr\bin
|
||||||
|
|
||||||
cmake .. -G %GENERATOR% -DCMAKE_BUILD_TYPE=%BUILD_TYPE% -DSPDLOG_WCHAR_SUPPORT=%WCHAR% -DSPDLOG_BUILD_EXAMPLE=ON -DSPDLOG_BUILD_EXAMPLE_HO=ON -DSPDLOG_BUILD_TESTS=ON -DSPDLOG_BUILD_TESTS_HO=OFF
|
cmake .. -G %GENERATOR% -DCMAKE_BUILD_TYPE=%BUILD_TYPE% -DSPDLOG_WCHAR_SUPPORT=%WCHAR% -DSPDLOG_BUILD_EXAMPLE=ON -DSPDLOG_BUILD_EXAMPLE_HO=ON -DSPDLOG_BUILD_TESTS=ON -DSPDLOG_BUILD_TESTS_HO=OFF -DSPDLOG_ENABLE_WARNINGS=ON
|
||||||
|
|
||||||
cmake --build . --config %BUILD_TYPE%
|
cmake --build . --config %BUILD_TYPE%
|
||||||
|
|
||||||
|
56
third_party/spdlog/bench/bench.cpp
vendored
56
third_party/spdlog/bench/bench.cpp
vendored
@ -19,19 +19,15 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace std::chrono;
|
|
||||||
using namespace spdlog;
|
|
||||||
using namespace spdlog::sinks;
|
|
||||||
using namespace utils;
|
|
||||||
|
|
||||||
void bench(int howmany, std::shared_ptr<spdlog::logger> log);
|
void bench(int howmany, std::shared_ptr<spdlog::logger> log);
|
||||||
void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count);
|
void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count);
|
||||||
void bench_default_api(int howmany, std::shared_ptr<spdlog::logger> log);
|
|
||||||
void bench_c_string(int howmany, std::shared_ptr<spdlog::logger> log);
|
|
||||||
|
|
||||||
static size_t file_size = 30 * 1024 * 1024;
|
// void bench_default_api(int howmany, std::shared_ptr<spdlog::logger> log);
|
||||||
static size_t rotating_files = 5;
|
// void bench_c_string(int howmany, std::shared_ptr<spdlog::logger> log);
|
||||||
|
|
||||||
|
static const size_t file_size = 30 * 1024 * 1024;
|
||||||
|
static const size_t rotating_files = 5;
|
||||||
|
static const int max_threads = 1000;
|
||||||
|
|
||||||
void bench_threaded_logging(int threads, int iters)
|
void bench_threaded_logging(int threads, int iters)
|
||||||
{
|
{
|
||||||
@ -116,9 +112,18 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
|
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
iters = atoi(argv[1]);
|
{
|
||||||
|
iters = std::stoi(argv[1]);
|
||||||
|
}
|
||||||
if (argc > 2)
|
if (argc > 2)
|
||||||
threads = atoi(argv[2]);
|
{
|
||||||
|
threads = std::stoi(argv[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (threads > max_threads)
|
||||||
|
{
|
||||||
|
throw std::runtime_error(fmt::format("Number of threads exceeds maximum({}})", max_threads));
|
||||||
|
}
|
||||||
|
|
||||||
bench_single_threaded(iters);
|
bench_single_threaded(iters);
|
||||||
bench_threaded_logging(1, iters);
|
bench_threaded_logging(1, iters);
|
||||||
@ -134,7 +139,10 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
void bench(int howmany, std::shared_ptr<spdlog::logger> log)
|
void bench(int howmany, std::shared_ptr<spdlog::logger> log)
|
||||||
{
|
{
|
||||||
|
using std::chrono::duration;
|
||||||
|
using std::chrono::duration_cast;
|
||||||
using std::chrono::high_resolution_clock;
|
using std::chrono::high_resolution_clock;
|
||||||
|
|
||||||
auto start = high_resolution_clock::now();
|
auto start = high_resolution_clock::now();
|
||||||
for (auto i = 0; i < howmany; ++i)
|
for (auto i = 0; i < howmany; ++i)
|
||||||
{
|
{
|
||||||
@ -150,17 +158,21 @@ void bench(int howmany, std::shared_ptr<spdlog::logger> log)
|
|||||||
|
|
||||||
void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count)
|
void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count)
|
||||||
{
|
{
|
||||||
|
using std::chrono::duration;
|
||||||
|
using std::chrono::duration_cast;
|
||||||
using std::chrono::high_resolution_clock;
|
using std::chrono::high_resolution_clock;
|
||||||
vector<thread> threads;
|
|
||||||
|
std::vector<std::thread> threads;
|
||||||
|
threads.reserve(thread_count);
|
||||||
auto start = high_resolution_clock::now();
|
auto start = high_resolution_clock::now();
|
||||||
for (int t = 0; t < thread_count; ++t)
|
for (int t = 0; t < thread_count; ++t)
|
||||||
{
|
{
|
||||||
threads.push_back(std::thread([&]() {
|
threads.emplace_back([&]() {
|
||||||
for (int j = 0; j < howmany / thread_count; j++)
|
for (int j = 0; j < howmany / thread_count; j++)
|
||||||
{
|
{
|
||||||
log->info("Hello logger: msg number {}", j);
|
log->info("Hello logger: msg number {}", j);
|
||||||
}
|
}
|
||||||
}));
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &t : threads)
|
for (auto &t : threads)
|
||||||
@ -174,9 +186,13 @@ void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count
|
|||||||
spdlog::drop(log->name());
|
spdlog::drop(log->name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
void bench_default_api(int howmany, std::shared_ptr<spdlog::logger> log)
|
void bench_default_api(int howmany, std::shared_ptr<spdlog::logger> log)
|
||||||
{
|
{
|
||||||
using std::chrono::high_resolution_clock;
|
using std::chrono::high_resolution_clock;
|
||||||
|
using std::chrono::duration;
|
||||||
|
using std::chrono::duration_cast;
|
||||||
|
|
||||||
auto orig_default = spdlog::default_logger();
|
auto orig_default = spdlog::default_logger();
|
||||||
spdlog::set_default_logger(log);
|
spdlog::set_default_logger(log);
|
||||||
auto start = high_resolution_clock::now();
|
auto start = high_resolution_clock::now();
|
||||||
@ -194,18 +210,22 @@ void bench_default_api(int howmany, std::shared_ptr<spdlog::logger> log)
|
|||||||
|
|
||||||
void bench_c_string(int howmany, std::shared_ptr<spdlog::logger> log)
|
void bench_c_string(int howmany, std::shared_ptr<spdlog::logger> log)
|
||||||
{
|
{
|
||||||
|
using std::chrono::high_resolution_clock;
|
||||||
|
using std::chrono::duration;
|
||||||
|
using std::chrono::duration_cast;
|
||||||
|
|
||||||
const char *msg = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum pharetra metus cursus "
|
const char *msg = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum pharetra metus cursus "
|
||||||
"lacus placerat congue. Nulla egestas, mauris a tincidunt tempus, enim lectus volutpat mi, eu consequat sem "
|
"lacus placerat congue. Nulla egestas, mauris a tincidunt tempus, enim lectus volutpat mi, eu consequat sem "
|
||||||
"libero nec massa. In dapibus ipsum a diam rhoncus gravida. Etiam non dapibus eros. Donec fringilla dui sed "
|
"libero nec massa. In dapibus ipsum a diam rhoncus gravida. Etiam non dapibus eros. Donec fringilla dui sed "
|
||||||
"augue pretium, nec scelerisque est maximus. Nullam convallis, sem nec blandit maximus, nisi turpis ornare "
|
"augue pretium, nec scelerisque est maximus. Nullam convallis, sem nec blandit maximus, nisi turpis ornare "
|
||||||
"nisl, sit amet volutpat neque massa eu odio. Maecenas malesuada quam ex, posuere congue nibh turpis duis.";
|
"nisl, sit amet volutpat neque massa eu odio. Maecenas malesuada quam ex, posuere congue nibh turpis duis.";
|
||||||
using std::chrono::high_resolution_clock;
|
|
||||||
auto orig_default = spdlog::default_logger();
|
auto orig_default = spdlog::default_logger();
|
||||||
spdlog::set_default_logger(log);
|
spdlog::set_default_logger(log);
|
||||||
auto start = high_resolution_clock::now();
|
auto start = high_resolution_clock::now();
|
||||||
for (auto i = 0; i < howmany; ++i)
|
for (auto i = 0; i < howmany; ++i)
|
||||||
{
|
{
|
||||||
spdlog::log(level::info, msg);
|
spdlog::log(spdlog::level::info, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto delta = high_resolution_clock::now() - start;
|
auto delta = high_resolution_clock::now() - start;
|
||||||
@ -214,3 +234,5 @@ void bench_c_string(int howmany, std::shared_ptr<spdlog::logger> log)
|
|||||||
spdlog::set_default_logger(std::move(orig_default));
|
spdlog::set_default_logger(std::move(orig_default));
|
||||||
spdlog::info("{:<30} Elapsed: {:0.2f} secs {:>16n}/sec", log->name(), delta_d, int(howmany / delta_d));
|
spdlog::info("{:<30} Elapsed: {:0.2f} secs {:>16n}/sec", log->name(), delta_d, int(howmany / delta_d));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*/
|
2
third_party/spdlog/bench/formatter-bench.cpp
vendored
2
third_party/spdlog/bench/formatter-bench.cpp
vendored
@ -6,7 +6,7 @@
|
|||||||
#include "benchmark/benchmark.h"
|
#include "benchmark/benchmark.h"
|
||||||
|
|
||||||
#include "spdlog/spdlog.h"
|
#include "spdlog/spdlog.h"
|
||||||
#include "spdlog/details/pattern_formatter.h"
|
#include "spdlog/pattern_formatter.h"
|
||||||
|
|
||||||
void bench_formatter(benchmark::State &state, std::string pattern)
|
void bench_formatter(benchmark::State &state, std::string pattern)
|
||||||
{
|
{
|
||||||
|
25
third_party/spdlog/bench/latency.cpp
vendored
25
third_party/spdlog/bench/latency.cpp
vendored
@ -51,11 +51,21 @@ void bench_disabled_macro(benchmark::State &state, std::shared_ptr<spdlog::logge
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
void bench_dev_null()
|
||||||
|
{
|
||||||
|
auto dev_null_st = spdlog::basic_logger_st("/dev/null_st", "/dev/null");
|
||||||
|
benchmark::RegisterBenchmark("/dev/null_st", bench_logger, std::move(dev_null_st))->UseRealTime();
|
||||||
|
spdlog::drop("/dev/null_st");
|
||||||
|
|
||||||
|
auto dev_null_mt = spdlog::basic_logger_mt("/dev/null_mt", "/dev/null");
|
||||||
|
benchmark::RegisterBenchmark("/dev/null_mt", bench_logger, std::move(dev_null_mt))->UseRealTime();
|
||||||
|
spdlog::drop("/dev/null_mt");
|
||||||
|
}
|
||||||
|
#endif // __linux__
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
|
||||||
using spdlog::sinks::basic_file_sink_mt;
|
|
||||||
using spdlog::sinks::basic_file_sink_st;
|
|
||||||
using spdlog::sinks::null_sink_mt;
|
using spdlog::sinks::null_sink_mt;
|
||||||
using spdlog::sinks::null_sink_st;
|
using spdlog::sinks::null_sink_st;
|
||||||
|
|
||||||
@ -63,6 +73,8 @@ int main(int argc, char *argv[])
|
|||||||
size_t rotating_files = 5;
|
size_t rotating_files = 5;
|
||||||
int n_threads = benchmark::CPUInfo::Get().num_cpus;
|
int n_threads = benchmark::CPUInfo::Get().num_cpus;
|
||||||
|
|
||||||
|
auto full_bench = argc > 1 && std::string(argv[1]) == "full";
|
||||||
|
|
||||||
// disabled loggers
|
// disabled loggers
|
||||||
auto disabled_logger = std::make_shared<spdlog::logger>("bench", std::make_shared<null_sink_mt>());
|
auto disabled_logger = std::make_shared<spdlog::logger>("bench", std::make_shared<null_sink_mt>());
|
||||||
disabled_logger->set_level(spdlog::level::off);
|
disabled_logger->set_level(spdlog::level::off);
|
||||||
@ -81,6 +93,12 @@ int main(int argc, char *argv[])
|
|||||||
tracing_null_logger_st->enable_backtrace(64);
|
tracing_null_logger_st->enable_backtrace(64);
|
||||||
benchmark::RegisterBenchmark("null_sink_st/backtrace", bench_logger, tracing_null_logger_st);
|
benchmark::RegisterBenchmark("null_sink_st/backtrace", bench_logger, tracing_null_logger_st);
|
||||||
|
|
||||||
|
#ifdef __linux
|
||||||
|
bench_dev_null();
|
||||||
|
#endif // __linux__
|
||||||
|
|
||||||
|
if (full_bench)
|
||||||
|
{
|
||||||
// basic_st
|
// basic_st
|
||||||
auto basic_st = spdlog::basic_logger_st("basic_st", "latency_logs/basic_st.log", true);
|
auto basic_st = spdlog::basic_logger_st("basic_st", "latency_logs/basic_st.log", true);
|
||||||
benchmark::RegisterBenchmark("basic_st", bench_logger, std::move(basic_st))->UseRealTime();
|
benchmark::RegisterBenchmark("basic_st", bench_logger, std::move(basic_st))->UseRealTime();
|
||||||
@ -129,6 +147,7 @@ int main(int argc, char *argv[])
|
|||||||
auto daily_mt = spdlog::daily_logger_mt("daily_mt", "latency_logs/daily_mt.log");
|
auto daily_mt = spdlog::daily_logger_mt("daily_mt", "latency_logs/daily_mt.log");
|
||||||
benchmark::RegisterBenchmark("daily_mt", bench_logger, std::move(daily_mt))->Threads(n_threads)->UseRealTime();
|
benchmark::RegisterBenchmark("daily_mt", bench_logger, std::move(daily_mt))->Threads(n_threads)->UseRealTime();
|
||||||
spdlog::drop("daily_mt");
|
spdlog::drop("daily_mt");
|
||||||
|
}
|
||||||
|
|
||||||
// async
|
// async
|
||||||
auto queue_size = 1024 * 1024 * 3;
|
auto queue_size = 1024 * 1024 * 3;
|
||||||
|
258
third_party/spdlog/cmake/pch.h.in
vendored
Normal file
258
third_party/spdlog/cmake/pch.h.in
vendored
Normal file
@ -0,0 +1,258 @@
|
|||||||
|
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||||
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// details/pattern_formatter-inl.h
|
||||||
|
// fmt/bin_to_hex.h
|
||||||
|
// fmt/bundled/format-inl.h
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
|
// details/file_helper-inl.h
|
||||||
|
// details/os-inl.h
|
||||||
|
// fmt/bundled/core.h
|
||||||
|
// fmt/bundled/posix.h
|
||||||
|
// logger-inl.h
|
||||||
|
// sinks/daily_file_sink.h
|
||||||
|
// sinks/stdout_sinks.h
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
// details/os-inl.h
|
||||||
|
// fmt/bundled/posix.h
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
// details/os-inl.h
|
||||||
|
// details/pattern_formatter-inl.h
|
||||||
|
// fmt/bundled/core.h
|
||||||
|
// fmt/bundled/format-inl.h
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
// details/os-inl.h
|
||||||
|
// details/os.h
|
||||||
|
// details/pattern_formatter-inl.h
|
||||||
|
// details/pattern_formatter.h
|
||||||
|
// fmt/bundled/chrono.h
|
||||||
|
// sinks/daily_file_sink.h
|
||||||
|
// sinks/rotating_file_sink-inl.h
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
// fmt/bundled/format-inl.h
|
||||||
|
#include <climits>
|
||||||
|
|
||||||
|
// fmt/bundled/format-inl.h
|
||||||
|
#include <cwchar>
|
||||||
|
|
||||||
|
// fmt/bundled/format-inl.h
|
||||||
|
// fmt/bundled/format.h
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
// fmt/bundled/format-inl.h
|
||||||
|
#include <cstdarg>
|
||||||
|
|
||||||
|
// details/file_helper-inl.h
|
||||||
|
// fmt/bundled/format.h
|
||||||
|
// fmt/bundled/posix.h
|
||||||
|
// sinks/rotating_file_sink-inl.h
|
||||||
|
#include <cerrno>
|
||||||
|
|
||||||
|
// details/circular_q.h
|
||||||
|
// details/thread_pool-inl.h
|
||||||
|
// fmt/bundled/format-inl.h
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
// async_logger-inl.h
|
||||||
|
// cfg/helpers-inl.h
|
||||||
|
// log_levels.h
|
||||||
|
// common.h
|
||||||
|
// details/file_helper-inl.h
|
||||||
|
// details/log_msg.h
|
||||||
|
// details/os-inl.h
|
||||||
|
// details/pattern_formatter-inl.h
|
||||||
|
// details/pattern_formatter.h
|
||||||
|
// details/registry-inl.h
|
||||||
|
// details/registry.h
|
||||||
|
// details/tcp_client-windows.h
|
||||||
|
// details/tcp_client.h
|
||||||
|
// fmt/bundled/core.h
|
||||||
|
// sinks/android_sink.h
|
||||||
|
// sinks/ansicolor_sink.h
|
||||||
|
// sinks/basic_file_sink.h
|
||||||
|
// sinks/daily_file_sink.h
|
||||||
|
// sinks/dup_filter_sink.h
|
||||||
|
// sinks/msvc_sink.h
|
||||||
|
// sinks/ringbuffer_sink.h
|
||||||
|
// sinks/rotating_file_sink-inl.h
|
||||||
|
// sinks/rotating_file_sink.h
|
||||||
|
// sinks/syslog_sink.h
|
||||||
|
// sinks/tcp_sink.h
|
||||||
|
// sinks/win_eventlog_sink.h
|
||||||
|
// sinks/wincolor_sink.h
|
||||||
|
// spdlog.h:
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// cfg/helpers-inl.h
|
||||||
|
// fmt/bundled/chrono.h
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
// fmt/bundled/ostream.h
|
||||||
|
// sinks/ostream_sink.h
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
// cfg/log_levels.h
|
||||||
|
// details/registry-inl.h
|
||||||
|
// details/registry.h
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
// details/circular_q.h
|
||||||
|
// details/pattern_formatter-inl.h
|
||||||
|
// details/pattern_formatter.h
|
||||||
|
// details/thread_pool.h
|
||||||
|
// fmt/bundled/compile.h
|
||||||
|
// logger.h
|
||||||
|
// sinks/dist_sink.h
|
||||||
|
// sinks/ringbuffer_sink.h
|
||||||
|
// sinks/win_eventlog_sink.h
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
// details/os-inl.h
|
||||||
|
// details/pattern_formatter-inl.h
|
||||||
|
// sinks/ansicolor_sink.h
|
||||||
|
// sinks/syslog_sink.h
|
||||||
|
// sinks/systemd_sink.h
|
||||||
|
// sinks/wincolor_sink.h
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
// details/file_helper-inl.h
|
||||||
|
// details/file_helper.h
|
||||||
|
// sinks/rotating_file_sink-inl.h
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
// details/os-inl.h
|
||||||
|
// fmt/bundled/format.h
|
||||||
|
// fmt/bundled/printf.h
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
// common.h
|
||||||
|
// details/backtracer.h
|
||||||
|
// details/null_mutex.h
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
|
// common.h
|
||||||
|
// details/backtracer.h
|
||||||
|
// details/null_mutex.h
|
||||||
|
#include <locale>
|
||||||
|
|
||||||
|
// common.h
|
||||||
|
#include <initializer_list>
|
||||||
|
|
||||||
|
// common.h
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
|
// common.h
|
||||||
|
// details/fmt_helper.h
|
||||||
|
// fmt/bundled/core.h
|
||||||
|
// fmt/bundled/ranges.h
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
// cfg/helpers-inl.h
|
||||||
|
// details/null_mutex.h
|
||||||
|
// details/pattern_formatter-inl.h
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
// async.h
|
||||||
|
// async_logger-inl.h
|
||||||
|
// common.h
|
||||||
|
// details/pattern_formatter-inl.h
|
||||||
|
// details/pattern_formatter.h
|
||||||
|
// details/registry-inl.h
|
||||||
|
// details/registry.h
|
||||||
|
// details/thread_pool.h
|
||||||
|
// fmt/bundled/format.h
|
||||||
|
// sinks/ansicolor_sink.h
|
||||||
|
// sinks/base_sink-inl.h
|
||||||
|
// sinks/dist_sink.h
|
||||||
|
// sinks/stdout_sinks-inl.h
|
||||||
|
// sinks/wincolor_sink.h
|
||||||
|
// spdlog.h
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
// async.h
|
||||||
|
// common.h
|
||||||
|
// details/backtracer.h
|
||||||
|
// details/periodic_worker.h
|
||||||
|
// details/registry-inl.h
|
||||||
|
// details/registry.h
|
||||||
|
// details/thread_pool.h
|
||||||
|
// sinks/tcp_sink.h
|
||||||
|
// spdlog.h
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
// details/mpmc_blocking_q.h
|
||||||
|
// details/periodic_worker.h
|
||||||
|
#include <condition_variable>
|
||||||
|
|
||||||
|
// details/os-inl.h
|
||||||
|
// fmt/bundled/format.h
|
||||||
|
// fmt/bundled/printf.h
|
||||||
|
// sinks/dist_sink.h
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
// common.h
|
||||||
|
// details/file_helper-inl.h
|
||||||
|
// details/fmt_helper.h
|
||||||
|
// details/os-inl.h
|
||||||
|
// details/pattern_formatter-inl.h
|
||||||
|
// details/pattern_formatter.h
|
||||||
|
// details/periodic_worker.h
|
||||||
|
// details/registry-inl.h
|
||||||
|
// details/registry.h
|
||||||
|
// details/thread_pool.h
|
||||||
|
// fmt/bundled/chrono.h
|
||||||
|
// sinks/android_sink.h
|
||||||
|
// sinks/daily_file_sink.h
|
||||||
|
// sinks/dup_filter_sink.h
|
||||||
|
// sinks/rotating_file_sink-inl.h
|
||||||
|
// sinks/rotating_file_sink.h
|
||||||
|
// sinks/tcp_sink.h
|
||||||
|
// spdlog.h
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
// details/file_helper-inl.h
|
||||||
|
// details/os-inl.h
|
||||||
|
// details/pattern_formatter-inl.h
|
||||||
|
// details/periodic_worker.h
|
||||||
|
// details/thread_pool.h
|
||||||
|
// sinks/android_sink.h
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
// async.h
|
||||||
|
// details/backtracer.h
|
||||||
|
// details/console_globals.h
|
||||||
|
// details/mpmc_blocking_q.h
|
||||||
|
// details/pattern_formatter-inl.h
|
||||||
|
// details/periodic_worker.h
|
||||||
|
// details/registry.h
|
||||||
|
// sinks/android_sink.h
|
||||||
|
// sinks/ansicolor_sink.h
|
||||||
|
// sinks/basic_file_sink.h
|
||||||
|
// sinks/daily_file_sink.h
|
||||||
|
// sinks/dist_sink.h
|
||||||
|
// sinks/dup_filter_sink.h
|
||||||
|
// sinks/msvc_sink.h
|
||||||
|
// sinks/null_sink.h
|
||||||
|
// sinks/ostream_sink.h
|
||||||
|
// sinks/ringbuffer_sink.h
|
||||||
|
// sinks/rotating_file_sink-inl.h
|
||||||
|
// sinks/rotating_file_sink.h
|
||||||
|
// sinks/tcp_sink.h
|
||||||
|
// sinks/win_eventlog_sink.h
|
||||||
|
// sinks/wincolor_sink.h
|
||||||
|
//
|
||||||
|
// color_sinks.cpp
|
||||||
|
// file_sinks.cpp
|
||||||
|
// spdlog.cpp
|
||||||
|
// stdout_sinks.cpp
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
// spdlog
|
||||||
|
#include <spdlog/common.h>
|
30
third_party/spdlog/cmake/spdlogCPack.cmake
vendored
30
third_party/spdlog/cmake/spdlogCPack.cmake
vendored
@ -1,7 +1,4 @@
|
|||||||
set(CPACK_GENERATOR
|
set(CPACK_GENERATOR "TGZ;ZIP" CACHE STRING "Semicolon separated list of generators")
|
||||||
TGZ
|
|
||||||
ZIP
|
|
||||||
)
|
|
||||||
|
|
||||||
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY 0)
|
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY 0)
|
||||||
set(CPACK_INSTALL_CMAKE_PROJECTS
|
set(CPACK_INSTALL_CMAKE_PROJECTS
|
||||||
@ -22,11 +19,32 @@ set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PR
|
|||||||
if (PROJECT_VERSION_TWEAK)
|
if (PROJECT_VERSION_TWEAK)
|
||||||
set(CPACK_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION}.${PROJECT_VERSION_TWEAK})
|
set(CPACK_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION}.${PROJECT_VERSION_TWEAK})
|
||||||
endif ()
|
endif ()
|
||||||
set(CPACK_PACKAGE_RELOCATABLE ON)
|
set(CPACK_PACKAGE_RELOCATABLE ON CACHE BOOL "Build relocatable package")
|
||||||
|
|
||||||
set(CPACK_RPM_PACKAGE_LICENSE "MIT")
|
set(CPACK_RPM_PACKAGE_LICENSE "MIT")
|
||||||
set(CPACK_RPM_PACKAGE_GROUP "System Environment/Libraries")
|
set(CPACK_RPM_PACKAGE_GROUP "Development/Libraries")
|
||||||
set(CPACK_RPM_PACKAGE_URL ${CPACK_PROJECT_URL})
|
set(CPACK_RPM_PACKAGE_URL ${CPACK_PROJECT_URL})
|
||||||
set(CPACK_RPM_PACKAGE_DESCRIPTION "Very fast, header-only/compiled, C++ logging library.")
|
set(CPACK_RPM_PACKAGE_DESCRIPTION "Very fast, header-only/compiled, C++ logging library.")
|
||||||
|
|
||||||
|
if (CPACK_PACKAGE_NAME)
|
||||||
|
set(CPACK_RPM_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
|
||||||
|
else()
|
||||||
|
set(CPACK_RPM_FILE_NAME "${PROJECT_NAME}-${CPACK_PACKAGE_VERSION}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (CPACK_RPM_PACKAGE_RELEASE)
|
||||||
|
set(CPACK_RPM_FILE_NAME "${CPACK_RPM_FILE_NAME}-${CPACK_RPM_PACKAGE_RELEASE}")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (CPACK_RPM_PACKAGE_ARCHITECTURE)
|
||||||
|
set(CPACK_RPM_FILE_NAME "${CPACK_RPM_FILE_NAME}.${CPACK_RPM_PACKAGE_ARCHITECTURE}")
|
||||||
|
endif ()
|
||||||
|
set(CPACK_RPM_FILE_NAME "${CPACK_RPM_FILE_NAME}.rpm")
|
||||||
|
|
||||||
|
if (NOT CPACK_PACKAGE_RELOCATABLE)
|
||||||
|
# Depend on pkgconfig rpm to create the system pkgconfig folder
|
||||||
|
set(CPACK_RPM_PACKAGE_REQUIRES pkgconfig)
|
||||||
|
set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
||||||
|
endif ()
|
||||||
|
|
||||||
include(CPack)
|
include(CPack)
|
||||||
|
15
third_party/spdlog/cmake/utils.cmake
vendored
15
third_party/spdlog/cmake/utils.cmake
vendored
@ -20,19 +20,28 @@ function(spdlog_extract_version)
|
|||||||
set(ver_patch ${CMAKE_MATCH_1})
|
set(ver_patch ${CMAKE_MATCH_1})
|
||||||
|
|
||||||
set(SPDLOG_VERSION_MAJOR ${ver_major} PARENT_SCOPE)
|
set(SPDLOG_VERSION_MAJOR ${ver_major} PARENT_SCOPE)
|
||||||
|
set(SPDLOG_VERSION_MINOR ${ver_minor} PARENT_SCOPE)
|
||||||
|
set(SPDLOG_VERSION_PATCH ${ver_patch} PARENT_SCOPE)
|
||||||
set (SPDLOG_VERSION "${ver_major}.${ver_minor}.${ver_patch}" PARENT_SCOPE)
|
set (SPDLOG_VERSION "${ver_major}.${ver_minor}.${ver_patch}" PARENT_SCOPE)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
|
|
||||||
# Turn on warnings on the given target
|
# Turn on warnings on the given target
|
||||||
function(spdlog_enable_warnings target_name)
|
function(spdlog_enable_warnings target_name)
|
||||||
|
if(SPDLOG_BUILD_WARNINGS)
|
||||||
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||||
|
list(APPEND MSVC_OPTIONS "/W3")
|
||||||
|
if(MSVC_VERSION GREATER 1900) #Allow non fatal security wanrnings for msvc 2015
|
||||||
|
list(APPEND MSVC_OPTIONS "/WX")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
target_compile_options(${target_name} PRIVATE
|
target_compile_options(${target_name} PRIVATE
|
||||||
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>:
|
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:GNU>>:
|
||||||
-Wall -Wextra -Wconversion -pedantic -Wfatal-errors>
|
-Wall -Wextra -Wconversion -pedantic -Wfatal-errors>
|
||||||
$<$<CXX_COMPILER_ID:MSVC>:/W4>)
|
$<$<CXX_COMPILER_ID:MSVC>:${MSVC_OPTIONS}>)
|
||||||
if(MSVC_VERSION GREATER_EQUAL 1910) #Allow non fatal security wanrnings for msvc 2015
|
|
||||||
target_compile_options(${target_name} PRIVATE /WX)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
|
|
||||||
|
42
third_party/spdlog/cmake/version.rc.in
vendored
Normal file
42
third_party/spdlog/cmake/version.rc.in
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#define APSTUDIO_READONLY_SYMBOLS
|
||||||
|
#include "winres.h"
|
||||||
|
#undef APSTUDIO_READONLY_SYMBOLS
|
||||||
|
|
||||||
|
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||||
|
|
||||||
|
|
||||||
|
VS_VERSION_INFO VERSIONINFO
|
||||||
|
FILEVERSION @SPDLOG_VERSION_MAJOR@,@SPDLOG_VERSION_MINOR@,@SPDLOG_VERSION_PATCH@,0
|
||||||
|
PRODUCTVERSION @SPDLOG_VERSION_MAJOR@,@SPDLOG_VERSION_MINOR@,@SPDLOG_VERSION_PATCH@,0
|
||||||
|
FILEFLAGSMASK 0x3fL
|
||||||
|
#ifdef _DEBUG
|
||||||
|
FILEFLAGS 0x1L
|
||||||
|
#else
|
||||||
|
FILEFLAGS 0x0L
|
||||||
|
#endif
|
||||||
|
FILEOS 0x40004L
|
||||||
|
FILETYPE 0x2L
|
||||||
|
FILESUBTYPE 0x0L
|
||||||
|
BEGIN
|
||||||
|
BLOCK "StringFileInfo"
|
||||||
|
BEGIN
|
||||||
|
BLOCK "040904b0"
|
||||||
|
BEGIN
|
||||||
|
VALUE "FileDescription", "spdlog dll\0"
|
||||||
|
VALUE "FileVersion", "@SPDLOG_VERSION@.0\0"
|
||||||
|
VALUE "InternalName", "spdlog.dll\0"
|
||||||
|
VALUE "LegalCopyright", "Copyright (C) spdlog\0"
|
||||||
|
VALUE "ProductName", "spdlog\0"
|
||||||
|
VALUE "ProductVersion", "@SPDLOG_VERSION@.0\0"
|
||||||
|
END
|
||||||
|
END
|
||||||
|
BLOCK "VarFileInfo"
|
||||||
|
BEGIN
|
||||||
|
VALUE "Translation", 0x409, 1200
|
||||||
|
END
|
||||||
|
END
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
4
third_party/spdlog/example/CMakeLists.txt
vendored
4
third_party/spdlog/example/CMakeLists.txt
vendored
@ -1,7 +1,7 @@
|
|||||||
# Copyright(c) 2019 spdlog authors
|
# Copyright(c) 2019 spdlog authors
|
||||||
# Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
# Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.1)
|
cmake_minimum_required(VERSION 3.2)
|
||||||
project(spdlog_examples CXX)
|
project(spdlog_examples CXX)
|
||||||
|
|
||||||
if(NOT TARGET spdlog)
|
if(NOT TARGET spdlog)
|
||||||
@ -13,7 +13,6 @@ endif()
|
|||||||
# Example of using pre-compiled library
|
# Example of using pre-compiled library
|
||||||
#---------------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------------
|
||||||
add_executable(example example.cpp)
|
add_executable(example example.cpp)
|
||||||
spdlog_enable_warnings(example)
|
|
||||||
target_link_libraries(example PRIVATE spdlog::spdlog)
|
target_link_libraries(example PRIVATE spdlog::spdlog)
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------------
|
||||||
@ -21,7 +20,6 @@ target_link_libraries(example PRIVATE spdlog::spdlog)
|
|||||||
#---------------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------------
|
||||||
if(SPDLOG_BUILD_EXAMPLE_HO)
|
if(SPDLOG_BUILD_EXAMPLE_HO)
|
||||||
add_executable(example_header_only example.cpp)
|
add_executable(example_header_only example.cpp)
|
||||||
spdlog_enable_warnings(example_header_only)
|
|
||||||
target_link_libraries(example_header_only PRIVATE spdlog::spdlog_header_only)
|
target_link_libraries(example_header_only PRIVATE spdlog::spdlog_header_only)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
50
third_party/spdlog/example/example.cpp
vendored
50
third_party/spdlog/example/example.cpp
vendored
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
|
void load_levels_example();
|
||||||
void stdout_logger_example();
|
void stdout_logger_example();
|
||||||
void basic_example();
|
void basic_example();
|
||||||
void rotating_example();
|
void rotating_example();
|
||||||
@ -17,12 +18,18 @@ void multi_sink_example();
|
|||||||
void user_defined_example();
|
void user_defined_example();
|
||||||
void err_handler_example();
|
void err_handler_example();
|
||||||
void syslog_example();
|
void syslog_example();
|
||||||
|
void custom_flags_example();
|
||||||
|
|
||||||
#include "spdlog/spdlog.h"
|
#include "spdlog/spdlog.h"
|
||||||
|
#include "spdlog/cfg/env.h" // for loading levels from the environment variable
|
||||||
|
|
||||||
int main(int, char *[])
|
int main(int, char *[])
|
||||||
{
|
{
|
||||||
|
// Log levels can be loaded from argv/env using "SPDLOG_LEVEL"
|
||||||
|
load_levels_example();
|
||||||
|
|
||||||
spdlog::info("Welcome to spdlog version {}.{}.{} !", SPDLOG_VER_MAJOR, SPDLOG_VER_MINOR, SPDLOG_VER_PATCH);
|
spdlog::info("Welcome to spdlog version {}.{}.{} !", SPDLOG_VER_MAJOR, SPDLOG_VER_MINOR, SPDLOG_VER_PATCH);
|
||||||
|
|
||||||
spdlog::warn("Easy padding in numbers like {:08d}", 12);
|
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::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("Support for floats {:03.2f}", 1.23456);
|
||||||
@ -64,6 +71,7 @@ int main(int, char *[])
|
|||||||
user_defined_example();
|
user_defined_example();
|
||||||
err_handler_example();
|
err_handler_example();
|
||||||
trace_example();
|
trace_example();
|
||||||
|
custom_flags_example();
|
||||||
|
|
||||||
// Flush all *registered* loggers using a worker thread every 3 seconds.
|
// Flush all *registered* loggers using a worker thread every 3 seconds.
|
||||||
// note: registered loggers *must* be thread safe for this to work correctly!
|
// note: registered loggers *must* be thread safe for this to work correctly!
|
||||||
@ -116,6 +124,18 @@ void daily_example()
|
|||||||
auto daily_logger = spdlog::daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30);
|
auto daily_logger = spdlog::daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "spdlog/cfg/env.h"
|
||||||
|
void load_levels_example()
|
||||||
|
{
|
||||||
|
// Set the log level to "info" and mylogger to to "trace":
|
||||||
|
// SPDLOG_LEVEL=info,mylogger=trace && ./example
|
||||||
|
spdlog::cfg::load_env_levels();
|
||||||
|
// or from command line:
|
||||||
|
// ./example SPDLOG_LEVEL=info,mylogger=trace
|
||||||
|
// #include "spdlog/cfg/argv.h" // for loading levels from argv
|
||||||
|
// spdlog::cfg::load_argv_levels(args, argv);
|
||||||
|
}
|
||||||
|
|
||||||
#include "spdlog/async.h"
|
#include "spdlog/async.h"
|
||||||
void async_example()
|
void async_example()
|
||||||
{
|
{
|
||||||
@ -154,6 +174,8 @@ void binary_example()
|
|||||||
// logger->info("uppercase: {:X}", spdlog::to_hex(buf));
|
// logger->info("uppercase: {:X}", spdlog::to_hex(buf));
|
||||||
// logger->info("uppercase, no delimiters: {:Xs}", 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->info("uppercase, no delimiters, no position info: {:Xsp}", spdlog::to_hex(buf));
|
||||||
|
// logger->info("hexdump style: {:a}", spdlog::to_hex(buf));
|
||||||
|
// logger->info("hexdump style, 20 chars per line {:a}", spdlog::to_hex(buf, 20));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compile time log levels.
|
// Compile time log levels.
|
||||||
@ -230,5 +252,31 @@ void android_example()
|
|||||||
auto android_logger = spdlog::android_logger_mt("android", tag);
|
auto android_logger = spdlog::android_logger_mt("android", tag);
|
||||||
android_logger->critical("Use \"adb shell logcat\" to view this message.");
|
android_logger->critical("Use \"adb shell logcat\" to view this message.");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Log patterns can contain custom flags.
|
||||||
|
// this will add custom flag '%*' which will be bound to a <my_formatter_flag> instance
|
||||||
|
#include "spdlog/pattern_formatter.h"
|
||||||
|
class my_formatter_flag : public spdlog::custom_flag_formatter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void format(const spdlog::details::log_msg &, const std::tm &, spdlog::memory_buf_t &dest) override
|
||||||
|
{
|
||||||
|
std::string some_txt = "custom-flag";
|
||||||
|
dest.append(some_txt.data(), some_txt.data() + some_txt.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<custom_flag_formatter> clone() const override
|
||||||
|
{
|
||||||
|
return spdlog::details::make_unique<my_formatter_flag>();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void custom_flags_example()
|
||||||
|
{
|
||||||
|
|
||||||
|
using spdlog::details::make_unique; // for pre c++14
|
||||||
|
auto formatter = make_unique<spdlog::pattern_formatter>();
|
||||||
|
formatter->add_flag<my_formatter_flag>('*').set_pattern("[%n] [%*] [%^%l%$] %v");
|
||||||
|
spdlog::set_formatter(std::move(formatter));
|
||||||
|
}
|
||||||
|
@ -32,7 +32,7 @@ SPDLOG_INLINE void spdlog::async_logger::sink_it_(const details::log_msg &msg)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SPDLOG_THROW(spdlog_ex("async log: thread pool doesn't exist anymore"));
|
throw_spdlog_ex("async log: thread pool doesn't exist anymore");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ SPDLOG_INLINE void spdlog::async_logger::flush_()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SPDLOG_THROW(spdlog_ex("async flush: thread pool doesn't exist anymore"));
|
throw_spdlog_ex("async flush: thread pool doesn't exist anymore");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ namespace details {
|
|||||||
class thread_pool;
|
class thread_pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
class async_logger final : public std::enable_shared_from_this<async_logger>, public logger
|
class SPDLOG_API async_logger final : public std::enable_shared_from_this<async_logger>, public logger
|
||||||
{
|
{
|
||||||
friend class details::thread_pool;
|
friend class details::thread_pool;
|
||||||
|
|
||||||
|
45
third_party/spdlog/include/spdlog/cfg/argv.h
vendored
Normal file
45
third_party/spdlog/include/spdlog/cfg/argv.h
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||||
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <spdlog/cfg/helpers.h>
|
||||||
|
#include <spdlog/details/registry.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// Init log levels using each argv entry that starts with "SPDLOG_LEVEL="
|
||||||
|
//
|
||||||
|
// set all loggers to debug level:
|
||||||
|
// example.exe "SPDLOG_LEVEL=debug"
|
||||||
|
|
||||||
|
// set logger1 to trace level
|
||||||
|
// example.exe "SPDLOG_LEVEL=logger1=trace"
|
||||||
|
|
||||||
|
// turn off all logging except for logger1 and logger2:
|
||||||
|
// example.exe "SPDLOG_LEVEL=off,logger1=debug,logger2=info"
|
||||||
|
|
||||||
|
namespace spdlog {
|
||||||
|
namespace cfg {
|
||||||
|
|
||||||
|
// search for SPDLOG_LEVEL= in the args and use it to init the levels
|
||||||
|
void load_argv_levels(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
const std::string spdlog_level_prefix = "SPDLOG_LEVEL=";
|
||||||
|
for (int i = 1; i < argc; i++)
|
||||||
|
{
|
||||||
|
std::string arg = argv[i];
|
||||||
|
if (arg.find(spdlog_level_prefix) == 0)
|
||||||
|
{
|
||||||
|
auto levels_string = arg.substr(spdlog_level_prefix.size());
|
||||||
|
auto levels = helpers::extract_levels(levels_string);
|
||||||
|
details::registry::instance().update_levels(std::move(levels));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_argv_levels(int argc, char **argv)
|
||||||
|
{
|
||||||
|
load_argv_levels(argc, const_cast<const char **>(argv));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace cfg
|
||||||
|
} // namespace spdlog
|
36
third_party/spdlog/include/spdlog/cfg/env.h
vendored
Normal file
36
third_party/spdlog/include/spdlog/cfg/env.h
vendored
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||||
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <spdlog/cfg/helpers.h>
|
||||||
|
#include <spdlog/details/registry.h>
|
||||||
|
#include <spdlog/details/os.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// Init levels and patterns from env variables SPDLOG_LEVEL
|
||||||
|
// Inspired from Rust's "env_logger" crate (https://crates.io/crates/env_logger).
|
||||||
|
// Note - fallback to "info" level on unrecognized levels
|
||||||
|
//
|
||||||
|
// Examples:
|
||||||
|
//
|
||||||
|
// set global level to debug:
|
||||||
|
// export SPDLOG_LEVEL=debug
|
||||||
|
//
|
||||||
|
// turn off all logging except for logger1:
|
||||||
|
// export SPDLOG_LEVEL="off,logger1=debug"
|
||||||
|
//
|
||||||
|
|
||||||
|
// turn off all logging except for logger1 and logger2:
|
||||||
|
// export SPDLOG_LEVEL="off,logger1=debug,logger2=info"
|
||||||
|
|
||||||
|
namespace spdlog {
|
||||||
|
namespace cfg {
|
||||||
|
void load_env_levels()
|
||||||
|
{
|
||||||
|
auto env_val = details::os::getenv("SPDLOG_LEVEL");
|
||||||
|
auto levels = helpers::extract_levels(env_val);
|
||||||
|
details::registry::instance().update_levels(std::move(levels));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace cfg
|
||||||
|
} // namespace spdlog
|
103
third_party/spdlog/include/spdlog/cfg/helpers-inl.h
vendored
Normal file
103
third_party/spdlog/include/spdlog/cfg/helpers-inl.h
vendored
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||||
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef SPDLOG_HEADER_ONLY
|
||||||
|
#include <spdlog/cfg/helpers.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <spdlog/spdlog.h>
|
||||||
|
#include <spdlog/details/os.h>
|
||||||
|
#include <spdlog/details/registry.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace spdlog {
|
||||||
|
namespace cfg {
|
||||||
|
namespace helpers {
|
||||||
|
|
||||||
|
// inplace convert to lowercase
|
||||||
|
inline std::string &to_lower_(std::string &str)
|
||||||
|
{
|
||||||
|
std::transform(
|
||||||
|
str.begin(), str.end(), str.begin(), [](char ch) { return static_cast<char>((ch >= 'A' && ch <= 'Z') ? ch + ('a' - 'A') : ch); });
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
// inplace trim spaces
|
||||||
|
inline std::string &trim_(std::string &str)
|
||||||
|
{
|
||||||
|
const char *spaces = " \n\r\t";
|
||||||
|
str.erase(str.find_last_not_of(spaces) + 1);
|
||||||
|
str.erase(0, str.find_first_not_of(spaces));
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return (name,value) trimmed pair from given "name=value" string.
|
||||||
|
// return empty string on missing parts
|
||||||
|
// "key=val" => ("key", "val")
|
||||||
|
// " key = val " => ("key", "val")
|
||||||
|
// "key=" => ("key", "")
|
||||||
|
// "val" => ("", "val")
|
||||||
|
|
||||||
|
inline std::pair<std::string, std::string> extract_kv_(char sep, const std::string &str)
|
||||||
|
{
|
||||||
|
auto n = str.find(sep);
|
||||||
|
std::string k, v;
|
||||||
|
if (n == std::string::npos)
|
||||||
|
{
|
||||||
|
v = str;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
k = str.substr(0, n);
|
||||||
|
v = str.substr(n + 1);
|
||||||
|
}
|
||||||
|
return std::make_pair(trim_(k), trim_(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
// return vector of key/value pairs from sequence of "K1=V1,K2=V2,.."
|
||||||
|
// "a=AAA,b=BBB,c=CCC,.." => {("a","AAA"),("b","BBB"),("c", "CCC"),...}
|
||||||
|
inline std::unordered_map<std::string, std::string> extract_key_vals_(const std::string &str)
|
||||||
|
{
|
||||||
|
std::string token;
|
||||||
|
std::istringstream token_stream(str);
|
||||||
|
std::unordered_map<std::string, std::string> rv{};
|
||||||
|
while (std::getline(token_stream, token, ','))
|
||||||
|
{
|
||||||
|
if (token.empty())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto kv = extract_kv_('=', token);
|
||||||
|
rv[kv.first] = kv.second;
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
SPDLOG_INLINE log_levels extract_levels(const std::string &input)
|
||||||
|
{
|
||||||
|
auto key_vals = extract_key_vals_(input);
|
||||||
|
log_levels rv;
|
||||||
|
|
||||||
|
for (auto &name_level : key_vals)
|
||||||
|
{
|
||||||
|
auto &logger_name = name_level.first;
|
||||||
|
auto level_name = to_lower_(name_level.second);
|
||||||
|
auto level = level::from_str(level_name);
|
||||||
|
// fallback to "info" if unrecognized level name
|
||||||
|
if (level == level::off && level_name != "off")
|
||||||
|
{
|
||||||
|
level = level::info;
|
||||||
|
}
|
||||||
|
rv.set(logger_name, level);
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace helpers
|
||||||
|
} // namespace cfg
|
||||||
|
} // namespace spdlog
|
28
third_party/spdlog/include/spdlog/cfg/helpers.h
vendored
Normal file
28
third_party/spdlog/include/spdlog/cfg/helpers.h
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||||
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <spdlog/cfg/log_levels.h>
|
||||||
|
|
||||||
|
namespace spdlog {
|
||||||
|
namespace cfg {
|
||||||
|
namespace helpers {
|
||||||
|
//
|
||||||
|
// Init levels from given string
|
||||||
|
//
|
||||||
|
// Examples:
|
||||||
|
//
|
||||||
|
// set global level to debug: "debug"
|
||||||
|
// turn off all logging except for logger1: "off,logger1=debug"
|
||||||
|
// turn off all logging except for logger1 and logger2: "off,logger1=debug,logger2=info"
|
||||||
|
//
|
||||||
|
SPDLOG_API log_levels extract_levels(const std::string &txt);
|
||||||
|
} // namespace helpers
|
||||||
|
|
||||||
|
} // namespace cfg
|
||||||
|
} // namespace spdlog
|
||||||
|
|
||||||
|
#ifdef SPDLOG_HEADER_ONLY
|
||||||
|
#include "helpers-inl.h"
|
||||||
|
#endif // SPDLOG_HEADER_ONLY
|
47
third_party/spdlog/include/spdlog/cfg/log_levels.h
vendored
Normal file
47
third_party/spdlog/include/spdlog/cfg/log_levels.h
vendored
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||||
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <spdlog/common.h>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
namespace spdlog {
|
||||||
|
namespace cfg {
|
||||||
|
class log_levels
|
||||||
|
{
|
||||||
|
std::unordered_map<std::string, spdlog::level::level_enum> levels_;
|
||||||
|
spdlog::level::level_enum default_level_ = level::info;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void set(const std::string &logger_name, level::level_enum lvl)
|
||||||
|
{
|
||||||
|
if (logger_name.empty())
|
||||||
|
{
|
||||||
|
default_level_ = lvl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
levels_[logger_name] = lvl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_default(level::level_enum lvl)
|
||||||
|
{
|
||||||
|
default_level_ = lvl;
|
||||||
|
}
|
||||||
|
|
||||||
|
level::level_enum get(const std::string &logger_name)
|
||||||
|
{
|
||||||
|
auto it = levels_.find(logger_name);
|
||||||
|
return it != levels_.end() ? it->second : default_level_;
|
||||||
|
}
|
||||||
|
|
||||||
|
level::level_enum default_level()
|
||||||
|
{
|
||||||
|
return default_level_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace cfg
|
||||||
|
} // namespace spdlog
|
19
third_party/spdlog/include/spdlog/common-inl.h
vendored
19
third_party/spdlog/include/spdlog/common-inl.h
vendored
@ -34,6 +34,15 @@ SPDLOG_INLINE spdlog::level::level_enum from_str(const std::string &name) SPDLOG
|
|||||||
}
|
}
|
||||||
level++;
|
level++;
|
||||||
}
|
}
|
||||||
|
// check also for "warn" and "err" before giving up..
|
||||||
|
if (name == "warn")
|
||||||
|
{
|
||||||
|
return level::warn;
|
||||||
|
}
|
||||||
|
if (name == "err")
|
||||||
|
{
|
||||||
|
return level::err;
|
||||||
|
}
|
||||||
return level::off;
|
return level::off;
|
||||||
}
|
}
|
||||||
} // namespace level
|
} // namespace level
|
||||||
@ -54,4 +63,14 @@ SPDLOG_INLINE const char *spdlog_ex::what() const SPDLOG_NOEXCEPT
|
|||||||
return msg_.c_str();
|
return msg_.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SPDLOG_INLINE void throw_spdlog_ex(const std::string &msg, int last_errno)
|
||||||
|
{
|
||||||
|
SPDLOG_THROW(spdlog_ex(msg, last_errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
SPDLOG_INLINE void throw_spdlog_ex(std::string msg)
|
||||||
|
{
|
||||||
|
SPDLOG_THROW(spdlog_ex(std::move(msg)));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace spdlog
|
} // namespace spdlog
|
||||||
|
35
third_party/spdlog/include/spdlog/common.h
vendored
35
third_party/spdlog/include/spdlog/common.h
vendored
@ -15,22 +15,20 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#ifndef NOMINMAX
|
|
||||||
#define NOMINMAX // prevent windows redefining min/max
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef WIN32_LEAN_AND_MEAN
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#endif //_WIN32
|
|
||||||
|
|
||||||
#ifdef SPDLOG_COMPILED_LIB
|
#ifdef SPDLOG_COMPILED_LIB
|
||||||
#undef SPDLOG_HEADER_ONLY
|
#undef SPDLOG_HEADER_ONLY
|
||||||
|
#if defined(_WIN32) && defined(SPDLOG_SHARED_LIB)
|
||||||
|
#ifdef spdlog_EXPORTS
|
||||||
|
#define SPDLOG_API __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define SPDLOG_API __declspec(dllimport)
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define SPDLOG_API
|
||||||
|
#endif
|
||||||
#define SPDLOG_INLINE
|
#define SPDLOG_INLINE
|
||||||
#else
|
#else
|
||||||
|
#define SPDLOG_API
|
||||||
#define SPDLOG_HEADER_ONLY
|
#define SPDLOG_HEADER_ONLY
|
||||||
#define SPDLOG_INLINE inline
|
#define SPDLOG_INLINE inline
|
||||||
#endif
|
#endif
|
||||||
@ -147,6 +145,7 @@ enum level_enum
|
|||||||
err = SPDLOG_LEVEL_ERROR,
|
err = SPDLOG_LEVEL_ERROR,
|
||||||
critical = SPDLOG_LEVEL_CRITICAL,
|
critical = SPDLOG_LEVEL_CRITICAL,
|
||||||
off = SPDLOG_LEVEL_OFF,
|
off = SPDLOG_LEVEL_OFF,
|
||||||
|
n_levels
|
||||||
};
|
};
|
||||||
|
|
||||||
#if !defined(SPDLOG_LEVEL_NAMES)
|
#if !defined(SPDLOG_LEVEL_NAMES)
|
||||||
@ -164,9 +163,9 @@ enum level_enum
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
string_view_t &to_string_view(spdlog::level::level_enum l) SPDLOG_NOEXCEPT;
|
SPDLOG_API string_view_t &to_string_view(spdlog::level::level_enum l) SPDLOG_NOEXCEPT;
|
||||||
const char *to_short_c_str(spdlog::level::level_enum l) SPDLOG_NOEXCEPT;
|
SPDLOG_API const char *to_short_c_str(spdlog::level::level_enum l) SPDLOG_NOEXCEPT;
|
||||||
spdlog::level::level_enum from_str(const std::string &name) SPDLOG_NOEXCEPT;
|
SPDLOG_API spdlog::level::level_enum from_str(const std::string &name) SPDLOG_NOEXCEPT;
|
||||||
|
|
||||||
using level_hasher = std::hash<int>;
|
using level_hasher = std::hash<int>;
|
||||||
} // namespace level
|
} // namespace level
|
||||||
@ -194,7 +193,7 @@ enum class pattern_time_type
|
|||||||
//
|
//
|
||||||
// Log exception
|
// Log exception
|
||||||
//
|
//
|
||||||
class spdlog_ex : public std::exception
|
class SPDLOG_API spdlog_ex : public std::exception
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit spdlog_ex(std::string msg);
|
explicit spdlog_ex(std::string msg);
|
||||||
@ -205,6 +204,9 @@ private:
|
|||||||
std::string msg_;
|
std::string msg_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void throw_spdlog_ex(const std::string &msg, int last_errno);
|
||||||
|
void throw_spdlog_ex(std::string msg);
|
||||||
|
|
||||||
struct source_loc
|
struct source_loc
|
||||||
{
|
{
|
||||||
SPDLOG_CONSTEXPR source_loc() = default;
|
SPDLOG_CONSTEXPR source_loc() = default;
|
||||||
@ -237,7 +239,6 @@ std::unique_ptr<T> make_unique(Args &&... args)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} // namespace details
|
} // namespace details
|
||||||
|
|
||||||
} // namespace spdlog
|
} // namespace spdlog
|
||||||
|
|
||||||
#ifdef SPDLOG_HEADER_ONLY
|
#ifdef SPDLOG_HEADER_ONLY
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
namespace spdlog {
|
namespace spdlog {
|
||||||
namespace details {
|
namespace details {
|
||||||
class backtracer
|
class SPDLOG_API backtracer
|
||||||
{
|
{
|
||||||
mutable std::mutex mutex_;
|
mutable std::mutex mutex_;
|
||||||
std::atomic<bool> enabled_{false};
|
std::atomic<bool> enabled_{false};
|
||||||
|
@ -43,14 +43,14 @@ SPDLOG_INLINE void file_helper::open(const filename_t &fname, bool truncate)
|
|||||||
details::os::sleep_for_millis(open_interval_);
|
details::os::sleep_for_millis(open_interval_);
|
||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_THROW(spdlog_ex("Failed opening file " + os::filename_to_str(filename_) + " for writing", errno));
|
throw_spdlog_ex("Failed opening file " + os::filename_to_str(filename_) + " for writing", errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_INLINE void file_helper::reopen(bool truncate)
|
SPDLOG_INLINE void file_helper::reopen(bool truncate)
|
||||||
{
|
{
|
||||||
if (filename_.empty())
|
if (filename_.empty())
|
||||||
{
|
{
|
||||||
SPDLOG_THROW(spdlog_ex("Failed re opening file - was not opened before"));
|
throw_spdlog_ex("Failed re opening file - was not opened before");
|
||||||
}
|
}
|
||||||
this->open(filename_, truncate);
|
this->open(filename_, truncate);
|
||||||
}
|
}
|
||||||
@ -75,7 +75,7 @@ SPDLOG_INLINE void file_helper::write(const memory_buf_t &buf)
|
|||||||
auto data = buf.data();
|
auto data = buf.data();
|
||||||
if (std::fwrite(data, 1, msg_size, fd_) != msg_size)
|
if (std::fwrite(data, 1, msg_size, fd_) != msg_size)
|
||||||
{
|
{
|
||||||
SPDLOG_THROW(spdlog_ex("Failed writing to file " + os::filename_to_str(filename_), errno));
|
throw_spdlog_ex("Failed writing to file " + os::filename_to_str(filename_), errno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ SPDLOG_INLINE size_t file_helper::size() const
|
|||||||
{
|
{
|
||||||
if (fd_ == nullptr)
|
if (fd_ == nullptr)
|
||||||
{
|
{
|
||||||
SPDLOG_THROW(spdlog_ex("Cannot use size() on closed file " + os::filename_to_str(filename_)));
|
throw_spdlog_ex("Cannot use size() on closed file " + os::filename_to_str(filename_));
|
||||||
}
|
}
|
||||||
return os::filesize(fd_);
|
return os::filesize(fd_);
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ namespace details {
|
|||||||
// When failing to open a file, retry several times(5) with a delay interval(10 ms).
|
// When failing to open a file, retry several times(5) with a delay interval(10 ms).
|
||||||
// Throw spdlog_ex exception on errors.
|
// Throw spdlog_ex exception on errors.
|
||||||
|
|
||||||
class file_helper
|
class SPDLOG_API file_helper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit file_helper() = default;
|
explicit file_helper() = default;
|
||||||
|
@ -20,11 +20,8 @@ inline spdlog::string_view_t to_string_view(const memory_buf_t &buf) SPDLOG_NOEX
|
|||||||
inline void append_string_view(spdlog::string_view_t view, memory_buf_t &dest)
|
inline void append_string_view(spdlog::string_view_t view, memory_buf_t &dest)
|
||||||
{
|
{
|
||||||
auto *buf_ptr = view.data();
|
auto *buf_ptr = view.data();
|
||||||
if (buf_ptr != nullptr)
|
|
||||||
{
|
|
||||||
dest.append(buf_ptr, buf_ptr + view.size());
|
dest.append(buf_ptr, buf_ptr + view.size());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline void append_int(T n, memory_buf_t &dest)
|
inline void append_int(T n, memory_buf_t &dest)
|
||||||
@ -34,10 +31,10 @@ inline void append_int(T n, memory_buf_t &dest)
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline unsigned count_digits(T n)
|
inline unsigned int count_digits(T n)
|
||||||
{
|
{
|
||||||
using count_type = typename std::conditional<(sizeof(T) > sizeof(uint32_t)), uint64_t, uint32_t>::type;
|
using count_type = typename std::conditional<(sizeof(T) > sizeof(uint32_t)), uint64_t, uint32_t>::type;
|
||||||
return static_cast<unsigned>(fmt::internal::count_digits(static_cast<count_type>(n)));
|
return static_cast<unsigned int>(fmt::internal::count_digits(static_cast<count_type>(n)));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void pad2(int n, memory_buf_t &dest)
|
inline void pad2(int n, memory_buf_t &dest)
|
||||||
@ -66,11 +63,9 @@ template<typename T>
|
|||||||
inline void pad_uint(T n, unsigned int width, memory_buf_t &dest)
|
inline void pad_uint(T n, unsigned int width, memory_buf_t &dest)
|
||||||
{
|
{
|
||||||
static_assert(std::is_unsigned<T>::value, "pad_uint must get unsigned T");
|
static_assert(std::is_unsigned<T>::value, "pad_uint must get unsigned T");
|
||||||
auto digits = count_digits(n);
|
for (auto digits = count_digits(n); digits < width; digits++)
|
||||||
if (width > digits)
|
|
||||||
{
|
{
|
||||||
const char *zeroes = "0000000000000000000";
|
dest.push_back('0');
|
||||||
dest.append(zeroes, zeroes + width - digits);
|
|
||||||
}
|
}
|
||||||
append_int(n, dest);
|
append_int(n, dest);
|
||||||
}
|
}
|
||||||
@ -78,7 +73,18 @@ inline void pad_uint(T n, unsigned int width, memory_buf_t &dest)
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
inline void pad3(T n, memory_buf_t &dest)
|
inline void pad3(T n, memory_buf_t &dest)
|
||||||
{
|
{
|
||||||
pad_uint(n, 3, dest);
|
static_assert(std::is_unsigned<T>::value, "pad3 must get unsigned T");
|
||||||
|
if(n < 1000)
|
||||||
|
{
|
||||||
|
dest.push_back(static_cast<char>(n / 100 + '0'));
|
||||||
|
n = n % 100;
|
||||||
|
dest.push_back(static_cast<char>((n / 10) + '0'));
|
||||||
|
dest.push_back(static_cast<char>((n % 10) + '0'));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
append_int(n, dest);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
namespace spdlog {
|
namespace spdlog {
|
||||||
namespace details {
|
namespace details {
|
||||||
struct log_msg
|
struct SPDLOG_API log_msg
|
||||||
{
|
{
|
||||||
log_msg() = default;
|
log_msg() = default;
|
||||||
log_msg(source_loc loc, string_view_t logger_name, level::level_enum lvl, string_view_t msg);
|
log_msg(source_loc loc, string_view_t logger_name, level::level_enum lvl, string_view_t msg);
|
||||||
|
@ -11,7 +11,7 @@ namespace details {
|
|||||||
// Extend log_msg with internal buffer to store its payload.
|
// Extend log_msg with internal buffer to store its payload.
|
||||||
// THis is needed since log_msg holds string_views that points to stack data.
|
// THis is needed since log_msg holds string_views that points to stack data.
|
||||||
|
|
||||||
class log_msg_buffer : public log_msg
|
class SPDLOG_API log_msg_buffer : public log_msg
|
||||||
{
|
{
|
||||||
memory_buf_t buffer;
|
memory_buf_t buffer;
|
||||||
void update_string_views();
|
void update_string_views();
|
||||||
|
@ -23,16 +23,9 @@
|
|||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
#ifndef NOMINMAX
|
|
||||||
#define NOMINMAX // prevent windows redefining min/max
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef WIN32_LEAN_AND_MEAN
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#endif
|
|
||||||
#include <io.h> // _get_osfhandle and _isatty support
|
#include <io.h> // _get_osfhandle and _isatty support
|
||||||
#include <process.h> // _get_pid support
|
#include <process.h> // _get_pid support
|
||||||
#include <windows.h>
|
#include <spdlog/details/windows_include.h>
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
#include <share.h>
|
#include <share.h>
|
||||||
@ -126,23 +119,6 @@ SPDLOG_INLINE std::tm gmtime() SPDLOG_NOEXCEPT
|
|||||||
return gmtime(now_t);
|
return gmtime(now_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SPDLOG_PREVENT_CHILD_FD
|
|
||||||
SPDLOG_INLINE void prevent_child_fd(FILE *f)
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
auto file_handle = reinterpret_cast<HANDLE>(_get_osfhandle(::_fileno(f)));
|
|
||||||
if (!::SetHandleInformation(file_handle, HANDLE_FLAG_INHERIT, 0))
|
|
||||||
SPDLOG_THROW(spdlog_ex("SetHandleInformation failed", errno));
|
|
||||||
#else
|
|
||||||
auto fd = ::fileno(f);
|
|
||||||
if (::fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
|
|
||||||
{
|
|
||||||
SPDLOG_THROW(spdlog_ex("fcntl with FD_CLOEXEC failed", errno));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif // SPDLOG_PREVENT_CHILD_FD
|
|
||||||
|
|
||||||
// fopen_s on non windows for writing
|
// fopen_s on non windows for writing
|
||||||
SPDLOG_INLINE bool fopen_s(FILE **fp, const filename_t &filename, const filename_t &mode)
|
SPDLOG_INLINE bool fopen_s(FILE **fp, const filename_t &filename, const filename_t &mode)
|
||||||
{
|
{
|
||||||
@ -152,17 +128,35 @@ SPDLOG_INLINE bool fopen_s(FILE **fp, const filename_t &filename, const filename
|
|||||||
#else
|
#else
|
||||||
*fp = ::_fsopen((filename.c_str()), mode.c_str(), _SH_DENYNO);
|
*fp = ::_fsopen((filename.c_str()), mode.c_str(), _SH_DENYNO);
|
||||||
#endif
|
#endif
|
||||||
#else // unix
|
#if defined(SPDLOG_PREVENT_CHILD_FD)
|
||||||
*fp = ::fopen((filename.c_str()), mode.c_str());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SPDLOG_PREVENT_CHILD_FD
|
|
||||||
// prevent child processes from inheriting log file descriptors
|
|
||||||
if (*fp != nullptr)
|
if (*fp != nullptr)
|
||||||
{
|
{
|
||||||
prevent_child_fd(*fp);
|
auto file_handle = reinterpret_cast<HANDLE>(_get_osfhandle(::_fileno(*fp)));
|
||||||
|
if (!::SetHandleInformation(file_handle, HANDLE_FLAG_INHERIT, 0))
|
||||||
|
{
|
||||||
|
::fclose(*fp);
|
||||||
|
*fp = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#else // unix
|
||||||
|
#if defined(SPDLOG_PREVENT_CHILD_FD)
|
||||||
|
const int mode_flag = mode == SPDLOG_FILENAME_T("ab") ? O_APPEND : O_TRUNC;
|
||||||
|
const int fd = ::open((filename.c_str()), O_CREAT | O_WRONLY | O_CLOEXEC | mode_flag, mode_t(0644));
|
||||||
|
if (fd == -1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*fp = ::fdopen(fd, mode.c_str());
|
||||||
|
if (*fp == nullptr)
|
||||||
|
{
|
||||||
|
::close(fd);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
*fp = ::fopen((filename.c_str()), mode.c_str());
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
return *fp == nullptr;
|
return *fp == nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,7 +204,7 @@ SPDLOG_INLINE size_t filesize(FILE *f)
|
|||||||
{
|
{
|
||||||
if (f == nullptr)
|
if (f == nullptr)
|
||||||
{
|
{
|
||||||
SPDLOG_THROW(spdlog_ex("Failed getting file size. fd is null"));
|
throw_spdlog_ex("Failed getting file size. fd is null");
|
||||||
}
|
}
|
||||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||||
int fd = ::_fileno(f);
|
int fd = ::_fileno(f);
|
||||||
@ -251,7 +245,8 @@ SPDLOG_INLINE size_t filesize(FILE *f)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
SPDLOG_THROW(spdlog_ex("Failed getting file size from fd", errno));
|
throw_spdlog_ex("Failed getting file size from fd", errno);
|
||||||
|
return 0; // will not be reached.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return utc offset in minutes or throw spdlog_ex on failure
|
// Return utc offset in minutes or throw spdlog_ex on failure
|
||||||
@ -267,7 +262,7 @@ SPDLOG_INLINE int utc_minutes_offset(const std::tm &tm)
|
|||||||
auto rv = ::GetDynamicTimeZoneInformation(&tzinfo);
|
auto rv = ::GetDynamicTimeZoneInformation(&tzinfo);
|
||||||
#endif
|
#endif
|
||||||
if (rv == TIME_ZONE_ID_INVALID)
|
if (rv == TIME_ZONE_ID_INVALID)
|
||||||
SPDLOG_THROW(spdlog::spdlog_ex("Failed getting timezone info. ", errno));
|
throw_spdlog_ex("Failed getting timezone info. ", errno);
|
||||||
|
|
||||||
int offset = -tzinfo.Bias;
|
int offset = -tzinfo.Bias;
|
||||||
if (tm.tm_isdst)
|
if (tm.tm_isdst)
|
||||||
@ -396,13 +391,13 @@ SPDLOG_INLINE int pid() SPDLOG_NOEXCEPT
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Determine if the terminal supports colors
|
// Determine if the terminal supports colors
|
||||||
// Source: https://github.com/agauniyal/rang/
|
// Based on: https://github.com/agauniyal/rang/
|
||||||
SPDLOG_INLINE bool is_color_terminal() SPDLOG_NOEXCEPT
|
SPDLOG_INLINE bool is_color_terminal() SPDLOG_NOEXCEPT
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
static constexpr std::array<const char *, 14> Terms = {
|
static constexpr std::array<const char *, 14> terms = {
|
||||||
{"ansi", "color", "console", "cygwin", "gnome", "konsole", "kterm", "linux", "msys", "putty", "rxvt", "screen", "vt100", "xterm"}};
|
{"ansi", "color", "console", "cygwin", "gnome", "konsole", "kterm", "linux", "msys", "putty", "rxvt", "screen", "vt100", "xterm"}};
|
||||||
|
|
||||||
const char *env_p = std::getenv("TERM");
|
const char *env_p = std::getenv("TERM");
|
||||||
@ -412,7 +407,7 @@ SPDLOG_INLINE bool is_color_terminal() SPDLOG_NOEXCEPT
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const bool result =
|
static const bool result =
|
||||||
std::any_of(std::begin(Terms), std::end(Terms), [&](const char *term) { return std::strstr(env_p, term) != nullptr; });
|
std::any_of(terms.begin(), terms.end(), [&](const char *term) { return std::strstr(env_p, term) != nullptr; });
|
||||||
return result;
|
return result;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -434,7 +429,7 @@ SPDLOG_INLINE void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target)
|
|||||||
{
|
{
|
||||||
if (wstr.size() > static_cast<size_t>((std::numeric_limits<int>::max)()))
|
if (wstr.size() > static_cast<size_t>((std::numeric_limits<int>::max)()))
|
||||||
{
|
{
|
||||||
SPDLOG_THROW(spdlog::spdlog_ex("UTF-16 string is too big to be converted to UTF-8"));
|
throw_spdlog_ex("UTF-16 string is too big to be converted to UTF-8");
|
||||||
}
|
}
|
||||||
|
|
||||||
int wstr_size = static_cast<int>(wstr.size());
|
int wstr_size = static_cast<int>(wstr.size());
|
||||||
@ -462,7 +457,7 @@ SPDLOG_INLINE void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_THROW(spdlog::spdlog_ex(fmt::format("WideCharToMultiByte failed. Last error: {}", ::GetLastError())));
|
throw_spdlog_ex(fmt::format("WideCharToMultiByte failed. Last error: {}", ::GetLastError()));
|
||||||
}
|
}
|
||||||
#endif // (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) && defined(_WIN32)
|
#endif // (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) && defined(_WIN32)
|
||||||
|
|
||||||
@ -536,6 +531,24 @@ SPDLOG_INLINE filename_t dir_name(filename_t path)
|
|||||||
return pos != filename_t::npos ? path.substr(0, pos) : filename_t{};
|
return pos != filename_t::npos ? path.substr(0, pos) : filename_t{};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string SPDLOG_INLINE getenv(const char *field)
|
||||||
|
{
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#if defined(__cplusplus_winrt)
|
||||||
|
return std::string{}; // not supported under uwp
|
||||||
|
#else
|
||||||
|
size_t len = 0;
|
||||||
|
char buf[128];
|
||||||
|
bool ok = ::getenv_s(&len, buf, sizeof(buf), field) == 0;
|
||||||
|
return ok ? buf : std::string{};
|
||||||
|
#endif
|
||||||
|
#else // revert to getenv
|
||||||
|
char *buf = ::getenv(field);
|
||||||
|
return buf ? buf : std::string{};
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace os
|
} // namespace os
|
||||||
} // namespace details
|
} // namespace details
|
||||||
} // namespace spdlog
|
} // namespace spdlog
|
||||||
|
50
third_party/spdlog/include/spdlog/details/os.h
vendored
50
third_party/spdlog/include/spdlog/details/os.h
vendored
@ -10,15 +10,15 @@ namespace spdlog {
|
|||||||
namespace details {
|
namespace details {
|
||||||
namespace os {
|
namespace os {
|
||||||
|
|
||||||
spdlog::log_clock::time_point now() SPDLOG_NOEXCEPT;
|
SPDLOG_API spdlog::log_clock::time_point now() SPDLOG_NOEXCEPT;
|
||||||
|
|
||||||
std::tm localtime(const std::time_t &time_tt) SPDLOG_NOEXCEPT;
|
SPDLOG_API std::tm localtime(const std::time_t &time_tt) SPDLOG_NOEXCEPT;
|
||||||
|
|
||||||
std::tm localtime() SPDLOG_NOEXCEPT;
|
SPDLOG_API std::tm localtime() SPDLOG_NOEXCEPT;
|
||||||
|
|
||||||
std::tm gmtime(const std::time_t &time_tt) SPDLOG_NOEXCEPT;
|
SPDLOG_API std::tm gmtime(const std::time_t &time_tt) SPDLOG_NOEXCEPT;
|
||||||
|
|
||||||
std::tm gmtime() SPDLOG_NOEXCEPT;
|
SPDLOG_API std::tm gmtime() SPDLOG_NOEXCEPT;
|
||||||
|
|
||||||
// eol definition
|
// eol definition
|
||||||
#if !defined(SPDLOG_EOL)
|
#if !defined(SPDLOG_EOL)
|
||||||
@ -38,54 +38,50 @@ static const char folder_sep = '\\';
|
|||||||
SPDLOG_CONSTEXPR static const char folder_sep = '/';
|
SPDLOG_CONSTEXPR static const char folder_sep = '/';
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SPDLOG_PREVENT_CHILD_FD
|
|
||||||
void prevent_child_fd(FILE *f);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// fopen_s on non windows for writing
|
// fopen_s on non windows for writing
|
||||||
bool fopen_s(FILE **fp, const filename_t &filename, const filename_t &mode);
|
SPDLOG_API bool fopen_s(FILE **fp, const filename_t &filename, const filename_t &mode);
|
||||||
|
|
||||||
// Remove filename. return 0 on success
|
// Remove filename. return 0 on success
|
||||||
int remove(const filename_t &filename) SPDLOG_NOEXCEPT;
|
SPDLOG_API int remove(const filename_t &filename) SPDLOG_NOEXCEPT;
|
||||||
|
|
||||||
// Remove file if exists. return 0 on success
|
// Remove file if exists. return 0 on success
|
||||||
// Note: Non atomic (might return failure to delete if concurrently deleted by other process/thread)
|
// Note: Non atomic (might return failure to delete if concurrently deleted by other process/thread)
|
||||||
int remove_if_exists(const filename_t &filename) SPDLOG_NOEXCEPT;
|
SPDLOG_API int remove_if_exists(const filename_t &filename) SPDLOG_NOEXCEPT;
|
||||||
|
|
||||||
int rename(const filename_t &filename1, const filename_t &filename2) SPDLOG_NOEXCEPT;
|
SPDLOG_API int rename(const filename_t &filename1, const filename_t &filename2) SPDLOG_NOEXCEPT;
|
||||||
|
|
||||||
// Return if file exists.
|
// Return if file exists.
|
||||||
bool path_exists(const filename_t &filename) SPDLOG_NOEXCEPT;
|
SPDLOG_API bool path_exists(const filename_t &filename) SPDLOG_NOEXCEPT;
|
||||||
|
|
||||||
// Return file size according to open FILE* object
|
// Return file size according to open FILE* object
|
||||||
size_t filesize(FILE *f);
|
SPDLOG_API size_t filesize(FILE *f);
|
||||||
|
|
||||||
// Return utc offset in minutes or throw spdlog_ex on failure
|
// Return utc offset in minutes or throw spdlog_ex on failure
|
||||||
int utc_minutes_offset(const std::tm &tm = details::os::localtime());
|
SPDLOG_API int utc_minutes_offset(const std::tm &tm = details::os::localtime());
|
||||||
|
|
||||||
// Return current thread id as size_t
|
// Return current thread id as size_t
|
||||||
// It exists because the std::this_thread::get_id() is much slower(especially
|
// It exists because the std::this_thread::get_id() is much slower(especially
|
||||||
// under VS 2013)
|
// under VS 2013)
|
||||||
size_t _thread_id() SPDLOG_NOEXCEPT;
|
SPDLOG_API size_t _thread_id() SPDLOG_NOEXCEPT;
|
||||||
|
|
||||||
// Return current thread id as size_t (from thread local storage)
|
// Return current thread id as size_t (from thread local storage)
|
||||||
size_t thread_id() SPDLOG_NOEXCEPT;
|
SPDLOG_API size_t thread_id() SPDLOG_NOEXCEPT;
|
||||||
|
|
||||||
// This is avoid msvc issue in sleep_for that happens if the clock changes.
|
// This is avoid msvc issue in sleep_for that happens if the clock changes.
|
||||||
// See https://github.com/gabime/spdlog/issues/609
|
// See https://github.com/gabime/spdlog/issues/609
|
||||||
void sleep_for_millis(int milliseconds) SPDLOG_NOEXCEPT;
|
SPDLOG_API void sleep_for_millis(int milliseconds) SPDLOG_NOEXCEPT;
|
||||||
|
|
||||||
std::string filename_to_str(const filename_t &filename);
|
SPDLOG_API std::string filename_to_str(const filename_t &filename);
|
||||||
|
|
||||||
int pid() SPDLOG_NOEXCEPT;
|
SPDLOG_API int pid() SPDLOG_NOEXCEPT;
|
||||||
|
|
||||||
// Determine if the terminal supports colors
|
// Determine if the terminal supports colors
|
||||||
// Source: https://github.com/agauniyal/rang/
|
// Source: https://github.com/agauniyal/rang/
|
||||||
bool is_color_terminal() SPDLOG_NOEXCEPT;
|
SPDLOG_API bool is_color_terminal() SPDLOG_NOEXCEPT;
|
||||||
|
|
||||||
// Determine if the terminal attached
|
// Determine if the terminal attached
|
||||||
// Source: https://github.com/agauniyal/rang/
|
// Source: https://github.com/agauniyal/rang/
|
||||||
bool in_terminal(FILE *file) SPDLOG_NOEXCEPT;
|
SPDLOG_API bool in_terminal(FILE *file) SPDLOG_NOEXCEPT;
|
||||||
|
|
||||||
#if (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) && defined(_WIN32)
|
#if (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) && defined(_WIN32)
|
||||||
void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target);
|
void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target);
|
||||||
@ -96,11 +92,15 @@ void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target);
|
|||||||
// "abc/" => "abc"
|
// "abc/" => "abc"
|
||||||
// "abc" => ""
|
// "abc" => ""
|
||||||
// "abc///" => "abc//"
|
// "abc///" => "abc//"
|
||||||
filename_t dir_name(filename_t path);
|
SPDLOG_API filename_t dir_name(filename_t path);
|
||||||
|
|
||||||
// Create a dir from the given path.
|
// Create a dir from the given path.
|
||||||
// Return true if succeeded or if this dir already exists.
|
// Return true if succeeded or if this dir already exists.
|
||||||
bool create_dir(filename_t path);
|
SPDLOG_API bool create_dir(filename_t path);
|
||||||
|
|
||||||
|
// non thread safe, cross platform getenv/getenv_s
|
||||||
|
// return empty string if field not found
|
||||||
|
SPDLOG_API std::string getenv(const char *field);
|
||||||
|
|
||||||
} // namespace os
|
} // namespace os
|
||||||
} // namespace details
|
} // namespace details
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
namespace spdlog {
|
namespace spdlog {
|
||||||
namespace details {
|
namespace details {
|
||||||
|
|
||||||
class periodic_worker
|
class SPDLOG_API periodic_worker
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
periodic_worker(const std::function<void()> &callback_fun, std::chrono::seconds interval);
|
periodic_worker(const std::function<void()> &callback_fun, std::chrono::seconds interval);
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#include <spdlog/common.h>
|
#include <spdlog/common.h>
|
||||||
#include <spdlog/details/periodic_worker.h>
|
#include <spdlog/details/periodic_worker.h>
|
||||||
#include <spdlog/logger.h>
|
#include <spdlog/logger.h>
|
||||||
#include <spdlog/details/pattern_formatter.h>
|
#include <spdlog/pattern_formatter.h>
|
||||||
|
|
||||||
#ifndef SPDLOG_DISABLE_DEFAULT_LOGGER
|
#ifndef SPDLOG_DISABLE_DEFAULT_LOGGER
|
||||||
// support for the default stdout color logger
|
// support for the default stdout color logger
|
||||||
@ -48,6 +48,9 @@ SPDLOG_INLINE registry::registry()
|
|||||||
|
|
||||||
#endif // SPDLOG_DISABLE_DEFAULT_LOGGER
|
#endif // SPDLOG_DISABLE_DEFAULT_LOGGER
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SPDLOG_INLINE registry::~registry() = default;
|
||||||
|
|
||||||
SPDLOG_INLINE void registry::register_logger(std::shared_ptr<logger> new_logger)
|
SPDLOG_INLINE void registry::register_logger(std::shared_ptr<logger> new_logger)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||||
@ -64,7 +67,7 @@ SPDLOG_INLINE void registry::initialize_logger(std::shared_ptr<logger> new_logge
|
|||||||
new_logger->set_error_handler(err_handler_);
|
new_logger->set_error_handler(err_handler_);
|
||||||
}
|
}
|
||||||
|
|
||||||
new_logger->set_level(level_);
|
new_logger->set_level(levels_.get(new_logger->name()));
|
||||||
new_logger->flush_on(flush_level_);
|
new_logger->flush_on(flush_level_);
|
||||||
|
|
||||||
if (backtrace_n_messages_ > 0)
|
if (backtrace_n_messages_ > 0)
|
||||||
@ -168,7 +171,7 @@ SPDLOG_INLINE void registry::set_level(level::level_enum log_level)
|
|||||||
{
|
{
|
||||||
l.second->set_level(log_level);
|
l.second->set_level(log_level);
|
||||||
}
|
}
|
||||||
level_ = log_level;
|
levels_.set_default(log_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_INLINE void registry::flush_on(level::level_enum log_level)
|
SPDLOG_INLINE void registry::flush_on(level::level_enum log_level)
|
||||||
@ -184,7 +187,7 @@ SPDLOG_INLINE void registry::flush_on(level::level_enum log_level)
|
|||||||
SPDLOG_INLINE void registry::flush_every(std::chrono::seconds interval)
|
SPDLOG_INLINE void registry::flush_every(std::chrono::seconds interval)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(flusher_mutex_);
|
std::lock_guard<std::mutex> lock(flusher_mutex_);
|
||||||
std::function<void()> clbk = std::bind(®istry::flush_all, this);
|
auto clbk = [this]() { this->flush_all(); };
|
||||||
periodic_flusher_ = details::make_unique<periodic_worker>(clbk, interval);
|
periodic_flusher_ = details::make_unique<periodic_worker>(clbk, interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,6 +263,17 @@ SPDLOG_INLINE void registry::set_automatic_registration(bool automatic_registrat
|
|||||||
automatic_registration_ = automatic_registration;
|
automatic_registration_ = automatic_registration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SPDLOG_INLINE void registry::update_levels(cfg::log_levels levels)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||||
|
levels_ = std::move(levels);
|
||||||
|
for (auto &l : loggers_)
|
||||||
|
{
|
||||||
|
auto &logger = l.second;
|
||||||
|
logger->set_level(levels_.get(logger->name()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SPDLOG_INLINE registry ®istry::instance()
|
SPDLOG_INLINE registry ®istry::instance()
|
||||||
{
|
{
|
||||||
static registry s_instance;
|
static registry s_instance;
|
||||||
@ -270,7 +284,7 @@ SPDLOG_INLINE void registry::throw_if_exists_(const std::string &logger_name)
|
|||||||
{
|
{
|
||||||
if (loggers_.find(logger_name) != loggers_.end())
|
if (loggers_.find(logger_name) != loggers_.end())
|
||||||
{
|
{
|
||||||
SPDLOG_THROW(spdlog_ex("logger with name '" + logger_name + "' already exists"));
|
throw_spdlog_ex("logger with name '" + logger_name + "' already exists");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,5 +294,6 @@ SPDLOG_INLINE void registry::register_logger_(std::shared_ptr<logger> new_logger
|
|||||||
throw_if_exists_(logger_name);
|
throw_if_exists_(logger_name);
|
||||||
loggers_[logger_name] = std::move(new_logger);
|
loggers_[logger_name] = std::move(new_logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace details
|
} // namespace details
|
||||||
} // namespace spdlog
|
} // namespace spdlog
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
// This class is thread safe
|
// This class is thread safe
|
||||||
|
|
||||||
#include <spdlog/common.h>
|
#include <spdlog/common.h>
|
||||||
|
#include <spdlog/cfg/log_levels.h>
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
@ -24,7 +25,7 @@ namespace details {
|
|||||||
class thread_pool;
|
class thread_pool;
|
||||||
class periodic_worker;
|
class periodic_worker;
|
||||||
|
|
||||||
class registry
|
class SPDLOG_API registry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
registry(const registry &) = delete;
|
registry(const registry &) = delete;
|
||||||
@ -79,19 +80,21 @@ public:
|
|||||||
|
|
||||||
void set_automatic_registration(bool automatic_registration);
|
void set_automatic_registration(bool automatic_registration);
|
||||||
|
|
||||||
|
void update_levels(cfg::log_levels levels);
|
||||||
|
|
||||||
static registry &instance();
|
static registry &instance();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
registry();
|
registry();
|
||||||
~registry() = default;
|
~registry();
|
||||||
|
|
||||||
void throw_if_exists_(const std::string &logger_name);
|
void throw_if_exists_(const std::string &logger_name);
|
||||||
void register_logger_(std::shared_ptr<logger> new_logger);
|
void register_logger_(std::shared_ptr<logger> new_logger);
|
||||||
std::mutex logger_map_mutex_, flusher_mutex_;
|
std::mutex logger_map_mutex_, flusher_mutex_;
|
||||||
std::recursive_mutex tp_mutex_;
|
std::recursive_mutex tp_mutex_;
|
||||||
std::unordered_map<std::string, std::shared_ptr<logger>> loggers_;
|
std::unordered_map<std::string, std::shared_ptr<logger>> loggers_;
|
||||||
|
cfg::log_levels levels_;
|
||||||
std::unique_ptr<formatter> formatter_;
|
std::unique_ptr<formatter> formatter_;
|
||||||
level::level_enum level_ = level::info;
|
|
||||||
level::level_enum flush_level_ = level::off;
|
level::level_enum flush_level_ = level::off;
|
||||||
void (*err_handler_)(const std::string &msg);
|
void (*err_handler_)(const std::string &msg);
|
||||||
std::shared_ptr<thread_pool> tp_;
|
std::shared_ptr<thread_pool> tp_;
|
||||||
|
175
third_party/spdlog/include/spdlog/details/tcp_client-windows.h
vendored
Normal file
175
third_party/spdlog/include/spdlog/details/tcp_client-windows.h
vendored
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||||
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
// tcp client helper
|
||||||
|
#include <spdlog/common.h>
|
||||||
|
#include <spdlog/details/os.h>
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#pragma comment(lib, "Ws2_32.lib")
|
||||||
|
#pragma comment(lib, "Mswsock.lib")
|
||||||
|
#pragma comment(lib, "AdvApi32.lib")
|
||||||
|
|
||||||
|
namespace spdlog {
|
||||||
|
namespace details {
|
||||||
|
class tcp_client
|
||||||
|
{
|
||||||
|
SOCKET socket_ = INVALID_SOCKET;
|
||||||
|
|
||||||
|
static bool winsock_initialized_()
|
||||||
|
{
|
||||||
|
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
if (s == INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
closesocket(s);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init_winsock_()
|
||||||
|
{
|
||||||
|
WSADATA wsaData;
|
||||||
|
auto rv = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||||
|
if (rv != 0)
|
||||||
|
{
|
||||||
|
throw_winsock_error_("WSAStartup failed", ::WSAGetLastError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void throw_winsock_error_(const std::string &msg, int last_error)
|
||||||
|
{
|
||||||
|
char buf[512];
|
||||||
|
::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, last_error,
|
||||||
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, (sizeof(buf) / sizeof(char)), NULL);
|
||||||
|
|
||||||
|
throw_spdlog_ex(fmt::format("tcp_sink - {}: {}", msg, buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool is_connected() const
|
||||||
|
{
|
||||||
|
return socket_ != INVALID_SOCKET;
|
||||||
|
}
|
||||||
|
|
||||||
|
void close()
|
||||||
|
{
|
||||||
|
::closesocket(socket_);
|
||||||
|
socket_ = INVALID_SOCKET;
|
||||||
|
WSACleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
SOCKET fd() const
|
||||||
|
{
|
||||||
|
return socket_;
|
||||||
|
}
|
||||||
|
|
||||||
|
~tcp_client()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to connect or throw on failure
|
||||||
|
void connect(const std::string &host, int port)
|
||||||
|
{
|
||||||
|
// initialize winsock if needed
|
||||||
|
if (!winsock_initialized_())
|
||||||
|
{
|
||||||
|
init_winsock_();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_connected())
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
struct addrinfo hints
|
||||||
|
{};
|
||||||
|
ZeroMemory(&hints, sizeof(hints));
|
||||||
|
|
||||||
|
hints.ai_family = AF_INET; // IPv4
|
||||||
|
hints.ai_socktype = SOCK_STREAM; // TCP
|
||||||
|
hints.ai_flags = AI_NUMERICSERV; // port passed as as numeric value
|
||||||
|
hints.ai_protocol = 0;
|
||||||
|
|
||||||
|
auto port_str = std::to_string(port);
|
||||||
|
struct addrinfo *addrinfo_result;
|
||||||
|
auto rv = ::getaddrinfo(host.c_str(), port_str.c_str(), &hints, &addrinfo_result);
|
||||||
|
int last_error = 0;
|
||||||
|
if (rv != 0)
|
||||||
|
{
|
||||||
|
last_error = ::WSAGetLastError();
|
||||||
|
WSACleanup();
|
||||||
|
throw_winsock_error_("getaddrinfo failed", last_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try each address until we successfully connect(2).
|
||||||
|
|
||||||
|
for (auto *rp = addrinfo_result; rp != nullptr; rp = rp->ai_next)
|
||||||
|
{
|
||||||
|
socket_ = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
|
||||||
|
if (socket_ == INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
last_error = ::WSAGetLastError();
|
||||||
|
WSACleanup();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (::connect(socket_, rp->ai_addr, (int)rp->ai_addrlen) == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
last_error = ::WSAGetLastError();
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
::freeaddrinfo(addrinfo_result);
|
||||||
|
if (socket_ == INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
WSACleanup();
|
||||||
|
throw_winsock_error_("connect failed", last_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set TCP_NODELAY
|
||||||
|
int enable_flag = 1;
|
||||||
|
::setsockopt(socket_, IPPROTO_TCP, TCP_NODELAY, (char *)&enable_flag, sizeof(enable_flag));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send exactly n_bytes of the given data.
|
||||||
|
// On error close the connection and throw.
|
||||||
|
void send(const char *data, size_t n_bytes)
|
||||||
|
{
|
||||||
|
size_t bytes_sent = 0;
|
||||||
|
while (bytes_sent < n_bytes)
|
||||||
|
{
|
||||||
|
const int send_flags = 0;
|
||||||
|
auto write_result = ::send(socket_, data + bytes_sent, (int)(n_bytes - bytes_sent), send_flags);
|
||||||
|
if (write_result == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
int last_error = ::WSAGetLastError();
|
||||||
|
close();
|
||||||
|
throw_winsock_error_("send failed", last_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (write_result == 0) // (probably should not happen but in any case..)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bytes_sent += static_cast<size_t>(write_result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace details
|
||||||
|
} // namespace spdlog
|
145
third_party/spdlog/include/spdlog/details/tcp_client.h
vendored
Normal file
145
third_party/spdlog/include/spdlog/details/tcp_client.h
vendored
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||||
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#error include tcp_client-windows.h instead
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// tcp client helper
|
||||||
|
#include <spdlog/common.h>
|
||||||
|
#include <spdlog/details/os.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace spdlog {
|
||||||
|
namespace details {
|
||||||
|
class tcp_client
|
||||||
|
{
|
||||||
|
int socket_ = -1;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool is_connected() const
|
||||||
|
{
|
||||||
|
return socket_ != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void close()
|
||||||
|
{
|
||||||
|
if (is_connected())
|
||||||
|
{
|
||||||
|
::close(socket_);
|
||||||
|
socket_ = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int fd() const
|
||||||
|
{
|
||||||
|
return socket_;
|
||||||
|
}
|
||||||
|
|
||||||
|
~tcp_client()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to connect or throw on failure
|
||||||
|
void connect(const std::string &host, int port)
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
struct addrinfo hints
|
||||||
|
{};
|
||||||
|
memset(&hints, 0, sizeof(struct addrinfo));
|
||||||
|
hints.ai_family = AF_INET; // IPv4
|
||||||
|
hints.ai_socktype = SOCK_STREAM; // TCP
|
||||||
|
hints.ai_flags = AI_NUMERICSERV; // port passed as as numeric value
|
||||||
|
hints.ai_protocol = 0;
|
||||||
|
|
||||||
|
auto port_str = std::to_string(port);
|
||||||
|
struct addrinfo *addrinfo_result;
|
||||||
|
auto rv = ::getaddrinfo(host.c_str(), port_str.c_str(), &hints, &addrinfo_result);
|
||||||
|
if (rv != 0)
|
||||||
|
{
|
||||||
|
auto msg = fmt::format("::getaddrinfo failed: {}", gai_strerror(rv));
|
||||||
|
throw_spdlog_ex(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try each address until we successfully connect(2).
|
||||||
|
int last_errno = 0;
|
||||||
|
for (auto *rp = addrinfo_result; rp != nullptr; rp = rp->ai_next)
|
||||||
|
{
|
||||||
|
int const flags = SOCK_CLOEXEC;
|
||||||
|
socket_ = ::socket(rp->ai_family, rp->ai_socktype | flags, rp->ai_protocol);
|
||||||
|
if (socket_ == -1)
|
||||||
|
{
|
||||||
|
last_errno = errno;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
rv = ::connect(socket_, rp->ai_addr, rp->ai_addrlen);
|
||||||
|
if (rv == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
last_errno = errno;
|
||||||
|
::close(socket_);
|
||||||
|
socket_ = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
::freeaddrinfo(addrinfo_result);
|
||||||
|
if (socket_ == -1)
|
||||||
|
{
|
||||||
|
throw_spdlog_ex("::connect failed", last_errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set TCP_NODELAY
|
||||||
|
int enable_flag = 1;
|
||||||
|
::setsockopt(socket_, IPPROTO_TCP, TCP_NODELAY, (char *)&enable_flag, sizeof(enable_flag));
|
||||||
|
|
||||||
|
// prevent sigpipe on systems where MSG_NOSIGNAL is not available
|
||||||
|
#if defined(SO_NOSIGPIPE) && !defined(MSG_NOSIGNAL)
|
||||||
|
::setsockopt(socket_, SOL_SOCKET, SO_NOSIGPIPE, (char *)&enable_flag, sizeof(enable_flag));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(SO_NOSIGPIPE) && !defined(MSG_NOSIGNAL)
|
||||||
|
#error "tcp_sink would raise SIGPIPE since niether SO_NOSIGPIPE nor MSG_NOSIGNAL are available"
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send exactly n_bytes of the given data.
|
||||||
|
// On error close the connection and throw.
|
||||||
|
void send(const char *data, size_t n_bytes)
|
||||||
|
{
|
||||||
|
size_t bytes_sent = 0;
|
||||||
|
while (bytes_sent < n_bytes)
|
||||||
|
{
|
||||||
|
#if defined(MSG_NOSIGNAL)
|
||||||
|
const int send_flags = MSG_NOSIGNAL;
|
||||||
|
#else
|
||||||
|
const int send_flags = 0;
|
||||||
|
#endif
|
||||||
|
auto write_result = ::send(socket_, data + bytes_sent, n_bytes - bytes_sent, send_flags);
|
||||||
|
if (write_result < 0)
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
throw_spdlog_ex("write(2) failed", errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (write_result == 0) // (probably should not happen but in any case..)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bytes_sent += static_cast<size_t>(write_result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace details
|
||||||
|
} // namespace spdlog
|
@ -18,8 +18,8 @@ SPDLOG_INLINE thread_pool::thread_pool(size_t q_max_items, size_t threads_n, std
|
|||||||
{
|
{
|
||||||
if (threads_n == 0 || threads_n > 1000)
|
if (threads_n == 0 || threads_n > 1000)
|
||||||
{
|
{
|
||||||
SPDLOG_THROW(spdlog_ex("spdlog::thread_pool(): invalid threads_n param (valid "
|
throw_spdlog_ex("spdlog::thread_pool(): invalid threads_n param (valid "
|
||||||
"range is 1-1000)"));
|
"range is 1-1000)");
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < threads_n; i++)
|
for (size_t i = 0; i < threads_n; i++)
|
||||||
{
|
{
|
||||||
@ -113,7 +113,7 @@ bool SPDLOG_INLINE thread_pool::process_next_msg_()
|
|||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
assert(false && "Unexpected async_msg_type");
|
assert(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ struct async_msg : log_msg_buffer
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
class thread_pool
|
class SPDLOG_API thread_pool
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using item_type = async_msg;
|
using item_type = async_msg;
|
||||||
|
11
third_party/spdlog/include/spdlog/details/windows_include.h
vendored
Normal file
11
third_party/spdlog/include/spdlog/details/windows_include.h
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NOMINMAX
|
||||||
|
#define NOMINMAX // prevent windows redefining min/max
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <windows.h>
|
101
third_party/spdlog/include/spdlog/fmt/bin_to_hex.h
vendored
101
third_party/spdlog/include/spdlog/fmt/bin_to_hex.h
vendored
@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
//
|
//
|
||||||
// Support for logging binary data as hex
|
// Support for logging binary data as hex
|
||||||
// format flags:
|
// format flags:
|
||||||
@ -12,6 +14,7 @@
|
|||||||
// {:s} - don't separate each byte with space.
|
// {:s} - don't separate each byte with space.
|
||||||
// {:p} - don't print the position on each line start.
|
// {:p} - don't print the position on each line start.
|
||||||
// {:n} - don't split the output to lines.
|
// {:n} - don't split the output to lines.
|
||||||
|
// {:a} - show ASCII if :n is not set
|
||||||
|
|
||||||
//
|
//
|
||||||
// Examples:
|
// Examples:
|
||||||
@ -20,17 +23,19 @@
|
|||||||
// logger->info("Some buffer {}", spdlog::to_hex(v));
|
// logger->info("Some buffer {}", spdlog::to_hex(v));
|
||||||
// char buf[128];
|
// char buf[128];
|
||||||
// logger->info("Some buffer {:X}", spdlog::to_hex(std::begin(buf), std::end(buf)));
|
// logger->info("Some buffer {:X}", spdlog::to_hex(std::begin(buf), std::end(buf)));
|
||||||
|
// logger->info("Some buffer {:X}", spdlog::to_hex(std::begin(buf), std::end(buf), 16));
|
||||||
|
|
||||||
namespace spdlog {
|
namespace spdlog {
|
||||||
namespace details {
|
namespace details {
|
||||||
|
|
||||||
template<typename It>
|
template<typename It>
|
||||||
class bytes_range
|
class dump_info
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bytes_range(It range_begin, It range_end)
|
dump_info(It range_begin, It range_end, size_t size_per_line)
|
||||||
: begin_(range_begin)
|
: begin_(range_begin)
|
||||||
, end_(range_end)
|
, end_(range_end)
|
||||||
|
, size_per_line_(size_per_line)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
It begin() const
|
It begin() const
|
||||||
@ -41,26 +46,31 @@ public:
|
|||||||
{
|
{
|
||||||
return end_;
|
return end_;
|
||||||
}
|
}
|
||||||
|
size_t size_per_line() const
|
||||||
|
{
|
||||||
|
return size_per_line_;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
It begin_, end_;
|
It begin_, end_;
|
||||||
|
size_t size_per_line_;
|
||||||
};
|
};
|
||||||
} // namespace details
|
} // namespace details
|
||||||
|
|
||||||
// create a bytes_range that wraps the given container
|
// create a dump_info that wraps the given container
|
||||||
template<typename Container>
|
template<typename Container>
|
||||||
inline details::bytes_range<typename Container::const_iterator> to_hex(const Container &container)
|
inline details::dump_info<typename Container::const_iterator> to_hex(const Container &container, size_t size_per_line = 32)
|
||||||
{
|
{
|
||||||
static_assert(sizeof(typename Container::value_type) == 1, "sizeof(Container::value_type) != 1");
|
static_assert(sizeof(typename Container::value_type) == 1, "sizeof(Container::value_type) != 1");
|
||||||
using Iter = typename Container::const_iterator;
|
using Iter = typename Container::const_iterator;
|
||||||
return details::bytes_range<Iter>(std::begin(container), std::end(container));
|
return details::dump_info<Iter>(std::begin(container), std::end(container), size_per_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create bytes_range from ranges
|
// create dump_info from ranges
|
||||||
template<typename It>
|
template<typename It>
|
||||||
inline details::bytes_range<It> to_hex(const It range_begin, const It range_end)
|
inline details::dump_info<It> to_hex(const It range_begin, const It range_end, size_t size_per_line = 32)
|
||||||
{
|
{
|
||||||
return details::bytes_range<It>(range_begin, range_end);
|
return details::dump_info<It>(range_begin, range_end, size_per_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace spdlog
|
} // namespace spdlog
|
||||||
@ -68,15 +78,14 @@ inline details::bytes_range<It> to_hex(const It range_begin, const It range_end)
|
|||||||
namespace fmt {
|
namespace fmt {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct formatter<spdlog::details::bytes_range<T>>
|
struct formatter<spdlog::details::dump_info<T>>
|
||||||
{
|
{
|
||||||
const std::size_t line_size = 100;
|
|
||||||
const char delimiter = ' ';
|
const char delimiter = ' ';
|
||||||
|
|
||||||
bool put_newlines = true;
|
bool put_newlines = true;
|
||||||
bool put_delimiters = true;
|
bool put_delimiters = true;
|
||||||
bool use_uppercase = false;
|
bool use_uppercase = false;
|
||||||
bool put_positions = true; // position on start of each line
|
bool put_positions = true; // position on start of each line
|
||||||
|
bool show_ascii = false;
|
||||||
|
|
||||||
// parse the format string flags
|
// parse the format string flags
|
||||||
template<typename ParseContext>
|
template<typename ParseContext>
|
||||||
@ -98,6 +107,13 @@ struct formatter<spdlog::details::bytes_range<T>>
|
|||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
put_newlines = false;
|
put_newlines = false;
|
||||||
|
show_ascii = false;
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
if (put_newlines)
|
||||||
|
{
|
||||||
|
show_ascii = true;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,53 +124,83 @@ struct formatter<spdlog::details::bytes_range<T>>
|
|||||||
|
|
||||||
// format the given bytes range as hex
|
// format the given bytes range as hex
|
||||||
template<typename FormatContext, typename Container>
|
template<typename FormatContext, typename Container>
|
||||||
auto format(const spdlog::details::bytes_range<Container> &the_range, FormatContext &ctx) -> decltype(ctx.out())
|
auto format(const spdlog::details::dump_info<Container> &the_range, FormatContext &ctx) -> decltype(ctx.out())
|
||||||
{
|
{
|
||||||
SPDLOG_CONSTEXPR const char *hex_upper = "0123456789ABCDEF";
|
SPDLOG_CONSTEXPR const char *hex_upper = "0123456789ABCDEF";
|
||||||
SPDLOG_CONSTEXPR const char *hex_lower = "0123456789abcdef";
|
SPDLOG_CONSTEXPR const char *hex_lower = "0123456789abcdef";
|
||||||
const char *hex_chars = use_uppercase ? hex_upper : hex_lower;
|
const char *hex_chars = use_uppercase ? hex_upper : hex_lower;
|
||||||
|
|
||||||
std::size_t pos = 0;
|
|
||||||
std::size_t column = line_size;
|
|
||||||
#if FMT_VERSION < 60000
|
#if FMT_VERSION < 60000
|
||||||
auto inserter = ctx.begin();
|
auto inserter = ctx.begin();
|
||||||
#else
|
#else
|
||||||
auto inserter = ctx.out();
|
auto inserter = ctx.out();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (auto &item : the_range)
|
int size_per_line = static_cast<int>(the_range.size_per_line());
|
||||||
|
auto start_of_line = the_range.begin();
|
||||||
|
for (auto i = the_range.begin(); i != the_range.end(); i++)
|
||||||
{
|
{
|
||||||
auto ch = static_cast<unsigned char>(item);
|
auto ch = static_cast<unsigned char>(*i);
|
||||||
pos++;
|
|
||||||
|
|
||||||
if (put_newlines && column >= line_size)
|
if (put_newlines && (i == the_range.begin() || i - start_of_line >= size_per_line))
|
||||||
{
|
{
|
||||||
column = put_newline(inserter, pos);
|
if (show_ascii && i != the_range.begin())
|
||||||
|
{
|
||||||
|
*inserter++ = delimiter;
|
||||||
|
*inserter++ = delimiter;
|
||||||
|
for (auto j = start_of_line; j < i; j++)
|
||||||
|
{
|
||||||
|
auto pc = static_cast<unsigned char>(*j);
|
||||||
|
*inserter++ = std::isprint(pc) ? static_cast<char>(*j) : '.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
put_newline(inserter, static_cast<size_t>(i - the_range.begin()));
|
||||||
|
|
||||||
// put first byte without delimiter in front of it
|
// put first byte without delimiter in front of it
|
||||||
*inserter++ = hex_chars[(ch >> 4) & 0x0f];
|
*inserter++ = hex_chars[(ch >> 4) & 0x0f];
|
||||||
*inserter++ = hex_chars[ch & 0x0f];
|
*inserter++ = hex_chars[ch & 0x0f];
|
||||||
column += 2;
|
start_of_line = i;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (put_delimiters)
|
if (put_delimiters)
|
||||||
{
|
{
|
||||||
*inserter++ = delimiter;
|
*inserter++ = delimiter;
|
||||||
++column;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*inserter++ = hex_chars[(ch >> 4) & 0x0f];
|
*inserter++ = hex_chars[(ch >> 4) & 0x0f];
|
||||||
*inserter++ = hex_chars[ch & 0x0f];
|
*inserter++ = hex_chars[ch & 0x0f];
|
||||||
column += 2;
|
}
|
||||||
|
if (show_ascii) // add ascii to last line
|
||||||
|
{
|
||||||
|
if (the_range.end() - the_range.begin() > size_per_line)
|
||||||
|
{
|
||||||
|
auto blank_num = size_per_line - (the_range.end() - start_of_line);
|
||||||
|
while (blank_num-- > 0)
|
||||||
|
{
|
||||||
|
*inserter++ = delimiter;
|
||||||
|
*inserter++ = delimiter;
|
||||||
|
if (put_delimiters)
|
||||||
|
{
|
||||||
|
*inserter++ = delimiter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*inserter++ = delimiter;
|
||||||
|
*inserter++ = delimiter;
|
||||||
|
for (auto j = start_of_line; j != the_range.end(); j++)
|
||||||
|
{
|
||||||
|
auto pc = static_cast<unsigned char>(*j);
|
||||||
|
*inserter++ = std::isprint(pc) ? static_cast<char>(*j) : '.';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return inserter;
|
return inserter;
|
||||||
}
|
}
|
||||||
|
|
||||||
// put newline(and position header)
|
// put newline(and position header)
|
||||||
// return the next column
|
|
||||||
template<typename It>
|
template<typename It>
|
||||||
std::size_t put_newline(It inserter, std::size_t pos)
|
void put_newline(It inserter, std::size_t pos)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
*inserter++ = '\r';
|
*inserter++ = '\r';
|
||||||
@ -163,12 +209,7 @@ struct formatter<spdlog::details::bytes_range<T>>
|
|||||||
|
|
||||||
if (put_positions)
|
if (put_positions)
|
||||||
{
|
{
|
||||||
fmt::format_to(inserter, "{:<04X}: ", pos - 1);
|
fmt::format_to(inserter, "{:<04X}: ", pos);
|
||||||
return 7;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -696,7 +696,7 @@ inline int to_nonnegative_int(T value, int upper) {
|
|||||||
|
|
||||||
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
|
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
|
||||||
inline T mod(T x, int y) {
|
inline T mod(T x, int y) {
|
||||||
return x % y;
|
return x % static_cast<T>(y);
|
||||||
}
|
}
|
||||||
template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
|
template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
|
||||||
inline T mod(T x, int y) {
|
inline T mod(T x, int y) {
|
||||||
@ -793,7 +793,10 @@ struct chrono_formatter {
|
|||||||
|
|
||||||
explicit chrono_formatter(FormatContext& ctx, OutputIt o,
|
explicit chrono_formatter(FormatContext& ctx, OutputIt o,
|
||||||
std::chrono::duration<Rep, Period> d)
|
std::chrono::duration<Rep, Period> d)
|
||||||
: context(ctx), out(o), val(d.count()), negative(false) {
|
: context(ctx),
|
||||||
|
out(o),
|
||||||
|
val(static_cast<rep>(d.count())),
|
||||||
|
negative(false) {
|
||||||
if (d.count() < 0) {
|
if (d.count() < 0) {
|
||||||
val = 0 - val;
|
val = 0 - val;
|
||||||
negative = true;
|
negative = true;
|
||||||
@ -1023,8 +1026,8 @@ struct formatter<std::chrono::duration<Rep, Period>, Char> {
|
|||||||
void on_error(const char* msg) { FMT_THROW(format_error(msg)); }
|
void on_error(const char* msg) { FMT_THROW(format_error(msg)); }
|
||||||
void on_fill(Char fill) { f.specs.fill[0] = fill; }
|
void on_fill(Char fill) { f.specs.fill[0] = fill; }
|
||||||
void on_align(align_t align) { f.specs.align = align; }
|
void on_align(align_t align) { f.specs.align = align; }
|
||||||
void on_width(unsigned width) { f.specs.width = width; }
|
void on_width(int width) { f.specs.width = width; }
|
||||||
void on_precision(unsigned _precision) { f.precision = _precision; }
|
void on_precision(int _precision) { f.precision = _precision; }
|
||||||
void end_precision() {}
|
void end_precision() {}
|
||||||
|
|
||||||
template <typename Id> void on_dynamic_width(Id arg_id) {
|
template <typename Id> void on_dynamic_width(Id arg_id) {
|
||||||
|
@ -26,11 +26,11 @@ template <typename Char> struct format_part {
|
|||||||
|
|
||||||
kind part_kind;
|
kind part_kind;
|
||||||
union value {
|
union value {
|
||||||
unsigned arg_index;
|
int arg_index;
|
||||||
basic_string_view<Char> str;
|
basic_string_view<Char> str;
|
||||||
replacement repl;
|
replacement repl;
|
||||||
|
|
||||||
FMT_CONSTEXPR value(unsigned index = 0) : arg_index(index) {}
|
FMT_CONSTEXPR value(int index = 0) : arg_index(index) {}
|
||||||
FMT_CONSTEXPR value(basic_string_view<Char> s) : str(s) {}
|
FMT_CONSTEXPR value(basic_string_view<Char> s) : str(s) {}
|
||||||
FMT_CONSTEXPR value(replacement r) : repl(r) {}
|
FMT_CONSTEXPR value(replacement r) : repl(r) {}
|
||||||
} val;
|
} val;
|
||||||
@ -40,7 +40,7 @@ template <typename Char> struct format_part {
|
|||||||
FMT_CONSTEXPR format_part(kind k = kind::arg_index, value v = {})
|
FMT_CONSTEXPR format_part(kind k = kind::arg_index, value v = {})
|
||||||
: part_kind(k), val(v) {}
|
: part_kind(k), val(v) {}
|
||||||
|
|
||||||
static FMT_CONSTEXPR format_part make_arg_index(unsigned index) {
|
static FMT_CONSTEXPR format_part make_arg_index(int index) {
|
||||||
return format_part(kind::arg_index, index);
|
return format_part(kind::arg_index, index);
|
||||||
}
|
}
|
||||||
static FMT_CONSTEXPR format_part make_arg_name(basic_string_view<Char> name) {
|
static FMT_CONSTEXPR format_part make_arg_name(basic_string_view<Char> name) {
|
||||||
@ -62,7 +62,7 @@ template <typename Char> struct part_counter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FMT_CONSTEXPR void on_arg_id() { ++num_parts; }
|
FMT_CONSTEXPR void on_arg_id() { ++num_parts; }
|
||||||
FMT_CONSTEXPR void on_arg_id(unsigned) { ++num_parts; }
|
FMT_CONSTEXPR void on_arg_id(int) { ++num_parts; }
|
||||||
FMT_CONSTEXPR void on_arg_id(basic_string_view<Char>) { ++num_parts; }
|
FMT_CONSTEXPR void on_arg_id(basic_string_view<Char>) { ++num_parts; }
|
||||||
|
|
||||||
FMT_CONSTEXPR void on_replacement_field(const Char*) {}
|
FMT_CONSTEXPR void on_replacement_field(const Char*) {}
|
||||||
@ -119,7 +119,7 @@ class format_string_compiler : public error_handler {
|
|||||||
part_ = part::make_arg_index(parse_context_.next_arg_id());
|
part_ = part::make_arg_index(parse_context_.next_arg_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
FMT_CONSTEXPR void on_arg_id(unsigned id) {
|
FMT_CONSTEXPR void on_arg_id(int id) {
|
||||||
parse_context_.check_arg_id(id);
|
parse_context_.check_arg_id(id);
|
||||||
part_ = part::make_arg_index(id);
|
part_ = part::make_arg_index(id);
|
||||||
}
|
}
|
||||||
@ -512,8 +512,6 @@ template <typename CompiledFormat, typename... Args,
|
|||||||
CompiledFormat>::value)>
|
CompiledFormat>::value)>
|
||||||
std::basic_string<Char> format(const CompiledFormat& cf, const Args&... args) {
|
std::basic_string<Char> format(const CompiledFormat& cf, const Args&... args) {
|
||||||
basic_memory_buffer<Char> buffer;
|
basic_memory_buffer<Char> buffer;
|
||||||
using range = buffer_range<Char>;
|
|
||||||
using context = buffer_context<Char>;
|
|
||||||
cf.format(std::back_inserter(buffer), args...);
|
cf.format(std::back_inserter(buffer), args...);
|
||||||
return to_string(buffer);
|
return to_string(buffer);
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
// The fmt library version in the form major * 10000 + minor * 100 + patch.
|
// The fmt library version in the form major * 10000 + minor * 100 + patch.
|
||||||
#define FMT_VERSION 60101
|
#define FMT_VERSION 60102
|
||||||
|
|
||||||
#ifdef __has_feature
|
#ifdef __has_feature
|
||||||
# define FMT_HAS_FEATURE(x) __has_feature(x)
|
# define FMT_HAS_FEATURE(x) __has_feature(x)
|
||||||
@ -878,7 +878,7 @@ template <typename Context> struct arg_mapper {
|
|||||||
FMT_ENABLE_IF(
|
FMT_ENABLE_IF(
|
||||||
std::is_constructible<std_string_view<char_type>, T>::value &&
|
std::is_constructible<std_string_view<char_type>, T>::value &&
|
||||||
!std::is_constructible<basic_string_view<char_type>, T>::value &&
|
!std::is_constructible<basic_string_view<char_type>, T>::value &&
|
||||||
!is_string<T>::value)>
|
!is_string<T>::value && !has_formatter<T, Context>::value)>
|
||||||
FMT_CONSTEXPR basic_string_view<char_type> map(const T& val) {
|
FMT_CONSTEXPR basic_string_view<char_type> map(const T& val) {
|
||||||
return std_string_view<char_type>(val);
|
return std_string_view<char_type>(val);
|
||||||
}
|
}
|
||||||
@ -911,12 +911,14 @@ template <typename Context> struct arg_mapper {
|
|||||||
map(static_cast<typename std::underlying_type<T>::type>(val))) {
|
map(static_cast<typename std::underlying_type<T>::type>(val))) {
|
||||||
return map(static_cast<typename std::underlying_type<T>::type>(val));
|
return map(static_cast<typename std::underlying_type<T>::type>(val));
|
||||||
}
|
}
|
||||||
template <typename T,
|
template <
|
||||||
FMT_ENABLE_IF(!is_string<T>::value && !is_char<T>::value &&
|
typename T,
|
||||||
!std::is_constructible<basic_string_view<char_type>,
|
FMT_ENABLE_IF(
|
||||||
T>::value &&
|
!is_string<T>::value && !is_char<T>::value &&
|
||||||
|
!std::is_constructible<basic_string_view<char_type>, T>::value &&
|
||||||
(has_formatter<T, Context>::value ||
|
(has_formatter<T, Context>::value ||
|
||||||
has_fallback_formatter<T, Context>::value))>
|
(has_fallback_formatter<T, Context>::value &&
|
||||||
|
!std::is_constructible<std_string_view<char_type>, T>::value)))>
|
||||||
FMT_CONSTEXPR const T& map(const T& val) {
|
FMT_CONSTEXPR const T& map(const T& val) {
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
@ -1283,7 +1285,7 @@ template <typename Context> class basic_format_args {
|
|||||||
*/
|
*/
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
basic_format_args(const format_arg_store<Context, Args...>& store)
|
basic_format_args(const format_arg_store<Context, Args...>& store)
|
||||||
: types_(static_cast<unsigned long long>(store.types)) {
|
: types_(store.types) {
|
||||||
set_data(store.data_);
|
set_data(store.data_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +69,8 @@
|
|||||||
# define FMT_HAS_BUILTIN(x) 0
|
# define FMT_HAS_BUILTIN(x) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if FMT_HAS_CPP_ATTRIBUTE(fallthrough) >= 201603 && __cplusplus >= 201703
|
#if FMT_HAS_CPP_ATTRIBUTE(fallthrough) && \
|
||||||
|
(__cplusplus >= 201703 || FMT_GCC_VERSION != 0)
|
||||||
# define FMT_FALLTHROUGH [[fallthrough]]
|
# define FMT_FALLTHROUGH [[fallthrough]]
|
||||||
#else
|
#else
|
||||||
# define FMT_FALLTHROUGH
|
# define FMT_FALLTHROUGH
|
||||||
@ -801,60 +802,6 @@ template <> int count_digits<4>(internal::fallback_uintptr n);
|
|||||||
# define FMT_ALWAYS_INLINE
|
# define FMT_ALWAYS_INLINE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Computes g = floor(log10(n)) and calls h.on<g>(n);
|
|
||||||
template <typename Handler> FMT_ALWAYS_INLINE char* lg(uint32_t n, Handler h) {
|
|
||||||
return n < 100 ? n < 10 ? h.template on<0>(n) : h.template on<1>(n)
|
|
||||||
: n < 1000000
|
|
||||||
? n < 10000 ? n < 1000 ? h.template on<2>(n)
|
|
||||||
: h.template on<3>(n)
|
|
||||||
: n < 100000 ? h.template on<4>(n)
|
|
||||||
: h.template on<5>(n)
|
|
||||||
: n < 100000000 ? n < 10000000 ? h.template on<6>(n)
|
|
||||||
: h.template on<7>(n)
|
|
||||||
: n < 1000000000 ? h.template on<8>(n)
|
|
||||||
: h.template on<9>(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
// An lg handler that formats a decimal number.
|
|
||||||
// Usage: lg(n, decimal_formatter(buffer));
|
|
||||||
class decimal_formatter {
|
|
||||||
private:
|
|
||||||
char* buffer_;
|
|
||||||
|
|
||||||
void write_pair(unsigned N, uint32_t index) {
|
|
||||||
std::memcpy(buffer_ + N, data::digits + index * 2, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit decimal_formatter(char* buf) : buffer_(buf) {}
|
|
||||||
|
|
||||||
template <unsigned N> char* on(uint32_t u) {
|
|
||||||
if (N == 0) {
|
|
||||||
*buffer_ = static_cast<char>(u) + '0';
|
|
||||||
} else if (N == 1) {
|
|
||||||
write_pair(0, u);
|
|
||||||
} else {
|
|
||||||
// The idea of using 4.32 fixed-point numbers is based on
|
|
||||||
// https://github.com/jeaiii/itoa
|
|
||||||
unsigned n = N - 1;
|
|
||||||
unsigned a = n / 5 * n * 53 / 16;
|
|
||||||
uint64_t t =
|
|
||||||
((1ULL << (32 + a)) / data::zero_or_powers_of_10_32[n] + 1 - n / 9);
|
|
||||||
t = ((t * u) >> a) + n / 5 * 4;
|
|
||||||
write_pair(0, t >> 32);
|
|
||||||
for (unsigned i = 2; i < N; i += 2) {
|
|
||||||
t = 100ULL * static_cast<uint32_t>(t);
|
|
||||||
write_pair(i, t >> 32);
|
|
||||||
}
|
|
||||||
if (N % 2 == 0) {
|
|
||||||
buffer_[N] =
|
|
||||||
static_cast<char>((10ULL * static_cast<uint32_t>(t)) >> 32) + '0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return buffer_ += N + 1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef FMT_BUILTIN_CLZ
|
#ifdef FMT_BUILTIN_CLZ
|
||||||
// Optional version of count_digits for better performance on 32-bit platforms.
|
// Optional version of count_digits for better performance on 32-bit platforms.
|
||||||
inline int count_digits(uint32_t n) {
|
inline int count_digits(uint32_t n) {
|
||||||
@ -2620,7 +2567,7 @@ class format_string_checker {
|
|||||||
public:
|
public:
|
||||||
explicit FMT_CONSTEXPR format_string_checker(
|
explicit FMT_CONSTEXPR format_string_checker(
|
||||||
basic_string_view<Char> format_str, ErrorHandler eh)
|
basic_string_view<Char> format_str, ErrorHandler eh)
|
||||||
: arg_id_(max_value<unsigned>()),
|
: arg_id_(-1),
|
||||||
context_(format_str, eh),
|
context_(format_str, eh),
|
||||||
parse_funcs_{&parse_format_specs<Args, parse_context_type>...} {}
|
parse_funcs_{&parse_format_specs<Args, parse_context_type>...} {}
|
||||||
|
|
||||||
@ -2661,7 +2608,7 @@ class format_string_checker {
|
|||||||
// Format specifier parsing function.
|
// Format specifier parsing function.
|
||||||
using parse_func = const Char* (*)(parse_context_type&);
|
using parse_func = const Char* (*)(parse_context_type&);
|
||||||
|
|
||||||
unsigned arg_id_;
|
int arg_id_;
|
||||||
parse_context_type context_;
|
parse_context_type context_;
|
||||||
parse_func parse_funcs_[num_args > 0 ? num_args : 1];
|
parse_func parse_funcs_[num_args > 0 ? num_args : 1];
|
||||||
};
|
};
|
||||||
|
@ -333,12 +333,12 @@ template <typename OutputIt, typename Char> class basic_printf_context {
|
|||||||
static void parse_flags(format_specs& specs, const Char*& it,
|
static void parse_flags(format_specs& specs, const Char*& it,
|
||||||
const Char* end);
|
const Char* end);
|
||||||
|
|
||||||
// Returns the argument with specified index or, if arg_index is equal
|
// Returns the argument with specified index or, if arg_index is -1, the next
|
||||||
// to the maximum unsigned value, the next argument.
|
// argument.
|
||||||
format_arg get_arg(unsigned arg_index = internal::max_value<unsigned>());
|
format_arg get_arg(int arg_index = -1);
|
||||||
|
|
||||||
// Parses argument index, flags and width and returns the argument index.
|
// Parses argument index, flags and width and returns the argument index.
|
||||||
unsigned parse_header(const Char*& it, const Char* end, format_specs& specs);
|
int parse_header(const Char*& it, const Char* end, format_specs& specs);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@ -355,7 +355,7 @@ template <typename OutputIt, typename Char> class basic_printf_context {
|
|||||||
OutputIt out() { return out_; }
|
OutputIt out() { return out_; }
|
||||||
void advance_to(OutputIt it) { out_ = it; }
|
void advance_to(OutputIt it) { out_ = it; }
|
||||||
|
|
||||||
format_arg arg(unsigned id) const { return args_.get(id); }
|
format_arg arg(int id) const { return args_.get(id); }
|
||||||
|
|
||||||
basic_format_parse_context<Char>& parse_context() { return parse_ctx_; }
|
basic_format_parse_context<Char>& parse_context() { return parse_ctx_; }
|
||||||
|
|
||||||
@ -397,8 +397,8 @@ void basic_printf_context<OutputIt, Char>::parse_flags(format_specs& specs,
|
|||||||
|
|
||||||
template <typename OutputIt, typename Char>
|
template <typename OutputIt, typename Char>
|
||||||
typename basic_printf_context<OutputIt, Char>::format_arg
|
typename basic_printf_context<OutputIt, Char>::format_arg
|
||||||
basic_printf_context<OutputIt, Char>::get_arg(unsigned arg_index) {
|
basic_printf_context<OutputIt, Char>::get_arg(int arg_index) {
|
||||||
if (arg_index == internal::max_value<unsigned>())
|
if (arg_index < 0)
|
||||||
arg_index = parse_ctx_.next_arg_id();
|
arg_index = parse_ctx_.next_arg_id();
|
||||||
else
|
else
|
||||||
parse_ctx_.check_arg_id(--arg_index);
|
parse_ctx_.check_arg_id(--arg_index);
|
||||||
@ -406,15 +406,15 @@ basic_printf_context<OutputIt, Char>::get_arg(unsigned arg_index) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename OutputIt, typename Char>
|
template <typename OutputIt, typename Char>
|
||||||
unsigned basic_printf_context<OutputIt, Char>::parse_header(
|
int basic_printf_context<OutputIt, Char>::parse_header(
|
||||||
const Char*& it, const Char* end, format_specs& specs) {
|
const Char*& it, const Char* end, format_specs& specs) {
|
||||||
unsigned arg_index = internal::max_value<unsigned>();
|
int arg_index = -1;
|
||||||
char_type c = *it;
|
char_type c = *it;
|
||||||
if (c >= '0' && c <= '9') {
|
if (c >= '0' && c <= '9') {
|
||||||
// Parse an argument index (if followed by '$') or a width possibly
|
// Parse an argument index (if followed by '$') or a width possibly
|
||||||
// preceded with '0' flag(s).
|
// preceded with '0' flag(s).
|
||||||
internal::error_handler eh;
|
internal::error_handler eh;
|
||||||
unsigned value = parse_nonnegative_int(it, end, eh);
|
int value = parse_nonnegative_int(it, end, eh);
|
||||||
if (it != end && *it == '$') { // value is an argument index
|
if (it != end && *it == '$') { // value is an argument index
|
||||||
++it;
|
++it;
|
||||||
arg_index = value;
|
arg_index = value;
|
||||||
@ -436,8 +436,8 @@ unsigned basic_printf_context<OutputIt, Char>::parse_header(
|
|||||||
specs.width = parse_nonnegative_int(it, end, eh);
|
specs.width = parse_nonnegative_int(it, end, eh);
|
||||||
} else if (*it == '*') {
|
} else if (*it == '*') {
|
||||||
++it;
|
++it;
|
||||||
specs.width = visit_format_arg(
|
specs.width = static_cast<int>(visit_format_arg(
|
||||||
internal::printf_width_handler<char_type>(specs), get_arg());
|
internal::printf_width_handler<char_type>(specs), get_arg()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return arg_index;
|
return arg_index;
|
||||||
@ -464,7 +464,7 @@ OutputIt basic_printf_context<OutputIt, Char>::format() {
|
|||||||
specs.align = align::right;
|
specs.align = align::right;
|
||||||
|
|
||||||
// Parse argument index, flags and width.
|
// Parse argument index, flags and width.
|
||||||
unsigned arg_index = parse_header(it, end, specs);
|
int arg_index = parse_header(it, end, specs);
|
||||||
if (arg_index == 0) on_error("argument index out of range");
|
if (arg_index == 0) on_error("argument index out of range");
|
||||||
|
|
||||||
// Parse precision.
|
// Parse precision.
|
||||||
@ -473,11 +473,11 @@ OutputIt basic_printf_context<OutputIt, Char>::format() {
|
|||||||
c = it != end ? *it : 0;
|
c = it != end ? *it : 0;
|
||||||
if ('0' <= c && c <= '9') {
|
if ('0' <= c && c <= '9') {
|
||||||
internal::error_handler eh;
|
internal::error_handler eh;
|
||||||
specs.precision = static_cast<int>(parse_nonnegative_int(it, end, eh));
|
specs.precision = parse_nonnegative_int(it, end, eh);
|
||||||
} else if (c == '*') {
|
} else if (c == '*') {
|
||||||
++it;
|
++it;
|
||||||
specs.precision =
|
specs.precision =
|
||||||
visit_format_arg(internal::printf_precision_handler(), get_arg());
|
static_cast<int>(visit_format_arg(internal::printf_precision_handler(), get_arg()));
|
||||||
} else {
|
} else {
|
||||||
specs.precision = 0;
|
specs.precision = 0;
|
||||||
}
|
}
|
||||||
|
20
third_party/spdlog/include/spdlog/fmt/fmt.h
vendored
20
third_party/spdlog/include/spdlog/fmt/fmt.h
vendored
@ -10,30 +10,16 @@
|
|||||||
// By default spdlog include its own copy.
|
// By default spdlog include its own copy.
|
||||||
//
|
//
|
||||||
|
|
||||||
#if defined(__GNUC__) || defined(__clang__)
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
|
|
||||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
|
||||||
#endif // __GNUC__ || __clang__
|
|
||||||
|
|
||||||
|
|
||||||
#if !defined(SPDLOG_FMT_EXTERNAL)
|
#if !defined(SPDLOG_FMT_EXTERNAL)
|
||||||
#ifdef SPDLOG_HEADER_ONLY
|
#if !defined(SPDLOG_COMPILED_LIB) && !defined(FMT_HEADER_ONLY)
|
||||||
#ifndef FMT_HEADER_ONLY
|
|
||||||
#define FMT_HEADER_ONLY
|
#define FMT_HEADER_ONLY
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
#ifndef FMT_USE_WINDOWS_H
|
#ifndef FMT_USE_WINDOWS_H
|
||||||
#define FMT_USE_WINDOWS_H 0
|
#define FMT_USE_WINDOWS_H 0
|
||||||
#endif
|
#endif
|
||||||
#include "bundled/core.h"
|
#include <spdlog/fmt/bundled/core.h>
|
||||||
#include "bundled/format.h"
|
#include <spdlog/fmt/bundled/format.h>
|
||||||
#else // SPDLOG_FMT_EXTERNAL is defined - use external fmtlib
|
#else // SPDLOG_FMT_EXTERNAL is defined - use external fmtlib
|
||||||
#include <fmt/core.h>
|
#include <fmt/core.h>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// pop warnings supressions
|
|
||||||
#if defined(__GNUC__) || defined(__clang__)
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
#endif
|
|
||||||
|
6
third_party/spdlog/include/spdlog/fmt/ostr.h
vendored
6
third_party/spdlog/include/spdlog/fmt/ostr.h
vendored
@ -7,12 +7,14 @@
|
|||||||
//
|
//
|
||||||
// include bundled or external copy of fmtlib's ostream support
|
// include bundled or external copy of fmtlib's ostream support
|
||||||
//
|
//
|
||||||
|
|
||||||
#if !defined(SPDLOG_FMT_EXTERNAL)
|
#if !defined(SPDLOG_FMT_EXTERNAL)
|
||||||
|
#ifdef SPDLOG_HEADER_ONLY
|
||||||
#ifndef FMT_HEADER_ONLY
|
#ifndef FMT_HEADER_ONLY
|
||||||
#define FMT_HEADER_ONLY
|
#define FMT_HEADER_ONLY
|
||||||
#endif
|
#endif
|
||||||
#include "bundled/ostream.h"
|
#endif
|
||||||
#include "fmt.h"
|
#include <spdlog/fmt/bundled/ostream.h>
|
||||||
#else
|
#else
|
||||||
#include <fmt/ostream.h>
|
#include <fmt/ostream.h>
|
||||||
#endif
|
#endif
|
||||||
|
14
third_party/spdlog/include/spdlog/fwd.h
vendored
Normal file
14
third_party/spdlog/include/spdlog/fwd.h
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||||
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace spdlog {
|
||||||
|
class logger;
|
||||||
|
class formatter;
|
||||||
|
|
||||||
|
namespace sinks {
|
||||||
|
class sink;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace spdlog
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
#include <spdlog/sinks/sink.h>
|
#include <spdlog/sinks/sink.h>
|
||||||
#include <spdlog/details/backtracer.h>
|
#include <spdlog/details/backtracer.h>
|
||||||
#include <spdlog/details/pattern_formatter.h>
|
#include <spdlog/pattern_formatter.h>
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
@ -89,6 +89,7 @@ SPDLOG_INLINE void logger::set_formatter(std::unique_ptr<formatter> f)
|
|||||||
{
|
{
|
||||||
// last element - we can be move it.
|
// last element - we can be move it.
|
||||||
(*it)->set_formatter(std::move(f));
|
(*it)->set_formatter(std::move(f));
|
||||||
|
break; // to prevent clang-tidy warning
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
7
third_party/spdlog/include/spdlog/logger.h
vendored
7
third_party/spdlog/include/spdlog/logger.h
vendored
@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
namespace spdlog {
|
namespace spdlog {
|
||||||
|
|
||||||
class logger
|
class SPDLOG_API logger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Empty logger
|
// Empty logger
|
||||||
@ -143,6 +143,11 @@ public:
|
|||||||
// T can be statically converted to string_view
|
// T can be statically converted to string_view
|
||||||
template<class T, typename std::enable_if<std::is_convertible<const T &, spdlog::string_view_t>::value, T>::type * = nullptr>
|
template<class T, typename std::enable_if<std::is_convertible<const T &, spdlog::string_view_t>::value, T>::type * = nullptr>
|
||||||
void log(source_loc loc, level::level_enum lvl, const T &msg)
|
void log(source_loc loc, level::level_enum lvl, const T &msg)
|
||||||
|
{
|
||||||
|
log(loc, lvl, string_view_t{msg});
|
||||||
|
}
|
||||||
|
|
||||||
|
void log(source_loc loc, level::level_enum lvl, string_view_t msg)
|
||||||
{
|
{
|
||||||
bool log_enabled = should_log(lvl);
|
bool log_enabled = should_log(lvl);
|
||||||
bool traceback_enabled = tracer_.enabled();
|
bool traceback_enabled = tracer_.enabled();
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef SPDLOG_HEADER_ONLY
|
#ifndef SPDLOG_HEADER_ONLY
|
||||||
#include <spdlog/details/pattern_formatter.h>
|
#include <spdlog/pattern_formatter.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <spdlog/details/fmt_helper.h>
|
#include <spdlog/details/fmt_helper.h>
|
||||||
@ -90,7 +90,7 @@ struct null_scoped_padder
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename ScopedPadder>
|
template<typename ScopedPadder>
|
||||||
class name_formatter : public flag_formatter
|
class name_formatter final : public flag_formatter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit name_formatter(padding_info padinfo)
|
explicit name_formatter(padding_info padinfo)
|
||||||
@ -106,7 +106,7 @@ public:
|
|||||||
|
|
||||||
// log level appender
|
// log level appender
|
||||||
template<typename ScopedPadder>
|
template<typename ScopedPadder>
|
||||||
class level_formatter : public flag_formatter
|
class level_formatter final : public flag_formatter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit level_formatter(padding_info padinfo)
|
explicit level_formatter(padding_info padinfo)
|
||||||
@ -123,7 +123,7 @@ public:
|
|||||||
|
|
||||||
// short log level appender
|
// short log level appender
|
||||||
template<typename ScopedPadder>
|
template<typename ScopedPadder>
|
||||||
class short_level_formatter : public flag_formatter
|
class short_level_formatter final : public flag_formatter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit short_level_formatter(padding_info padinfo)
|
explicit short_level_formatter(padding_info padinfo)
|
||||||
@ -156,7 +156,7 @@ static int to12h(const tm &t)
|
|||||||
static std::array<const char *, 7> days{{"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}};
|
static std::array<const char *, 7> days{{"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}};
|
||||||
|
|
||||||
template<typename ScopedPadder>
|
template<typename ScopedPadder>
|
||||||
class a_formatter : public flag_formatter
|
class a_formatter final : public flag_formatter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit a_formatter(padding_info padinfo)
|
explicit a_formatter(padding_info padinfo)
|
||||||
@ -194,7 +194,7 @@ public:
|
|||||||
static const std::array<const char *, 12> months{{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec"}};
|
static const std::array<const char *, 12> months{{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec"}};
|
||||||
|
|
||||||
template<typename ScopedPadder>
|
template<typename ScopedPadder>
|
||||||
class b_formatter : public flag_formatter
|
class b_formatter final : public flag_formatter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit b_formatter(padding_info padinfo)
|
explicit b_formatter(padding_info padinfo)
|
||||||
@ -214,7 +214,7 @@ static const std::array<const char *, 12> full_months{
|
|||||||
{"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}};
|
{"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}};
|
||||||
|
|
||||||
template<typename ScopedPadder>
|
template<typename ScopedPadder>
|
||||||
class B_formatter : public flag_formatter
|
class B_formatter final : public flag_formatter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit B_formatter(padding_info padinfo)
|
explicit B_formatter(padding_info padinfo)
|
||||||
@ -933,16 +933,15 @@ public:
|
|||||||
dest.push_back(']');
|
dest.push_back(']');
|
||||||
dest.push_back(' ');
|
dest.push_back(' ');
|
||||||
|
|
||||||
#ifndef SPDLOG_NO_NAME
|
// append logger name if exists
|
||||||
if (msg.logger_name.size() > 0)
|
if (msg.logger_name.size() > 0)
|
||||||
{
|
{
|
||||||
dest.push_back('[');
|
dest.push_back('[');
|
||||||
// fmt_helper::append_str(*msg.logger_name, dest);
|
|
||||||
fmt_helper::append_string_view(msg.logger_name, dest);
|
fmt_helper::append_string_view(msg.logger_name, dest);
|
||||||
dest.push_back(']');
|
dest.push_back(']');
|
||||||
dest.push_back(' ');
|
dest.push_back(' ');
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
dest.push_back('[');
|
dest.push_back('[');
|
||||||
// wrap the level name with color
|
// wrap the level name with color
|
||||||
msg.color_range_start = dest.size();
|
msg.color_range_start = dest.size();
|
||||||
@ -974,11 +973,13 @@ private:
|
|||||||
|
|
||||||
} // namespace details
|
} // namespace details
|
||||||
|
|
||||||
SPDLOG_INLINE pattern_formatter::pattern_formatter(std::string pattern, pattern_time_type time_type, std::string eol)
|
SPDLOG_INLINE pattern_formatter::pattern_formatter(
|
||||||
|
std::string pattern, pattern_time_type time_type, std::string eol, custom_flags custom_user_flags)
|
||||||
: pattern_(std::move(pattern))
|
: pattern_(std::move(pattern))
|
||||||
, eol_(std::move(eol))
|
, eol_(std::move(eol))
|
||||||
, pattern_time_type_(time_type)
|
, pattern_time_type_(time_type)
|
||||||
, last_log_secs_(0)
|
, last_log_secs_(0)
|
||||||
|
, custom_handlers_(std::move(custom_user_flags))
|
||||||
{
|
{
|
||||||
std::memset(&cached_tm_, 0, sizeof(cached_tm_));
|
std::memset(&cached_tm_, 0, sizeof(cached_tm_));
|
||||||
compile_pattern_(pattern_);
|
compile_pattern_(pattern_);
|
||||||
@ -997,7 +998,12 @@ SPDLOG_INLINE pattern_formatter::pattern_formatter(pattern_time_type time_type,
|
|||||||
|
|
||||||
SPDLOG_INLINE std::unique_ptr<formatter> pattern_formatter::clone() const
|
SPDLOG_INLINE std::unique_ptr<formatter> pattern_formatter::clone() const
|
||||||
{
|
{
|
||||||
return details::make_unique<pattern_formatter>(pattern_, pattern_time_type_, eol_);
|
custom_flags cloned_custom_formatters;
|
||||||
|
for (auto &it : custom_handlers_)
|
||||||
|
{
|
||||||
|
cloned_custom_formatters[it.first] = it.second->clone();
|
||||||
|
}
|
||||||
|
return details::make_unique<pattern_formatter>(pattern_, pattern_time_type_, eol_, std::move(cloned_custom_formatters));
|
||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_INLINE void pattern_formatter::format(const details::log_msg &msg, memory_buf_t &dest)
|
SPDLOG_INLINE void pattern_formatter::format(const details::log_msg &msg, memory_buf_t &dest)
|
||||||
@ -1017,6 +1023,12 @@ SPDLOG_INLINE void pattern_formatter::format(const details::log_msg &msg, memory
|
|||||||
details::fmt_helper::append_string_view(eol_, dest);
|
details::fmt_helper::append_string_view(eol_, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SPDLOG_INLINE void pattern_formatter::set_pattern(std::string pattern)
|
||||||
|
{
|
||||||
|
pattern_ = std::move(pattern);
|
||||||
|
compile_pattern_(pattern_);
|
||||||
|
}
|
||||||
|
|
||||||
SPDLOG_INLINE std::tm pattern_formatter::get_time_(const details::log_msg &msg)
|
SPDLOG_INLINE std::tm pattern_formatter::get_time_(const details::log_msg &msg)
|
||||||
{
|
{
|
||||||
if (pattern_time_type_ == pattern_time_type::local)
|
if (pattern_time_type_ == pattern_time_type::local)
|
||||||
@ -1029,9 +1041,19 @@ SPDLOG_INLINE std::tm pattern_formatter::get_time_(const details::log_msg &msg)
|
|||||||
template<typename Padder>
|
template<typename Padder>
|
||||||
SPDLOG_INLINE void pattern_formatter::handle_flag_(char flag, details::padding_info padding)
|
SPDLOG_INLINE void pattern_formatter::handle_flag_(char flag, details::padding_info padding)
|
||||||
{
|
{
|
||||||
|
// process custom flags
|
||||||
|
auto it = custom_handlers_.find(flag);
|
||||||
|
if (it != custom_handlers_.end())
|
||||||
|
{
|
||||||
|
auto custom_handler = it->second->clone();
|
||||||
|
custom_handler->set_padding_info(padding);
|
||||||
|
formatters_.push_back(std::move(custom_handler));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// process built-in flags
|
||||||
switch (flag)
|
switch (flag)
|
||||||
{
|
{
|
||||||
|
|
||||||
case ('+'): // default formatter
|
case ('+'): // default formatter
|
||||||
formatters_.push_back(details::make_unique<details::full_formatter>(padding));
|
formatters_.push_back(details::make_unique<details::full_formatter>(padding));
|
||||||
break;
|
break;
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
namespace spdlog {
|
namespace spdlog {
|
||||||
namespace details {
|
namespace details {
|
||||||
@ -40,13 +41,13 @@ struct padding_info
|
|||||||
{
|
{
|
||||||
return enabled_;
|
return enabled_;
|
||||||
}
|
}
|
||||||
const size_t width_ = 0;
|
size_t width_ = 0;
|
||||||
const pad_side side_ = left;
|
pad_side side_ = left;
|
||||||
bool truncate_ = false;
|
bool truncate_ = false;
|
||||||
bool enabled_ = false;
|
bool enabled_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class flag_formatter
|
class SPDLOG_API flag_formatter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit flag_formatter(padding_info padinfo)
|
explicit flag_formatter(padding_info padinfo)
|
||||||
@ -62,11 +63,24 @@ protected:
|
|||||||
|
|
||||||
} // namespace details
|
} // namespace details
|
||||||
|
|
||||||
class pattern_formatter final : public formatter
|
class SPDLOG_API custom_flag_formatter : public details::flag_formatter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit pattern_formatter(
|
virtual std::unique_ptr<custom_flag_formatter> clone() const = 0;
|
||||||
std::string pattern, pattern_time_type time_type = pattern_time_type::local, std::string eol = spdlog::details::os::default_eol);
|
|
||||||
|
void set_padding_info(details::padding_info padding)
|
||||||
|
{
|
||||||
|
flag_formatter::padinfo_ = padding;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SPDLOG_API pattern_formatter final : public formatter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using custom_flags = std::unordered_map<char, std::unique_ptr<custom_flag_formatter>>;
|
||||||
|
|
||||||
|
explicit pattern_formatter(std::string pattern, pattern_time_type time_type = pattern_time_type::local,
|
||||||
|
std::string eol = spdlog::details::os::default_eol, custom_flags custom_user_flags = {});
|
||||||
|
|
||||||
// use default pattern is not given
|
// use default pattern is not given
|
||||||
explicit pattern_formatter(pattern_time_type time_type = pattern_time_type::local, std::string eol = spdlog::details::os::default_eol);
|
explicit pattern_formatter(pattern_time_type time_type = pattern_time_type::local, std::string eol = spdlog::details::os::default_eol);
|
||||||
@ -77,6 +91,14 @@ public:
|
|||||||
std::unique_ptr<formatter> clone() const override;
|
std::unique_ptr<formatter> clone() const override;
|
||||||
void format(const details::log_msg &msg, memory_buf_t &dest) override;
|
void format(const details::log_msg &msg, memory_buf_t &dest) override;
|
||||||
|
|
||||||
|
template<typename T, typename... Args>
|
||||||
|
pattern_formatter &add_flag(char flag, const Args &... args)
|
||||||
|
{
|
||||||
|
custom_handlers_[flag] = details::make_unique<T>(args...);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
void set_pattern(std::string pattern);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string pattern_;
|
std::string pattern_;
|
||||||
std::string eol_;
|
std::string eol_;
|
||||||
@ -84,6 +106,7 @@ private:
|
|||||||
std::tm cached_tm_;
|
std::tm cached_tm_;
|
||||||
std::chrono::seconds last_log_secs_;
|
std::chrono::seconds last_log_secs_;
|
||||||
std::vector<std::unique_ptr<details::flag_formatter>> formatters_;
|
std::vector<std::unique_ptr<details::flag_formatter>> formatters_;
|
||||||
|
custom_flags custom_handlers_;
|
||||||
|
|
||||||
std::tm get_time_(const details::log_msg &msg);
|
std::tm get_time_(const details::log_msg &msg);
|
||||||
template<typename Padder>
|
template<typename Padder>
|
||||||
@ -92,7 +115,7 @@ private:
|
|||||||
// Extract given pad spec (e.g. %8X)
|
// Extract given pad spec (e.g. %8X)
|
||||||
// Advance the given it pass the end of the padding spec found (if any)
|
// Advance the given it pass the end of the padding spec found (if any)
|
||||||
// Return padding.
|
// Return padding.
|
||||||
details::padding_info handle_padspec_(std::string::const_iterator &it, std::string::const_iterator end);
|
static details::padding_info handle_padspec_(std::string::const_iterator &it, std::string::const_iterator end);
|
||||||
|
|
||||||
void compile_pattern_(const std::string &pattern);
|
void compile_pattern_(const std::string &pattern);
|
||||||
};
|
};
|
@ -64,7 +64,7 @@ protected:
|
|||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
SPDLOG_THROW(spdlog_ex("__android_log_write() failed", ret));
|
throw_spdlog_ex("__android_log_write() failed", ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include <spdlog/sinks/ansicolor_sink.h>
|
#include <spdlog/sinks/ansicolor_sink.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <spdlog/details/pattern_formatter.h>
|
#include <spdlog/pattern_formatter.h>
|
||||||
#include <spdlog/details/os.h>
|
#include <spdlog/details/os.h>
|
||||||
|
|
||||||
namespace spdlog {
|
namespace spdlog {
|
||||||
@ -43,7 +43,8 @@ SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::log(const details::log_msg &msg
|
|||||||
// Wrap the originally formatted message in color codes.
|
// Wrap the originally formatted message in color codes.
|
||||||
// If color is not supported in the terminal, log as is instead.
|
// If color is not supported in the terminal, log as is instead.
|
||||||
std::lock_guard<mutex_t> lock(mutex_);
|
std::lock_guard<mutex_t> lock(mutex_);
|
||||||
|
msg.color_range_start = 0;
|
||||||
|
msg.color_range_end = 0;
|
||||||
memory_buf_t formatted;
|
memory_buf_t formatted;
|
||||||
formatter_->format(msg, formatted);
|
formatter_->format(msg, formatted);
|
||||||
if (should_do_colors_ && msg.color_range_end > msg.color_range_start)
|
if (should_do_colors_ && msg.color_range_end > msg.color_range_start)
|
||||||
@ -111,7 +112,7 @@ SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::set_color_mode(color_mode mode)
|
|||||||
template<typename ConsoleMutex>
|
template<typename ConsoleMutex>
|
||||||
SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::print_ccode_(const string_view_t &color_code)
|
SPDLOG_INLINE void ansicolor_sink<ConsoleMutex>::print_ccode_(const string_view_t &color_code)
|
||||||
{
|
{
|
||||||
fwrite(color_code.data(), sizeof(string_view_t::char_type), color_code.size(), target_file_);
|
fwrite(color_code.data(), sizeof(char), color_code.size(), target_file_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ConsoleMutex>
|
template<typename ConsoleMutex>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <array>
|
||||||
|
|
||||||
namespace spdlog {
|
namespace spdlog {
|
||||||
namespace sinks {
|
namespace sinks {
|
||||||
@ -30,7 +30,11 @@ public:
|
|||||||
~ansicolor_sink() override = default;
|
~ansicolor_sink() override = default;
|
||||||
|
|
||||||
ansicolor_sink(const ansicolor_sink &other) = delete;
|
ansicolor_sink(const ansicolor_sink &other) = delete;
|
||||||
|
ansicolor_sink(ansicolor_sink &&other) = delete;
|
||||||
|
|
||||||
ansicolor_sink &operator=(const ansicolor_sink &other) = delete;
|
ansicolor_sink &operator=(const ansicolor_sink &other) = delete;
|
||||||
|
ansicolor_sink &operator=(ansicolor_sink &&other) = delete;
|
||||||
|
|
||||||
void set_color(level::level_enum color_level, string_view_t color);
|
void set_color(level::level_enum color_level, string_view_t color);
|
||||||
void set_color_mode(color_mode mode);
|
void set_color_mode(color_mode mode);
|
||||||
bool should_color();
|
bool should_color();
|
||||||
@ -80,7 +84,7 @@ private:
|
|||||||
mutex_t &mutex_;
|
mutex_t &mutex_;
|
||||||
bool should_do_colors_;
|
bool should_do_colors_;
|
||||||
std::unique_ptr<spdlog::formatter> formatter_;
|
std::unique_ptr<spdlog::formatter> formatter_;
|
||||||
std::unordered_map<level::level_enum, string_view_t, level::level_hasher> colors_;
|
std::array<string_view_t, level::n_levels> colors_;
|
||||||
void print_ccode_(const string_view_t &color_code);
|
void print_ccode_(const string_view_t &color_code);
|
||||||
void print_range_(const memory_buf_t &formatted, size_t start, size_t end);
|
void print_range_(const memory_buf_t &formatted, size_t start, size_t end);
|
||||||
};
|
};
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <spdlog/common.h>
|
#include <spdlog/common.h>
|
||||||
#include <spdlog/details/pattern_formatter.h>
|
#include <spdlog/pattern_formatter.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
@ -21,8 +21,14 @@ class base_sink : public sink
|
|||||||
public:
|
public:
|
||||||
base_sink();
|
base_sink();
|
||||||
explicit base_sink(std::unique_ptr<spdlog::formatter> formatter);
|
explicit base_sink(std::unique_ptr<spdlog::formatter> formatter);
|
||||||
|
~base_sink() override = default;
|
||||||
|
|
||||||
base_sink(const base_sink &) = delete;
|
base_sink(const base_sink &) = delete;
|
||||||
|
base_sink(base_sink &&) = delete;
|
||||||
|
|
||||||
base_sink &operator=(const base_sink &) = delete;
|
base_sink &operator=(const base_sink &) = delete;
|
||||||
|
base_sink &operator=(base_sink &&) = delete;
|
||||||
|
|
||||||
void log(const details::log_msg &msg) final;
|
void log(const details::log_msg &msg) final;
|
||||||
void flush() final;
|
void flush() final;
|
||||||
void set_pattern(const std::string &pattern) final;
|
void set_pattern(const std::string &pattern) final;
|
||||||
|
@ -56,7 +56,7 @@ public:
|
|||||||
{
|
{
|
||||||
if (rotation_hour < 0 || rotation_hour > 23 || rotation_minute < 0 || rotation_minute > 59)
|
if (rotation_hour < 0 || rotation_hour > 23 || rotation_minute < 0 || rotation_minute > 59)
|
||||||
{
|
{
|
||||||
SPDLOG_THROW(spdlog_ex("daily_file_sink: Invalid rotation time in ctor"));
|
throw_spdlog_ex("daily_file_sink: Invalid rotation time in ctor");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto now = log_clock::now();
|
auto now = log_clock::now();
|
||||||
@ -66,13 +66,13 @@ public:
|
|||||||
|
|
||||||
if (max_files_ > 0)
|
if (max_files_ > 0)
|
||||||
{
|
{
|
||||||
filenames_q_ = details::circular_q<filename_t>(static_cast<size_t>(max_files_));
|
init_filenames_q_();
|
||||||
filenames_q_.push_back(std::move(filename));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const filename_t &filename() const
|
filename_t filename()
|
||||||
{
|
{
|
||||||
|
std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_);
|
||||||
return file_helper_.filename();
|
return file_helper_.filename();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,6 +104,29 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void init_filenames_q_()
|
||||||
|
{
|
||||||
|
using details::os::path_exists;
|
||||||
|
|
||||||
|
filenames_q_ = details::circular_q<filename_t>(static_cast<size_t>(max_files_));
|
||||||
|
std::vector<filename_t> filenames;
|
||||||
|
auto now = log_clock::now();
|
||||||
|
while (filenames.size() < max_files_)
|
||||||
|
{
|
||||||
|
auto filename = FileNameCalc::calc_filename(base_filename_, now_tm(now));
|
||||||
|
if (!path_exists(filename))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
filenames.emplace_back(filename);
|
||||||
|
now -= std::chrono::hours(24);
|
||||||
|
}
|
||||||
|
for (auto iter = filenames.rbegin(); iter != filenames.rend(); ++iter)
|
||||||
|
{
|
||||||
|
filenames_q_.push_back(std::move(*iter));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tm now_tm(log_clock::time_point tp)
|
tm now_tm(log_clock::time_point tp)
|
||||||
{
|
{
|
||||||
time_t tnow = log_clock::to_time_t(tp);
|
time_t tnow = log_clock::to_time_t(tp);
|
||||||
@ -141,7 +164,7 @@ private:
|
|||||||
if (!ok)
|
if (!ok)
|
||||||
{
|
{
|
||||||
filenames_q_.push_back(std::move(current_file));
|
filenames_q_.push_back(std::move(current_file));
|
||||||
SPDLOG_THROW(spdlog_ex("Failed removing daily file " + filename_to_str(old_filename), errno));
|
throw_spdlog_ex("Failed removing daily file " + filename_to_str(old_filename), errno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
filenames_q_.push_back(std::move(current_file));
|
filenames_q_.push_back(std::move(current_file));
|
||||||
@ -167,15 +190,15 @@ using daily_file_sink_st = daily_file_sink<details::null_mutex>;
|
|||||||
//
|
//
|
||||||
template<typename Factory = spdlog::synchronous_factory>
|
template<typename Factory = spdlog::synchronous_factory>
|
||||||
inline std::shared_ptr<logger> daily_logger_mt(
|
inline std::shared_ptr<logger> daily_logger_mt(
|
||||||
const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false)
|
const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false, uint16_t max_files = 0)
|
||||||
{
|
{
|
||||||
return Factory::template create<sinks::daily_file_sink_mt>(logger_name, filename, hour, minute, truncate);
|
return Factory::template create<sinks::daily_file_sink_mt>(logger_name, filename, hour, minute, truncate, max_files);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Factory = spdlog::synchronous_factory>
|
template<typename Factory = spdlog::synchronous_factory>
|
||||||
inline std::shared_ptr<logger> daily_logger_st(
|
inline std::shared_ptr<logger> daily_logger_st(
|
||||||
const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false)
|
const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false, uint16_t max_files = 0)
|
||||||
{
|
{
|
||||||
return Factory::template create<sinks::daily_file_sink_st>(logger_name, filename, hour, minute, truncate);
|
return Factory::template create<sinks::daily_file_sink_st>(logger_name, filename, hour, minute, truncate, max_files);
|
||||||
}
|
}
|
||||||
} // namespace spdlog
|
} // namespace spdlog
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include "base_sink.h"
|
#include "base_sink.h"
|
||||||
#include <spdlog/details/log_msg.h>
|
#include <spdlog/details/log_msg.h>
|
||||||
#include <spdlog/details/null_mutex.h>
|
#include <spdlog/details/null_mutex.h>
|
||||||
#include <spdlog/details/pattern_formatter.h>
|
#include <spdlog/pattern_formatter.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <spdlog/details/null_mutex.h>
|
#include <spdlog/details/null_mutex.h>
|
||||||
#include <spdlog/sinks/base_sink.h>
|
#include <spdlog/sinks/base_sink.h>
|
||||||
|
|
||||||
|
#include <spdlog/details/windows_include.h>
|
||||||
#include <winbase.h>
|
#include <winbase.h>
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
@ -54,8 +54,9 @@ SPDLOG_INLINE filename_t rotating_file_sink<Mutex>::calc_filename(const filename
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Mutex>
|
template<typename Mutex>
|
||||||
SPDLOG_INLINE const filename_t &rotating_file_sink<Mutex>::filename() const
|
SPDLOG_INLINE filename_t rotating_file_sink<Mutex>::filename()
|
||||||
{
|
{
|
||||||
|
std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_);
|
||||||
return file_helper_.filename();
|
return file_helper_.filename();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,18 +100,17 @@ SPDLOG_INLINE void rotating_file_sink<Mutex>::rotate_()
|
|||||||
}
|
}
|
||||||
filename_t target = calc_filename(base_filename_, i);
|
filename_t target = calc_filename(base_filename_, i);
|
||||||
|
|
||||||
if (!rename_file(src, target))
|
if (!rename_file_(src, target))
|
||||||
{
|
{
|
||||||
// if failed try again after a small delay.
|
// if failed try again after a small delay.
|
||||||
// this is a workaround to a windows issue, where very high rotation
|
// this is a workaround to a windows issue, where very high rotation
|
||||||
// rates can cause the rename to fail with permission denied (because of antivirus?).
|
// rates can cause the rename to fail with permission denied (because of antivirus?).
|
||||||
details::os::sleep_for_millis(100);
|
details::os::sleep_for_millis(100);
|
||||||
if (!rename_file(src, target))
|
if (!rename_file_(src, target))
|
||||||
{
|
{
|
||||||
file_helper_.reopen(true); // truncate the log file anyway to prevent it to grow beyond its limit!
|
file_helper_.reopen(true); // truncate the log file anyway to prevent it to grow beyond its limit!
|
||||||
current_size_ = 0;
|
current_size_ = 0;
|
||||||
SPDLOG_THROW(
|
throw_spdlog_ex("rotating_file_sink: failed renaming " + filename_to_str(src) + " to " + filename_to_str(target), errno);
|
||||||
spdlog_ex("rotating_file_sink: failed renaming " + filename_to_str(src) + " to " + filename_to_str(target), errno));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,7 +120,7 @@ SPDLOG_INLINE void rotating_file_sink<Mutex>::rotate_()
|
|||||||
// delete the target if exists, and rename the src file to target
|
// delete the target if exists, and rename the src file to target
|
||||||
// return true on success, false otherwise.
|
// return true on success, false otherwise.
|
||||||
template<typename Mutex>
|
template<typename Mutex>
|
||||||
SPDLOG_INLINE bool rotating_file_sink<Mutex>::rename_file(const filename_t &src_filename, const filename_t &target_filename)
|
SPDLOG_INLINE bool rotating_file_sink<Mutex>::rename_file_(const filename_t &src_filename, const filename_t &target_filename)
|
||||||
{
|
{
|
||||||
// try to delete the target file in case it already exists.
|
// try to delete the target file in case it already exists.
|
||||||
(void)details::os::remove(target_filename);
|
(void)details::os::remove(target_filename);
|
||||||
|
@ -24,7 +24,7 @@ class rotating_file_sink final : public base_sink<Mutex>
|
|||||||
public:
|
public:
|
||||||
rotating_file_sink(filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open = false);
|
rotating_file_sink(filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open = false);
|
||||||
static filename_t calc_filename(const filename_t &filename, std::size_t index);
|
static filename_t calc_filename(const filename_t &filename, std::size_t index);
|
||||||
const filename_t &filename() const;
|
filename_t filename();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void sink_it_(const details::log_msg &msg) override;
|
void sink_it_(const details::log_msg &msg) override;
|
||||||
@ -40,7 +40,7 @@ private:
|
|||||||
|
|
||||||
// delete the target if exists, and rename the src file to target
|
// delete the target if exists, and rename the src file to target
|
||||||
// return true on success, false otherwise.
|
// return true on success, false otherwise.
|
||||||
bool rename_file(const filename_t &src_filename, const filename_t &target_filename);
|
bool rename_file_(const filename_t &src_filename, const filename_t &target_filename);
|
||||||
|
|
||||||
filename_t base_filename_;
|
filename_t base_filename_;
|
||||||
std::size_t max_size_;
|
std::size_t max_size_;
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
namespace spdlog {
|
namespace spdlog {
|
||||||
|
|
||||||
namespace sinks {
|
namespace sinks {
|
||||||
class sink
|
class SPDLOG_API sink
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~sink() = default;
|
virtual ~sink() = default;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <spdlog/details/console_globals.h>
|
#include <spdlog/details/console_globals.h>
|
||||||
#include <spdlog/details/pattern_formatter.h>
|
#include <spdlog/pattern_formatter.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace spdlog {
|
namespace spdlog {
|
||||||
|
@ -19,8 +19,12 @@ public:
|
|||||||
using mutex_t = typename ConsoleMutex::mutex_t;
|
using mutex_t = typename ConsoleMutex::mutex_t;
|
||||||
explicit stdout_sink_base(FILE *file);
|
explicit stdout_sink_base(FILE *file);
|
||||||
~stdout_sink_base() override = default;
|
~stdout_sink_base() override = default;
|
||||||
|
|
||||||
stdout_sink_base(const stdout_sink_base &other) = delete;
|
stdout_sink_base(const stdout_sink_base &other) = delete;
|
||||||
|
stdout_sink_base(stdout_sink_base &&other) = delete;
|
||||||
|
|
||||||
stdout_sink_base &operator=(const stdout_sink_base &other) = delete;
|
stdout_sink_base &operator=(const stdout_sink_base &other) = delete;
|
||||||
|
stdout_sink_base &operator=(stdout_sink_base &&other) = delete;
|
||||||
|
|
||||||
void log(const details::log_msg &msg) override;
|
void log(const details::log_msg &msg) override;
|
||||||
void flush() override;
|
void flush() override;
|
||||||
|
@ -72,7 +72,7 @@ protected:
|
|||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
SPDLOG_THROW(spdlog_ex("Failed writing to systemd", errno));
|
throw_spdlog_ex("Failed writing to systemd", errno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
81
third_party/spdlog/include/spdlog/sinks/tcp_sink.h
vendored
Normal file
81
third_party/spdlog/include/spdlog/sinks/tcp_sink.h
vendored
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||||
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <spdlog/common.h>
|
||||||
|
#include <spdlog/sinks/base_sink.h>
|
||||||
|
#include <spdlog/details/null_mutex.h>
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <spdlog/details/tcp_client-windows.h>
|
||||||
|
#else
|
||||||
|
#include <spdlog/details/tcp_client.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <string>
|
||||||
|
#include <chrono>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Simple tcp client sink
|
||||||
|
// Connects to remote address and send the formatted log.
|
||||||
|
// Will attempt to reconnect if connection drops.
|
||||||
|
// If more complicated behaviour is needed (i.e get responses), you can inherit it and override the sink_it_ method.
|
||||||
|
|
||||||
|
namespace spdlog {
|
||||||
|
namespace sinks {
|
||||||
|
|
||||||
|
struct tcp_sink_config
|
||||||
|
{
|
||||||
|
std::string server_host;
|
||||||
|
int server_port;
|
||||||
|
bool lazy_connect = false; // if true connect on first log call instead of on construction
|
||||||
|
|
||||||
|
tcp_sink_config(std::string host, int port)
|
||||||
|
: server_host{std::move(host)}
|
||||||
|
, server_port{port}
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Mutex>
|
||||||
|
class tcp_sink : public spdlog::sinks::base_sink<Mutex>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// connect to tcp host/port or throw if failed
|
||||||
|
// host can be hostname or ip address
|
||||||
|
|
||||||
|
explicit tcp_sink(tcp_sink_config sink_config)
|
||||||
|
: config_{std::move(sink_config)}
|
||||||
|
{
|
||||||
|
if (!config_.lazy_connect)
|
||||||
|
{
|
||||||
|
this->client_.connect(config_.server_host, config_.server_port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~tcp_sink() override = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void sink_it_(const spdlog::details::log_msg &msg) override
|
||||||
|
{
|
||||||
|
spdlog::memory_buf_t formatted;
|
||||||
|
spdlog::sinks::base_sink<Mutex>::formatter_->format(msg, formatted);
|
||||||
|
if (!client_.is_connected())
|
||||||
|
{
|
||||||
|
client_.connect(config_.server_host, config_.server_port);
|
||||||
|
}
|
||||||
|
client_.send(formatted.data(), formatted.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void flush_() override {}
|
||||||
|
tcp_sink_config config_;
|
||||||
|
details::tcp_client client_;
|
||||||
|
};
|
||||||
|
|
||||||
|
using tcp_sink_mt = tcp_sink<std::mutex>;
|
||||||
|
using tcp_sink_st = tcp_sink<spdlog::details::null_mutex>;
|
||||||
|
|
||||||
|
} // namespace sinks
|
||||||
|
} // namespace spdlog
|
266
third_party/spdlog/include/spdlog/sinks/win_eventlog_sink.h
vendored
Normal file
266
third_party/spdlog/include/spdlog/sinks/win_eventlog_sink.h
vendored
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||||
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
|
// Writing to Windows Event Log requires the registry entries below to be present, with the following modifications:
|
||||||
|
// 1. <log_name> should be replaced with your log name (e.g. your application name)
|
||||||
|
// 2. <source_name> should be replaced with the specific source name and the key should be duplicated for
|
||||||
|
// each source used in the application
|
||||||
|
//
|
||||||
|
// Since typically modifications of this kind require elevation, it's better to do it as a part of setup procedure.
|
||||||
|
// The snippet below uses mscoree.dll as the message file as it exists on most of the Windows systems anyway and
|
||||||
|
// happens to contain the needed resource.
|
||||||
|
//
|
||||||
|
// You can also specify a custom message file if needed.
|
||||||
|
// Please refer to Event Log functions descriptions in MSDN for more details on custom message files.
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Windows Registry Editor Version 5.00
|
||||||
|
|
||||||
|
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\<log_name>]
|
||||||
|
|
||||||
|
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\<log_name>\<source_name>]
|
||||||
|
"TypesSupported"=dword:00000007
|
||||||
|
"EventMessageFile"=hex(2):25,00,73,00,79,00,73,00,74,00,65,00,6d,00,72,00,6f,\
|
||||||
|
00,6f,00,74,00,25,00,5c,00,53,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,\
|
||||||
|
5c,00,6d,00,73,00,63,00,6f,00,72,00,65,00,65,00,2e,00,64,00,6c,00,6c,00,00,\
|
||||||
|
00
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <spdlog/details/null_mutex.h>
|
||||||
|
#include <spdlog/sinks/base_sink.h>
|
||||||
|
|
||||||
|
#include <spdlog/details/windows_include.h>
|
||||||
|
#include <winbase.h>
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace spdlog {
|
||||||
|
namespace sinks {
|
||||||
|
|
||||||
|
namespace win_eventlog {
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
/** Windows error */
|
||||||
|
struct win32_error : public spdlog_ex
|
||||||
|
{
|
||||||
|
/** Formats an error report line: "user-message: error-code (system message)" */
|
||||||
|
static std::string format(std::string const &user_message, DWORD error_code = GetLastError())
|
||||||
|
{
|
||||||
|
std::string system_message;
|
||||||
|
|
||||||
|
LPSTR format_message_result{};
|
||||||
|
auto format_message_succeeded =
|
||||||
|
::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr,
|
||||||
|
error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&format_message_result, 0, nullptr);
|
||||||
|
|
||||||
|
if (format_message_succeeded && format_message_result)
|
||||||
|
{
|
||||||
|
system_message = fmt::format(" ({})", format_message_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format_message_result)
|
||||||
|
{
|
||||||
|
LocalFree((HLOCAL)format_message_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt::format("{}: {}{}", user_message, error_code, system_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit win32_error(std::string const &func_name, DWORD error = GetLastError())
|
||||||
|
: spdlog_ex(format(func_name, error))
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Wrapper for security identifiers (SID) on Windows */
|
||||||
|
struct sid_t
|
||||||
|
{
|
||||||
|
std::vector<char> buffer_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
sid_t() {}
|
||||||
|
|
||||||
|
/** creates a wrapped SID copy */
|
||||||
|
static sid_t duplicate_sid(PSID psid)
|
||||||
|
{
|
||||||
|
if (!::IsValidSid(psid))
|
||||||
|
{
|
||||||
|
throw_spdlog_ex("sid_t::sid_t(): invalid SID received");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const sid_length{::GetLengthSid(psid)};
|
||||||
|
|
||||||
|
sid_t result;
|
||||||
|
result.buffer_.resize(sid_length);
|
||||||
|
if (!::CopySid(sid_length, (PSID)result.as_sid(), psid))
|
||||||
|
{
|
||||||
|
SPDLOG_THROW(win32_error("CopySid"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Retrieves pointer to the internal buffer contents as SID* */
|
||||||
|
SID *as_sid() const
|
||||||
|
{
|
||||||
|
return buffer_.empty() ? nullptr : (SID *)buffer_.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get SID for the current user */
|
||||||
|
static sid_t get_current_user_sid()
|
||||||
|
{
|
||||||
|
/* create and init RAII holder for process token */
|
||||||
|
struct process_token_t
|
||||||
|
{
|
||||||
|
HANDLE token_handle_ = INVALID_HANDLE_VALUE;
|
||||||
|
explicit process_token_t(HANDLE process)
|
||||||
|
{
|
||||||
|
if (!::OpenProcessToken(process, TOKEN_QUERY, &token_handle_))
|
||||||
|
{
|
||||||
|
SPDLOG_THROW(win32_error("OpenProcessToken"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~process_token_t()
|
||||||
|
{
|
||||||
|
::CloseHandle(token_handle_);
|
||||||
|
}
|
||||||
|
|
||||||
|
} current_process_token(::GetCurrentProcess()); // GetCurrentProcess returns pseudohandle, no leak here!
|
||||||
|
|
||||||
|
// Get the required size, this is expected to fail with ERROR_INSUFFICIENT_BUFFER and return the token size
|
||||||
|
DWORD tusize = 0;
|
||||||
|
if (::GetTokenInformation(current_process_token.token_handle_, TokenUser, NULL, 0, &tusize))
|
||||||
|
{
|
||||||
|
SPDLOG_THROW(win32_error("GetTokenInformation should fail"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// get user token
|
||||||
|
std::vector<unsigned char> buffer(static_cast<size_t>(tusize));
|
||||||
|
if (!::GetTokenInformation(current_process_token.token_handle_, TokenUser, (LPVOID)buffer.data(), tusize, &tusize))
|
||||||
|
{
|
||||||
|
SPDLOG_THROW(win32_error("GetTokenInformation"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a wrapper of the SID data as stored in the user token
|
||||||
|
return sid_t::duplicate_sid(((TOKEN_USER *)buffer.data())->User.Sid);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct eventlog
|
||||||
|
{
|
||||||
|
static WORD get_event_type(details::log_msg const &msg)
|
||||||
|
{
|
||||||
|
switch (msg.level)
|
||||||
|
{
|
||||||
|
case level::trace:
|
||||||
|
case level::debug:
|
||||||
|
return EVENTLOG_SUCCESS;
|
||||||
|
|
||||||
|
case level::info:
|
||||||
|
return EVENTLOG_INFORMATION_TYPE;
|
||||||
|
|
||||||
|
case level::warn:
|
||||||
|
return EVENTLOG_WARNING_TYPE;
|
||||||
|
|
||||||
|
case level::err:
|
||||||
|
case level::critical:
|
||||||
|
case level::off:
|
||||||
|
return EVENTLOG_ERROR_TYPE;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return EVENTLOG_INFORMATION_TYPE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static WORD get_event_category(details::log_msg const &msg)
|
||||||
|
{
|
||||||
|
return (WORD)msg.level;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Windows Event Log sink
|
||||||
|
*/
|
||||||
|
template<typename Mutex>
|
||||||
|
class win_eventlog_sink : public base_sink<Mutex>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
HANDLE hEventLog_{NULL};
|
||||||
|
internal::sid_t current_user_sid_;
|
||||||
|
std::string source_;
|
||||||
|
WORD event_id_;
|
||||||
|
|
||||||
|
HANDLE event_log_handle()
|
||||||
|
{
|
||||||
|
if (!hEventLog_)
|
||||||
|
{
|
||||||
|
hEventLog_ = ::RegisterEventSource(nullptr, source_.c_str());
|
||||||
|
if (!hEventLog_ || hEventLog_ == (HANDLE)ERROR_ACCESS_DENIED)
|
||||||
|
{
|
||||||
|
SPDLOG_THROW(internal::win32_error("RegisterEventSource"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hEventLog_;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void sink_it_(const details::log_msg &msg) override
|
||||||
|
{
|
||||||
|
using namespace internal;
|
||||||
|
|
||||||
|
memory_buf_t formatted;
|
||||||
|
base_sink<Mutex>::formatter_->format(msg, formatted);
|
||||||
|
formatted.push_back('\0');
|
||||||
|
LPCSTR lp_str = static_cast<LPCSTR>(formatted.data());
|
||||||
|
|
||||||
|
auto succeeded = ::ReportEvent(event_log_handle(), eventlog::get_event_type(msg), eventlog::get_event_category(msg), event_id_,
|
||||||
|
current_user_sid_.as_sid(), 1, 0, &lp_str, nullptr);
|
||||||
|
|
||||||
|
if (!succeeded)
|
||||||
|
{
|
||||||
|
SPDLOG_THROW(win32_error("ReportEvent"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void flush_() override {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
win_eventlog_sink(std::string const &source, WORD event_id = 1000 /* according to mscoree.dll */)
|
||||||
|
: source_(source)
|
||||||
|
, event_id_(event_id)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
current_user_sid_ = internal::sid_t::get_current_user_sid();
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
// get_current_user_sid() is unlikely to fail and if it does, we can still proceed without
|
||||||
|
// current_user_sid but in the event log the record will have no user name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~win_eventlog_sink()
|
||||||
|
{
|
||||||
|
if (hEventLog_)
|
||||||
|
DeregisterEventSource(hEventLog_);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace win_eventlog
|
||||||
|
|
||||||
|
using win_eventlog_sink_mt = win_eventlog::win_eventlog_sink<std::mutex>;
|
||||||
|
using win_eventlog_sink_st = win_eventlog::win_eventlog_sink<details::null_mutex>;
|
||||||
|
|
||||||
|
} // namespace sinks
|
||||||
|
} // namespace spdlog
|
@ -8,7 +8,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <spdlog/common.h>
|
#include <spdlog/common.h>
|
||||||
#include <spdlog/details/pattern_formatter.h>
|
#include <spdlog/pattern_formatter.h>
|
||||||
|
|
||||||
namespace spdlog {
|
namespace spdlog {
|
||||||
namespace sinks {
|
namespace sinks {
|
||||||
@ -52,6 +52,8 @@ template<typename ConsoleMutex>
|
|||||||
void SPDLOG_INLINE wincolor_sink<ConsoleMutex>::log(const details::log_msg &msg)
|
void SPDLOG_INLINE wincolor_sink<ConsoleMutex>::log(const details::log_msg &msg)
|
||||||
{
|
{
|
||||||
std::lock_guard<mutex_t> lock(mutex_);
|
std::lock_guard<mutex_t> lock(mutex_);
|
||||||
|
msg.color_range_start = 0;
|
||||||
|
msg.color_range_end = 0;
|
||||||
memory_buf_t formatted;
|
memory_buf_t formatted;
|
||||||
formatter_->format(msg, formatted);
|
formatter_->format(msg, formatted);
|
||||||
if (!in_console_)
|
if (!in_console_)
|
||||||
@ -59,7 +61,6 @@ void SPDLOG_INLINE wincolor_sink<ConsoleMutex>::log(const details::log_msg &msg)
|
|||||||
write_to_file_(formatted);
|
write_to_file_(formatted);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (should_do_colors_ && msg.color_range_end > msg.color_range_start)
|
if (should_do_colors_ && msg.color_range_end > msg.color_range_start)
|
||||||
{
|
{
|
||||||
// before color range
|
// before color range
|
||||||
@ -157,7 +158,7 @@ void SPDLOG_INLINE wincolor_sink<ConsoleMutex>::write_to_file_(const memory_buf_
|
|||||||
bool ok = ::WriteFile(out_handle_, formatted.data() + total_written, size - total_written, &bytes_written, nullptr) != 0;
|
bool ok = ::WriteFile(out_handle_, formatted.data() + total_written, size - total_written, &bytes_written, nullptr) != 0;
|
||||||
if (!ok || bytes_written == 0)
|
if (!ok || bytes_written == 0)
|
||||||
{
|
{
|
||||||
SPDLOG_THROW(spdlog_ex("wincolor_sink: write_to_file_ failed. GetLastError(): " + std::to_string(::GetLastError())));
|
throw_spdlog_ex("wincolor_sink: write_to_file_ failed. GetLastError(): " + std::to_string(::GetLastError()));
|
||||||
}
|
}
|
||||||
total_written += bytes_written;
|
total_written += bytes_written;
|
||||||
} while (total_written < size);
|
} while (total_written < size);
|
||||||
|
@ -11,7 +11,9 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <array>
|
||||||
|
|
||||||
|
#include <spdlog/details/windows_include.h>
|
||||||
#include <wincon.h>
|
#include <wincon.h>
|
||||||
|
|
||||||
namespace spdlog {
|
namespace spdlog {
|
||||||
@ -52,7 +54,7 @@ protected:
|
|||||||
bool in_console_;
|
bool in_console_;
|
||||||
bool should_do_colors_;
|
bool should_do_colors_;
|
||||||
std::unique_ptr<spdlog::formatter> formatter_;
|
std::unique_ptr<spdlog::formatter> formatter_;
|
||||||
std::unordered_map<level::level_enum, WORD, level::level_hasher> colors_;
|
std::array<WORD, level::n_levels> colors_;
|
||||||
|
|
||||||
// set foreground color and return the orig console attributes (for resetting later)
|
// set foreground color and return the orig console attributes (for resetting later)
|
||||||
WORD set_foreground_color_(WORD attribs);
|
WORD set_foreground_color_(WORD attribs);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <spdlog/common.h>
|
#include <spdlog/common.h>
|
||||||
#include <spdlog/details/pattern_formatter.h>
|
#include <spdlog/pattern_formatter.h>
|
||||||
|
|
||||||
namespace spdlog {
|
namespace spdlog {
|
||||||
|
|
||||||
|
48
third_party/spdlog/include/spdlog/spdlog.h
vendored
48
third_party/spdlog/include/spdlog/spdlog.h
vendored
@ -39,68 +39,66 @@ inline std::shared_ptr<spdlog::logger> create(std::string logger_name, SinkArgs
|
|||||||
// Initialize and register a logger,
|
// Initialize and register a logger,
|
||||||
// formatter and flush level will be set according the global settings.
|
// formatter and flush level will be set according the global settings.
|
||||||
//
|
//
|
||||||
// NOTE:
|
// Useful for initializing manually created loggers with the global settings.
|
||||||
// Use this function when creating loggers manually.
|
|
||||||
//
|
//
|
||||||
// Example:
|
// Example:
|
||||||
// auto console_sink = std::make_shared<spdlog::sinks::stdout_sink_mt>();
|
// auto mylogger = std::make_shared<spdlog::logger>("mylogger", ...);
|
||||||
// auto console_logger = std::make_shared<spdlog::logger>("console_logger", console_sink);
|
// spdlog::initialize_logger(mylogger);
|
||||||
// spdlog::initialize_logger(console_logger);
|
SPDLOG_API void initialize_logger(std::shared_ptr<logger> logger);
|
||||||
void initialize_logger(std::shared_ptr<logger> logger);
|
|
||||||
|
|
||||||
// Return an existing logger or nullptr if a logger with such name doesn't
|
// Return an existing logger or nullptr if a logger with such name doesn't
|
||||||
// exist.
|
// exist.
|
||||||
// example: spdlog::get("my_logger")->info("hello {}", "world");
|
// example: spdlog::get("my_logger")->info("hello {}", "world");
|
||||||
std::shared_ptr<logger> get(const std::string &name);
|
SPDLOG_API std::shared_ptr<logger> get(const std::string &name);
|
||||||
|
|
||||||
// Set global formatter. Each sink in each logger will get a clone of this object
|
// Set global formatter. Each sink in each logger will get a clone of this object
|
||||||
void set_formatter(std::unique_ptr<spdlog::formatter> formatter);
|
SPDLOG_API void set_formatter(std::unique_ptr<spdlog::formatter> formatter);
|
||||||
|
|
||||||
// Set global format string.
|
// Set global format string.
|
||||||
// example: spdlog::set_pattern("%Y-%m-%d %H:%M:%S.%e %l : %v");
|
// example: spdlog::set_pattern("%Y-%m-%d %H:%M:%S.%e %l : %v");
|
||||||
void set_pattern(std::string pattern, pattern_time_type time_type = pattern_time_type::local);
|
SPDLOG_API void set_pattern(std::string pattern, pattern_time_type time_type = pattern_time_type::local);
|
||||||
|
|
||||||
// enable global backtrace support
|
// enable global backtrace support
|
||||||
void enable_backtrace(size_t n_messages);
|
SPDLOG_API void enable_backtrace(size_t n_messages);
|
||||||
|
|
||||||
// disable global backtrace support
|
// disable global backtrace support
|
||||||
void disable_backtrace();
|
SPDLOG_API void disable_backtrace();
|
||||||
|
|
||||||
// call dump backtrace on default logger
|
// call dump backtrace on default logger
|
||||||
void dump_backtrace();
|
SPDLOG_API void dump_backtrace();
|
||||||
|
|
||||||
// Set global logging level
|
// Set global logging level
|
||||||
void set_level(level::level_enum log_level);
|
SPDLOG_API void set_level(level::level_enum log_level);
|
||||||
|
|
||||||
// Set global flush level
|
// Set global flush level
|
||||||
void flush_on(level::level_enum log_level);
|
SPDLOG_API void flush_on(level::level_enum log_level);
|
||||||
|
|
||||||
// Start/Restart a periodic flusher thread
|
// Start/Restart a periodic flusher thread
|
||||||
// Warning: Use only if all your loggers are thread safe!
|
// Warning: Use only if all your loggers are thread safe!
|
||||||
void flush_every(std::chrono::seconds interval);
|
SPDLOG_API void flush_every(std::chrono::seconds interval);
|
||||||
|
|
||||||
// Set global error handler
|
// Set global error handler
|
||||||
void set_error_handler(void (*handler)(const std::string &msg));
|
SPDLOG_API void set_error_handler(void (*handler)(const std::string &msg));
|
||||||
|
|
||||||
// Register the given logger with the given name
|
// Register the given logger with the given name
|
||||||
void register_logger(std::shared_ptr<logger> logger);
|
SPDLOG_API void register_logger(std::shared_ptr<logger> logger);
|
||||||
|
|
||||||
// Apply a user defined function on all registered loggers
|
// Apply a user defined function on all registered loggers
|
||||||
// Example:
|
// Example:
|
||||||
// spdlog::apply_all([&](std::shared_ptr<spdlog::logger> l) {l->flush();});
|
// spdlog::apply_all([&](std::shared_ptr<spdlog::logger> l) {l->flush();});
|
||||||
void apply_all(const std::function<void(std::shared_ptr<logger>)> &fun);
|
SPDLOG_API void apply_all(const std::function<void(std::shared_ptr<logger>)> &fun);
|
||||||
|
|
||||||
// Drop the reference to the given logger
|
// Drop the reference to the given logger
|
||||||
void drop(const std::string &name);
|
SPDLOG_API void drop(const std::string &name);
|
||||||
|
|
||||||
// Drop all references from the registry
|
// Drop all references from the registry
|
||||||
void drop_all();
|
SPDLOG_API void drop_all();
|
||||||
|
|
||||||
// stop any running threads started by spdlog and clean registry loggers
|
// stop any running threads started by spdlog and clean registry loggers
|
||||||
void shutdown();
|
SPDLOG_API void shutdown();
|
||||||
|
|
||||||
// Automatic registration of loggers when using spdlog::create() or spdlog::create_async
|
// Automatic registration of loggers when using spdlog::create() or spdlog::create_async
|
||||||
void set_automatic_registration(bool automatic_registration);
|
SPDLOG_API void set_automatic_registration(bool automatic_registration);
|
||||||
|
|
||||||
// API for using default logger (stdout_color_mt),
|
// API for using default logger (stdout_color_mt),
|
||||||
// e.g: spdlog::info("Message {}", 1);
|
// e.g: spdlog::info("Message {}", 1);
|
||||||
@ -117,11 +115,11 @@ void set_automatic_registration(bool automatic_registration);
|
|||||||
// set_default_logger() *should not* be used concurrently with the default API.
|
// set_default_logger() *should not* be used concurrently with the default API.
|
||||||
// e.g do not call set_default_logger() from one thread while calling spdlog::info() from another.
|
// e.g do not call set_default_logger() from one thread while calling spdlog::info() from another.
|
||||||
|
|
||||||
std::shared_ptr<spdlog::logger> default_logger();
|
SPDLOG_API std::shared_ptr<spdlog::logger> default_logger();
|
||||||
|
|
||||||
spdlog::logger *default_logger_raw();
|
SPDLOG_API spdlog::logger *default_logger_raw();
|
||||||
|
|
||||||
void set_default_logger(std::shared_ptr<spdlog::logger> default_logger);
|
SPDLOG_API void set_default_logger(std::shared_ptr<spdlog::logger> default_logger);
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
inline void log(source_loc source, level::level_enum lvl, string_view_t fmt, const Args &... args)
|
inline void log(source_loc source, level::level_enum lvl, string_view_t fmt, const Args &... args)
|
||||||
|
9
third_party/spdlog/include/spdlog/tweakme.h
vendored
9
third_party/spdlog/include/spdlog/tweakme.h
vendored
@ -24,7 +24,7 @@
|
|||||||
// This will prevent spdlog from querying the thread id on each log call.
|
// This will prevent spdlog from querying the thread id on each log call.
|
||||||
//
|
//
|
||||||
// WARNING: If the log pattern contains thread id (i.e, %t) while this flag is
|
// WARNING: If the log pattern contains thread id (i.e, %t) while this flag is
|
||||||
// on, the result is undefined.
|
// on, zero will be logged as thread id.
|
||||||
//
|
//
|
||||||
// #define SPDLOG_NO_THREAD_ID
|
// #define SPDLOG_NO_THREAD_ID
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@ -38,13 +38,6 @@
|
|||||||
// #define SPDLOG_NO_TLS
|
// #define SPDLOG_NO_TLS
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// Uncomment if logger name logging is not needed.
|
|
||||||
// This will prevent spdlog from copying the logger name on each log call.
|
|
||||||
//
|
|
||||||
// #define SPDLOG_NO_NAME
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// Uncomment to avoid spdlog's usage of atomic log levels
|
// Uncomment to avoid spdlog's usage of atomic log levels
|
||||||
// Use only if your code never modifies a logger's log levels concurrently by
|
// Use only if your code never modifies a logger's log levels concurrently by
|
||||||
|
2
third_party/spdlog/include/spdlog/version.h
vendored
2
third_party/spdlog/include/spdlog/version.h
vendored
@ -4,7 +4,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define SPDLOG_VER_MAJOR 1
|
#define SPDLOG_VER_MAJOR 1
|
||||||
#define SPDLOG_VER_MINOR 5
|
#define SPDLOG_VER_MINOR 6
|
||||||
#define SPDLOG_VER_PATCH 0
|
#define SPDLOG_VER_PATCH 0
|
||||||
|
|
||||||
#define SPDLOG_VERSION (SPDLOG_VER_MAJOR * 10000 + SPDLOG_VER_MINOR * 100 + SPDLOG_VER_PATCH)
|
#define SPDLOG_VERSION (SPDLOG_VER_MAJOR * 10000 + SPDLOG_VER_MINOR * 100 + SPDLOG_VER_PATCH)
|
||||||
|
43
third_party/spdlog/logos/jetbrains-variant-4.svg
vendored
Normal file
43
third_party/spdlog/logos/jetbrains-variant-4.svg
vendored
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="263" height="147" viewBox="0 0 263 147">
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="linear-gradient" x1="54.4568" y1="122.5936" x2="251.779" y2="10.2057" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0" stop-color="#00adee"/>
|
||||||
|
<stop offset="1" stop-color="#9f76a6"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="linear-gradient-2" x1="80.247" y1="38.7607" x2="241.2622" y2="10.9511" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0" stop-color="#ec037c"/>
|
||||||
|
<stop offset="1" stop-color="#9f76a6"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="linear-gradient-3" x1="75.7205" y1="33.5582" x2="127.8253" y2="123.9392" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0" stop-color="#ec037c"/>
|
||||||
|
<stop offset="1" stop-color="#5c2d90"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="linear-gradient-4" x1="7.4647" y1="44.578" x2="129.4543" y2="125.0813" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0" stop-color="#44c7f4"/>
|
||||||
|
<stop offset="1" stop-color="#5c2d90"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<g>
|
||||||
|
<path d="M261.1839,10.3622a9.6784,9.6784,0,0,0-14.7448-8.2463l0-.0006L20.6942,136.0746h0a4.6974,4.6974,0,1,0,4.1326,8.4348h0q0.09-.0467.1784-0.097l230.5273-125.25a9.653,9.653,0,0,0,1.1508-.6253l0.0332-.018-0.0014-.0023A9.6682,9.6682,0,0,0,261.1839,10.3622Z" fill="url(#linear-gradient)"/>
|
||||||
|
<path d="M261.1839,10.3622A9.6782,9.6782,0,0,0,251.5057.684q-0.2747,0-.5456.0157-0.25.0143-.4975,0.041L76.7981,25.4187A13.7347,13.7347,0,1,0,83.5355,51.983L252.8044,19.9512a9.6363,9.6363,0,0,0,1.0358-.196l0.02-.0039,0-.0008A9.6811,9.6811,0,0,0,261.1839,10.3622Z" fill="url(#linear-gradient-2)"/>
|
||||||
|
<path d="M145.2028,123.63a17.2372,17.2372,0,0,0-3.0637-9.4254L91.3045,32.3521A13.7366,13.7366,0,0,0,66.1132,42.9507h0a13.6332,13.6332,0,0,0,1.043,2.4984s45.2334,86.37,45.5824,86.9979q0.3089,0.556.6567,1.0861h0A17.32,17.32,0,0,0,145.2028,123.63Z" fill="url(#linear-gradient-3)"/>
|
||||||
|
<path d="M145.2028,123.63a17.2979,17.2979,0,0,0-7.63-13.9419h0a17.3061,17.3061,0,0,0-2.6994-1.4911L9.5484,38.9679a6.064,6.064,0,0,0-6.5074,10.187l114.3963,88.704A17.3191,17.3191,0,0,0,145.2028,123.63Z" fill="url(#linear-gradient-4)"/>
|
||||||
|
<g>
|
||||||
|
<rect x="69" y="51" width="70" height="70"/>
|
||||||
|
<g>
|
||||||
|
<rect x="75.038" y="107.8746" width="26.2498" height="4.375" fill="#fff"/>
|
||||||
|
<g>
|
||||||
|
<path d="M74.7429,69.4315L76.78,67.5082a2.31,2.31,0,0,0,1.7929,1.0594A1.33,1.33,0,0,0,79.8607,66.97V59.75h3.1456v7.2366a4.2386,4.2386,0,0,1-1.1246,3.2108,4.2989,4.2989,0,0,1-3.1293,1.1572A4.6592,4.6592,0,0,1,74.7429,69.4315Z" fill="#fff"/>
|
||||||
|
<path d="M83.7394,59.75h9.1761v2.673H86.8688v1.744H92.345v2.4937H86.8688V68.47H92.997v2.6893H83.7394V59.75Z" fill="#fff"/>
|
||||||
|
<path d="M97.049,62.5208H93.6426V59.75h9.9911v2.7708h-3.4227v8.6383H97.049V62.5208Z" fill="#fff"/>
|
||||||
|
<path d="M75.0363,73.8257h5.8511A4.2728,4.2728,0,0,1,84,74.8363a2.5675,2.5675,0,0,1,.7335,1.858v0.0326a2.6407,2.6407,0,0,1-1.76,2.5425,2.7686,2.7686,0,0,1,2.2655,2.7871v0.0326c0,1.9558-1.5973,3.1456-4.3191,3.1456H75.0363V73.8257Zm6.5846,3.5206c0-.6357-0.5052-0.9779-1.4343-0.9779h-2.07v2.0047h1.9884c0.9616,0,1.5158-.326,1.5158-0.9942V77.3463ZM80.5289,80.59H78.1166v2.1025h2.4448c0.9779,0,1.5158-.3749,1.5158-1.0431V81.6165C82.0773,80.9972,81.5883,80.59,80.5289,80.59Z" fill="#fff"/>
|
||||||
|
<path d="M85.7116,73.8257h5.3949a5.0512,5.0512,0,0,1,3.7161,1.2224,3.5623,3.5623,0,0,1,1.01,2.6567v0.0326a3.6146,3.6146,0,0,1-2.3469,3.5205l2.7218,3.9769H92.5733l-2.2981-3.4553H88.8735v3.4553H85.7116V73.8257Zm5.2644,5.4764a1.433,1.433,0,0,0,1.6951-1.3528V77.9167c0-.9128-0.6682-1.3691-1.7114-1.3691H88.8735v2.7545H90.976Z" fill="#fff"/>
|
||||||
|
<path d="M99.5324,73.7443H102.58l4.8571,11.4905h-3.39l-0.815-2.0536H98.8153L98,85.2348H94.6917Zm2.7707,6.9758-1.2712-3.2271L99.7443,80.72h2.5589Z" fill="#fff"/>
|
||||||
|
<path d="M107.8117,73.8257h3.1619V85.2348h-3.1619V73.8257Z" fill="#fff"/>
|
||||||
|
<path d="M111.7558,73.8257h2.95l4.694,6.0306V73.8257h3.1294V85.2348h-2.7545l-4.89-6.2587v6.2587h-3.1293V73.8257Z" fill="#fff"/>
|
||||||
|
<path d="M122.7274,83.54l1.76-2.1025a5.9106,5.9106,0,0,0,3.7,1.3691c0.8638,0,1.32-.2934,1.32-0.7824V81.9914c0-.489-0.3749-0.7335-1.9395-1.1084-2.4285-.5541-4.3029-1.2387-4.3029-3.5694V77.2811c0-2.1188,1.6788-3.6509,4.417-3.6509a7.1807,7.1807,0,0,1,4.694,1.5158l-1.5809,2.2329a5.6006,5.6006,0,0,0-3.1946-1.1246c-0.766,0-1.1409.31-1.1409,0.7334V77.02c0,0.5216.3912,0.75,1.9884,1.1083,2.6077,0.57,4.2377,1.418,4.2377,3.5531v0.0326c0,2.3307-1.8418,3.7161-4.6126,3.7161A7.9992,7.9992,0,0,1,122.7274,83.54Z" fill="#fff"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.6 KiB |
7
third_party/spdlog/meson.build
vendored
7
third_party/spdlog/meson.build
vendored
@ -23,7 +23,7 @@ if get_option('external_fmt')
|
|||||||
if not meson.version().version_compare('>=0.49.0')
|
if not meson.version().version_compare('>=0.49.0')
|
||||||
warning('Finding fmt can fail with meson versions before 0.49.0')
|
warning('Finding fmt can fail with meson versions before 0.49.0')
|
||||||
endif
|
endif
|
||||||
dep_list += dependency('fmt')
|
dep_list += dependency('fmt', fallback : ['fmt', 'fmt_dep'])
|
||||||
compile_args += '-DSPDLOG_FMT_EXTERNAL'
|
compile_args += '-DSPDLOG_FMT_EXTERNAL'
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -82,7 +82,8 @@ spdlog_srcs = files([
|
|||||||
'src/color_sinks.cpp',
|
'src/color_sinks.cpp',
|
||||||
'src/file_sinks.cpp',
|
'src/file_sinks.cpp',
|
||||||
'src/spdlog.cpp',
|
'src/spdlog.cpp',
|
||||||
'src/stdout_sinks.cpp'
|
'src/stdout_sinks.cpp',
|
||||||
|
'src/cfg.cpp'
|
||||||
])
|
])
|
||||||
|
|
||||||
if not get_option('external_fmt')
|
if not get_option('external_fmt')
|
||||||
@ -148,7 +149,7 @@ endif
|
|||||||
# --- Conditionally add subdirs ---
|
# --- Conditionally add subdirs ---
|
||||||
# -------------------------------------
|
# -------------------------------------
|
||||||
|
|
||||||
if get_option('enable_tests') or get_option('enable_tests-ho')
|
if get_option('enable_tests') or get_option('enable_tests_ho')
|
||||||
subdir('tests')
|
subdir('tests')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
5
third_party/spdlog/scripts/clang_tidy.sh
vendored
5
third_party/spdlog/scripts/clang_tidy.sh
vendored
@ -1,5 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
cd "$(dirname "$0")"
|
|
||||||
|
|
||||||
clang-tidy ../example/example.cpp -- -I ../include
|
|
8
third_party/spdlog/scripts/format.sh
vendored
8
third_party/spdlog/scripts/format.sh
vendored
@ -1,12 +1,12 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
cd "$(dirname "$0")"
|
cd "$(dirname "$0")"/..
|
||||||
|
pwd
|
||||||
echo -n "Running dos2unix "
|
echo -n "Running dos2unix "
|
||||||
find .. -name "*\.h" -o -name "*\.cpp"|grep -v bundled|xargs -I {} sh -c "dos2unix '{}' 2>/dev/null; echo -n '.'"
|
find . -name "*\.h" -o -name "*\.cpp"|grep -v bundled|xargs -I {} sh -c "dos2unix '{}' 2>/dev/null; echo -n '.'"
|
||||||
echo
|
echo
|
||||||
echo -n "Running clang-format "
|
echo -n "Running clang-format "
|
||||||
find .. -name "*\.h" -o -name "*\.cpp"|grep -v bundled|xargs -I {} sh -c "clang-format -i {}; echo -n '.'"
|
find . -name "*\.h" -o -name "*\.cpp"|grep -v bundled|xargs -I {} sh -c "clang-format -i {}; echo -n '.'"
|
||||||
echo
|
echo
|
||||||
|
|
||||||
|
|
||||||
|
11
third_party/spdlog/src/async.cpp
vendored
11
third_party/spdlog/src/async.cpp
vendored
@ -5,8 +5,9 @@
|
|||||||
#error Please define SPDLOG_COMPILED_LIB to compile this file.
|
#error Please define SPDLOG_COMPILED_LIB to compile this file.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "spdlog/async.h"
|
#include <spdlog/async.h>
|
||||||
#include "spdlog/async_logger-inl.h"
|
#include <spdlog/async_logger-inl.h>
|
||||||
#include "spdlog/details/periodic_worker-inl.h"
|
#include <spdlog/details/periodic_worker-inl.h>
|
||||||
#include "spdlog/details/thread_pool-inl.h"
|
#include <spdlog/details/thread_pool-inl.h>
|
||||||
template class spdlog::details::mpmc_blocking_queue<spdlog::details::async_msg>;
|
|
||||||
|
template class SPDLOG_API spdlog::details::mpmc_blocking_queue<spdlog::details::async_msg>;
|
8
third_party/spdlog/src/cfg.cpp
vendored
Normal file
8
third_party/spdlog/src/cfg.cpp
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||||
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
|
#ifndef SPDLOG_COMPILED_LIB
|
||||||
|
#error Please define SPDLOG_COMPILED_LIB to compile this file.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <spdlog/cfg/helpers-inl.h>
|
38
third_party/spdlog/src/color_sinks.cpp
vendored
38
third_party/spdlog/src/color_sinks.cpp
vendored
@ -7,19 +7,19 @@
|
|||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include "spdlog/details/null_mutex.h"
|
#include <spdlog/details/null_mutex.h>
|
||||||
#include "spdlog/async.h"
|
#include <spdlog/async.h>
|
||||||
//
|
//
|
||||||
// color sinks
|
// color sinks
|
||||||
//
|
//
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include "spdlog/sinks/wincolor_sink-inl.h"
|
#include <spdlog/sinks/wincolor_sink-inl.h>
|
||||||
template class spdlog::sinks::wincolor_sink<spdlog::details::console_mutex>;
|
template class SPDLOG_API spdlog::sinks::wincolor_sink<spdlog::details::console_mutex>;
|
||||||
template class spdlog::sinks::wincolor_sink<spdlog::details::console_nullmutex>;
|
template class SPDLOG_API spdlog::sinks::wincolor_sink<spdlog::details::console_nullmutex>;
|
||||||
template class spdlog::sinks::wincolor_stdout_sink<spdlog::details::console_mutex>;
|
template class SPDLOG_API spdlog::sinks::wincolor_stdout_sink<spdlog::details::console_mutex>;
|
||||||
template class spdlog::sinks::wincolor_stdout_sink<spdlog::details::console_nullmutex>;
|
template class SPDLOG_API spdlog::sinks::wincolor_stdout_sink<spdlog::details::console_nullmutex>;
|
||||||
template class spdlog::sinks::wincolor_stderr_sink<spdlog::details::console_mutex>;
|
template class SPDLOG_API spdlog::sinks::wincolor_stderr_sink<spdlog::details::console_mutex>;
|
||||||
template class spdlog::sinks::wincolor_stderr_sink<spdlog::details::console_nullmutex>;
|
template class SPDLOG_API spdlog::sinks::wincolor_stderr_sink<spdlog::details::console_nullmutex>;
|
||||||
#else
|
#else
|
||||||
#include "spdlog/sinks/ansicolor_sink-inl.h"
|
#include "spdlog/sinks/ansicolor_sink-inl.h"
|
||||||
template class spdlog::sinks::ansicolor_sink<spdlog::details::console_mutex>;
|
template class spdlog::sinks::ansicolor_sink<spdlog::details::console_mutex>;
|
||||||
@ -32,16 +32,20 @@ template class spdlog::sinks::ansicolor_stderr_sink<spdlog::details::console_nul
|
|||||||
|
|
||||||
// factory methods for color loggers
|
// factory methods for color loggers
|
||||||
#include "spdlog/sinks/stdout_color_sinks-inl.h"
|
#include "spdlog/sinks/stdout_color_sinks-inl.h"
|
||||||
template std::shared_ptr<spdlog::logger> spdlog::stdout_color_mt<spdlog::synchronous_factory>(
|
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_color_mt<spdlog::synchronous_factory>(
|
||||||
const std::string &logger_name, color_mode mode);
|
const std::string &logger_name, color_mode mode);
|
||||||
template std::shared_ptr<spdlog::logger> spdlog::stdout_color_st<spdlog::synchronous_factory>(
|
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_color_st<spdlog::synchronous_factory>(
|
||||||
const std::string &logger_name, color_mode mode);
|
const std::string &logger_name, color_mode mode);
|
||||||
template std::shared_ptr<spdlog::logger> spdlog::stderr_color_mt<spdlog::synchronous_factory>(
|
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_color_mt<spdlog::synchronous_factory>(
|
||||||
const std::string &logger_name, color_mode mode);
|
const std::string &logger_name, color_mode mode);
|
||||||
template std::shared_ptr<spdlog::logger> spdlog::stderr_color_st<spdlog::synchronous_factory>(
|
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_color_st<spdlog::synchronous_factory>(
|
||||||
const std::string &logger_name, color_mode mode);
|
const std::string &logger_name, color_mode mode);
|
||||||
|
|
||||||
template std::shared_ptr<spdlog::logger> spdlog::stdout_color_mt<spdlog::async_factory>(const std::string &logger_name, color_mode mode);
|
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_color_mt<spdlog::async_factory>(
|
||||||
template std::shared_ptr<spdlog::logger> spdlog::stdout_color_st<spdlog::async_factory>(const std::string &logger_name, color_mode mode);
|
const std::string &logger_name, color_mode mode);
|
||||||
template std::shared_ptr<spdlog::logger> spdlog::stderr_color_mt<spdlog::async_factory>(const std::string &logger_name, color_mode mode);
|
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_color_st<spdlog::async_factory>(
|
||||||
template std::shared_ptr<spdlog::logger> spdlog::stderr_color_st<spdlog::async_factory>(const std::string &logger_name, color_mode mode);
|
const std::string &logger_name, color_mode mode);
|
||||||
|
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_color_mt<spdlog::async_factory>(
|
||||||
|
const std::string &logger_name, color_mode mode);
|
||||||
|
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_color_st<spdlog::async_factory>(
|
||||||
|
const std::string &logger_name, color_mode mode);
|
||||||
|
18
third_party/spdlog/src/file_sinks.cpp
vendored
18
third_party/spdlog/src/file_sinks.cpp
vendored
@ -5,14 +5,16 @@
|
|||||||
#error Please define SPDLOG_COMPILED_LIB to compile this file.
|
#error Please define SPDLOG_COMPILED_LIB to compile this file.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <spdlog/details/null_mutex.h>
|
||||||
|
#include <spdlog/details/file_helper-inl.h>
|
||||||
|
#include <spdlog/sinks/basic_file_sink-inl.h>
|
||||||
|
#include <spdlog/sinks/base_sink-inl.h>
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include "spdlog/details/null_mutex.h"
|
|
||||||
#include "spdlog/details/file_helper-inl.h"
|
|
||||||
#include "spdlog/sinks/basic_file_sink-inl.h"
|
|
||||||
|
|
||||||
template class spdlog::sinks::basic_file_sink<std::mutex>;
|
template class SPDLOG_API spdlog::sinks::basic_file_sink<std::mutex>;
|
||||||
template class spdlog::sinks::basic_file_sink<spdlog::details::null_mutex>;
|
template class SPDLOG_API spdlog::sinks::basic_file_sink<spdlog::details::null_mutex>;
|
||||||
|
|
||||||
#include "spdlog/sinks/rotating_file_sink-inl.h"
|
#include <spdlog/sinks/rotating_file_sink-inl.h>
|
||||||
template class spdlog::sinks::rotating_file_sink<std::mutex>;
|
template class SPDLOG_API spdlog::sinks::rotating_file_sink<std::mutex>;
|
||||||
template class spdlog::sinks::rotating_file_sink<spdlog::details::null_mutex>;
|
template class SPDLOG_API spdlog::sinks::rotating_file_sink<spdlog::details::null_mutex>;
|
185
third_party/spdlog/src/fmt.cpp
vendored
185
third_party/spdlog/src/fmt.cpp
vendored
@ -6,29 +6,150 @@
|
|||||||
// Copyright (c) 2012 - 2016, Victor Zverovich
|
// Copyright (c) 2012 - 2016, Victor Zverovich
|
||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
|
|
||||||
#if defined(__GNUC__) || defined(__clang__)
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
|
|
||||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(SPDLOG_FMT_EXTERNAL)
|
#if !defined(SPDLOG_FMT_EXTERNAL)
|
||||||
#include "spdlog/fmt/bundled/format-inl.h"
|
#include <spdlog/fmt/bundled/format-inl.h>
|
||||||
|
|
||||||
|
|
||||||
// pop warnings supressions
|
|
||||||
#if defined(__GNUC__) || defined(__clang__)
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
FMT_BEGIN_NAMESPACE
|
FMT_BEGIN_NAMESPACE
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
int format_float(char *buf, std::size_t size, const char *format, int precision, T value)
|
||||||
|
{
|
||||||
|
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
|
||||||
|
if (precision > 100000)
|
||||||
|
throw std::runtime_error("fuzz mode - avoid large allocation inside snprintf");
|
||||||
|
#endif
|
||||||
|
// Suppress the warning about nonliteral format string.
|
||||||
|
auto snprintf_ptr = FMT_SNPRINTF;
|
||||||
|
return precision < 0 ? snprintf_ptr(buf, size, format, value) : snprintf_ptr(buf, size, format, precision, value);
|
||||||
|
}
|
||||||
|
struct sprintf_specs
|
||||||
|
{
|
||||||
|
int precision;
|
||||||
|
char type;
|
||||||
|
bool alt : 1;
|
||||||
|
|
||||||
|
template<typename Char>
|
||||||
|
constexpr sprintf_specs(basic_format_specs<Char> specs)
|
||||||
|
: precision(specs.precision)
|
||||||
|
, type(specs.type)
|
||||||
|
, alt(specs.alt)
|
||||||
|
{}
|
||||||
|
|
||||||
|
constexpr bool has_precision() const
|
||||||
|
{
|
||||||
|
return precision >= 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is deprecated and is kept only to preserve ABI compatibility.
|
||||||
|
template<typename Double>
|
||||||
|
char *sprintf_format(Double value, internal::buffer<char> &buf, sprintf_specs specs)
|
||||||
|
{
|
||||||
|
// Buffer capacity must be non-zero, otherwise MSVC's vsnprintf_s will fail.
|
||||||
|
FMT_ASSERT(buf.capacity() != 0, "empty buffer");
|
||||||
|
|
||||||
|
// Build format string.
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
max_format_size = 10
|
||||||
|
}; // longest format: %#-*.*Lg
|
||||||
|
char format[max_format_size];
|
||||||
|
char *format_ptr = format;
|
||||||
|
*format_ptr++ = '%';
|
||||||
|
if (specs.alt || !specs.type)
|
||||||
|
*format_ptr++ = '#';
|
||||||
|
if (specs.precision >= 0)
|
||||||
|
{
|
||||||
|
*format_ptr++ = '.';
|
||||||
|
*format_ptr++ = '*';
|
||||||
|
}
|
||||||
|
if (std::is_same<Double, long double>::value)
|
||||||
|
*format_ptr++ = 'L';
|
||||||
|
|
||||||
|
char type = specs.type;
|
||||||
|
|
||||||
|
if (type == '%')
|
||||||
|
type = 'f';
|
||||||
|
else if (type == 0 || type == 'n')
|
||||||
|
type = 'g';
|
||||||
|
#if FMT_MSC_VER
|
||||||
|
if (type == 'F')
|
||||||
|
{
|
||||||
|
// MSVC's printf doesn't support 'F'.
|
||||||
|
type = 'f';
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
*format_ptr++ = type;
|
||||||
|
*format_ptr = '\0';
|
||||||
|
|
||||||
|
// Format using snprintf.
|
||||||
|
char *start = nullptr;
|
||||||
|
char *decimal_point_pos = nullptr;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
std::size_t buffer_size = buf.capacity();
|
||||||
|
start = &buf[0];
|
||||||
|
int result = format_float(start, buffer_size, format, specs.precision, value);
|
||||||
|
if (result >= 0)
|
||||||
|
{
|
||||||
|
unsigned n = internal::to_unsigned(result);
|
||||||
|
if (n < buf.capacity())
|
||||||
|
{
|
||||||
|
// Find the decimal point.
|
||||||
|
auto p = buf.data(), end = p + n;
|
||||||
|
if (*p == '+' || *p == '-')
|
||||||
|
++p;
|
||||||
|
if (specs.type != 'a' && specs.type != 'A')
|
||||||
|
{
|
||||||
|
while (p < end && *p >= '0' && *p <= '9')
|
||||||
|
++p;
|
||||||
|
if (p < end && *p != 'e' && *p != 'E')
|
||||||
|
{
|
||||||
|
decimal_point_pos = p;
|
||||||
|
if (!specs.type)
|
||||||
|
{
|
||||||
|
// Keep only one trailing zero after the decimal point.
|
||||||
|
++p;
|
||||||
|
if (*p == '0')
|
||||||
|
++p;
|
||||||
|
while (p != end && *p >= '1' && *p <= '9')
|
||||||
|
++p;
|
||||||
|
char *where = p;
|
||||||
|
while (p != end && *p == '0')
|
||||||
|
++p;
|
||||||
|
if (p == end || *p < '0' || *p > '9')
|
||||||
|
{
|
||||||
|
if (p != end)
|
||||||
|
std::memmove(where, p, to_unsigned(end - p));
|
||||||
|
n -= static_cast<unsigned>(p - where);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf.resize(n);
|
||||||
|
break; // The buffer is large enough - continue with formatting.
|
||||||
|
}
|
||||||
|
buf.reserve(n + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If result is negative we ask to increase the capacity by at least 1,
|
||||||
|
// but as std::vector, the buffer grows exponentially.
|
||||||
|
buf.reserve(buf.capacity() + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return decimal_point_pos;
|
||||||
|
}
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
template FMT_API char *internal::sprintf_format(double, internal::buffer<char> &, sprintf_specs);
|
||||||
|
template FMT_API char *internal::sprintf_format(long double, internal::buffer<char> &, sprintf_specs);
|
||||||
|
|
||||||
template struct FMT_API internal::basic_data<void>;
|
template struct FMT_API internal::basic_data<void>;
|
||||||
|
|
||||||
// Workaround a bug in MSVC2013 that prevents instantiation of format_float.
|
// Workaround a bug in MSVC2013 that prevents instantiation of format_float.
|
||||||
int (*instantiate_format_float)(double, int, internal::float_specs,
|
int (*instantiate_format_float)(double, int, internal::float_specs, internal::buffer<char> &) = internal::format_float;
|
||||||
internal::buffer<char>&) =
|
|
||||||
internal::format_float;
|
|
||||||
|
|
||||||
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
|
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
|
||||||
template FMT_API internal::locale_ref::locale_ref(const std::locale &loc);
|
template FMT_API internal::locale_ref::locale_ref(const std::locale &loc);
|
||||||
@ -43,26 +164,16 @@ template FMT_API char internal::decimal_point_impl(locale_ref);
|
|||||||
|
|
||||||
template FMT_API void internal::buffer<char>::append(const char *, const char *);
|
template FMT_API void internal::buffer<char>::append(const char *, const char *);
|
||||||
|
|
||||||
template FMT_API void internal::arg_map<format_context>::init(
|
template FMT_API void internal::arg_map<format_context>::init(const basic_format_args<format_context> &args);
|
||||||
const basic_format_args<format_context>& args);
|
|
||||||
|
|
||||||
template FMT_API std::string internal::vformat<char>(
|
template FMT_API std::string internal::vformat<char>(string_view, basic_format_args<format_context>);
|
||||||
string_view, basic_format_args<format_context>);
|
|
||||||
|
|
||||||
template FMT_API format_context::iterator internal::vformat_to(
|
template FMT_API format_context::iterator internal::vformat_to(internal::buffer<char> &, string_view, basic_format_args<format_context>);
|
||||||
internal::buffer<char>&, string_view, basic_format_args<format_context>);
|
|
||||||
|
|
||||||
template FMT_API int internal::snprintf_float(double, int,
|
template FMT_API int internal::snprintf_float(double, int, internal::float_specs, internal::buffer<char> &);
|
||||||
internal::float_specs,
|
template FMT_API int internal::snprintf_float(long double, int, internal::float_specs, internal::buffer<char> &);
|
||||||
internal::buffer<char>&);
|
template FMT_API int internal::format_float(double, int, internal::float_specs, internal::buffer<char> &);
|
||||||
template FMT_API int internal::snprintf_float(long double, int,
|
template FMT_API int internal::format_float(long double, int, internal::float_specs, internal::buffer<char> &);
|
||||||
internal::float_specs,
|
|
||||||
internal::buffer<char>&);
|
|
||||||
template FMT_API int internal::format_float(double, int, internal::float_specs,
|
|
||||||
internal::buffer<char>&);
|
|
||||||
template FMT_API int internal::format_float(long double, int,
|
|
||||||
internal::float_specs,
|
|
||||||
internal::buffer<char>&);
|
|
||||||
|
|
||||||
// Explicit instantiations for wchar_t.
|
// Explicit instantiations for wchar_t.
|
||||||
|
|
||||||
@ -70,11 +181,9 @@ template FMT_API std::string internal::grouping_impl<wchar_t>(locale_ref);
|
|||||||
template FMT_API wchar_t internal::thousands_sep_impl(locale_ref);
|
template FMT_API wchar_t internal::thousands_sep_impl(locale_ref);
|
||||||
template FMT_API wchar_t internal::decimal_point_impl(locale_ref);
|
template FMT_API wchar_t internal::decimal_point_impl(locale_ref);
|
||||||
|
|
||||||
template FMT_API void internal::buffer<wchar_t>::append(const wchar_t*,
|
template FMT_API void internal::buffer<wchar_t>::append(const wchar_t *, const wchar_t *);
|
||||||
const wchar_t*);
|
|
||||||
|
|
||||||
template FMT_API std::wstring internal::vformat<wchar_t>(
|
template FMT_API std::wstring internal::vformat<wchar_t>(wstring_view, basic_format_args<wformat_context>);
|
||||||
wstring_view, basic_format_args<wformat_context>);
|
|
||||||
FMT_END_NAMESPACE
|
FMT_END_NAMESPACE
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
30
third_party/spdlog/src/spdlog.cpp
vendored
30
third_party/spdlog/src/spdlog.cpp
vendored
@ -5,22 +5,22 @@
|
|||||||
#error Please define SPDLOG_COMPILED_LIB to compile this file.
|
#error Please define SPDLOG_COMPILED_LIB to compile this file.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "spdlog/spdlog-inl.h"
|
#include <spdlog/spdlog-inl.h>
|
||||||
#include "spdlog/common-inl.h"
|
#include <spdlog/common-inl.h>
|
||||||
#include "spdlog/details/backtracer-inl.h"
|
#include <spdlog/details/backtracer-inl.h>
|
||||||
#include "spdlog/details/registry-inl.h"
|
#include <spdlog/details/registry-inl.h>
|
||||||
#include "spdlog/details/os-inl.h"
|
#include <spdlog/details/os-inl.h>
|
||||||
#include "spdlog/details/pattern_formatter-inl.h"
|
#include <spdlog/pattern_formatter-inl.h>
|
||||||
#include "spdlog/details/log_msg-inl.h"
|
#include <spdlog/details/log_msg-inl.h>
|
||||||
#include "spdlog/details/log_msg_buffer-inl.h"
|
#include <spdlog/details/log_msg_buffer-inl.h>
|
||||||
#include "spdlog/logger-inl.h"
|
#include <spdlog/logger-inl.h>
|
||||||
#include "spdlog/sinks/sink-inl.h"
|
#include <spdlog/sinks/sink-inl.h>
|
||||||
#include "spdlog/sinks/base_sink-inl.h"
|
#include <spdlog/sinks/base_sink-inl.h>
|
||||||
#include "spdlog/details/null_mutex.h"
|
#include <spdlog/details/null_mutex.h>
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
// template instantiate logger constructor with sinks init list
|
// template instantiate logger constructor with sinks init list
|
||||||
template spdlog::logger::logger(std::string name, sinks_init_list::iterator begin, sinks_init_list::iterator end);
|
template SPDLOG_API spdlog::logger::logger(std::string name, sinks_init_list::iterator begin, sinks_init_list::iterator end);
|
||||||
template class spdlog::sinks::base_sink<std::mutex>;
|
template class SPDLOG_API spdlog::sinks::base_sink<std::mutex>;
|
||||||
template class spdlog::sinks::base_sink<spdlog::details::null_mutex>;
|
template class SPDLOG_API spdlog::sinks::base_sink<spdlog::details::null_mutex>;
|
34
third_party/spdlog/src/stdout_sinks.cpp
vendored
34
third_party/spdlog/src/stdout_sinks.cpp
vendored
@ -7,23 +7,23 @@
|
|||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include "spdlog/details/null_mutex.h"
|
#include <spdlog/details/null_mutex.h>
|
||||||
#include "spdlog/async.h"
|
#include <spdlog/async.h>
|
||||||
#include "spdlog/sinks/stdout_sinks-inl.h"
|
#include <spdlog/sinks/stdout_sinks-inl.h>
|
||||||
|
|
||||||
template class spdlog::sinks::stdout_sink_base<spdlog::details::console_mutex>;
|
template class SPDLOG_API spdlog::sinks::stdout_sink_base<spdlog::details::console_mutex>;
|
||||||
template class spdlog::sinks::stdout_sink_base<spdlog::details::console_nullmutex>;
|
template class SPDLOG_API spdlog::sinks::stdout_sink_base<spdlog::details::console_nullmutex>;
|
||||||
template class spdlog::sinks::stdout_sink<spdlog::details::console_mutex>;
|
template class SPDLOG_API spdlog::sinks::stdout_sink<spdlog::details::console_mutex>;
|
||||||
template class spdlog::sinks::stdout_sink<spdlog::details::console_nullmutex>;
|
template class SPDLOG_API spdlog::sinks::stdout_sink<spdlog::details::console_nullmutex>;
|
||||||
template class spdlog::sinks::stderr_sink<spdlog::details::console_mutex>;
|
template class SPDLOG_API spdlog::sinks::stderr_sink<spdlog::details::console_mutex>;
|
||||||
template class spdlog::sinks::stderr_sink<spdlog::details::console_nullmutex>;
|
template class SPDLOG_API spdlog::sinks::stderr_sink<spdlog::details::console_nullmutex>;
|
||||||
|
|
||||||
template std::shared_ptr<spdlog::logger> spdlog::stdout_logger_mt<spdlog::synchronous_factory>(const std::string &logger_name);
|
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_logger_mt<spdlog::synchronous_factory>(const std::string &logger_name);
|
||||||
template std::shared_ptr<spdlog::logger> spdlog::stdout_logger_st<spdlog::synchronous_factory>(const std::string &logger_name);
|
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_logger_st<spdlog::synchronous_factory>(const std::string &logger_name);
|
||||||
template std::shared_ptr<spdlog::logger> spdlog::stderr_logger_mt<spdlog::synchronous_factory>(const std::string &logger_name);
|
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_logger_mt<spdlog::synchronous_factory>(const std::string &logger_name);
|
||||||
template std::shared_ptr<spdlog::logger> spdlog::stderr_logger_st<spdlog::synchronous_factory>(const std::string &logger_name);
|
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_logger_st<spdlog::synchronous_factory>(const std::string &logger_name);
|
||||||
|
|
||||||
template std::shared_ptr<spdlog::logger> spdlog::stdout_logger_mt<spdlog::async_factory>(const std::string &logger_name);
|
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_logger_mt<spdlog::async_factory>(const std::string &logger_name);
|
||||||
template std::shared_ptr<spdlog::logger> spdlog::stdout_logger_st<spdlog::async_factory>(const std::string &logger_name);
|
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_logger_st<spdlog::async_factory>(const std::string &logger_name);
|
||||||
template std::shared_ptr<spdlog::logger> spdlog::stderr_logger_mt<spdlog::async_factory>(const std::string &logger_name);
|
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_logger_mt<spdlog::async_factory>(const std::string &logger_name);
|
||||||
template std::shared_ptr<spdlog::logger> spdlog::stderr_logger_st<spdlog::async_factory>(const std::string &logger_name);
|
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_logger_st<spdlog::async_factory>(const std::string &logger_name);
|
12
third_party/spdlog/tests/CMakeLists.txt
vendored
12
third_party/spdlog/tests/CMakeLists.txt
vendored
@ -1,5 +1,12 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.2)
|
||||||
|
|
||||||
project(spdlog_utests CXX)
|
project(spdlog_utests CXX)
|
||||||
|
|
||||||
|
if(NOT TARGET spdlog)
|
||||||
|
# Stand-alone build
|
||||||
|
find_package(spdlog REQUIRED)
|
||||||
|
endif()
|
||||||
|
|
||||||
include(../cmake/utils.cmake)
|
include(../cmake/utils.cmake)
|
||||||
|
|
||||||
find_package(PkgConfig)
|
find_package(PkgConfig)
|
||||||
@ -12,6 +19,7 @@ set(SPDLOG_UTESTS_SOURCES
|
|||||||
test_file_logging.cpp
|
test_file_logging.cpp
|
||||||
test_daily_logger.cpp
|
test_daily_logger.cpp
|
||||||
test_misc.cpp
|
test_misc.cpp
|
||||||
|
test_eventlog.cpp
|
||||||
test_pattern_formatter.cpp
|
test_pattern_formatter.cpp
|
||||||
test_async.cpp
|
test_async.cpp
|
||||||
test_registry.cpp
|
test_registry.cpp
|
||||||
@ -23,7 +31,8 @@ set(SPDLOG_UTESTS_SOURCES
|
|||||||
test_fmt_helper.cpp
|
test_fmt_helper.cpp
|
||||||
test_stdout_api.cpp
|
test_stdout_api.cpp
|
||||||
test_backtrace.cpp
|
test_backtrace.cpp
|
||||||
test_create_dir.cpp)
|
test_create_dir.cpp
|
||||||
|
test_cfg.cpp)
|
||||||
|
|
||||||
if(NOT SPDLOG_NO_EXCEPTIONS)
|
if(NOT SPDLOG_NO_EXCEPTIONS)
|
||||||
list(APPEND SPDLOG_UTESTS_SOURCES test_errors.cpp)
|
list(APPEND SPDLOG_UTESTS_SOURCES test_errors.cpp)
|
||||||
@ -47,6 +56,7 @@ function(spdlog_prepare_test test_target spdlog_lib)
|
|||||||
spdlog_enable_sanitizer(${test_target})
|
spdlog_enable_sanitizer(${test_target})
|
||||||
endif()
|
endif()
|
||||||
add_test(NAME ${test_target} COMMAND ${test_target})
|
add_test(NAME ${test_target} COMMAND ${test_target})
|
||||||
|
set_tests_properties(${test_target} PROPERTIES RUN_SERIAL ON)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
# The compiled library tests
|
# The compiled library tests
|
||||||
|
3
third_party/spdlog/tests/includes.h
vendored
3
third_party/spdlog/tests/includes.h
vendored
@ -11,6 +11,7 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_DEBUG
|
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_DEBUG
|
||||||
|
|
||||||
@ -22,4 +23,4 @@
|
|||||||
#include "spdlog/sinks/ostream_sink.h"
|
#include "spdlog/sinks/ostream_sink.h"
|
||||||
#include "spdlog/sinks/rotating_file_sink.h"
|
#include "spdlog/sinks/rotating_file_sink.h"
|
||||||
#include "spdlog/sinks/stdout_color_sinks.h"
|
#include "spdlog/sinks/stdout_color_sinks.h"
|
||||||
#include "spdlog/details/pattern_formatter.h"
|
#include "spdlog/pattern_formatter.h"
|
3
third_party/spdlog/tests/meson.build
vendored
3
third_party/spdlog/tests/meson.build
vendored
@ -14,7 +14,8 @@ test_sources = files([
|
|||||||
'test_fmt_helper.cpp',
|
'test_fmt_helper.cpp',
|
||||||
'test_stdout_api.cpp',
|
'test_stdout_api.cpp',
|
||||||
'test_backtrace.cpp',
|
'test_backtrace.cpp',
|
||||||
'test_create_dir.cpp'
|
'test_create_dir.cpp',
|
||||||
|
'test_cfg.cpp',
|
||||||
])
|
])
|
||||||
|
|
||||||
if not get_option('no_exceptions')
|
if not get_option('no_exceptions')
|
||||||
|
53
third_party/spdlog/tests/test_async.cpp
vendored
53
third_party/spdlog/tests/test_async.cpp
vendored
@ -5,14 +5,13 @@
|
|||||||
|
|
||||||
TEST_CASE("basic async test ", "[async]")
|
TEST_CASE("basic async test ", "[async]")
|
||||||
{
|
{
|
||||||
using namespace spdlog;
|
auto test_sink = std::make_shared<spdlog::sinks::test_sink_mt>();
|
||||||
auto test_sink = std::make_shared<sinks::test_sink_mt>();
|
|
||||||
size_t overrun_counter = 0;
|
size_t overrun_counter = 0;
|
||||||
size_t queue_size = 128;
|
size_t queue_size = 128;
|
||||||
size_t messages = 256;
|
size_t messages = 256;
|
||||||
{
|
{
|
||||||
auto tp = std::make_shared<details::thread_pool>(queue_size, 1);
|
auto tp = std::make_shared<spdlog::details::thread_pool>(queue_size, 1);
|
||||||
auto logger = std::make_shared<async_logger>("as", test_sink, tp, async_overflow_policy::block);
|
auto logger = std::make_shared<spdlog::async_logger>("as", test_sink, tp, spdlog::async_overflow_policy::block);
|
||||||
for (size_t i = 0; i < messages; i++)
|
for (size_t i = 0; i < messages; i++)
|
||||||
{
|
{
|
||||||
logger->info("Hello message #{}", i);
|
logger->info("Hello message #{}", i);
|
||||||
@ -27,14 +26,13 @@ TEST_CASE("basic async test ", "[async]")
|
|||||||
|
|
||||||
TEST_CASE("discard policy ", "[async]")
|
TEST_CASE("discard policy ", "[async]")
|
||||||
{
|
{
|
||||||
using namespace spdlog;
|
auto test_sink = std::make_shared<spdlog::sinks::test_sink_mt>();
|
||||||
auto test_sink = std::make_shared<sinks::test_sink_mt>();
|
|
||||||
test_sink->set_delay(std::chrono::milliseconds(1));
|
test_sink->set_delay(std::chrono::milliseconds(1));
|
||||||
size_t queue_size = 4;
|
size_t queue_size = 4;
|
||||||
size_t messages = 1024;
|
size_t messages = 1024;
|
||||||
|
|
||||||
auto tp = std::make_shared<details::thread_pool>(queue_size, 1);
|
auto tp = std::make_shared<spdlog::details::thread_pool>(queue_size, 1);
|
||||||
auto logger = std::make_shared<async_logger>("as", test_sink, tp, async_overflow_policy::overrun_oldest);
|
auto logger = std::make_shared<spdlog::async_logger>("as", test_sink, tp, spdlog::async_overflow_policy::overrun_oldest);
|
||||||
for (size_t i = 0; i < messages; i++)
|
for (size_t i = 0; i < messages; i++)
|
||||||
{
|
{
|
||||||
logger->info("Hello message");
|
logger->info("Hello message");
|
||||||
@ -45,13 +43,12 @@ TEST_CASE("discard policy ", "[async]")
|
|||||||
|
|
||||||
TEST_CASE("discard policy using factory ", "[async]")
|
TEST_CASE("discard policy using factory ", "[async]")
|
||||||
{
|
{
|
||||||
using namespace spdlog;
|
|
||||||
size_t queue_size = 4;
|
size_t queue_size = 4;
|
||||||
size_t messages = 1024;
|
size_t messages = 1024;
|
||||||
spdlog::init_thread_pool(queue_size, 1);
|
spdlog::init_thread_pool(queue_size, 1);
|
||||||
|
|
||||||
auto logger = spdlog::create_async_nb<sinks::test_sink_mt>("as2");
|
auto logger = spdlog::create_async_nb<spdlog::sinks::test_sink_mt>("as2");
|
||||||
auto test_sink = std::static_pointer_cast<sinks::test_sink_mt>(logger->sinks()[0]);
|
auto test_sink = std::static_pointer_cast<spdlog::sinks::test_sink_mt>(logger->sinks()[0]);
|
||||||
test_sink->set_delay(std::chrono::milliseconds(1));
|
test_sink->set_delay(std::chrono::milliseconds(1));
|
||||||
|
|
||||||
for (size_t i = 0; i < messages; i++)
|
for (size_t i = 0; i < messages; i++)
|
||||||
@ -65,13 +62,12 @@ TEST_CASE("discard policy using factory ", "[async]")
|
|||||||
|
|
||||||
TEST_CASE("flush", "[async]")
|
TEST_CASE("flush", "[async]")
|
||||||
{
|
{
|
||||||
using namespace spdlog;
|
auto test_sink = std::make_shared<spdlog::sinks::test_sink_mt>();
|
||||||
auto test_sink = std::make_shared<sinks::test_sink_mt>();
|
|
||||||
size_t queue_size = 256;
|
size_t queue_size = 256;
|
||||||
size_t messages = 256;
|
size_t messages = 256;
|
||||||
{
|
{
|
||||||
auto tp = std::make_shared<details::thread_pool>(queue_size, 1);
|
auto tp = std::make_shared<spdlog::details::thread_pool>(queue_size, 1);
|
||||||
auto logger = std::make_shared<async_logger>("as", test_sink, tp, async_overflow_policy::block);
|
auto logger = std::make_shared<spdlog::async_logger>("as", test_sink, tp, spdlog::async_overflow_policy::block);
|
||||||
for (size_t i = 0; i < messages; i++)
|
for (size_t i = 0; i < messages; i++)
|
||||||
{
|
{
|
||||||
logger->info("Hello message #{}", i);
|
logger->info("Hello message #{}", i);
|
||||||
@ -86,11 +82,9 @@ TEST_CASE("flush", "[async]")
|
|||||||
|
|
||||||
TEST_CASE("async periodic flush", "[async]")
|
TEST_CASE("async periodic flush", "[async]")
|
||||||
{
|
{
|
||||||
using namespace spdlog;
|
|
||||||
|
|
||||||
auto logger = spdlog::create_async<sinks::test_sink_mt>("as");
|
auto logger = spdlog::create_async<spdlog::sinks::test_sink_mt>("as");
|
||||||
|
auto test_sink = std::static_pointer_cast<spdlog::sinks::test_sink_mt>(logger->sinks()[0]);
|
||||||
auto test_sink = std::static_pointer_cast<sinks::test_sink_mt>(logger->sinks()[0]);
|
|
||||||
|
|
||||||
spdlog::flush_every(std::chrono::seconds(1));
|
spdlog::flush_every(std::chrono::seconds(1));
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1100));
|
std::this_thread::sleep_for(std::chrono::milliseconds(1100));
|
||||||
@ -101,13 +95,12 @@ TEST_CASE("async periodic flush", "[async]")
|
|||||||
|
|
||||||
TEST_CASE("tp->wait_empty() ", "[async]")
|
TEST_CASE("tp->wait_empty() ", "[async]")
|
||||||
{
|
{
|
||||||
using namespace spdlog;
|
auto test_sink = std::make_shared<spdlog::sinks::test_sink_mt>();
|
||||||
auto test_sink = std::make_shared<sinks::test_sink_mt>();
|
|
||||||
test_sink->set_delay(std::chrono::milliseconds(5));
|
test_sink->set_delay(std::chrono::milliseconds(5));
|
||||||
size_t messages = 100;
|
size_t messages = 100;
|
||||||
|
|
||||||
auto tp = std::make_shared<details::thread_pool>(messages, 2);
|
auto tp = std::make_shared<spdlog::details::thread_pool>(messages, 2);
|
||||||
auto logger = std::make_shared<async_logger>("as", test_sink, tp, async_overflow_policy::block);
|
auto logger = std::make_shared<spdlog::async_logger>("as", test_sink, tp, spdlog::async_overflow_policy::block);
|
||||||
for (size_t i = 0; i < messages; i++)
|
for (size_t i = 0; i < messages; i++)
|
||||||
{
|
{
|
||||||
logger->info("Hello message #{}", i);
|
logger->info("Hello message #{}", i);
|
||||||
@ -121,14 +114,13 @@ TEST_CASE("tp->wait_empty() ", "[async]")
|
|||||||
|
|
||||||
TEST_CASE("multi threads", "[async]")
|
TEST_CASE("multi threads", "[async]")
|
||||||
{
|
{
|
||||||
using namespace spdlog;
|
auto test_sink = std::make_shared<spdlog::sinks::test_sink_mt>();
|
||||||
auto test_sink = std::make_shared<sinks::test_sink_mt>();
|
|
||||||
size_t queue_size = 128;
|
size_t queue_size = 128;
|
||||||
size_t messages = 256;
|
size_t messages = 256;
|
||||||
size_t n_threads = 10;
|
size_t n_threads = 10;
|
||||||
{
|
{
|
||||||
auto tp = std::make_shared<details::thread_pool>(queue_size, 1);
|
auto tp = std::make_shared<spdlog::details::thread_pool>(queue_size, 1);
|
||||||
auto logger = std::make_shared<async_logger>("as", test_sink, tp, async_overflow_policy::block);
|
auto logger = std::make_shared<spdlog::async_logger>("as", test_sink, tp, spdlog::async_overflow_policy::block);
|
||||||
|
|
||||||
std::vector<std::thread> threads;
|
std::vector<std::thread> threads;
|
||||||
for (size_t i = 0; i < n_threads; i++)
|
for (size_t i = 0; i < n_threads; i++)
|
||||||
@ -169,9 +161,10 @@ TEST_CASE("to_file", "[async]")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
REQUIRE(count_lines(filename) == messages);
|
require_message_count(filename, messages);
|
||||||
auto contents = file_contents(filename);
|
auto contents = file_contents(filename);
|
||||||
REQUIRE(ends_with(contents, std::string("Hello message #1023\n")));
|
using spdlog::details::os::default_eol;
|
||||||
|
REQUIRE(ends_with(contents, fmt::format("Hello message #1023{}", default_eol)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("to_file multi-workers", "[async]")
|
TEST_CASE("to_file multi-workers", "[async]")
|
||||||
@ -191,5 +184,5 @@ TEST_CASE("to_file multi-workers", "[async]")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
REQUIRE(count_lines(filename) == messages);
|
require_message_count(filename, messages);
|
||||||
}
|
}
|
||||||
|
93
third_party/spdlog/tests/test_cfg.cpp
vendored
Normal file
93
third_party/spdlog/tests/test_cfg.cpp
vendored
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#include "includes.h"
|
||||||
|
#include "test_sink.h"
|
||||||
|
|
||||||
|
#include <spdlog/cfg/env.h>
|
||||||
|
#include <spdlog/cfg/argv.h>
|
||||||
|
|
||||||
|
using spdlog::cfg::load_argv_levels;
|
||||||
|
using spdlog::cfg::load_env_levels;
|
||||||
|
using spdlog::sinks::test_sink_st;
|
||||||
|
|
||||||
|
TEST_CASE("env", "[cfg]")
|
||||||
|
{
|
||||||
|
spdlog::drop("l1");
|
||||||
|
auto l1 = spdlog::create<test_sink_st>("l1");
|
||||||
|
#ifdef CATCH_PLATFORM_WINDOWS
|
||||||
|
_putenv_s("SPDLOG_LEVEL", "l1=warn");
|
||||||
|
#else
|
||||||
|
setenv("SPDLOG_LEVEL", "l1=warn", 1);
|
||||||
|
#endif
|
||||||
|
load_env_levels();
|
||||||
|
REQUIRE(l1->level() == spdlog::level::warn);
|
||||||
|
spdlog::set_default_logger(spdlog::create<test_sink_st>("cfg-default"));
|
||||||
|
REQUIRE(spdlog::default_logger()->level() == spdlog::level::info);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("argv1", "[cfg]")
|
||||||
|
{
|
||||||
|
spdlog::drop("l1");
|
||||||
|
const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=warn"};
|
||||||
|
load_argv_levels(2, argv);
|
||||||
|
auto l1 = spdlog::create<spdlog::sinks::test_sink_st>("l1");
|
||||||
|
REQUIRE(l1->level() == spdlog::level::warn);
|
||||||
|
REQUIRE(spdlog::default_logger()->level() == spdlog::level::info);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("argv2", "[cfg]")
|
||||||
|
{
|
||||||
|
spdlog::drop("l1");
|
||||||
|
const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=warn,trace"};
|
||||||
|
load_argv_levels(2, argv);
|
||||||
|
auto l1 = spdlog::create<test_sink_st>("l1");
|
||||||
|
REQUIRE(l1->level() == spdlog::level::warn);
|
||||||
|
REQUIRE(spdlog::default_logger()->level() == spdlog::level::trace);
|
||||||
|
spdlog::set_level(spdlog::level::info);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("argv3", "[cfg]")
|
||||||
|
{
|
||||||
|
spdlog::drop("l1");
|
||||||
|
const char *argv[] = {"ignore", "SPDLOG_LEVEL="};
|
||||||
|
load_argv_levels(2, argv);
|
||||||
|
auto l1 = spdlog::create<test_sink_st>("l1");
|
||||||
|
REQUIRE(l1->level() == spdlog::level::info);
|
||||||
|
REQUIRE(spdlog::default_logger()->level() == spdlog::level::info);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("argv4", "[cfg]")
|
||||||
|
{
|
||||||
|
spdlog::drop("l1");
|
||||||
|
const char *argv[] = {"ignore", "SPDLOG_LEVEL=junk"};
|
||||||
|
load_argv_levels(2, argv);
|
||||||
|
auto l1 = spdlog::create<test_sink_st>("l1");
|
||||||
|
REQUIRE(l1->level() == spdlog::level::info);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("argv5", "[cfg]")
|
||||||
|
{
|
||||||
|
spdlog::drop("l1");
|
||||||
|
const char *argv[] = {"ignore", "ignore", "SPDLOG_LEVEL=l1=warn,trace"};
|
||||||
|
load_argv_levels(3, argv);
|
||||||
|
auto l1 = spdlog::create<test_sink_st>("l1");
|
||||||
|
REQUIRE(l1->level() == spdlog::level::warn);
|
||||||
|
REQUIRE(spdlog::default_logger()->level() == spdlog::level::trace);
|
||||||
|
spdlog::set_level(spdlog::level::info);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("argv6", "[cfg]")
|
||||||
|
{
|
||||||
|
spdlog::set_level(spdlog::level::err);
|
||||||
|
const char *argv[] = {""};
|
||||||
|
load_argv_levels(1, argv);
|
||||||
|
REQUIRE(spdlog::default_logger()->level() == spdlog::level::err);
|
||||||
|
spdlog::set_level(spdlog::level::info);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("argv7", "[cfg]")
|
||||||
|
{
|
||||||
|
spdlog::set_level(spdlog::level::err);
|
||||||
|
const char *argv[] = {""};
|
||||||
|
load_argv_levels(0, argv);
|
||||||
|
REQUIRE(spdlog::default_logger()->level() == spdlog::level::err);
|
||||||
|
spdlog::set_level(spdlog::level::info);
|
||||||
|
}
|
@ -24,7 +24,7 @@ TEST_CASE("daily_logger with dateonly calculator", "[daily_logger]")
|
|||||||
logger->flush();
|
logger->flush();
|
||||||
|
|
||||||
auto filename = fmt::to_string(w);
|
auto filename = fmt::to_string(w);
|
||||||
REQUIRE(count_lines(filename) == 10);
|
require_message_count(filename, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct custom_daily_file_name_calculator
|
struct custom_daily_file_name_calculator
|
||||||
@ -55,12 +55,10 @@ TEST_CASE("daily_logger with custom calculator", "[daily_logger]")
|
|||||||
logger->info("Test message {}", i);
|
logger->info("Test message {}", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
logger->
|
logger->flush();
|
||||||
|
|
||||||
flush();
|
|
||||||
|
|
||||||
auto filename = fmt::to_string(w);
|
auto filename = fmt::to_string(w);
|
||||||
REQUIRE(count_lines(filename) == 10);
|
require_message_count(filename, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -115,7 +113,6 @@ static void test_rotate(int days_to_run, uint16_t max_days, uint16_t expected_n_
|
|||||||
using spdlog::log_clock;
|
using spdlog::log_clock;
|
||||||
using spdlog::details::log_msg;
|
using spdlog::details::log_msg;
|
||||||
using spdlog::sinks::daily_file_sink_st;
|
using spdlog::sinks::daily_file_sink_st;
|
||||||
using namespace spdlog::details;
|
|
||||||
|
|
||||||
prepare_logdir();
|
prepare_logdir();
|
||||||
|
|
||||||
|
18
third_party/spdlog/tests/test_dup_filter.cpp
vendored
18
third_party/spdlog/tests/test_dup_filter.cpp
vendored
@ -2,11 +2,11 @@
|
|||||||
#include "spdlog/sinks/dup_filter_sink.h"
|
#include "spdlog/sinks/dup_filter_sink.h"
|
||||||
#include "test_sink.h"
|
#include "test_sink.h"
|
||||||
|
|
||||||
using namespace spdlog;
|
|
||||||
using namespace spdlog::sinks;
|
|
||||||
|
|
||||||
TEST_CASE("dup_filter_test1", "[dup_filter_sink]")
|
TEST_CASE("dup_filter_test1", "[dup_filter_sink]")
|
||||||
{
|
{
|
||||||
|
using spdlog::sinks::dup_filter_sink_st;
|
||||||
|
using spdlog::sinks::test_sink_mt;
|
||||||
|
|
||||||
dup_filter_sink_st dup_sink{std::chrono::seconds{5}};
|
dup_filter_sink_st dup_sink{std::chrono::seconds{5}};
|
||||||
auto test_sink = std::make_shared<test_sink_mt>();
|
auto test_sink = std::make_shared<test_sink_mt>();
|
||||||
dup_sink.add_sink(test_sink);
|
dup_sink.add_sink(test_sink);
|
||||||
@ -21,6 +21,9 @@ TEST_CASE("dup_filter_test1", "[dup_filter_sink]")
|
|||||||
|
|
||||||
TEST_CASE("dup_filter_test2", "[dup_filter_sink]")
|
TEST_CASE("dup_filter_test2", "[dup_filter_sink]")
|
||||||
{
|
{
|
||||||
|
using spdlog::sinks::dup_filter_sink_st;
|
||||||
|
using spdlog::sinks::test_sink_mt;
|
||||||
|
|
||||||
dup_filter_sink_st dup_sink{std::chrono::seconds{0}};
|
dup_filter_sink_st dup_sink{std::chrono::seconds{0}};
|
||||||
auto test_sink = std::make_shared<test_sink_mt>();
|
auto test_sink = std::make_shared<test_sink_mt>();
|
||||||
dup_sink.add_sink(test_sink);
|
dup_sink.add_sink(test_sink);
|
||||||
@ -36,6 +39,9 @@ TEST_CASE("dup_filter_test2", "[dup_filter_sink]")
|
|||||||
|
|
||||||
TEST_CASE("dup_filter_test3", "[dup_filter_sink]")
|
TEST_CASE("dup_filter_test3", "[dup_filter_sink]")
|
||||||
{
|
{
|
||||||
|
using spdlog::sinks::dup_filter_sink_st;
|
||||||
|
using spdlog::sinks::test_sink_mt;
|
||||||
|
|
||||||
dup_filter_sink_st dup_sink{std::chrono::seconds{1}};
|
dup_filter_sink_st dup_sink{std::chrono::seconds{1}};
|
||||||
auto test_sink = std::make_shared<test_sink_mt>();
|
auto test_sink = std::make_shared<test_sink_mt>();
|
||||||
dup_sink.add_sink(test_sink);
|
dup_sink.add_sink(test_sink);
|
||||||
@ -51,6 +57,9 @@ TEST_CASE("dup_filter_test3", "[dup_filter_sink]")
|
|||||||
|
|
||||||
TEST_CASE("dup_filter_test4", "[dup_filter_sink]")
|
TEST_CASE("dup_filter_test4", "[dup_filter_sink]")
|
||||||
{
|
{
|
||||||
|
using spdlog::sinks::dup_filter_sink_mt;
|
||||||
|
using spdlog::sinks::test_sink_mt;
|
||||||
|
|
||||||
dup_filter_sink_mt dup_sink{std::chrono::milliseconds{10}};
|
dup_filter_sink_mt dup_sink{std::chrono::milliseconds{10}};
|
||||||
auto test_sink = std::make_shared<test_sink_mt>();
|
auto test_sink = std::make_shared<test_sink_mt>();
|
||||||
dup_sink.add_sink(test_sink);
|
dup_sink.add_sink(test_sink);
|
||||||
@ -63,6 +72,9 @@ TEST_CASE("dup_filter_test4", "[dup_filter_sink]")
|
|||||||
|
|
||||||
TEST_CASE("dup_filter_test5", "[dup_filter_sink]")
|
TEST_CASE("dup_filter_test5", "[dup_filter_sink]")
|
||||||
{
|
{
|
||||||
|
using spdlog::sinks::dup_filter_sink_mt;
|
||||||
|
using spdlog::sinks::test_sink_mt;
|
||||||
|
|
||||||
dup_filter_sink_mt dup_sink{std::chrono::seconds{5}};
|
dup_filter_sink_mt dup_sink{std::chrono::seconds{5}};
|
||||||
auto test_sink = std::make_shared<test_sink_mt>();
|
auto test_sink = std::make_shared<test_sink_mt>();
|
||||||
dup_sink.add_sink(test_sink);
|
dup_sink.add_sink(test_sink);
|
||||||
|
11
third_party/spdlog/tests/test_errors.cpp
vendored
11
third_party/spdlog/tests/test_errors.cpp
vendored
@ -7,10 +7,6 @@
|
|||||||
|
|
||||||
class failing_sink : public spdlog::sinks::base_sink<std::mutex>
|
class failing_sink : public spdlog::sinks::base_sink<std::mutex>
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
failing_sink() = default;
|
|
||||||
~failing_sink() final = default;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void sink_it_(const spdlog::details::log_msg &) final
|
void sink_it_(const spdlog::details::log_msg &) final
|
||||||
{
|
{
|
||||||
@ -34,7 +30,8 @@ TEST_CASE("default_error_handler", "[errors]]")
|
|||||||
logger->info("Test message {}", 2);
|
logger->info("Test message {}", 2);
|
||||||
logger->flush();
|
logger->flush();
|
||||||
|
|
||||||
REQUIRE(file_contents(filename) == std::string("Test message 2\n"));
|
using spdlog::details::os::default_eol;
|
||||||
|
REQUIRE(file_contents(filename) == fmt::format("Test message 2{}", default_eol));
|
||||||
REQUIRE(count_lines(filename) == 1);
|
REQUIRE(count_lines(filename) == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,7 +48,7 @@ TEST_CASE("custom_error_handler", "[errors]]")
|
|||||||
|
|
||||||
REQUIRE_THROWS_AS(logger->info("Bad format msg {} {}", "xxx"), custom_ex);
|
REQUIRE_THROWS_AS(logger->info("Bad format msg {} {}", "xxx"), custom_ex);
|
||||||
logger->info("Good message #2");
|
logger->info("Good message #2");
|
||||||
REQUIRE(count_lines(filename) == 2);
|
require_message_count(filename, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("default_error_handler2", "[errors]]")
|
TEST_CASE("default_error_handler2", "[errors]]")
|
||||||
@ -93,7 +90,7 @@ TEST_CASE("async_error_handler", "[errors]]")
|
|||||||
spdlog::drop("logger"); // force logger to drain the queue and shutdown
|
spdlog::drop("logger"); // force logger to drain the queue and shutdown
|
||||||
}
|
}
|
||||||
spdlog::init_thread_pool(128, 1);
|
spdlog::init_thread_pool(128, 1);
|
||||||
REQUIRE(count_lines(filename) == 2);
|
require_message_count(filename, 2);
|
||||||
REQUIRE(file_contents("test_logs/custom_err.txt") == err_msg);
|
REQUIRE(file_contents("test_logs/custom_err.txt") == err_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
71
third_party/spdlog/tests/test_eventlog.cpp
vendored
Normal file
71
third_party/spdlog/tests/test_eventlog.cpp
vendored
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#if _WIN32
|
||||||
|
|
||||||
|
#include "includes.h"
|
||||||
|
#include "test_sink.h"
|
||||||
|
|
||||||
|
#include "spdlog/sinks/win_eventlog_sink.h"
|
||||||
|
|
||||||
|
static const LPCSTR TEST_SOURCE = "spdlog_test";
|
||||||
|
|
||||||
|
static void test_single_print(std::function<void(std::string const &)> do_log, std::string const &expected_contents, WORD expected_ev_type)
|
||||||
|
{
|
||||||
|
using namespace std::chrono;
|
||||||
|
do_log(expected_contents);
|
||||||
|
const auto expected_time_generated = duration_cast<seconds>(system_clock::now().time_since_epoch()).count();
|
||||||
|
|
||||||
|
struct handle_t
|
||||||
|
{
|
||||||
|
HANDLE handle_;
|
||||||
|
|
||||||
|
~handle_t()
|
||||||
|
{
|
||||||
|
if (handle_)
|
||||||
|
{
|
||||||
|
REQUIRE(CloseEventLog(handle_));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} event_log{::OpenEventLog(nullptr, TEST_SOURCE)};
|
||||||
|
|
||||||
|
REQUIRE(event_log.handle_);
|
||||||
|
|
||||||
|
DWORD read_bytes{}, size_needed{};
|
||||||
|
auto ok =
|
||||||
|
::ReadEventLog(event_log.handle_, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ, 0, &read_bytes, 0, &read_bytes, &size_needed);
|
||||||
|
REQUIRE(!ok);
|
||||||
|
REQUIRE(::GetLastError() == ERROR_INSUFFICIENT_BUFFER);
|
||||||
|
|
||||||
|
std::vector<char> record_buffer(size_needed);
|
||||||
|
PEVENTLOGRECORD record = (PEVENTLOGRECORD)record_buffer.data();
|
||||||
|
|
||||||
|
ok = ::ReadEventLog(
|
||||||
|
event_log.handle_, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ, 0, record, size_needed, &read_bytes, &size_needed);
|
||||||
|
REQUIRE(ok);
|
||||||
|
|
||||||
|
REQUIRE(record->NumStrings == 1);
|
||||||
|
REQUIRE(record->EventType == expected_ev_type);
|
||||||
|
REQUIRE((expected_time_generated - record->TimeGenerated) <= 3u);
|
||||||
|
|
||||||
|
std::string message_in_log(((char *)record + record->StringOffset));
|
||||||
|
REQUIRE(message_in_log == expected_contents + spdlog::details::os::default_eol);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("eventlog", "[eventlog]")
|
||||||
|
{
|
||||||
|
using namespace spdlog;
|
||||||
|
|
||||||
|
auto test_sink = std::make_shared<sinks::win_eventlog_sink_mt>(TEST_SOURCE);
|
||||||
|
|
||||||
|
spdlog::logger test_logger("eventlog", test_sink);
|
||||||
|
test_logger.set_level(level::trace);
|
||||||
|
|
||||||
|
test_sink->set_pattern("%v");
|
||||||
|
|
||||||
|
test_single_print([&test_logger](std::string const &msg) { test_logger.trace(msg); }, "my trace message", EVENTLOG_SUCCESS);
|
||||||
|
test_single_print([&test_logger](std::string const &msg) { test_logger.debug(msg); }, "my debug message", EVENTLOG_SUCCESS);
|
||||||
|
test_single_print([&test_logger](std::string const &msg) { test_logger.info(msg); }, "my info message", EVENTLOG_INFORMATION_TYPE);
|
||||||
|
test_single_print([&test_logger](std::string const &msg) { test_logger.warn(msg); }, "my warn message", EVENTLOG_WARNING_TYPE);
|
||||||
|
test_single_print([&test_logger](std::string const &msg) { test_logger.error(msg); }, "my error message", EVENTLOG_ERROR_TYPE);
|
||||||
|
test_single_print([&test_logger](std::string const &msg) { test_logger.critical(msg); }, "my critical message", EVENTLOG_ERROR_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //_WIN32
|
10
third_party/spdlog/tests/test_file_helper.cpp
vendored
10
third_party/spdlog/tests/test_file_helper.cpp
vendored
@ -4,9 +4,6 @@
|
|||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
|
|
||||||
using spdlog::details::file_helper;
|
using spdlog::details::file_helper;
|
||||||
using spdlog::details::log_msg;
|
|
||||||
|
|
||||||
static const std::string target_filename = "test_logs/file_helper_test.txt";
|
|
||||||
|
|
||||||
static void write_with_helper(file_helper &helper, size_t howmany)
|
static void write_with_helper(file_helper &helper, size_t howmany)
|
||||||
{
|
{
|
||||||
@ -21,6 +18,7 @@ TEST_CASE("file_helper_filename", "[file_helper::filename()]]")
|
|||||||
prepare_logdir();
|
prepare_logdir();
|
||||||
|
|
||||||
file_helper helper;
|
file_helper helper;
|
||||||
|
std::string target_filename = "test_logs/file_helper_test.txt";
|
||||||
helper.open(target_filename);
|
helper.open(target_filename);
|
||||||
REQUIRE(helper.filename() == target_filename);
|
REQUIRE(helper.filename() == target_filename);
|
||||||
}
|
}
|
||||||
@ -28,6 +26,7 @@ TEST_CASE("file_helper_filename", "[file_helper::filename()]]")
|
|||||||
TEST_CASE("file_helper_size", "[file_helper::size()]]")
|
TEST_CASE("file_helper_size", "[file_helper::size()]]")
|
||||||
{
|
{
|
||||||
prepare_logdir();
|
prepare_logdir();
|
||||||
|
std::string target_filename = "test_logs/file_helper_test.txt";
|
||||||
size_t expected_size = 123;
|
size_t expected_size = 123;
|
||||||
{
|
{
|
||||||
file_helper helper;
|
file_helper helper;
|
||||||
@ -41,6 +40,7 @@ TEST_CASE("file_helper_size", "[file_helper::size()]]")
|
|||||||
TEST_CASE("file_helper_reopen", "[file_helper::reopen()]]")
|
TEST_CASE("file_helper_reopen", "[file_helper::reopen()]]")
|
||||||
{
|
{
|
||||||
prepare_logdir();
|
prepare_logdir();
|
||||||
|
std::string target_filename = "test_logs/file_helper_test.txt";
|
||||||
file_helper helper;
|
file_helper helper;
|
||||||
helper.open(target_filename);
|
helper.open(target_filename);
|
||||||
write_with_helper(helper, 12);
|
write_with_helper(helper, 12);
|
||||||
@ -52,6 +52,7 @@ TEST_CASE("file_helper_reopen", "[file_helper::reopen()]]")
|
|||||||
TEST_CASE("file_helper_reopen2", "[file_helper::reopen(false)]]")
|
TEST_CASE("file_helper_reopen2", "[file_helper::reopen(false)]]")
|
||||||
{
|
{
|
||||||
prepare_logdir();
|
prepare_logdir();
|
||||||
|
std::string target_filename = "test_logs/file_helper_test.txt";
|
||||||
size_t expected_size = 14;
|
size_t expected_size = 14;
|
||||||
file_helper helper;
|
file_helper helper;
|
||||||
helper.open(target_filename);
|
helper.open(target_filename);
|
||||||
@ -71,7 +72,8 @@ static void test_split_ext(const char *fname, const char *expect_base, const cha
|
|||||||
std::replace(filename.begin(), filename.end(), '/', '\\');
|
std::replace(filename.begin(), filename.end(), '/', '\\');
|
||||||
std::replace(expected_base.begin(), expected_base.end(), '/', '\\');
|
std::replace(expected_base.begin(), expected_base.end(), '/', '\\');
|
||||||
#endif
|
#endif
|
||||||
spdlog::filename_t basename, ext;
|
spdlog::filename_t basename;
|
||||||
|
spdlog::filename_t ext;
|
||||||
std::tie(basename, ext) = file_helper::split_by_extension(filename);
|
std::tie(basename, ext) = file_helper::split_by_extension(filename);
|
||||||
REQUIRE(basename == expected_base);
|
REQUIRE(basename == expected_base);
|
||||||
REQUIRE(ext == expected_ext);
|
REQUIRE(ext == expected_ext);
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user