Skip to content
Commits on Source (3)
......@@ -61,4 +61,7 @@ install_manifest.txt
/tests/tests.VC.VC.opendb
/tests/tests.VC.db
/tests/tests
/tests/logs/file_helper_test.txt
/tests/logs/*
# idea
.idea/
\ No newline at end of file
......@@ -85,6 +85,7 @@ script:
- ./"${BIN}"
- valgrind --trace-children=yes --leak-check=full ./"${BIN}"
- cd $CHECKOUT_PATH/tests; make rebuild; ./tests
- cd $CHECKOUT_PATH/tests; STYLE=printf make rebuild; ./tests
notifications:
email: false
......@@ -4,9 +4,14 @@
#
cmake_minimum_required(VERSION 3.1)
project(spdlog VERSION 1.0.0)
project(spdlog VERSION 0.16.2)
include(CTest)
include(CMakeDependentOption)
include(GNUInstallDirs)
#---------------------------------------------------------------------------------------
# compiler config
#---------------------------------------------------------------------------------------
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
......@@ -14,16 +19,22 @@ if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCH
set(CMAKE_CXX_FLAGS "-Wall ${CMAKE_CXX_FLAGS}")
endif()
#---------------------------------------------------------------------------------------
# spdlog target
#---------------------------------------------------------------------------------------
add_library(spdlog INTERFACE)
option(SPDLOG_BUILD_EXAMPLES "Build examples" OFF)
option(SPDLOG_BUILD_TESTING "Build spdlog tests" ON)
cmake_dependent_option(SPDLOG_BUILD_TESTING
"Build spdlog tests" ON
"BUILD_TESTING" OFF
)
target_include_directories(
spdlog
INTERFACE
"$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>"
"$<INSTALL_INTERFACE:include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)
set(HEADER_BASE "${CMAKE_CURRENT_SOURCE_DIR}/include")
......@@ -36,52 +47,70 @@ if(SPDLOG_BUILD_TESTING)
add_subdirectory(tests)
endif()
### Install ###
# * https://github.com/forexample/package-example
set(generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated")
set(config_install_dir "lib/cmake/${PROJECT_NAME}")
set(include_install_dir "include")
set(pkgconfig_install_dir "lib/pkgconfig")
set(version_config "${generated_dir}/${PROJECT_NAME}ConfigVersion.cmake")
set(project_config "${generated_dir}/${PROJECT_NAME}Config.cmake")
set(pkg_config "${generated_dir}/${PROJECT_NAME}.pc")
#---------------------------------------------------------------------------------------
# Install/export targets and files
#---------------------------------------------------------------------------------------
# set files and directories
set(config_install_dir "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
set(include_install_dir "${CMAKE_INSTALL_INCLUDEDIR}")
set(pkgconfig_install_dir "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
set(version_config "${CMAKE_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake")
set(project_config "${PROJECT_NAME}Config.cmake")
set(pkg_config "${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc")
set(targets_export_name "${PROJECT_NAME}Targets")
set(namespace "${PROJECT_NAME}::")
# generate package version file
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"${version_config}" COMPATIBILITY SameMajorVersion
)
# Note: use 'targets_export_name'
configure_file("cmake/Config.cmake.in" "${project_config}" @ONLY)
# configure pkg config file
configure_file("cmake/spdlog.pc.in" "${pkg_config}" @ONLY)
# install targets
install(
TARGETS spdlog
EXPORT "${targets_export_name}"
INCLUDES DESTINATION "${include_install_dir}"
)
install(DIRECTORY "include/spdlog" DESTINATION "${include_install_dir}")
# install headers
install(
DIRECTORY "${HEADER_BASE}/${PROJECT_NAME}"
DESTINATION "${include_install_dir}"
)
# install project version file
install(
FILES "${project_config}" "${version_config}"
FILES "${version_config}"
DESTINATION "${config_install_dir}"
)
# install pkg config file
install(
FILES "${pkg_config}"
DESTINATION "${pkgconfig_install_dir}"
)
# install project config file
install(
EXPORT "${targets_export_name}"
NAMESPACE "${namespace}"
DESTINATION "${config_install_dir}"
FILE ${project_config}
)
# export build directory config file
export(
EXPORT ${targets_export_name}
NAMESPACE "${namespace}"
FILE ${project_config}
)
# register project in CMake user registry
export(PACKAGE ${PROJECT_NAME})
file(GLOB_RECURSE spdlog_include_SRCS "${HEADER_BASE}/*.h")
add_custom_target(spdlog_headers_for_ide SOURCES ${spdlog_include_SRCS})
......@@ -8,20 +8,20 @@ Very fast, header only, C++ logging library. [![Build Status](https://travis-ci.
* Copy the source [folder](https://github.com/gabime/spdlog/tree/master/include/spdlog) to your build tree and use a C++11 compiler.
#### Or use your favourite package manager:
#### Or use your favorite package manager:
* Ubuntu: `apt-get install libspdlog-dev`
* Homebrew: `brew install spdlog`
* FreeBSD: `cd /usr/ports/devel/spdlog/ && make install clean`
* Fedora: `yum install spdlog`
* Gentoo: `emerge dev-libs/spdlog`
* Arch Linux: `pacman -S spdlog-git`
* Arch Linux: `yaourt -S spdlog-git`
* vcpkg: `vcpkg install spdlog`
## Platforms
* Linux, FreeBSD, Solaris
* Windows (vc 2013+, cygwin/mingw)
* Windows (vc 2013+, cygwin)
* Mac OSX (clang 3.5+)
* Android
......@@ -29,6 +29,7 @@ Very fast, header only, C++ logging library. [![Build Status](https://travis-ci.
* Very fast - performance is the primary goal (see [benchmarks](#benchmarks) below).
* Headers only, just copy and use.
* Feature rich [call style](#usage-example) using the excellent [fmt](https://github.com/fmtlib/fmt) library.
* Optional printf syntax support.
* Extremely fast asynchronous mode (optional) - using lockfree queues and other tricks to reach millions of calls/sec.
* [Custom](https://github.com/gabime/spdlog/wiki/3.-Custom-formatting) formatting.
* Conditional Logging
......@@ -93,10 +94,6 @@ int main(int, char*[])
console->info("Welcome to spdlog!");
console->error("Some error message with arg{}..", 1);
// Conditional logging example
auto i = 2;
console->warn_if(i != 0, "an important message");
// Formatting examples
console->warn("Easy padding in numbers like {:08d}", 12);
console->critical("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42);
......@@ -104,7 +101,7 @@ int main(int, char*[])
console->info("Positional args are {1} {0}..", "too", "supported");
console->info("{:<30}", "left aligned");
// Use global registry to retrieve loggers
spd::get("console")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name) function");
// Create basic file logger (not rotated)
......@@ -112,12 +109,12 @@ int main(int, char*[])
my_logger->info("Some log message");
// Create a file rotating logger with 5mb size max and 3 rotated files
auto rotating_logger = spd::rotating_logger_mt("some_logger_name", "logs/mylogfile", 1048576 * 5, 3);
auto rotating_logger = spd::rotating_logger_mt("some_logger_name", "logs/mylogfile.txt", 1048576 * 5, 3);
for (int i = 0; i < 10; ++i)
rotating_logger->info("{} * {} equals {:>10}", i, i, i*i);
// Create a daily logger - a new file is created every day on 2:30am
auto daily_logger = spd::daily_logger_mt("daily_logger", "logs/daily", 2, 30);
auto daily_logger = spd::daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30);
// trigger flush if the log severity is error or higher
daily_logger->flush_on(spd::level::err);
daily_logger->info(123.44);
......@@ -129,9 +126,9 @@ int main(int, char*[])
// Runtime log levels
spd::set_level(spd::level::info); //Set global log level to info
console->debug("This message shold not be displayed!");
console->debug("This message should not be displayed!");
console->set_level(spd::level::debug); // Set specific logger's log level
console->debug("This message shold be displayed..");
console->debug("This message should be displayed..");
// Compile time log levels
// define SPDLOG_DEBUG_ON or SPDLOG_TRACE_ON
......
version: 1.0.{build}
image: Visual Studio 2015
environment:
matrix:
- GENERATOR: '"MinGW Makefiles"'
BUILD_TYPE: Debug
- GENERATOR: '"MinGW Makefiles"'
BUILD_TYPE: Release
- GENERATOR: '"Visual Studio 14 2015"'
BUILD_TYPE: Debug
- GENERATOR: '"Visual Studio 14 2015"'
BUILD_TYPE: Release
- GENERATOR: '"Visual Studio 14 2015 Win64"'
BUILD_TYPE: Debug
- GENERATOR: '"Visual Studio 14 2015 Win64"'
BUILD_TYPE: Release
build_script:
- cmd: >-
set
mkdir build
cd build
set PATH=%PATH:C:\Program Files\Git\usr\bin;=%
set PATH=C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin;%PATH%
cmake .. -G %GENERATOR% -DCMAKE_BUILD_TYPE=%BUILD_TYPE%
cmake --build . --config %BUILD_TYPE%
test: off
spdlog (1:0.16.3-1) unstable; urgency=medium
* New upstream version
-- Michael R. Crusoe <michael.crusoe@gmail.com> Sat, 17 Feb 2018 09:02:28 -0800
spdlog (1:0.14.0-1) unstable; urgency=medium
* Team upload.
......
......@@ -5,7 +5,7 @@ Section: libdevel
Priority: optional
Build-Depends: debhelper (>= 10),
cmake
Standards-Version: 4.1.1
Standards-Version: 4.1.3
Vcs-Browser: https://anonscm.debian.org/cgit/debian-med/spdlog.git
Vcs-Git: https://anonscm.debian.org/git/debian-med/spdlog.git
Homepage: https://github.com/gabime/spdlog
......
include/spdlog usr/include/
......@@ -6,6 +6,7 @@
override_dh_auto_install:
rm -f example/logs/.gitignore
dh_auto_install
rm debian/libspdlog-dev/usr/include/spdlog/fmt/bundled/LICENSE.rst
override_dh_auto_test:
cd tests && ${MAKE} tests clean
......
CXX ?= g++
CXXFLAGS = -D_WIN32_WINNT=0x600 -march=native -Wall -Wextra -Wshadow -pedantic -std=c++11 -pthread -Wl,--no-as-needed -I../include
CXXFLAGS = -D_WIN32_WINNT=0x600 -march=native -Wall -Wextra -Wshadow -pedantic -std=gnu++0x -pthread -Wl,--no-as-needed -I../include
CXX_RELEASE_FLAGS = -O3
CXX_DEBUG_FLAGS= -g
......
......@@ -31,8 +31,6 @@ int main(int, char*[])
console->info("Welcome to spdlog!");
console->error("Some error message with arg{}..", 1);
// Conditional logging example
console->info_if(true, "Welcome to spdlog conditional logging!");
// Formatting examples
console->warn("Easy padding in numbers like {:08d}", 12);
......@@ -41,23 +39,20 @@ int main(int, char*[])
console->info("Positional args are {1} {0}..", "too", "supported");
console->info("{:<30}", "left aligned");
SPDLOG_DEBUG_IF(console, true, "This is a debug log");
spd::get("console")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name) function");
// Create basic file logger (not rotated)
auto my_logger = spd::basic_logger_mt("basic_logger", "logs/basic");
auto my_logger = spd::basic_logger_mt("basic_logger", "logs/basic-log.txt");
my_logger->info("Some log message");
// Create a file rotating logger with 5mb size max and 3 rotated files
auto rotating_logger = spd::rotating_logger_mt("some_logger_name", "logs/mylogfile", 1048576 * 5, 3);
auto rotating_logger = spd::rotating_logger_mt("some_logger_name", "logs/rotating.txt", 1048576 * 5, 3);
for (int i = 0; i < 10; ++i)
rotating_logger->info("{} * {} equals {:>10}", i, i, i*i);
// Create a daily logger - a new file is created every day on 2:30am
auto daily_logger = spd::daily_logger_mt("daily_logger", "logs/daily", 2, 30);
auto daily_logger = spd::daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30);
// trigger flush if the log severity is error or higher
daily_logger->flush_on(spd::level::err);
daily_logger->info(123.44);
......@@ -77,7 +72,6 @@ int main(int, char*[])
// define SPDLOG_DEBUG_ON or SPDLOG_TRACE_ON
SPDLOG_TRACE(console, "Enabled only #ifdef SPDLOG_TRACE_ON..{} ,{}", 1, 3.23);
SPDLOG_DEBUG(console, "Enabled only #ifdef SPDLOG_DEBUG_ON.. {} ,{}", 1, 3.23);
SPDLOG_DEBUG_IF(console, true, "This is a debug log");
// Asynchronous logging is very fast..
......@@ -117,8 +111,7 @@ void async_example()
{
size_t q_size = 4096; //queue size must be power of 2
spdlog::set_async_mode(q_size);
auto async_file = spd::daily_logger_st("async_file_logger", "logs/async_log");
auto async_file = spd::daily_logger_st("async_file_logger", "logs/async_log.txt");
for (int i = 0; i < 100; ++i)
async_file->info("Async message #{}", i);
}
......
......@@ -15,8 +15,8 @@
// 3. will throw spdlog_ex upon log exceptions
// Upon destruction, logs all remaining messages in the queue before destructing..
#include "spdlog/common.h"
#include "spdlog/logger.h"
#include "common.h"
#include "logger.h"
#include <chrono>
#include <functional>
......@@ -79,4 +79,4 @@ private:
}
#include "spdlog/details/async_logger_impl.h"
#include "details/async_logger_impl.h"
......@@ -18,7 +18,7 @@
#include <locale>
#endif
#include "spdlog/details/null_mutex.h"
#include "details/null_mutex.h"
//visual studio upto 2013 does not support noexcept nor constexpr
#if defined(_MSC_VER) && (_MSC_VER < 1900)
......@@ -29,9 +29,11 @@
#define SPDLOG_CONSTEXPR constexpr
#endif
// See tweakme.h
#if !defined(SPDLOG_FINAL)
// final keyword support. On by default. See tweakme.h
#if defined(SPDLOG_NO_FINAL)
#define SPDLOG_FINAL
#else
#define SPDLOG_FINAL final
#endif
#if defined(__GNUC__) || defined(__clang__)
......@@ -42,8 +44,7 @@
#define SPDLOG_DEPRECATED
#endif
#include "spdlog/fmt/fmt.h"
#include "fmt/fmt.h"
namespace spdlog
{
......@@ -82,9 +83,9 @@ typedef enum
} level_enum;
#if !defined(SPDLOG_LEVEL_NAMES)
#define SPDLOG_LEVEL_NAMES { "trace", "debug", "info", "warning", "error", "critical", "off" };
#define SPDLOG_LEVEL_NAMES { "trace", "debug", "info", "warning", "error", "critical", "off" }
#endif
static const char* level_names[] SPDLOG_LEVEL_NAMES
static const char* level_names[] SPDLOG_LEVEL_NAMES;
static const char* short_level_names[] { "T", "D", "I", "W", "E", "C", "O" };
......
......@@ -12,12 +12,12 @@
#pragma once
#include "spdlog/common.h"
#include "spdlog/sinks/sink.h"
#include "spdlog/details/mpmc_bounded_q.h"
#include "spdlog/details/log_msg.h"
#include "spdlog/details/os.h"
#include "spdlog/formatter.h"
#include "../common.h"
#include "../sinks/sink.h"
#include "../details/mpmc_bounded_q.h"
#include "../details/log_msg.h"
#include "../details/os.h"
#include "../formatter.h"
#include <chrono>
#include <exception>
......@@ -261,7 +261,7 @@ inline void spdlog::details::async_log_helper::flush(bool wait_for_q)
{
push_msg(async_msg(async_msg_type::flush));
if (wait_for_q)
wait_empty_q(); //return only make after the above flush message was processed
wait_empty_q(); //return when queue is empty
}
inline void spdlog::details::async_log_helper::worker_loop()
......@@ -282,7 +282,7 @@ inline void spdlog::details::async_log_helper::worker_loop()
}
catch(...)
{
_err_handler("Unknown exception");
_err_handler("Unknown exeption in async logger worker loop.");
}
}
if (_worker_teardown_cb) _worker_teardown_cb();
......@@ -358,7 +358,6 @@ inline void spdlog::details::async_log_helper::set_formatter(formatter_ptr msg_f
// spin, yield or sleep. use the time passed since last message as a hint
inline void spdlog::details::async_log_helper::sleep_or_yield(const spdlog::log_clock::time_point& now, const spdlog::log_clock::time_point& last_op_time)
{
using namespace std::this_thread;
using std::chrono::milliseconds;
using std::chrono::microseconds;
......@@ -374,17 +373,17 @@ inline void spdlog::details::async_log_helper::sleep_or_yield(const spdlog::log_
// sleep for 20 ms upto 200 ms
if (time_since_op <= milliseconds(200))
return sleep_for(milliseconds(20));
return details::os::sleep_for_millis(20);
// sleep for 200 ms
return sleep_for(milliseconds(200));
// sleep for 500 ms
return details::os::sleep_for_millis(500);
}
// wait for the queue to be empty
inline void spdlog::details::async_log_helper::wait_empty_q()
{
auto last_op = details::os::now();
while (_q.approx_size() > 0)
while (!_q.is_empty())
{
sleep_or_yield(details::os::now(), last_op);
}
......
......@@ -8,8 +8,8 @@
// Async Logger implementation
// Use an async_sink (queue per logger) to perform the logging in a worker thread
#include "spdlog/details/async_log_helper.h"
#include "spdlog/async_logger.h"
#include "../details/async_log_helper.h"
#include "../async_logger.h"
#include <string>
#include <functional>
......@@ -88,7 +88,7 @@ inline void spdlog::async_logger::_sink_it(details::log_msg& msg)
try
{
#if defined(SPDLOG_ENABLE_MESSAGE_COUNTER)
msg.msg_id = _msg_counter.fetch_add(1, std::memory_order_relaxed);
_incr_msg_counter(msg);
#endif
_async_log_helper->log(msg);
if (_should_flush_on(msg))
......@@ -100,6 +100,8 @@ inline void spdlog::async_logger::_sink_it(details::log_msg& msg)
}
catch(...)
{
_err_handler("Unknown exception");
_err_handler("Unknown exception in logger " + _name);
throw;
}
}
......@@ -9,13 +9,14 @@
// When failing to open a file, retry several times(5) with small delay between the tries(10 ms)
// Throw spdlog_ex exception on errors
#include "spdlog/details/os.h"
#include "spdlog/details/log_msg.h"
#include "../details/os.h"
#include "../details/log_msg.h"
#include <chrono>
#include <cstdio>
#include <string>
#include <thread>
#include <tuple>
#include <cerrno>
namespace spdlog
......@@ -54,7 +55,7 @@ public:
if (!os::fopen_s(&_fd, fname, mode))
return;
std::this_thread::sleep_for(std::chrono::milliseconds(open_interval));
details::os::sleep_for_millis(open_interval);
}
throw spdlog_ex("Failed opening file " + os::filename_to_str(_filename) + " for writing", errno);
......@@ -84,14 +85,13 @@ public:
void write(const log_msg& msg)
{
size_t msg_size = msg.formatted.size();
auto data = msg.formatted.data();
if (std::fwrite(data, 1, msg_size, _fd) != msg_size)
throw spdlog_ex("Failed writing to file " + os::filename_to_str(_filename), errno);
}
size_t size()
size_t size() const
{
if (!_fd)
throw spdlog_ex("Cannot use size() on closed file " + os::filename_to_str(_filename));
......@@ -103,12 +103,40 @@ public:
return _filename;
}
static bool file_exists(const filename_t& name)
static bool file_exists(const filename_t& fname)
{
return os::file_exists(name);
return os::file_exists(fname);
}
//
// return file path and its extension:
//
// "mylog.txt" => ("mylog", ".txt")
// "mylog" => ("mylog", "")
// "mylog." => ("mylog.", "")
// "/dir1/dir2/mylog.txt" => ("/dir1/dir2/mylog", ".txt")
//
// the starting dot in filenames is ignored (hidden files):
//
// ".mylog" => (".mylog". "")
// "my_folder/.mylog" => ("my_folder/.mylog", "")
// "my_folder/.mylog.txt" => ("my_folder/.mylog", ".txt")
static std::tuple<filename_t, filename_t> split_by_extenstion(const spdlog::filename_t& fname)
{
auto ext_index = fname.rfind('.');
// no valid extension found - return whole path and empty string as extension
if (ext_index == filename_t::npos || ext_index == 0 || ext_index == fname.size() - 1)
return std::make_tuple(fname, spdlog::filename_t());
// treat casese like "/etc/rc.d/somelogfile or "/abc/.hiddenfile"
auto folder_index = fname.rfind(details::os::folder_sep);
if (folder_index != fname.npos && folder_index >= ext_index - 1)
return std::make_tuple(fname, spdlog::filename_t());
// finally - return a valid base and extension tuple
return std::make_tuple(fname.substr(0, ext_index), fname.substr(ext_index));
}
private:
FILE* _fd;
filename_t _filename;
......
......@@ -5,8 +5,8 @@
#pragma once
#include "spdlog/common.h"
#include "spdlog/details/os.h"
#include "../common.h"
#include "../details/os.h"
#include <string>
......
......@@ -5,13 +5,12 @@
#pragma once
#include "spdlog/logger.h"
#include "spdlog/sinks/stdout_sinks.h"
#include "../logger.h"
#include "../sinks/stdout_sinks.h"
#include <memory>
#include <string>
// create logger with given name, sinks and the default pattern formatter
// all other ctors will call this one
template<class It>
......@@ -58,7 +57,6 @@ inline void spdlog::logger::set_pattern(const std::string& pattern, pattern_time
_set_pattern(pattern, pattern_time);
}
template <typename... Args>
inline void spdlog::logger::log(level::level_enum lvl, const char* fmt, const Args&... args)
{
......@@ -67,7 +65,12 @@ inline void spdlog::logger::log(level::level_enum lvl, const char* fmt, const Ar
try
{
details::log_msg log_msg(&_name, lvl);
#if defined(SPDLOG_FMT_PRINTF)
fmt::printf(log_msg.raw, fmt, args...);
#else
log_msg.raw.write(fmt, args...);
#endif
_sink_it(log_msg);
}
catch (const std::exception &ex)
......@@ -76,7 +79,8 @@ inline void spdlog::logger::log(level::level_enum lvl, const char* fmt, const Ar
}
catch(...)
{
_err_handler("Unknown exception");
_err_handler("Unknown exception in logger " + _name);
throw;
}
}
......@@ -96,9 +100,9 @@ inline void spdlog::logger::log(level::level_enum lvl, const char* msg)
}
catch (...)
{
_err_handler("Unknown exception");
_err_handler("Unknown exception in logger " + _name);
throw;
}
}
template<typename T>
......@@ -117,7 +121,8 @@ inline void spdlog::logger::log(level::level_enum lvl, const T& msg)
}
catch (...)
{
_err_handler("Unknown exception");
_err_handler("Unknown exception in logger " + _name);
throw;
}
}
......@@ -158,78 +163,6 @@ inline void spdlog::logger::critical(const char* fmt, const Arg1 &arg1, const Ar
log(level::critical, fmt, arg1, args...);
}
template <typename... Args>
inline void spdlog::logger::log_if(const bool flag, level::level_enum lvl, const char* msg)
{
if (flag)
{
log(lvl, msg);
}
}
template<typename T>
inline void spdlog::logger::log_if(const bool flag, level::level_enum lvl, const T& msg)
{
if (flag)
{
log(lvl, msg);
}
}
template <typename Arg1, typename... Args>
inline void spdlog::logger::trace_if(const bool flag, const char* fmt, const Arg1 &arg1, const Args&... args)
{
if (flag)
{
log(level::trace, fmt, arg1, args...);
}
}
template <typename Arg1, typename... Args>
inline void spdlog::logger::debug_if(const bool flag, const char* fmt, const Arg1 &arg1, const Args&... args)
{
if (flag)
{
log(level::debug, fmt, arg1, args...);
}
}
template <typename Arg1, typename... Args>
inline void spdlog::logger::info_if(const bool flag, const char* fmt, const Arg1 &arg1, const Args&... args)
{
if (flag)
{
log(level::info, fmt, arg1, args...);
}
}
template <typename Arg1, typename... Args>
inline void spdlog::logger::warn_if(const bool flag, const char* fmt, const Arg1& arg1, const Args&... args)
{
if (flag)
{
log(level::warn, fmt, arg1, args...);
}
}
template <typename Arg1, typename... Args>
inline void spdlog::logger::error_if(const bool flag, const char* fmt, const Arg1 &arg1, const Args&... args)
{
if (flag)
{
log(level::err, fmt, arg1, args...);
}
}
template <typename Arg1, typename... Args>
inline void spdlog::logger::critical_if(const bool flag, const char* fmt, const Arg1 &arg1, const Args&... args)
{
if (flag)
{
log(level::critical, fmt, arg1, args...);
}
}
template<typename T>
inline void spdlog::logger::trace(const T& msg)
......@@ -269,63 +202,11 @@ inline void spdlog::logger::critical(const T& msg)
log(level::critical, msg);
}
template<typename T>
inline void spdlog::logger::trace_if(const bool flag, const T& msg)
{
if (flag)
{
log(level::trace, msg);
}
}
template<typename T>
inline void spdlog::logger::debug_if(const bool flag, const T& msg)
{
if (flag)
{
log(level::debug, msg);
}
}
template<typename T>
inline void spdlog::logger::info_if(const bool flag, const T& msg)
{
if (flag)
{
log(level::info, msg);
}
}
template<typename T>
inline void spdlog::logger::warn_if(const bool flag, const T& msg)
{
if (flag)
{
log(level::warn, msg);
}
}
template<typename T>
inline void spdlog::logger::error_if(const bool flag, const T& msg)
{
if (flag)
{
log(level::err, msg);
}
}
template<typename T>
inline void spdlog::logger::critical_if(const bool flag, const T& msg)
{
if (flag)
{
log(level::critical, msg);
}
}
#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
#include <codecvt>
#include <locale>
template <typename... Args>
inline void spdlog::logger::log(level::level_enum lvl, const wchar_t* msg)
......@@ -381,83 +262,6 @@ inline void spdlog::logger::critical(const wchar_t* fmt, const Args&... args)
log(level::critical, fmt, args...);
}
//
// conditional logging
//
template <typename... Args>
inline void spdlog::logger::log_if(const bool flag, level::level_enum lvl, const wchar_t* msg)
{
if (flag)
{
log(lvl, msg);
}
}
template <typename... Args>
inline void spdlog::logger::log_if(const bool flag, level::level_enum lvl, const wchar_t* fmt, const Args&... args)
{
if (flag)
{
log(lvl, fmt, args);
}
}
template <typename... Args>
inline void spdlog::logger::trace_if(const bool flag, const wchar_t* fmt, const Args&... args)
{
if (flag)
{
log(level::trace, fmt, args...);
}
}
template <typename... Args>
inline void spdlog::logger::debug_if(const bool flag, const wchar_t* fmt, const Args&... args)
{
if (flag)
{
log(level::debug, fmt, args...);
}
}
template <typename... Args>
inline void spdlog::logger::info_if(const bool flag, const wchar_t* fmt, const Args&... args)
{
if (flag)
{
log(level::info, fmt, args...);
}
}
template <typename... Args>
inline void spdlog::logger::warn_if(const bool flag, const wchar_t* fmt, const Args&... args)
{
if (flag)
{
log(level::warn, fmt, args...);
}
}
template <typename... Args>
inline void spdlog::logger::error_if(const bool flag, const wchar_t* fmt, const Args&... args)
{
if (flag)
{
log(level::err, fmt, args...);
}
}
template <typename... Args>
inline void spdlog::logger::critical_if(const bool flag, const wchar_t* fmt, const Args&... args)
{
if (flag)
{
log(level::critical, fmt, args...);
}
}
#endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT
......@@ -507,7 +311,7 @@ inline bool spdlog::logger::should_log(spdlog::level::level_enum msg_level) cons
inline void spdlog::logger::_sink_it(details::log_msg& msg)
{
#if defined(SPDLOG_ENABLE_MESSAGE_COUNTER)
msg.msg_id = _msg_counter.fetch_add(1, std::memory_order_relaxed);
_incr_msg_counter(msg);
#endif
_formatter->format(msg);
for (auto &sink : _sinks)
......@@ -557,7 +361,13 @@ inline bool spdlog::logger::_should_flush_on(const details::log_msg &msg)
return (msg.level >= flush_level) && (msg.level != level::off);
}
inline void spdlog::logger::_incr_msg_counter(details::log_msg &msg)
{
msg.msg_id = _msg_counter.fetch_add(1, std::memory_order_relaxed);
}
inline const std::vector<spdlog::sink_ptr>& spdlog::logger::sinks() const
{
return _sinks;
}
......@@ -43,7 +43,7 @@ Distributed under the MIT License (http://opensource.org/licenses/MIT)
#pragma once
#include "spdlog/common.h"
#include "../common.h"
#include <atomic>
#include <utility>
......@@ -88,7 +88,7 @@ public:
{
cell = &buffer_[pos & buffer_mask_];
size_t seq = cell->sequence_.load(std::memory_order_acquire);
intptr_t dif = (intptr_t)seq - (intptr_t)pos;
intptr_t dif = static_cast<intptr_t>(seq) - static_cast<intptr_t>(pos);
if (dif == 0)
{
if (enqueue_pos_.compare_exchange_weak(pos, pos + 1, std::memory_order_relaxed))
......@@ -117,7 +117,7 @@ public:
cell = &buffer_[pos & buffer_mask_];
size_t seq =
cell->sequence_.load(std::memory_order_acquire);
intptr_t dif = (intptr_t)seq - (intptr_t)(pos + 1);
intptr_t dif = static_cast<intptr_t>(seq) - static_cast<intptr_t>(pos + 1);
if (dif == 0)
{
if (dequeue_pos_.compare_exchange_weak(pos, pos + 1, std::memory_order_relaxed))
......@@ -133,14 +133,18 @@ public:
return true;
}
size_t approx_size()
bool is_empty()
{
size_t first_pos = dequeue_pos_.load(std::memory_order_relaxed);
size_t last_pos = enqueue_pos_.load(std::memory_order_relaxed);
if (last_pos <= first_pos)
return 0;
auto size = last_pos - first_pos;
return size < max_size_ ? size : max_size_;
size_t front, front1, back;
// try to take a consistent snapshot of front/tail.
do
{
front = enqueue_pos_.load(std::memory_order_acquire);
back = dequeue_pos_.load(std::memory_order_acquire);
front1 = enqueue_pos_.load(std::memory_order_relaxed);
}
while (front != front1);
return back == front;
}
private:
......
......@@ -4,7 +4,7 @@
//
#pragma once
#include "spdlog/common.h"
#include "../common.h"
#include <cstdio>
#include <ctime>
......@@ -143,6 +143,16 @@ inline bool operator!=(const std::tm& tm1, const std::tm& tm2)
SPDLOG_CONSTEXPR static const char* eol = SPDLOG_EOL;
SPDLOG_CONSTEXPR static int eol_size = sizeof(SPDLOG_EOL) - 1;
// folder separator
#ifdef _WIN32
SPDLOG_CONSTEXPR static const char folder_sep = '\\';
#else
SPDLOG_CONSTEXPR static const char folder_sep = '/';
#endif
inline void prevent_child_fd(FILE *f)
{
#ifdef _WIN32
......@@ -221,7 +231,7 @@ inline size_t filesize(FILE *f)
{
if (f == nullptr)
throw spdlog_ex("Failed getting file size. fd is null");
#ifdef _WIN32
#if defined ( _WIN32) && !defined(__CYGWIN__)
int fd = _fileno(f);
#if _WIN64 //64 bits
struct _stat64 st;
......@@ -236,12 +246,12 @@ inline size_t filesize(FILE *f)
#else // unix
int fd = fileno(f);
//64 bits(but not in osx, where fstat64 is deprecated)
#if !defined(__FreeBSD__) && !defined(__APPLE__) && (defined(__x86_64__) || defined(__ppc64__))
//64 bits(but not in osx or cygwin, where fstat64 is deprecated)
#if !defined(__FreeBSD__) && !defined(__APPLE__) && (defined(__x86_64__) || defined(__ppc64__)) && !defined(__CYGWIN__)
struct stat64 st;
if (fstat64(fd, &st) == 0)
return static_cast<size_t>(st.st_size);
#else // unix 32 bits or osx
#else // unix 32 bits or cygwin
struct stat st;
if (fstat(fd, &st) == 0)
return static_cast<size_t>(st.st_size);
......@@ -316,7 +326,7 @@ inline int utc_minutes_offset(const std::tm& tm = details::os::localtime())
}
//Return current thread id as size_t
//It exists because the std::this_thread::get_id() is much slower(espcially under VS 2013)
//It exists because the std::this_thread::get_id() is much slower(especially under VS 2013)
inline size_t _thread_id()
{
#ifdef _WIN32
......@@ -342,16 +352,27 @@ inline size_t _thread_id()
//Return current thread id as size_t (from thread local storage)
inline size_t thread_id()
{
#if defined(_MSC_VER) && (_MSC_VER < 1900) || defined(__clang__) && !__has_feature(cxx_thread_local)
#if defined(SPDLOG_DISABLE_TID_CACHING) || (defined(_MSC_VER) && (_MSC_VER < 1900)) || (defined(__clang__) && !__has_feature(cxx_thread_local))
return _thread_id();
#else
#else // cache thread id in tls
static thread_local const size_t tid = _thread_id();
return tid;
#endif
}
}
// This is avoid msvc issue in sleep_for that happens if the clock changes.
// See https://github.com/gabime/spdlog/issues/609
inline void sleep_for_millis(int milliseconds)
{
#if defined(_WIN32)
Sleep(milliseconds);
#else
std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds));
#endif
}
// wchar support for windows file names (SPDLOG_WCHAR_FILENAMES must be defined)
#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
......@@ -424,7 +445,7 @@ inline int pid()
}
// Detrmine if the terminal supports colors
// Determine if the terminal supports colors
// Source: https://github.com/agauniyal/rang/
inline bool is_color_terminal()
{
......