Commit 495ecaea authored by gabime's avatar gabime

astyle

parent 9230d9e6
# Adapted from various sources, including:
# - Louis Dionne's Hana: https://github.com/ldionne/hana
# - Paul Fultz II's FIT: https://github.com/pfultz2/Fit
# - Eric Niebler's range-v3: https://github.com/ericniebler/range-v3
language: cpp
# Test matrix:
# - Build matrix per compiler: C++11/C++14 + Debug/Release
# - Optionally: AddressSanitizer (ASAN)
# - Valgrind: all release builds are also tested with valgrind
# - clang 3.4, 3.5, 3.6, trunk
# - Note: 3.4 and trunk are tested with/without ASAN,
# the rest is only tested with ASAN=On.
# - gcc 4.9, 5.0
#
matrix:
include:
# Test clang-3.5: C++11/C++14, Buidd=Debug/Release, ASAN=On/Off
- env: CLANG_VERSION=3.5 BUILD_TYPE=Debug CPP=11 ASAN=On LIBCXX=On
os: linux
addons: &clang35
apt:
packages:
- clang-3.5
- valgrind
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.5
- env: CLANG_VERSION=3.5 BUILD_TYPE=Release CPP=11 ASAN=Off LIBCXX=On
os: linux
addons: *clang35
# Test gcc-4.8: C++11, Build=Debug/Release, ASAN=Off
- env: GCC_VERSION=4.8 BUILD_TYPE=Debug CPP=11 ASAN=Off LIBCXX=Off
os: linux
addons: &gcc48
apt:
packages:
- g++-4.8
- valgrind
sources:
- ubuntu-toolchain-r-test
- env: GCC_VERSION=4.8 BUILD_TYPE=Release CPP=11 ASAN=Off LIBCXX=Off
os: linux
addons: *gcc48
# Test gcc-4.9: C++11, Build=Debug/Release, ASAN=Off
- env: GCC_VERSION=4.9 BUILD_TYPE=Debug CPP=11 ASAN=Off LIBCXX=Off
os: linux
addons: &gcc49
apt:
packages:
- g++-4.9
- valgrind
sources:
- ubuntu-toolchain-r-test
- env: GCC_VERSION=4.9 BUILD_TYPE=Release CPP=11 ASAN=Off LIBCXX=Off
os: linux
addons: *gcc49
# Install dependencies
before_install:
- export CHECKOUT_PATH=`pwd`;
- if [ -n "$GCC_VERSION" ]; then export CXX="g++-${GCC_VERSION}" CC="gcc-${GCC_VERSION}"; fi
- if [ -n "$CLANG_VERSION" ]; then export CXX="clang++-${CLANG_VERSION}" CC="clang-${CLANG_VERSION}"; fi
- if [ "$CLANG_VERSION" == "3.4" ]; then export CXX="/usr/local/clang-3.4/bin/clang++" CC="/usr/local/clang-3.4/bin/clang"; fi
- which $CXX
- which $CC
- which valgrind
- if [ -n "$CLANG_VERSION" ]; then sudo CXX=$CXX CC=$CC ./tests/install_libcxx.sh; fi
install:
- cd $CHECKOUT_PATH
# Workaround for valgrind bug: https://bugs.kde.org/show_bug.cgi?id=326469.
# It is fixed in valgrind 3.10 so this won't be necessary if someone
# replaces the current valgrind (3.7) with valgrind-3.10
- sed -i 's/march=native/msse4.2/' example/Makefile
- if [ ! -d build ]; then mkdir build; fi
- export CXX_FLAGS="-I${CHECKOUT_PATH}/include"
- export CXX_LINKER_FLAGS=""
- if [ -z "$BUILD_TYPE" ]; then export BUILD_TYPE=Release; fi
- if [ "$ASAN" == "On"]; then export CXX_FLAGS="${CXX_FLAGS} -fsanitize=address,undefined,integer -fno-omit-frame-pointer -fno-sanitize=unsigned-integer-overflow"; fi
- if [ -n "$CLANG_VERSION" ]; then CXX_FLAGS="${CXX_FLAGS} -D__extern_always_inline=inline"; fi
- if [ "$LIBCXX" == "On" ]; then CXX_FLAGS="${CXX_FLAGS} -stdlib=libc++ -I/usr/include/c++/v1/"; fi
- if [ "$LIBCXX" == "On" ]; then CXX_LINKER_FLAGS="${CXX_FLAGS} -L/usr/lib/ -lc++"; fi
- CXX_FLAGS="${CXX_FLAGS} -std=c++${CPP}"
# Build examples
- cd example
- if [ "$BUILD_TYPE" == "Release" ]; then make rebuild CXXFLAGS="${CXX_FLAGS} ${CXX_LINKER_FLAGS}" VERBOSE=1; export BIN=example; fi
- if [ "$BUILD_TYPE" == "Debug" ]; then make rebuild debug CXXFLAGS="${CXX_FLAGS} ${CXX_LINKER_FLAGS}" VERBOSE=1; export BIN=example-debug; fi
script:
- ./"${BIN}"
- valgrind --trace-children=yes --leak-check=full ./"${BIN}"
- cd $CHECKOUT_PATH/tests; make rebuild; ./tests
notifications:
email: false
# Adapted from various sources, including:
# - Louis Dionne's Hana: https://github.com/ldionne/hana
# - Paul Fultz II's FIT: https://github.com/pfultz2/Fit
# - Eric Niebler's range-v3: https://github.com/ericniebler/range-v3
language: cpp
# Test matrix:
# - Build matrix per compiler: C++11/C++14 + Debug/Release
# - Optionally: AddressSanitizer (ASAN)
# - Valgrind: all release builds are also tested with valgrind
# - clang 3.4, 3.5, 3.6, trunk
# - Note: 3.4 and trunk are tested with/without ASAN,
# the rest is only tested with ASAN=On.
# - gcc 4.9, 5.0
#
matrix:
include:
# Test clang-3.5: C++11/C++14, Buidd=Debug/Release, ASAN=On/Off
- env: CLANG_VERSION=3.5 BUILD_TYPE=Debug CPP=11 ASAN=On LIBCXX=On
os: linux
addons: &clang35
apt:
packages:
- clang-3.5
- valgrind
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.5
- env: CLANG_VERSION=3.5 BUILD_TYPE=Release CPP=11 ASAN=Off LIBCXX=On
os: linux
addons: *clang35
# Test gcc-4.8: C++11, Build=Debug/Release, ASAN=Off
- env: GCC_VERSION=4.8 BUILD_TYPE=Debug CPP=11 ASAN=Off LIBCXX=Off
os: linux
addons: &gcc48
apt:
packages:
- g++-4.8
- valgrind
sources:
- ubuntu-toolchain-r-test
- env: GCC_VERSION=4.8 BUILD_TYPE=Release CPP=11 ASAN=Off LIBCXX=Off
os: linux
addons: *gcc48
# Test gcc-4.9: C++11, Build=Debug/Release, ASAN=Off
- env: GCC_VERSION=4.9 BUILD_TYPE=Debug CPP=11 ASAN=Off LIBCXX=Off
os: linux
addons: &gcc49
apt:
packages:
- g++-4.9
- valgrind
sources:
- ubuntu-toolchain-r-test
- env: GCC_VERSION=4.9 BUILD_TYPE=Release CPP=11 ASAN=Off LIBCXX=Off
os: linux
addons: *gcc49
# Install dependencies
before_install:
- export CHECKOUT_PATH=`pwd`;
- if [ -n "$GCC_VERSION" ]; then export CXX="g++-${GCC_VERSION}" CC="gcc-${GCC_VERSION}"; fi
- if [ -n "$CLANG_VERSION" ]; then export CXX="clang++-${CLANG_VERSION}" CC="clang-${CLANG_VERSION}"; fi
- if [ "$CLANG_VERSION" == "3.4" ]; then export CXX="/usr/local/clang-3.4/bin/clang++" CC="/usr/local/clang-3.4/bin/clang"; fi
- which $CXX
- which $CC
- which valgrind
- if [ -n "$CLANG_VERSION" ]; then sudo CXX=$CXX CC=$CC ./tests/install_libcxx.sh; fi
install:
- cd $CHECKOUT_PATH
# Workaround for valgrind bug: https://bugs.kde.org/show_bug.cgi?id=326469.
# It is fixed in valgrind 3.10 so this won't be necessary if someone
# replaces the current valgrind (3.7) with valgrind-3.10
- sed -i 's/march=native/msse4.2/' example/Makefile
- if [ ! -d build ]; then mkdir build; fi
- export CXX_FLAGS="-I${CHECKOUT_PATH}/include"
- export CXX_LINKER_FLAGS=""
- if [ -z "$BUILD_TYPE" ]; then export BUILD_TYPE=Release; fi
- if [ "$ASAN" == "On"]; then export CXX_FLAGS="${CXX_FLAGS} -fsanitize=address,undefined,integer -fno-omit-frame-pointer -fno-sanitize=unsigned-integer-overflow"; fi
- if [ -n "$CLANG_VERSION" ]; then CXX_FLAGS="${CXX_FLAGS} -D__extern_always_inline=inline"; fi
- if [ "$LIBCXX" == "On" ]; then CXX_FLAGS="${CXX_FLAGS} -stdlib=libc++ -I/usr/include/c++/v1/"; fi
- if [ "$LIBCXX" == "On" ]; then CXX_LINKER_FLAGS="${CXX_FLAGS} -L/usr/lib/ -lc++"; fi
- CXX_FLAGS="${CXX_FLAGS} -std=c++${CPP}"
# Build examples
- cd example
- if [ "$BUILD_TYPE" == "Release" ]; then make rebuild CXXFLAGS="${CXX_FLAGS} ${CXX_LINKER_FLAGS}" VERBOSE=1; export BIN=example; fi
- if [ "$BUILD_TYPE" == "Debug" ]; then make rebuild debug CXXFLAGS="${CXX_FLAGS} ${CXX_LINKER_FLAGS}" VERBOSE=1; export BIN=example-debug; fi
script:
- ./"${BIN}"
- valgrind --trace-children=yes --leak-check=full ./"${BIN}"
- cd $CHECKOUT_PATH/tests; make rebuild; ./tests
notifications:
email: false
#
# Copyright(c) 2015 Ruslan Baratov.
# Distributed under the MIT License (http://opensource.org/licenses/MIT)
#
cmake_minimum_required(VERSION 3.0)
project(spdlog VERSION 1.0.0)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_library(spdlog INTERFACE)
option(SPDLOG_BUILD_EXAMPLES "Build examples" OFF)
target_include_directories(
spdlog
INTERFACE
"$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>"
"$<INSTALL_INTERFACE:include>"
)
if(SPDLOG_BUILD_EXAMPLES)
enable_testing()
add_subdirectory(example)
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(version_config "${generated_dir}/${PROJECT_NAME}ConfigVersion.cmake")
set(project_config "${generated_dir}/${PROJECT_NAME}Config.cmake")
set(targets_export_name "${PROJECT_NAME}Targets")
set(namespace "${PROJECT_NAME}::")
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)
install(
TARGETS spdlog
EXPORT "${targets_export_name}"
INCLUDES DESTINATION "${include_install_dir}"
)
install(DIRECTORY "include/spdlog" DESTINATION "${include_install_dir}")
install(
FILES "${project_config}" "${version_config}"
DESTINATION "${config_install_dir}"
)
install(
EXPORT "${targets_export_name}"
NAMESPACE "${namespace}"
DESTINATION "${config_install_dir}"
)
#
# Copyright(c) 2015 Ruslan Baratov.
# Distributed under the MIT License (http://opensource.org/licenses/MIT)
#
cmake_minimum_required(VERSION 3.0)
project(spdlog VERSION 1.0.0)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_library(spdlog INTERFACE)
option(SPDLOG_BUILD_EXAMPLES "Build examples" OFF)
target_include_directories(
spdlog
INTERFACE
"$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>"
"$<INSTALL_INTERFACE:include>"
)
if(SPDLOG_BUILD_EXAMPLES)
enable_testing()
add_subdirectory(example)
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(version_config "${generated_dir}/${PROJECT_NAME}ConfigVersion.cmake")
set(project_config "${generated_dir}/${PROJECT_NAME}Config.cmake")
set(targets_export_name "${PROJECT_NAME}Targets")
set(namespace "${PROJECT_NAME}::")
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)
install(
TARGETS spdlog
EXPORT "${targets_export_name}"
INCLUDES DESTINATION "${include_install_dir}"
)
install(DIRECTORY "include/spdlog" DESTINATION "${include_install_dir}")
install(
FILES "${project_config}" "${version_config}"
DESTINATION "${config_install_dir}"
)
install(
EXPORT "${targets_export_name}"
NAMESPACE "${namespace}"
DESTINATION "${config_install_dir}"
)
This diff is collapsed.
CXX ?= g++
CXXFLAGS = -march=native -Wall -Wextra -pedantic -std=c++11 -pthread -Wl,--no-as-needed -I../include
CXX_RELEASE_FLAGS = -O3 -flto -DNDEBUG
binaries=spdlog-bench spdlog-bench-mt spdlog-async zf_log-bench zf_log-bench-mt boost-bench boost-bench-mt glog-bench glog-bench-mt g2log-async easylogging-bench easylogging-bench-mt
all: $(binaries)
spdlog-bench: spdlog-bench.cpp
$(CXX) spdlog-bench.cpp -o spdlog-bench $(CXXFLAGS) $(CXX_RELEASE_FLAGS)
spdlog-bench-mt: spdlog-bench-mt.cpp
$(CXX) spdlog-bench-mt.cpp -o spdlog-bench-mt $(CXXFLAGS) $(CXX_RELEASE_FLAGS)
spdlog-async: spdlog-async.cpp
$(CXX) spdlog-async.cpp -o spdlog-async $(CXXFLAGS) $(CXX_RELEASE_FLAGS)
ZF_LOG_FLAGS = -I../../zf_log.git/zf_log/
zf_log-bench: zf_log-bench.cpp
$(CXX) zf_log-bench.cpp -o zf_log-bench $(CXXFLAGS) $(CXX_RELEASE_FLAGS) $(ZF_LOG_FLAGS)
zf_log-bench-mt: zf_log-bench-mt.cpp
$(CXX) zf_log-bench-mt.cpp -o zf_log-bench-mt $(CXXFLAGS) $(CXX_RELEASE_FLAGS) $(ZF_LOG_FLAGS)
BOOST_FLAGS = -DBOOST_LOG_DYN_LINK -I/usr/include -lboost_log -lboost_log_setup -lboost_filesystem -lboost_system -lboost_thread -lboost_regex -lboost_date_time -lboost_chrono
boost-bench: boost-bench.cpp
$(CXX) boost-bench.cpp -o boost-bench $(CXXFLAGS) $(BOOST_FLAGS) $(CXX_RELEASE_FLAGS)
boost-bench-mt: boost-bench-mt.cpp
$(CXX) boost-bench-mt.cpp -o boost-bench-mt $(CXXFLAGS) $(BOOST_FLAGS) $(CXX_RELEASE_FLAGS)
GLOG_FLAGS = -lglog
glog-bench: glog-bench.cpp
$(CXX) glog-bench.cpp -o glog-bench $(CXXFLAGS) $(GLOG_FLAGS) $(CXX_RELEASE_FLAGS)
glog-bench-mt: glog-bench-mt.cpp
$(CXX) glog-bench-mt.cpp -o glog-bench-mt $(CXXFLAGS) $(GLOG_FLAGS) $(CXX_RELEASE_FLAGS)
G2LOG_FLAGS = -I/home/gabi/devel/g2log/g2log/src -L/home/gabi/devel/g2log/g2log -llib_g2logger
g2log-async: g2log-async.cpp
$(CXX) g2log-async.cpp -o g2log-async $(CXXFLAGS) $(G2LOG_FLAGS) $(CXX_RELEASE_FLAGS)
EASYL_FLAGS = -I../../easylogging/src/
easylogging-bench: easylogging-bench.cpp
$(CXX) easylogging-bench.cpp -o easylogging-bench $(CXXFLAGS) $(EASYL_FLAGS) $(CXX_RELEASE_FLAGS)
easylogging-bench-mt: easylogging-bench-mt.cpp
$(CXX) easylogging-bench-mt.cpp -o easylogging-bench-mt $(CXXFLAGS) $(EASYL_FLAGS) $(CXX_RELEASE_FLAGS)
.PHONY: clean
clean:
rm -f *.o logs/* $(binaries)
rebuild: clean all
CXX ?= g++
CXXFLAGS = -march=native -Wall -Wextra -pedantic -std=c++11 -pthread -Wl,--no-as-needed -I../include
CXX_RELEASE_FLAGS = -O3 -flto -DNDEBUG
binaries=spdlog-bench spdlog-bench-mt spdlog-async zf_log-bench zf_log-bench-mt boost-bench boost-bench-mt glog-bench glog-bench-mt g2log-async easylogging-bench easylogging-bench-mt
all: $(binaries)
spdlog-bench: spdlog-bench.cpp
$(CXX) spdlog-bench.cpp -o spdlog-bench $(CXXFLAGS) $(CXX_RELEASE_FLAGS)
spdlog-bench-mt: spdlog-bench-mt.cpp
$(CXX) spdlog-bench-mt.cpp -o spdlog-bench-mt $(CXXFLAGS) $(CXX_RELEASE_FLAGS)
spdlog-async: spdlog-async.cpp
$(CXX) spdlog-async.cpp -o spdlog-async $(CXXFLAGS) $(CXX_RELEASE_FLAGS)
ZF_LOG_FLAGS = -I../../zf_log.git/zf_log/
zf_log-bench: zf_log-bench.cpp
$(CXX) zf_log-bench.cpp -o zf_log-bench $(CXXFLAGS) $(CXX_RELEASE_FLAGS) $(ZF_LOG_FLAGS)
zf_log-bench-mt: zf_log-bench-mt.cpp
$(CXX) zf_log-bench-mt.cpp -o zf_log-bench-mt $(CXXFLAGS) $(CXX_RELEASE_FLAGS) $(ZF_LOG_FLAGS)
BOOST_FLAGS = -DBOOST_LOG_DYN_LINK -I/usr/include -lboost_log -lboost_log_setup -lboost_filesystem -lboost_system -lboost_thread -lboost_regex -lboost_date_time -lboost_chrono
boost-bench: boost-bench.cpp
$(CXX) boost-bench.cpp -o boost-bench $(CXXFLAGS) $(BOOST_FLAGS) $(CXX_RELEASE_FLAGS)
boost-bench-mt: boost-bench-mt.cpp
$(CXX) boost-bench-mt.cpp -o boost-bench-mt $(CXXFLAGS) $(BOOST_FLAGS) $(CXX_RELEASE_FLAGS)
GLOG_FLAGS = -lglog
glog-bench: glog-bench.cpp
$(CXX) glog-bench.cpp -o glog-bench $(CXXFLAGS) $(GLOG_FLAGS) $(CXX_RELEASE_FLAGS)
glog-bench-mt: glog-bench-mt.cpp
$(CXX) glog-bench-mt.cpp -o glog-bench-mt $(CXXFLAGS) $(GLOG_FLAGS) $(CXX_RELEASE_FLAGS)
G2LOG_FLAGS = -I/home/gabi/devel/g2log/g2log/src -L/home/gabi/devel/g2log/g2log -llib_g2logger
g2log-async: g2log-async.cpp
$(CXX) g2log-async.cpp -o g2log-async $(CXXFLAGS) $(G2LOG_FLAGS) $(CXX_RELEASE_FLAGS)
EASYL_FLAGS = -I../../easylogging/src/
easylogging-bench: easylogging-bench.cpp
$(CXX) easylogging-bench.cpp -o easylogging-bench $(CXXFLAGS) $(EASYL_FLAGS) $(CXX_RELEASE_FLAGS)
easylogging-bench-mt: easylogging-bench-mt.cpp
$(CXX) easylogging-bench-mt.cpp -o easylogging-bench-mt $(CXXFLAGS) $(EASYL_FLAGS) $(CXX_RELEASE_FLAGS)
.PHONY: clean
clean:
rm -f *.o logs/* $(binaries)
rebuild: clean all
#~/bin/bash
#execute each bench 3 times and print the timing
exec 2>&1
#execute and time given exe 3 times
bench_exe ()
{
echo "**************** $1 ****************"
for i in {1..3}; do
time ./$1 $2;
rm -f logs/*
sleep 3
done;
}
#execute given async tests 3 times (timing is already builtin)
bench_async ()
{
echo "**************** $1 ****************"
for i in {1..3}; do
./$1 $2;
echo
rm -f logs/*
sleep 3
done;
}
echo "----------------------------------------------------------"
echo "Single threaded benchmarks.. (1 thread, 1,000,000 lines)"
echo "----------------------------------------------------------"
for exe in boost-bench glog-bench easylogging-bench zf_log-bench spdlog-bench;
do
bench_exe $exe 1
done;
echo "----------------------------------------------------------"
echo "Multi threaded benchmarks.. (10 threads, 1,000,000 lines)"
echo "----------------------------------------------------------"
for exe in boost-bench-mt glog-bench-mt easylogging-bench-mt zf_log-bench-mt spdlog-bench-mt;
do
bench_exe $exe 10
done;
echo "----------------------------------------------------------"
echo "Multi threaded benchmarks.. (100 threads, 1,000,000 lines)"
echo "----------------------------------------------------------"
for exe in boost-bench-mt glog-bench-mt easylogging-bench-mt zf_log-bench-mt spdlog-bench-mt;
do
bench_exe $exe 100
done;
echo "---------------------------------------------------------------"
echo "Async, single threaded benchmark.. (1 thread, 1,000,000 lines)"
echo "---------------------------------------------------------------"
for exe in spdlog-async g2log-async
do
bench_async $exe 1
done;
echo "---------------------------------------------------------------"
echo "Async, multi threaded benchmark.. (10 threads, 1,000,000 lines)"
echo "---------------------------------------------------------------"
for exe in spdlog-async g2log-async
do
bench_async $exe 10
done;
echo "---------------------------------------------------------------"
echo "Async, multi threaded benchmark.. (100 threads, 1,000,000 lines)"
echo "---------------------------------------------------------------"
for exe in spdlog-async g2log-async
do
bench_async $exe 100
done;
#~/bin/bash
#execute each bench 3 times and print the timing
exec 2>&1
#execute and time given exe 3 times
bench_exe ()
{
echo "**************** $1 ****************"
for i in {1..3}; do
time ./$1 $2;
rm -f logs/*
sleep 3
done;
}
#execute given async tests 3 times (timing is already builtin)
bench_async ()
{
echo "**************** $1 ****************"
for i in {1..3}; do
./$1 $2;
echo
rm -f logs/*
sleep 3
done;
}
echo "----------------------------------------------------------"
echo "Single threaded benchmarks.. (1 thread, 1,000,000 lines)"
echo "----------------------------------------------------------"
for exe in boost-bench glog-bench easylogging-bench zf_log-bench spdlog-bench;
do
bench_exe $exe 1
done;
echo "----------------------------------------------------------"
echo "Multi threaded benchmarks.. (10 threads, 1,000,000 lines)"
echo "----------------------------------------------------------"
for exe in boost-bench-mt glog-bench-mt easylogging-bench-mt zf_log-bench-mt spdlog-bench-mt;
do
bench_exe $exe 10
done;
echo "----------------------------------------------------------"
echo "Multi threaded benchmarks.. (100 threads, 1,000,000 lines)"
echo "----------------------------------------------------------"
for exe in boost-bench-mt glog-bench-mt easylogging-bench-mt zf_log-bench-mt spdlog-bench-mt;
do
bench_exe $exe 100
done;
echo "---------------------------------------------------------------"
echo "Async, single threaded benchmark.. (1 thread, 1,000,000 lines)"
echo "---------------------------------------------------------------"
for exe in spdlog-async g2log-async
do
bench_async $exe 1
done;
echo "---------------------------------------------------------------"
echo "Async, multi threaded benchmark.. (10 threads, 1,000,000 lines)"
echo "---------------------------------------------------------------"
for exe in spdlog-async g2log-async
do
bench_async $exe 10
done;
echo "---------------------------------------------------------------"
echo "Async, multi threaded benchmark.. (100 threads, 1,000,000 lines)"
echo "---------------------------------------------------------------"
for exe in spdlog-async g2log-async
do
bench_async $exe 100
done;
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#include <thread>
#include <vector>
#include <atomic>
#include <iostream>
#include <chrono>
#include <cstdlib>
#include "spdlog/spdlog.h"
using namespace std;
int main(int argc, char* argv[])
{
using namespace std::chrono;
using clock=steady_clock;
namespace spd = spdlog;
int thread_count = 10;
if(argc > 1)
thread_count = ::atoi(argv[1]);
int howmany = 1000000;
spd::set_async_mode(1048576);
auto logger = spdlog::create<spd::sinks::simple_file_sink_mt>("file_logger", "logs/spd-bench-async.txt", false);
logger->set_pattern("[%Y-%b-%d %T.%e]: %v");
std::atomic<int > msg_counter {0};
vector<thread> threads;
auto start = clock::now();
for (int t = 0; t < thread_count; ++t)
{
threads.push_back(std::thread([&]()
{
while (true)
{
int counter = ++msg_counter;
if (counter > howmany) break;
logger->info() << "spdlog message #" << counter << ": This is some text for your pleasure";
}
}));
}
for(auto &t:threads)
{
t.join();
};
duration<float> delta = clock::now() - start;
float deltaf = delta.count();
auto rate = howmany/deltaf;
cout << "Total: " << howmany << std::endl;
cout << "Threads: " << thread_count << std::endl;
std::cout << "Delta = " << deltaf << " seconds" << std::endl;
std::cout << "Rate = " << rate << "/sec" << std::endl;
}
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#include <thread>
#include <vector>
#include <atomic>
#include <iostream>
#include <chrono>
#include <cstdlib>
#include "spdlog/spdlog.h"
using namespace std;
int main(int argc, char* argv[])
{
using namespace std::chrono;
using clock=steady_clock;
namespace spd = spdlog;
int thread_count = 10;
if(argc > 1)
thread_count = ::atoi(argv[1]);
int howmany = 1000000;
spd::set_async_mode(1048576);
auto logger = spdlog::create<spd::sinks::simple_file_sink_mt>("file_logger", "logs/spd-bench-async.txt", false);
logger->set_pattern("[%Y-%b-%d %T.%e]: %v");
std::atomic<int > msg_counter {0};
vector<thread> threads;
auto start = clock::now();
for (int t = 0; t < thread_count; ++t)
{
threads.push_back(std::thread([&]()
{
while (true)
{
int counter = ++msg_counter;
if (counter > howmany) break;
logger->info() << "spdlog message #" << counter << ": This is some text for your pleasure";
}
}));
}
for(auto &t:threads)
{
t.join();
};
duration<float> delta = clock::now() - start;
float deltaf = delta.count();
auto rate = howmany/deltaf;
cout << "Total: " << howmany << std::endl;
cout << "Threads: " << thread_count << std::endl;
std::cout << "Delta = " << deltaf << " seconds" << std::endl;
std::cout << "Rate = " << rate << "/sec" << std::endl;
}
#include <thread>
#include <vector>
#include <atomic>
#include <cstdlib>
#include <unistd.h>
#include <fcntl.h>
#include <zf_log.c>
const char g_path[] = "logs/zf_log.txt";
int g_fd;
static void output_callback(zf_log_message *msg)
{
*msg->p = '\n';
write(g_fd, msg->buf, msg->p - msg->buf + 1);
}
using namespace std;
int main(int argc, char* argv[])
{
g_fd = open(g_path, O_APPEND|O_CREAT|O_WRONLY);
if (0 > g_fd)
{
ZF_LOGE_AUX(ZF_LOG_STDERR, "Failed to open log file: %s", g_path);
return -1;
}
zf_log_set_output_callback(ZF_LOG_PUT_STD, output_callback);
int thread_count = 10;
if(argc > 1)
thread_count = std::atoi(argv[1]);
int howmany = 1000000;
std::atomic<int > msg_counter {0};
vector<thread> threads;
for (int t = 0; t < thread_count; ++t)
{
threads.push_back(std::thread([&]()
{
while (true)
{
int counter = ++msg_counter;
if (counter > howmany) break;
ZF_LOGI("zf_log message #%i: This is some text for your pleasure", counter);
}
}));
}
for (auto &t:threads)
{
t.join();
};
close(g_fd);
return 0;
}
#include <thread>
#include <vector>
#include <atomic>
#include <cstdlib>
#include <unistd.h>
#include <fcntl.h>
#include <zf_log.c>
const char g_path[] = "logs/zf_log.txt";
int g_fd;
static void output_callback(zf_log_message *msg)
{
*msg->p = '\n';
write(g_fd, msg->buf, msg->p - msg->buf + 1);
}
using namespace std;
int main(int argc, char* argv[])
{
g_fd = open(g_path, O_APPEND|O_CREAT|O_WRONLY);
if (0 > g_fd)
{
ZF_LOGE_AUX(ZF_LOG_STDERR, "Failed to open log file: %s", g_path);
return -1;
}
zf_log_set_output_callback(ZF_LOG_PUT_STD, output_callback);
int thread_count = 10;
if(argc > 1)
thread_count = std::atoi(argv[1]);
int howmany = 1000000;
std::atomic<int > msg_counter {0};
vector<thread> threads;
for (int t = 0; t < thread_count; ++t)
{
threads.push_back(std::thread([&]()
{
while (true)
{
int counter = ++msg_counter;
if (counter > howmany) break;
ZF_LOGI("zf_log message #%i: This is some text for your pleasure", counter);
}
}));
}
for (auto &t:threads)
{
t.join();
};
close(g_fd);
return 0;
}
#include <stdio.h>
#include <zf_log.c>
const char g_path[] = "logs/zf_log.txt";
static FILE *g_f;
static void output_callback(zf_log_message *msg)
{
*msg->p = '\n';
fwrite(msg->buf, msg->p - msg->buf + 1, 1, g_f);
}
int main(int, char* [])
{
g_f = fopen(g_path, "wb");
if (!g_f) {
ZF_LOGE_AUX(ZF_LOG_STDERR, "Failed to open log file: %s", g_path);
return -1;
}
zf_log_set_output_callback(ZF_LOG_PUT_STD, output_callback);
const int howmany = 1000000;
for(int i = 0 ; i < howmany; ++i)
ZF_LOGI("zf_log message #%i: This is some text for your pleasure", i);
fclose(g_f);
return 0;
}
#include <stdio.h>
#include <zf_log.c>
const char g_path[] = "logs/zf_log.txt";
static FILE *g_f;
static void output_callback(zf_log_message *msg)
{
*msg->p = '\n';
fwrite(msg->buf, msg->p - msg->buf + 1, 1, g_f);
}
int main(int, char* [])
{
g_f = fopen(g_path, "wb");
if (!g_f)
{
ZF_LOGE_AUX(ZF_LOG_STDERR, "Failed to open log file: %s", g_path);
return -1;
}
zf_log_set_output_callback(ZF_LOG_PUT_STD, output_callback);
const int howmany = 1000000;
for(int i = 0 ; i < howmany; ++i)
ZF_LOGI("zf_log message #%i: This is some text for your pleasure", i);
fclose(g_f);
return 0;
}
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
//
// spdlog usage example
//
#include "spdlog/spdlog.h"
#include <cstdlib> // EXIT_FAILURE
#include <iostream>
#include <memory>
void async_example();
void syslog_example();
namespace spd = spdlog;
int main(int, char*[])
{
try
{
// Multithreaded color console
auto console = spd::stdout_logger_mt("console", true);
console->info("Welcome to spdlog!");
console->info("An info message example {}..", 1);
console->info() << "Streams are supported too " << 1;
// Formatting examples
console->info("Easy padding in numbers like {:08d}", 12);
console->info("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42);
console->info("Support for floats {:03.2f}", 1.23456);
console->info("Positional args are {1} {0}..", "too", "supported");
console->info("{:<30}", "left aligned");
console->info("{:>30}", "right aligned");
console->info("{:^30}", "centered");
spd::get("console")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name) function");
// Runtime log levels
spd::set_level(spd::level::info); //Set global log level to info
console->debug("This message shold not be displayed!");
console->set_level(spd::level::debug); // Set specific logger's log level
console->debug("This message shold be displayed..");
// Create a file rotating logger with 5mb size max and 3 rotated files
auto file_logger = spd::rotating_logger_mt("file_logger", "logs/mylogfile", 1048576 * 5, 3);
for (int i = 0; i < 10; ++i)
file_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);
// Customize msg format for all messages
spd::set_pattern("*** [%H:%M:%S %z] [thread %t] %v ***");
file_logger->info("This is another message with custom format");
// Compile time debug or trace macros.
// Enabled #ifdef SPDLOG_DEBUG_ON or #ifdef 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);
// Asynchronous logging is very fast..
// Just call spdlog::set_async_mode(q_size) and all created loggers from now on will be asynchronous..
async_example();
// syslog example. linux/osx only..
syslog_example();
// Release and close all loggers
spdlog::drop_all();
}
catch (const spd::spdlog_ex& ex)
{
std::cout << "Log failed: " << ex.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
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.txt");
for (int i = 0; i < 100; ++i)
async_file->info("Async message #{}", i);
}
//syslog example (linux/osx only)
void syslog_example()
{
#if defined (__linux__) || defined(__APPLE__)
std::string ident = "spdlog-example";
auto syslog_logger = spd::syslog_logger("syslog", ident, LOG_PID);
syslog_logger->warn("This is warning that will end up in syslog. This is Linux only!");
#endif
}
// Example of user defined class with operator<<
class some_class {};
std::ostream& operator<<(std::ostream& os, const some_class&)
{
return os << "some_class";
}
void custom_class_example()
{
some_class c;
spdlog::get("console")->info("custom class with operator<<: {}..", c);
spdlog::get("console")->info() << "custom class with operator<<: " << c << "..";
}
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
//
// spdlog usage example
//
#include "spdlog/spdlog.h"
#include <cstdlib> // EXIT_FAILURE
#include <iostream>
#include <memory>
void async_example();
void syslog_example();
namespace spd = spdlog;
int main(int, char*[])
{
try
{
// Multithreaded color console
auto console = spd::stdout_logger_mt("console", true);
console->info("Welcome to spdlog!");
console->info("An info message example {}..", 1);
console->info() << "Streams are supported too " << 1;
// Formatting examples
console->info("Easy padding in numbers like {:08d}", 12);
console->info("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42);
console->info("Support for floats {:03.2f}", 1.23456);
console->info("Positional args are {1} {0}..", "too", "supported");
console->info("{:<30}", "left aligned");
console->info("{:>30}", "right aligned");
console->info("{:^30}", "centered");
spd::get("console")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name) function");
// Runtime log levels
spd::set_level(spd::level::info); //Set global log level to info
console->debug("This message shold not be displayed!");
console->set_level(spd::level::debug); // Set specific logger's log level
console->debug("This message shold be displayed..");
// Create a file rotating logger with 5mb size max and 3 rotated files
auto file_logger = spd::rotating_logger_mt("file_logger", "logs/mylogfile", 1048576 * 5, 3);
for (int i = 0; i < 10; ++i)
file_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);
// Customize msg format for all messages
spd::set_pattern("*** [%H:%M:%S %z] [thread %t] %v ***");
file_logger->info("This is another message with custom format");
// Compile time debug or trace macros.
// Enabled #ifdef SPDLOG_DEBUG_ON or #ifdef 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);
// Asynchronous logging is very fast..
// Just call spdlog::set_async_mode(q_size) and all created loggers from now on will be asynchronous..
async_example();
// syslog example. linux/osx only..
syslog_example();
// Release and close all loggers
spdlog::drop_all();
}
catch (const spd::spdlog_ex& ex)
{
std::cout << "Log failed: " << ex.what() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
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.txt");
for (int i = 0; i < 100; ++i)
async_file->info("Async message #{}", i);
}
//syslog example (linux/osx only)
void syslog_example()
{
#if defined (__linux__) || defined(__APPLE__)
std::string ident = "spdlog-example";
auto syslog_logger = spd::syslog_logger("syslog", ident, LOG_PID);
syslog_logger->warn("This is warning that will end up in syslog. This is Linux only!");
#endif
}
// Example of user defined class with operator<<
class some_class {};
std::ostream& operator<<(std::ostream& os, const some_class&)
{
return os << "some_class";
}
void custom_class_example()
{
some_class c;
spdlog::get("console")->info("custom class with operator<<: {}..", c);
spdlog::get("console")->info() << "custom class with operator<<: " << c << "..";
}
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="example.cpp" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{9E5AB93A-0CCE-4BAC-9FCB-0FC9CB5EB8D2}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>.</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PrecompiledHeaderFile />
<PrecompiledHeaderOutputFile />
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PrecompiledHeaderFile />
<PrecompiledHeaderOutputFile />
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="example.cpp" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{9E5AB93A-0CCE-4BAC-9FCB-0FC9CB5EB8D2}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>.</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PrecompiledHeaderFile />
<PrecompiledHeaderOutputFile />
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PrecompiledHeaderFile />
<PrecompiledHeaderOutputFile />
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
\ No newline at end of file
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
// Very fast asynchronous logger (millions of logs per second on an average desktop)
// Uses pre allocated lockfree queue for maximum throughput even under large number of threads.
// Creates a single back thread to pop messages from the queue and log them.
//
// Upon each log write the logger:
// 1. Checks if its log level is enough to log the message
// 2. Push a new copy of the message to a queue (or block the caller until space is available in the queue)
// 3. will throw spdlog_ex upon log exceptions
// Upong destruction, logs all remaining messages in the queue before destructing..
#include <spdlog/common.h>
#include <spdlog/logger.h>
#include <chrono>
#include <functional>
#include <string>
#include <memory>
namespace spdlog
{
namespace details
{
class async_log_helper;
}
class async_logger :public logger
{
public:
template<class It>
async_logger(const std::string& name,
const It& begin,
const It& end,
size_t queue_size,
const async_overflow_policy overflow_policy = async_overflow_policy::block_retry,
const std::function<void()>& worker_warmup_cb = nullptr,
const std::chrono::milliseconds& flush_interval_ms = std::chrono::milliseconds::zero());
async_logger(const std::string& logger_name,
sinks_init_list sinks,
size_t queue_size,
const async_overflow_policy overflow_policy = async_overflow_policy::block_retry,
const std::function<void()>& worker_warmup_cb = nullptr,
const std::chrono::milliseconds& flush_interval_ms = std::chrono::milliseconds::zero());
async_logger(const std::string& logger_name,
sink_ptr single_sink,
size_t queue_size,
const async_overflow_policy overflow_policy = async_overflow_policy::block_retry,
const std::function<void()>& worker_warmup_cb = nullptr,
const std::chrono::milliseconds& flush_interval_ms = std::chrono::milliseconds::zero());
void flush() override;
protected:
void _log_msg(details::log_msg& msg) override;
void _set_formatter(spdlog::formatter_ptr msg_formatter) override;
void _set_pattern(const std::string& pattern) override;
private:
std::unique_ptr<details::async_log_helper> _async_log_helper;
};
}
#include <spdlog/details/async_logger_impl.h>
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
// Very fast asynchronous logger (millions of logs per second on an average desktop)
// Uses pre allocated lockfree queue for maximum throughput even under large number of threads.
// Creates a single back thread to pop messages from the queue and log them.
//
// Upon each log write the logger:
// 1. Checks if its log level is enough to log the message
// 2. Push a new copy of the message to a queue (or block the caller until space is available in the queue)
// 3. will throw spdlog_ex upon log exceptions
// Upong destruction, logs all remaining messages in the queue before destructing..
#include <spdlog/common.h>
#include <spdlog/logger.h>
#include <chrono>
#include <functional>
#include <string>
#include <memory>
namespace spdlog
{
namespace details
{
class async_log_helper;
}
class async_logger :public logger
{
public:
template<class It>
async_logger(const std::string& name,
const It& begin,
const It& end,
size_t queue_size,
const async_overflow_policy overflow_policy = async_overflow_policy::block_retry,
const std::function<void()>& worker_warmup_cb = nullptr,
const std::chrono::milliseconds& flush_interval_ms = std::chrono::milliseconds::zero());
async_logger(const std::string& logger_name,
sinks_init_list sinks,
size_t queue_size,
const async_overflow_policy overflow_policy = async_overflow_policy::block_retry,
const std::function<void()>& worker_warmup_cb = nullptr,
const std::chrono::milliseconds& flush_interval_ms = std::chrono::milliseconds::zero());
async_logger(const std::string& logger_name,
sink_ptr single_sink,
size_t queue_size,
const async_overflow_policy overflow_policy = async_overflow_policy::block_retry,
const std::function<void()>& worker_warmup_cb = nullptr,
const std::chrono::milliseconds& flush_interval_ms = std::chrono::milliseconds::zero());
void flush() override;
protected:
void _log_msg(details::log_msg& msg) override;
void _set_formatter(spdlog::formatter_ptr msg_formatter) override;
void _set_pattern(const std::string& pattern) override;
private:
std::unique_ptr<details::async_log_helper> _async_log_helper;
};
}
#include <spdlog/details/async_logger_impl.h>
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
#include <string>
#include <initializer_list>
#include <chrono>
#include <memory>
#include <exception>
//visual studio does not support noexcept yet
#ifndef _MSC_VER
#define SPDLOG_NOEXCEPT noexcept
#else
#define SPDLOG_NOEXCEPT throw()
#endif
namespace spdlog
{
class formatter;
namespace sinks
{
class sink;
}
// Common types across the lib
using log_clock = std::chrono::system_clock;
using sink_ptr = std::shared_ptr < sinks::sink >;
using sinks_init_list = std::initializer_list < sink_ptr >;
using formatter_ptr = std::shared_ptr<spdlog::formatter>;
//Log level enum
namespace level
{
typedef enum
{
trace = 0,
debug = 1,
info = 2,
notice = 3,
warn = 4,
err = 5,
critical = 6,
alert = 7,
emerg = 8,
off = 9
} level_enum;
static const char* level_names[] { "trace", "debug", "info", "notice", "warning", "error", "critical", "alert", "emerg", "off"};
static const char* short_level_names[] { "T", "D", "I", "N", "W", "E", "C", "A", "M", "O"};
inline const char* to_str(spdlog::level::level_enum l)
{
return level_names[l];
}
inline const char* to_short_str(spdlog::level::level_enum l)
{
return short_level_names[l];
}
} //level
//
// Async overflow policy - block by default.
//
enum class async_overflow_policy
{
block_retry, // Block / yield / sleep until message can be enqueued
discard_log_msg // Discard the message it enqueue fails
};
//
// Log exception
//
class spdlog_ex : public std::exception
{
public:
spdlog_ex(const std::string& msg) :_msg(msg) {}
const char* what() const SPDLOG_NOEXCEPT override
{
return _msg.c_str();
}
private:
std::string _msg;
};
} //spdlog
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
#include <string>
#include <initializer_list>
#include <chrono>
#include <memory>
#include <exception>
//visual studio does not support noexcept yet
#ifndef _MSC_VER
#define SPDLOG_NOEXCEPT noexcept
#else
#define SPDLOG_NOEXCEPT throw()
#endif
namespace spdlog
{
class formatter;
namespace sinks
{
class sink;
}
// Common types across the lib
using log_clock = std::chrono::system_clock;
using sink_ptr = std::shared_ptr < sinks::sink >;
using sinks_init_list = std::initializer_list < sink_ptr >;
using formatter_ptr = std::shared_ptr<spdlog::formatter>;
//Log level enum
namespace level
{
typedef enum
{
trace = 0,
debug = 1,
info = 2,
notice = 3,
warn = 4,
err = 5,
critical = 6,
alert = 7,
emerg = 8,
off = 9
} level_enum;
static const char* level_names[] { "trace", "debug", "info", "notice", "warning", "error", "critical", "alert", "emerg", "off"};
static const char* short_level_names[] { "T", "D", "I", "N", "W", "E", "C", "A", "M", "O"};
inline const char* to_str(spdlog::level::level_enum l)
{
return level_names[l];
}
inline const char* to_short_str(spdlog::level::level_enum l)
{
return short_level_names[l];
}
} //level
//
// Async overflow policy - block by default.
//
enum class async_overflow_policy
{
block_retry, // Block / yield / sleep until message can be enqueued
discard_log_msg // Discard the message it enqueue fails
};
//
// Log exception
//
class spdlog_ex : public std::exception
{
public:
spdlog_ex(const std::string& msg) :_msg(msg) {}
const char* what() const SPDLOG_NOEXCEPT override
{
return _msg.c_str();
}
private:
std::string _msg;
};
} //spdlog
This diff is collapsed.
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
// 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 <string>
#include <functional>
#include <chrono>
#include <memory>
template<class It>
inline spdlog::async_logger::async_logger(const std::string& logger_name,
const It& begin,
const It& end,
size_t queue_size,
const async_overflow_policy overflow_policy,
const std::function<void()>& worker_warmup_cb,
const std::chrono::milliseconds& flush_interval_ms) :
logger(logger_name, begin, end),
_async_log_helper(new details::async_log_helper(_formatter, _sinks, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms))
{
}
inline spdlog::async_logger::async_logger(const std::string& logger_name,
sinks_init_list sinks,
size_t queue_size,
const async_overflow_policy overflow_policy,
const std::function<void()>& worker_warmup_cb,
const std::chrono::milliseconds& flush_interval_ms) :
async_logger(logger_name, sinks.begin(), sinks.end(), queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms) {}
inline spdlog::async_logger::async_logger(const std::string& logger_name,
sink_ptr single_sink,
size_t queue_size,
const async_overflow_policy overflow_policy,
const std::function<void()>& worker_warmup_cb,
const std::chrono::milliseconds& flush_interval_ms) :
async_logger(logger_name,
{
single_sink
}, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms) {}
inline void spdlog::async_logger::flush()
{
_async_log_helper->flush();
}
inline void spdlog::async_logger::_set_formatter(spdlog::formatter_ptr msg_formatter)
{
_formatter = msg_formatter;
_async_log_helper->set_formatter(_formatter);
}
inline void spdlog::async_logger::_set_pattern(const std::string& pattern)
{
_formatter = std::make_shared<pattern_formatter>(pattern);
_async_log_helper->set_formatter(_formatter);
}
inline void spdlog::async_logger::_log_msg(details::log_msg& msg)
{
_async_log_helper->log(msg);
}
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
// 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 <string>
#include <functional>
#include <chrono>
#include <memory>
template<class It>
inline spdlog::async_logger::async_logger(const std::string& logger_name,
const It& begin,
const It& end,
size_t queue_size,
const async_overflow_policy overflow_policy,
const std::function<void()>& worker_warmup_cb,
const std::chrono::milliseconds& flush_interval_ms) :
logger(logger_name, begin, end),
_async_log_helper(new details::async_log_helper(_formatter, _sinks, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms))
{
}
inline spdlog::async_logger::async_logger(const std::string& logger_name,
sinks_init_list sinks,
size_t queue_size,
const async_overflow_policy overflow_policy,
const std::function<void()>& worker_warmup_cb,
const std::chrono::milliseconds& flush_interval_ms) :
async_logger(logger_name, sinks.begin(), sinks.end(), queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms) {}
inline spdlog::async_logger::async_logger(const std::string& logger_name,
sink_ptr single_sink,
size_t queue_size,
const async_overflow_policy overflow_policy,
const std::function<void()>& worker_warmup_cb,
const std::chrono::milliseconds& flush_interval_ms) :
async_logger(logger_name,
{
single_sink
}, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms) {}
inline void spdlog::async_logger::flush()
{
_async_log_helper->flush();
}
inline void spdlog::async_logger::_set_formatter(spdlog::formatter_ptr msg_formatter)
{
_formatter = msg_formatter;
_async_log_helper->set_formatter(_formatter);
}
inline void spdlog::async_logger::_set_pattern(const std::string& pattern)
{
_formatter = std::make_shared<pattern_formatter>(pattern);
_async_log_helper->set_formatter(_formatter);
}
inline void spdlog::async_logger::_log_msg(details::log_msg& msg)
{
_async_log_helper->log(msg);
}
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
// Helper class for file sink
// When failing to open a file, retry several times(5) with small delay between the tries(10 ms)
// Can be set to auto flush on every line
// Throw spdlog_ex exception on errors
#include <spdlog/details/os.h>
#include <spdlog/details/log_msg.h>
#include <chrono>
#include <cstdio>
#include <string>
#include <thread>
namespace spdlog
{
namespace details
{
class file_helper
{
public:
const int open_tries = 5;
const int open_interval = 10;
explicit file_helper(bool force_flush) :
_fd(nullptr),
_force_flush(force_flush)
{}
file_helper(const file_helper&) = delete;
file_helper& operator=(const file_helper&) = delete;
~file_helper()
{
close();
}
void open(const std::string& fname, bool truncate = false)
{
close();
const char* mode = truncate ? "wb" : "ab";
_filename = fname;
for (int tries = 0; tries < open_tries; ++tries)
{
if (!os::fopen_s(&_fd, fname, mode))
return;
std::this_thread::sleep_for(std::chrono::milliseconds(open_interval));
}
throw spdlog_ex("Failed opening file " + fname + " for writing");
}
void reopen(bool truncate)
{
if (_filename.empty())
throw spdlog_ex("Failed re opening file - was not opened before");
open(_filename, truncate);
}
void flush()
{
std::fflush(_fd);
}
void close()
{
if (_fd)
{
std::fclose(_fd);
_fd = nullptr;
}
}
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 " + _filename);
if (_force_flush)
std::fflush(_fd);
}
long size()
{
if (!_fd)
throw spdlog_ex("Cannot use size() on closed file " + _filename);
auto pos = ftell(_fd);
if (fseek(_fd, 0, SEEK_END) != 0)
throw spdlog_ex("fseek failed on file " + _filename);
auto file_size = ftell(_fd);
if(fseek(_fd, pos, SEEK_SET) !=0)
throw spdlog_ex("fseek failed on file " + _filename);
if (file_size == -1)
throw spdlog_ex("ftell failed on file " + _filename);
return file_size;
}
const std::string& filename() const
{
return _filename;
}
static bool file_exists(const std::string& name)
{
return os::file_exists(name);
}
private:
FILE* _fd;
std::string _filename;
bool _force_flush;
};
}
}
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
// Helper class for file sink
// When failing to open a file, retry several times(5) with small delay between the tries(10 ms)
// Can be set to auto flush on every line
// Throw spdlog_ex exception on errors
#include <spdlog/details/os.h>
#include <spdlog/details/log_msg.h>
#include <chrono>
#include <cstdio>
#include <string>
#include <thread>
namespace spdlog
{
namespace details
{
class file_helper
{
public:
const int open_tries = 5;
const int open_interval = 10;
explicit file_helper(bool force_flush) :
_fd(nullptr),
_force_flush(force_flush)
{}
file_helper(const file_helper&) = delete;
file_helper& operator=(const file_helper&) = delete;
~file_helper()
{
close();
}
void open(const std::string& fname, bool truncate = false)
{
close();
const char* mode = truncate ? "wb" : "ab";
_filename = fname;
for (int tries = 0; tries < open_tries; ++tries)
{
if (!os::fopen_s(&_fd, fname, mode))
return;
std::this_thread::sleep_for(std::chrono::milliseconds(open_interval));
}
throw spdlog_ex("Failed opening file " + fname + " for writing");
}
void reopen(bool truncate)
{
if (_filename.empty())
throw spdlog_ex("Failed re opening file - was not opened before");
open(_filename, truncate);
}
void flush()
{
std::fflush(_fd);
}
void close()
{
if (_fd)
{
std::fclose(_fd);
_fd = nullptr;
}
}
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 " + _filename);
if (_force_flush)
std::fflush(_fd);
}
long size()
{
if (!_fd)
throw spdlog_ex("Cannot use size() on closed file " + _filename);
auto pos = ftell(_fd);
if (fseek(_fd, 0, SEEK_END) != 0)
throw spdlog_ex("fseek failed on file " + _filename);
auto file_size = ftell(_fd);
if(fseek(_fd, pos, SEEK_SET) !=0)
throw spdlog_ex("fseek failed on file " + _filename);
if (file_size == -1)
throw spdlog_ex("ftell failed on file " + _filename);
return file_size;
}
const std::string& filename() const
{
return _filename;
}
static bool file_exists(const std::string& name)
{
return os::file_exists(name);
}
private:
FILE* _fd;
std::string _filename;
bool _force_flush;
};
}
}
This diff is collapsed.
This diff is collapsed.
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
#include <spdlog/common.h>
#include <spdlog/details/log_msg.h>
#include <string>
// Line logger class - aggregates operator<< calls to fast ostream
// and logs upon destruction
namespace spdlog
{
// Forward declaration
class logger;
namespace details
{
class line_logger
{
public:
line_logger(logger* callback_logger, level::level_enum msg_level, bool enabled);
// No copy intended. Only move
line_logger(const line_logger& other) = delete;
line_logger& operator=(const line_logger&) = delete;
line_logger& operator=(line_logger&&) = delete;
line_logger(line_logger&& other);
//Log the log message using the callback logger
~line_logger();
//
// Support for format string with variadic args
//
void write(const char* what);
template <typename... Args>
void write(const char* fmt, const Args&... args);
//
// Support for operator<<
//
line_logger& operator<<(const char* what);
line_logger& operator<<(const std::string& what);
line_logger& operator<<(int what);
line_logger& operator<<(unsigned int what);
line_logger& operator<<(long what);
line_logger& operator<<(unsigned long what);
line_logger& operator<<(long long what);
line_logger& operator<<(unsigned long long what);
line_logger& operator<<(double what);
line_logger& operator<<(long double what);
line_logger& operator<<(float what);
line_logger& operator<<(char what);
//Support user types which implements operator<<
template<typename T>
line_logger& operator<<(const T& what);
void disable();
bool is_enabled() const;
private:
logger* _callback_logger;
log_msg _log_msg;
bool _enabled;
};
} //Namespace details
} // Namespace spdlog
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
#include <spdlog/common.h>
#include <spdlog/details/log_msg.h>
#include <string>
// Line logger class - aggregates operator<< calls to fast ostream
// and logs upon destruction
namespace spdlog
{
// Forward declaration
class logger;
namespace details
{
class line_logger
{
public:
line_logger(logger* callback_logger, level::level_enum msg_level, bool enabled);
// No copy intended. Only move
line_logger(const line_logger& other) = delete;
line_logger& operator=(const line_logger&) = delete;
line_logger& operator=(line_logger&&) = delete;
line_logger(line_logger&& other);
//Log the log message using the callback logger
~line_logger();
//
// Support for format string with variadic args
//
void write(const char* what);
template <typename... Args>
void write(const char* fmt, const Args&... args);
//
// Support for operator<<
//
line_logger& operator<<(const char* what);
line_logger& operator<<(const std::string& what);
line_logger& operator<<(int what);
line_logger& operator<<(unsigned int what);
line_logger& operator<<(long what);
line_logger& operator<<(unsigned long what);
line_logger& operator<<(long long what);
line_logger& operator<<(unsigned long long what);
line_logger& operator<<(double what);
line_logger& operator<<(long double what);
line_logger& operator<<(float what);
line_logger& operator<<(char what);
//Support user types which implements operator<<
template<typename T>
line_logger& operator<<(const T& what);
void disable();
bool is_enabled() const;
private:
logger* _callback_logger;
log_msg _log_msg;
bool _enabled;
};
} //Namespace details
} // Namespace spdlog
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
#include <type_traits>
#include <spdlog/details/line_logger_fwd.h>
#include <spdlog/common.h>
#include <spdlog/logger.h>
#include <string>
#include <utility>
// Line logger class - aggregates operator<< calls to fast ostream
// and logs upon destruction
inline spdlog::details::line_logger::line_logger(logger* callback_logger, level::level_enum msg_level, bool enabled):
_callback_logger(callback_logger),
_log_msg(msg_level),
_enabled(enabled)
{}
inline spdlog::details::line_logger::line_logger(line_logger&& other) :
_callback_logger(other._callback_logger),
_log_msg(std::move(other._log_msg)),
_enabled(other._enabled)
{
other.disable();
}
//Log the log message using the callback logger
inline spdlog::details::line_logger::~line_logger()
{
if (_enabled)
{
#ifndef SPDLOG_NO_NAME
_log_msg.logger_name = _callback_logger->name();
#endif
#ifndef SPDLOG_NO_DATETIME
_log_msg.time = os::now();
#endif
#ifndef SPDLOG_NO_THREAD_ID
_log_msg.thread_id = os::thread_id();
#endif
_callback_logger->_log_msg(_log_msg);
}
}
//
// Support for format string with variadic args
//
inline void spdlog::details::line_logger::write(const char* what)
{
if (_enabled)
_log_msg.raw << what;
}
template <typename... Args>
inline void spdlog::details::line_logger::write(const char* fmt, const Args&... args)
{
if (!_enabled)
return;
try
{
_log_msg.raw.write(fmt, args...);
}
catch (const fmt::FormatError& e)
{
throw spdlog_ex(fmt::format("formatting error while processing format string '{}': {}", fmt, e.what()));
}
}
//
// Support for operator<<
//
inline spdlog::details::line_logger& spdlog::details::line_logger::operator<<(const char* what)
{
if (_enabled)
_log_msg.raw << what;
return *this;
}
inline spdlog::details::line_logger& spdlog::details::line_logger::operator<<(const std::string& what)
{
if (_enabled)
_log_msg.raw << what;
return *this;
}
inline spdlog::details::line_logger& spdlog::details::line_logger::operator<<(int what)
{
if (_enabled)
_log_msg.raw << what;
return *this;
}
inline spdlog::details::line_logger& spdlog::details::line_logger::operator<<(unsigned int what)
{
if (_enabled)
_log_msg.raw << what;
return *this;
}
inline spdlog::details::line_logger& spdlog::details::line_logger::operator<<(long what)
{
if (_enabled)
_log_msg.raw << what;
return *this;
}
inline spdlog::details::line_logger& spdlog::details::line_logger::operator<<(unsigned long what)
{
if (_enabled)
_log_msg.raw << what;
return *this;
}
inline spdlog::details::line_logger& spdlog::details::line_logger::operator<<(long long what)
{
if (_enabled)
_log_msg.raw << what;
return *this;
}
inline spdlog::details::line_logger& spdlog::details::line_logger::operator<<(unsigned long long what)
{
if (_enabled)
_log_msg.raw << what;
return *this;
}
inline spdlog::details::line_logger& spdlog::details::line_logger::operator<<(double what)
{
if (_enabled)
_log_msg.raw << what;
return *this;
}
inline spdlog::details::line_logger& spdlog::details::line_logger::operator<<(long double what)
{
if (_enabled)
_log_msg.raw << what;
return *this;
}
inline spdlog::details::line_logger& spdlog::details::line_logger::operator<<(float what)
{
if (_enabled)
_log_msg.raw << what;
return *this;
}
inline spdlog::details::line_logger& spdlog::details::line_logger::operator<<(char what)
{
if (_enabled)
_log_msg.raw << what;
return *this;
}
//Support user types which implements operator<<
template<typename T>
inline spdlog::details::line_logger& spdlog::details::line_logger::operator<<(const T& what)
{
if (_enabled)
_log_msg.raw.write("{}", what);
return *this;
}
inline void spdlog::details::line_logger::disable()
{
_enabled = false;
}
inline bool spdlog::details::line_logger::is_enabled() const
{
return _enabled;
}
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
#include <type_traits>
#include <spdlog/details/line_logger_fwd.h>
#include <spdlog/common.h>
#include <spdlog/logger.h>
#include <string>
#include <utility>
// Line logger class - aggregates operator<< calls to fast ostream
// and logs upon destruction
inline spdlog::details::line_logger::line_logger(logger* callback_logger, level::level_enum msg_level, bool enabled):
_callback_logger(callback_logger),
_log_msg(msg_level),
_enabled(enabled)
{}
inline spdlog::details::line_logger::line_logger(line_logger&& other) :
_callback_logger(other._callback_logger),
_log_msg(std::move(other._log_msg)),
_enabled(other._enabled)
{
other.disable();
}
//Log the log message using the callback logger
inline spdlog::details::line_logger::~line_logger()
{
if (_enabled)
{
#ifndef SPDLOG_NO_NAME
_log_msg.logger_name = _callback_logger->name();
#endif
#ifndef SPDLOG_NO_DATETIME
_log_msg.time = os::now();
#endif
#ifndef SPDLOG_NO_THREAD_ID
_log_msg.thread_id = os::thread_id();
#endif
_callback_logger->_log_msg(_log_msg);
}
}
//
// Support for format string with variadic args
//
inline void spdlog::details::line_logger::write(const char* what)
{
if (_enabled)
_log_msg.raw << what;
}
template <typename... Args>
inline void spdlog::details::line_logger::write(const char* fmt, const Args&... args)
{
if (!_enabled)
return;
try
{
_log_msg.raw.write(fmt, args...);
}
catch (const fmt::FormatError& e)
{
throw spdlog_ex(fmt::format("formatting error while processing format string '{}': {}", fmt, e.what()));
}
}
//
// Support for operator<<
//
inline spdlog::details::line_logger& spdlog::details::line_logger::operator<<(const char* what)
{
if (_enabled)
_log_msg.raw << what;
return *this;
}
inline spdlog::details::line_logger& spdlog::details::line_logger::operator<<(const std::string& what)
{
if (_enabled)
_log_msg.raw << what;
return *this;
}
inline spdlog::details::line_logger& spdlog::details::line_logger::operator<<(int what)
{
if (_enabled)
_log_msg.raw << what;
return *this;
}
inline spdlog::details::line_logger& spdlog::details::line_logger::operator<<(unsigned int what)
{
if (_enabled)
_log_msg.raw << what;
return *this;
}
inline spdlog::details::line_logger& spdlog::details::line_logger::operator<<(long what)
{
if (_enabled)
_log_msg.raw << what;
return *this;
}
inline spdlog::details::line_logger& spdlog::details::line_logger::operator<<(unsigned long what)
{
if (_enabled)
_log_msg.raw << what;
return *this;
}
inline spdlog::details::line_logger& spdlog::details::line_logger::operator<<(long long what)
{
if (_enabled)
_log_msg.raw << what;
return *this;
}
inline spdlog::details::line_logger& spdlog::details::line_logger::operator<<(unsigned long long what)
{
if (_enabled)
_log_msg.raw << what;
return *this;
}
inline spdlog::details::line_logger& spdlog::details::line_logger::operator<<(double what)
{
if (_enabled)
_log_msg.raw << what;
return *this;
}
inline spdlog::details::line_logger& spdlog::details::line_logger::operator<<(long double what)
{
if (_enabled)
_log_msg.raw << what;
return *this;
}
inline spdlog::details::line_logger& spdlog::details::line_logger::operator<<(float what)
{
if (_enabled)
_log_msg.raw << what;
return *this;
}
inline spdlog::details::line_logger& spdlog::details::line_logger::operator<<(char what)
{
if (_enabled)
_log_msg.raw << what;
return *this;
}
//Support user types which implements operator<<
template<typename T>
inline spdlog::details::line_logger& spdlog::details::line_logger::operator<<(const T& what)
{
if (_enabled)
_log_msg.raw.write("{}", what);
return *this;
}
inline void spdlog::details::line_logger::disable()
{
_enabled = false;
}
inline bool spdlog::details::line_logger::is_enabled() const
{
return _enabled;
}
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
#include <spdlog/common.h>
#include <spdlog/details/format.h>
#include <string>
#include <utility>
namespace spdlog
{
namespace details
{
struct log_msg
{
log_msg() = default;
log_msg(level::level_enum l):
logger_name(),
level(l),
raw(),
formatted() {}
log_msg(const log_msg& other) :
logger_name(other.logger_name),
level(other.level),
time(other.time),
thread_id(other.thread_id)
{
if (other.raw.size())
raw << fmt::BasicStringRef<char>(other.raw.data(), other.raw.size());
if (other.formatted.size())
formatted << fmt::BasicStringRef<char>(other.formatted.data(), other.formatted.size());
}
log_msg(log_msg&& other) :
logger_name(std::move(other.logger_name)),
level(other.level),
time(std::move(other.time)),
thread_id(other.thread_id),
raw(std::move(other.raw)),
formatted(std::move(other.formatted))
{
other.clear();
}
log_msg& operator=(log_msg&& other)
{
if (this == &other)
return *this;
logger_name = std::move(other.logger_name);
level = other.level;
time = std::move(other.time);
thread_id = other.thread_id;
raw = std::move(other.raw);
formatted = std::move(other.formatted);
other.clear();
return *this;
}
void clear()
{
level = level::off;
raw.clear();
formatted.clear();
}
std::string logger_name;
level::level_enum level;
log_clock::time_point time;
size_t thread_id;
fmt::MemoryWriter raw;
fmt::MemoryWriter formatted;
};
}
}
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
#include <spdlog/common.h>
#include <spdlog/details/format.h>
#include <string>
#include <utility>
namespace spdlog
{
namespace details
{
struct log_msg
{
log_msg() = default;
log_msg(level::level_enum l):
logger_name(),
level(l),
raw(),
formatted() {}
log_msg(const log_msg& other) :
logger_name(other.logger_name),
level(other.level),
time(other.time),
thread_id(other.thread_id)
{
if (other.raw.size())
raw << fmt::BasicStringRef<char>(other.raw.data(), other.raw.size());
if (other.formatted.size())
formatted << fmt::BasicStringRef<char>(other.formatted.data(), other.formatted.size());
}
log_msg(log_msg&& other) :
logger_name(std::move(other.logger_name)),
level(other.level),
time(std::move(other.time)),
thread_id(other.thread_id),
raw(std::move(other.raw)),
formatted(std::move(other.formatted))
{
other.clear();
}
log_msg& operator=(log_msg&& other)
{
if (this == &other)
return *this;
logger_name = std::move(other.logger_name);
level = other.level;
time = std::move(other.time);
thread_id = other.thread_id;
raw = std::move(other.raw);
formatted = std::move(other.formatted);
other.clear();
return *this;
}
void clear()
{
level = level::off;
raw.clear();
formatted.clear();
}
std::string logger_name;
level::level_enum level;
log_clock::time_point time;
size_t thread_id;
fmt::MemoryWriter raw;
fmt::MemoryWriter formatted;
};
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
#include <spdlog/details/log_msg.h>
#include <vector>
#include <string>
#include <memory>
namespace spdlog
{
namespace details
{
class flag_formatter;
}
class formatter
{
public:
virtual ~formatter() {}
virtual void format(details::log_msg& msg) = 0;
};
class pattern_formatter : public formatter
{
public:
explicit pattern_formatter(const std::string& pattern);
pattern_formatter(const pattern_formatter&) = delete;
pattern_formatter& operator=(const pattern_formatter&) = delete;
void format(details::log_msg& msg) override;
private:
const std::string _pattern;
std::vector<std::unique_ptr<details::flag_formatter>> _formatters;
void handle_flag(char flag);
void compile_pattern(const std::string& pattern);
};
}
#include <spdlog/details/pattern_formatter_impl.h>
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
#include <spdlog/details/log_msg.h>
#include <vector>
#include <string>
#include <memory>
namespace spdlog
{
namespace details
{
class flag_formatter;
}
class formatter
{
public:
virtual ~formatter() {}
virtual void format(details::log_msg& msg) = 0;
};
class pattern_formatter : public formatter
{
public:
explicit pattern_formatter(const std::string& pattern);
pattern_formatter(const pattern_formatter&) = delete;
pattern_formatter& operator=(const pattern_formatter&) = delete;
void format(details::log_msg& msg) override;
private:
const std::string _pattern;
std::vector<std::unique_ptr<details::flag_formatter>> _formatters;
void handle_flag(char flag);
void compile_pattern(const std::string& pattern);
};
}
#include <spdlog/details/pattern_formatter_impl.h>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
//
// base sink templated over a mutex (either dummy or realy)
// concrete implementation should only overrid the _sink_it method.
// all locking is taken care of here so no locking needed by the implementors..
//
#include <spdlog/sinks/sink.h>
#include <spdlog/formatter.h>
#include <spdlog/common.h>
#include <spdlog/details/log_msg.h>
#include <mutex>
namespace spdlog
{
namespace sinks
{
template<class Mutex>
class base_sink:public sink
{
public:
base_sink():_mutex() {}
virtual ~base_sink() = default;
base_sink(const base_sink&) = delete;
base_sink& operator=(const base_sink&) = delete;
void log(const details::log_msg& msg) override
{
std::lock_guard<Mutex> lock(_mutex);
_sink_it(msg);
}
protected:
virtual void _sink_it(const details::log_msg& msg) = 0;
Mutex _mutex;
};
}
}
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
//
// base sink templated over a mutex (either dummy or realy)
// concrete implementation should only overrid the _sink_it method.
// all locking is taken care of here so no locking needed by the implementors..
//
#include <spdlog/sinks/sink.h>
#include <spdlog/formatter.h>
#include <spdlog/common.h>
#include <spdlog/details/log_msg.h>
#include <mutex>
namespace spdlog
{
namespace sinks
{
template<class Mutex>
class base_sink:public sink
{
public:
base_sink():_mutex() {}
virtual ~base_sink() = default;
base_sink(const base_sink&) = delete;
base_sink& operator=(const base_sink&) = delete;
void log(const details::log_msg& msg) override
{
std::lock_guard<Mutex> lock(_mutex);
_sink_it(msg);
}
protected:
virtual void _sink_it(const details::log_msg& msg) = 0;
Mutex _mutex;
};
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
CXX ?= g++
CXXFLAGS = -Wall -pedantic -std=c++11 -pthread -O2 -I../include
LDPFALGS = -pthread
CPP_FILES := $(wildcard *.cpp)
OBJ_FILES := $(addprefix ./,$(notdir $(CPP_FILES:.cpp=.o)))
tests: $(OBJ_FILES)
$(CXX) $(CXXFLAGS) $(LDPFALGS) -o $@ $^
mkdir -p logs
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
clean:
rm -f tests *.o logs/*.txt
rebuild: clean tests
CXX ?= g++
CXXFLAGS = -Wall -pedantic -std=c++11 -pthread -O2 -I../include
LDPFALGS = -pthread
CPP_FILES := $(wildcard *.cpp)
OBJ_FILES := $(addprefix ./,$(notdir $(CPP_FILES:.cpp=.o)))
tests: $(OBJ_FILES)
$(CXX) $(CXXFLAGS) $(LDPFALGS) -o $@ $^
mkdir -p logs
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
clean:
rm -f tests *.o logs/*.txt
rebuild: clean tests
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment