no streams

This commit is contained in:
gabime 2016-07-08 17:50:13 +03:00
parent 34bb86b293
commit 7885aa478c
32 changed files with 10025 additions and 10411 deletions

96
.gitignore vendored
View File

@ -1,48 +1,48 @@
# Compiled Object files # Compiled Object files
*.slo *.slo
*.lo *.lo
*.o *.o
*.obj *.obj
# Compiled Dynamic libraries # Compiled Dynamic libraries
*.so *.so
*.dylib *.dylib
*.dll *.dll
# Compiled Static libraries # Compiled Static libraries
*.lai *.lai
*.la *.la
*.a *.a
*.lib *.lib
# Executables # Executables
*.exe *.exe
*.out *.out
*.app *.app
# Codelite # Codelite
.codelite .codelite
# .orig files # .orig files
*.orig *.orig
# example files # example files
example/* example/*
!example/example.cpp !example/example.cpp
!example/bench.cpp !example/bench.cpp
!example/utils.h !example/utils.h
!example/Makefile* !example/Makefile*
!example/example.sln !example/example.sln
!example/example.vcxproj !example/example.vcxproj
!example/CMakeLists.txt !example/CMakeLists.txt
# generated files # generated files
generated generated
# Cmake # Cmake
CMakeCache.txt CMakeCache.txt
CMakeFiles CMakeFiles
CMakeScripts CMakeScripts
Makefile Makefile
cmake_install.cmake cmake_install.cmake
install_manifest.txt install_manifest.txt

26
INSTALL
View File

@ -1,13 +1,13 @@
spdlog is header only library. spdlog is header only library.
Just copy the files to your build tree and use a C++11 compiler Just copy the files to your build tree and use a C++11 compiler
Tested on: Tested on:
gcc 4.8.1 and above gcc 4.8.1 and above
clang 3.5 clang 3.5
Visual Studio 2013 Visual Studio 2013
gcc 4.8 flags: --std==c++11 -pthread -O3 -flto -Wl,--no-as-needed gcc 4.8 flags: --std==c++11 -pthread -O3 -flto -Wl,--no-as-needed
gcc 4.9 flags: --std=c++11 -pthread -O3 -flto gcc 4.9 flags: --std=c++11 -pthread -O3 -flto
see the makefile in the example folder see the makefile in the example folder

44
LICENSE
View File

@ -1,22 +1,22 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2016 Gabi Melman. Copyright (c) 2016 Gabi Melman.
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.

View File

@ -1,57 +1,57 @@
CXX ?= g++ CXX ?= g++
CXXFLAGS = -D_WIN32_WINNT=0x600 -march=native -Wall -Wextra -pedantic -std=c++11 -pthread -Wl,--no-as-needed -I../include CXXFLAGS = -D_WIN32_WINNT=0x600 -march=native -Wall -Wextra -pedantic -std=c++11 -pthread -Wl,--no-as-needed -I../include
CXX_RELEASE_FLAGS = -O3 -flto CXX_RELEASE_FLAGS = -O3 -flto
binaries=spdlog-bench spdlog-bench-mt spdlog-async boost-bench boost-bench-mt glog-bench glog-bench-mt g2log-async easylogging-bench easylogging-bench-mt binaries=spdlog-bench spdlog-bench-mt spdlog-async boost-bench boost-bench-mt glog-bench glog-bench-mt g2log-async easylogging-bench easylogging-bench-mt
all: $(binaries) all: $(binaries)
spdlog-bench: spdlog-bench.cpp spdlog-bench: spdlog-bench.cpp
$(CXX) spdlog-bench.cpp -o spdlog-bench $(CXXFLAGS) $(CXX_RELEASE_FLAGS) $(CXX) spdlog-bench.cpp -o spdlog-bench $(CXXFLAGS) $(CXX_RELEASE_FLAGS)
spdlog-bench-mt: spdlog-bench-mt.cpp spdlog-bench-mt: spdlog-bench-mt.cpp
$(CXX) spdlog-bench-mt.cpp -o spdlog-bench-mt $(CXXFLAGS) $(CXX_RELEASE_FLAGS) $(CXX) spdlog-bench-mt.cpp -o spdlog-bench-mt $(CXXFLAGS) $(CXX_RELEASE_FLAGS)
spdlog-async: spdlog-async.cpp spdlog-async: spdlog-async.cpp
$(CXX) spdlog-async.cpp -o spdlog-async $(CXXFLAGS) $(CXX_RELEASE_FLAGS) $(CXX) spdlog-async.cpp -o spdlog-async $(CXXFLAGS) $(CXX_RELEASE_FLAGS)
BOOST_FLAGS = -DBOOST_LOG_DYN_LINK -I/home/gabi/devel/boost_1_56_0/ -L/home/gabi/devel/boost_1_56_0/stage/lib -lboost_log -lboost_log_setup -lboost_filesystem -lboost_system -lboost_thread -lboost_regex -lboost_date_time -lboost_chrono BOOST_FLAGS = -DBOOST_LOG_DYN_LINK -I/home/gabi/devel/boost_1_56_0/ -L/home/gabi/devel/boost_1_56_0/stage/lib -lboost_log -lboost_log_setup -lboost_filesystem -lboost_system -lboost_thread -lboost_regex -lboost_date_time -lboost_chrono
boost-bench: boost-bench.cpp boost-bench: boost-bench.cpp
$(CXX) boost-bench.cpp -o boost-bench $(CXXFLAGS) $(BOOST_FLAGS) $(CXX_RELEASE_FLAGS) $(CXX) boost-bench.cpp -o boost-bench $(CXXFLAGS) $(BOOST_FLAGS) $(CXX_RELEASE_FLAGS)
boost-bench-mt: boost-bench-mt.cpp boost-bench-mt: boost-bench-mt.cpp
$(CXX) boost-bench-mt.cpp -o boost-bench-mt $(CXXFLAGS) $(BOOST_FLAGS) $(CXX_RELEASE_FLAGS) $(CXX) boost-bench-mt.cpp -o boost-bench-mt $(CXXFLAGS) $(BOOST_FLAGS) $(CXX_RELEASE_FLAGS)
GLOG_FLAGS = -lglog GLOG_FLAGS = -lglog
glog-bench: glog-bench.cpp glog-bench: glog-bench.cpp
$(CXX) glog-bench.cpp -o glog-bench $(CXXFLAGS) $(GLOG_FLAGS) $(CXX_RELEASE_FLAGS) $(CXX) glog-bench.cpp -o glog-bench $(CXXFLAGS) $(GLOG_FLAGS) $(CXX_RELEASE_FLAGS)
glog-bench-mt: glog-bench-mt.cpp glog-bench-mt: glog-bench-mt.cpp
$(CXX) glog-bench-mt.cpp -o glog-bench-mt $(CXXFLAGS) $(GLOG_FLAGS) $(CXX_RELEASE_FLAGS) $(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_FLAGS = -I/home/gabi/devel/g2log/g2log/src -L/home/gabi/devel/g2log/g2log -llib_g2logger
g2log-async: g2log-async.cpp g2log-async: g2log-async.cpp
$(CXX) g2log-async.cpp -o g2log-async $(CXXFLAGS) $(G2LOG_FLAGS) $(CXX_RELEASE_FLAGS) $(CXX) g2log-async.cpp -o g2log-async $(CXXFLAGS) $(G2LOG_FLAGS) $(CXX_RELEASE_FLAGS)
EASYL_FLAGS = -I../../easylogging/src/ EASYL_FLAGS = -I../../easylogging/src/
easylogging-bench: easylogging-bench.cpp easylogging-bench: easylogging-bench.cpp
$(CXX) easylogging-bench.cpp -o easylogging-bench $(CXXFLAGS) $(EASYL_FLAGS) $(CXX_RELEASE_FLAGS) $(CXX) easylogging-bench.cpp -o easylogging-bench $(CXXFLAGS) $(EASYL_FLAGS) $(CXX_RELEASE_FLAGS)
easylogging-bench-mt: easylogging-bench-mt.cpp easylogging-bench-mt: easylogging-bench-mt.cpp
$(CXX) easylogging-bench-mt.cpp -o easylogging-bench-mt $(CXXFLAGS) $(EASYL_FLAGS) $(CXX_RELEASE_FLAGS) $(CXX) easylogging-bench-mt.cpp -o easylogging-bench-mt $(CXXFLAGS) $(EASYL_FLAGS) $(CXX_RELEASE_FLAGS)
.PHONY: clean .PHONY: clean
clean: clean:
rm -f *.o logs/* $(binaries) rm -f *.o logs/* $(binaries)
rebuild: clean all rebuild: clean all

View File

@ -1,10 +1,10 @@
* GLOBAL: * GLOBAL:
FORMAT = "[%datetime]: %msg" FORMAT = "[%datetime]: %msg"
FILENAME = ./logs/easylogging.log FILENAME = ./logs/easylogging.log
ENABLED = true ENABLED = true
TO_FILE = true TO_FILE = true
TO_STANDARD_OUTPUT = false TO_STANDARD_OUTPUT = false
MILLISECONDS_WIDTH = 3 MILLISECONDS_WIDTH = 3
PERFORMANCE_TRACKING = false PERFORMANCE_TRACKING = false
MAX_LOG_FILE_SIZE = 10485760 MAX_LOG_FILE_SIZE = 10485760
Log_Flush_Threshold = 10485760 Log_Flush_Threshold = 10485760

View File

@ -1,4 +1,4 @@
# Ignore everything in this directory # Ignore everything in this directory
* *
# Except this file # Except this file
!.gitignore !.gitignore

View File

@ -1,76 +0,0 @@
#~/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;

View File

@ -1,24 +1,24 @@
# *************************************************************************/ # *************************************************************************/
# * Copyright (c) 2015 Ruslan Baratov. */ # * Copyright (c) 2015 Ruslan Baratov. */
# * */ # * */
# * Permission is hereby granted, free of charge, to any person obtaining */ # * Permission is hereby granted, free of charge, to any person obtaining */
# * a copy of this software and associated documentation files (the */ # * a copy of this software and associated documentation files (the */
# * "Software"), to deal in the Software without restriction, including */ # * "Software"), to deal in the Software without restriction, including */
# * without limitation the rights to use, copy, modify, merge, publish, */ # * without limitation the rights to use, copy, modify, merge, publish, */
# * distribute, sublicense, and/or sell copies of the Software, and to */ # * distribute, sublicense, and/or sell copies of the Software, and to */
# * permit persons to whom the Software is furnished to do so, subject to */ # * permit persons to whom the Software is furnished to do so, subject to */
# * the following conditions: */ # * the following conditions: */
# * */ # * */
# * The above copyright notice and this permission notice shall be */ # * The above copyright notice and this permission notice shall be */
# * included in all copies or substantial portions of the Software. */ # * included in all copies or substantial portions of the Software. */
# * */ # * */
# * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ # * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
# * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ # * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
# * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ # * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
# * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ # * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
# * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ # * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
# * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ # * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
# * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ # * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
# *************************************************************************/ # *************************************************************************/
include("${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake") include("${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake")

View File

@ -1,6 +1,6 @@
prefix=@CMAKE_INSTALL_PREFIX@ prefix=@CMAKE_INSTALL_PREFIX@
includedir=${prefix}/include includedir=${prefix}/include
Name: @PROJECT_NAME@ Name: @PROJECT_NAME@
Description: Super fast C++ logging library. Description: Super fast C++ logging library.
Version: @PROJECT_VERSION@ Version: @PROJECT_VERSION@

View File

@ -1,46 +1,46 @@
# *************************************************************************/ # *************************************************************************/
# * Copyright (c) 2015 Ruslan Baratov. */ # * Copyright (c) 2015 Ruslan Baratov. */
# * */ # * */
# * Permission is hereby granted, free of charge, to any person obtaining */ # * Permission is hereby granted, free of charge, to any person obtaining */
# * a copy of this software and associated documentation files (the */ # * a copy of this software and associated documentation files (the */
# * "Software"), to deal in the Software without restriction, including */ # * "Software"), to deal in the Software without restriction, including */
# * without limitation the rights to use, copy, modify, merge, publish, */ # * without limitation the rights to use, copy, modify, merge, publish, */
# * distribute, sublicense, and/or sell copies of the Software, and to */ # * distribute, sublicense, and/or sell copies of the Software, and to */
# * permit persons to whom the Software is furnished to do so, subject to */ # * permit persons to whom the Software is furnished to do so, subject to */
# * the following conditions: */ # * the following conditions: */
# * */ # * */
# * The above copyright notice and this permission notice shall be */ # * The above copyright notice and this permission notice shall be */
# * included in all copies or substantial portions of the Software. */ # * included in all copies or substantial portions of the Software. */
# * */ # * */
# * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ # * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
# * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ # * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
# * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ # * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
# * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ # * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
# * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ # * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
# * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ # * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
# * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ # * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
# *************************************************************************/ # *************************************************************************/
cmake_minimum_required(VERSION 3.0) cmake_minimum_required(VERSION 3.0)
project(SpdlogExamples) project(SpdlogExamples)
if(TARGET spdlog) if(TARGET spdlog)
# Part of the main project # Part of the main project
add_library(spdlog::spdlog ALIAS spdlog) add_library(spdlog::spdlog ALIAS spdlog)
else() else()
# Stand-alone build # Stand-alone build
find_package(spdlog CONFIG REQUIRED) find_package(spdlog CONFIG REQUIRED)
endif() endif()
find_package(Threads) find_package(Threads)
add_executable(example example.cpp) add_executable(example example.cpp)
target_link_libraries(example spdlog::spdlog ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries(example spdlog::spdlog ${CMAKE_THREAD_LIBS_INIT})
add_executable(benchmark bench.cpp) add_executable(benchmark bench.cpp)
target_link_libraries(benchmark spdlog::spdlog ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries(benchmark spdlog::spdlog ${CMAKE_THREAD_LIBS_INIT})
enable_testing() enable_testing()
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/logs") file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/logs")
add_test(NAME RunExample COMMAND example) add_test(NAME RunExample COMMAND example)
add_test(NAME RunBenchmark COMMAND benchmark) add_test(NAME RunBenchmark COMMAND benchmark)

View File

@ -1,29 +1,29 @@
CXX ?= g++ CXX ?= g++
CXXFLAGS = CXXFLAGS =
CXX_FLAGS = -Wall -Wshadow -Wextra -pedantic -std=c++11 -pthread -I../include CXX_FLAGS = -Wall -Wshadow -Wextra -pedantic -std=c++11 -pthread -I../include
CXX_RELEASE_FLAGS = -O3 -march=native CXX_RELEASE_FLAGS = -O3 -march=native
CXX_DEBUG_FLAGS= -g CXX_DEBUG_FLAGS= -g
all: example bench all: example bench
debug: example-debug bench-debug debug: example-debug bench-debug
example: example.cpp example: example.cpp
$(CXX) example.cpp -o example $(CXX_FLAGS) $(CXX_RELEASE_FLAGS) $(CXXFLAGS) $(CXX) example.cpp -o example $(CXX_FLAGS) $(CXX_RELEASE_FLAGS) $(CXXFLAGS)
bench: bench.cpp bench: bench.cpp
$(CXX) bench.cpp -o bench $(CXX_FLAGS) $(CXX_RELEASE_FLAGS) $(CXXFLAGS) $(CXX) bench.cpp -o bench $(CXX_FLAGS) $(CXX_RELEASE_FLAGS) $(CXXFLAGS)
example-debug: example.cpp example-debug: example.cpp
$(CXX) example.cpp -o example-debug $(CXX_FLAGS) $(CXX_DEBUG_FLAGS) $(CXXFLAGS) $(CXX) example.cpp -o example-debug $(CXX_FLAGS) $(CXX_DEBUG_FLAGS) $(CXXFLAGS)
bench-debug: bench.cpp bench-debug: bench.cpp
$(CXX) bench.cpp -o bench-debug $(CXX_FLAGS) $(CXX_DEBUG_FLAGS) $(CXXFLAGS) $(CXX) bench.cpp -o bench-debug $(CXX_FLAGS) $(CXX_DEBUG_FLAGS) $(CXXFLAGS)
clean: clean:
rm -f *.o logs/*.txt example example-debug bench bench-debug rm -f *.o logs/*.txt example example-debug bench bench-debug
rebuild: clean all rebuild: clean all
rebuild-debug: clean debug rebuild-debug: clean debug

View File

@ -1,32 +1,32 @@
CXX ?= clang++ CXX ?= clang++
CXXFLAGS = -march=native -Wall -Wextra -Wshadow -pedantic -std=c++11 -pthread -I../include CXXFLAGS = -march=native -Wall -Wextra -Wshadow -pedantic -std=c++11 -pthread -I../include
CXX_RELEASE_FLAGS = -O2 CXX_RELEASE_FLAGS = -O2
CXX_DEBUG_FLAGS= -g CXX_DEBUG_FLAGS= -g
all: example bench all: example bench
debug: example-debug bench-debug debug: example-debug bench-debug
example: example.cpp example: example.cpp
$(CXX) example.cpp -o example-clang $(CXXFLAGS) $(CXX_RELEASE_FLAGS) $(CXX) example.cpp -o example-clang $(CXXFLAGS) $(CXX_RELEASE_FLAGS)
bench: bench.cpp bench: bench.cpp
$(CXX) bench.cpp -o bench-clang $(CXXFLAGS) $(CXX_RELEASE_FLAGS) $(CXX) bench.cpp -o bench-clang $(CXXFLAGS) $(CXX_RELEASE_FLAGS)
example-debug: example.cpp example-debug: example.cpp
$(CXX) example.cpp -o example-clang-debug $(CXXFLAGS) $(CXX_DEBUG_FLAGS) $(CXX) example.cpp -o example-clang-debug $(CXXFLAGS) $(CXX_DEBUG_FLAGS)
bench-debug: bench.cpp bench-debug: bench.cpp
$(CXX) bench.cpp -o bench-clang-debug $(CXXFLAGS) $(CXX_DEBUG_FLAGS) $(CXX) bench.cpp -o bench-clang-debug $(CXXFLAGS) $(CXX_DEBUG_FLAGS)
clean: clean:
rm -f *.o logs/*.txt example-clang example-clang-debug bench-clang bench-clang-debug rm -f *.o logs/*.txt example-clang example-clang-debug bench-clang bench-clang-debug
rebuild: clean all rebuild: clean all
rebuild-debug: clean debug rebuild-debug: clean debug

View File

@ -1,32 +1,32 @@
CXX ?= g++ 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=c++11 -pthread -Wl,--no-as-needed -I../include
CXX_RELEASE_FLAGS = -O3 CXX_RELEASE_FLAGS = -O3
CXX_DEBUG_FLAGS= -g CXX_DEBUG_FLAGS= -g
all: example bench all: example bench
debug: example-debug bench-debug debug: example-debug bench-debug
example: example.cpp example: example.cpp
$(CXX) example.cpp -o example $(CXXFLAGS) $(CXX_RELEASE_FLAGS) $(CXX) example.cpp -o example $(CXXFLAGS) $(CXX_RELEASE_FLAGS)
bench: bench.cpp bench: bench.cpp
$(CXX) bench.cpp -o bench $(CXXFLAGS) $(CXX_RELEASE_FLAGS) $(CXX) bench.cpp -o bench $(CXXFLAGS) $(CXX_RELEASE_FLAGS)
example-debug: example.cpp example-debug: example.cpp
$(CXX) example.cpp -o example-debug $(CXXFLAGS) $(CXX_DEBUG_FLAGS) $(CXX) example.cpp -o example-debug $(CXXFLAGS) $(CXX_DEBUG_FLAGS)
bench-debug: bench.cpp bench-debug: bench.cpp
$(CXX) bench.cpp -o bench-debug $(CXXFLAGS) $(CXX_DEBUG_FLAGS) $(CXX) bench.cpp -o bench-debug $(CXXFLAGS) $(CXX_DEBUG_FLAGS)
clean: clean:
rm -f *.o logs/*.txt example example-debug bench bench-debug rm -f *.o logs/*.txt example example-debug bench bench-debug
rebuild: clean all rebuild: clean all
rebuild-debug: clean debug rebuild-debug: clean debug

View File

@ -106,4 +106,3 @@ void syslog_example()
#endif #endif
} }

View File

@ -1,22 +1,22 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013 # Visual Studio 2013
VisualStudioVersion = 12.0.40629.0 VisualStudioVersion = 12.0.40629.0
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example", "example.vcxproj", "{9E5AB93A-0CCE-4BAC-9FCB-0FC9CB5EB8D2}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example", "example.vcxproj", "{9E5AB93A-0CCE-4BAC-9FCB-0FC9CB5EB8D2}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32 Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32 Release|Win32 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9E5AB93A-0CCE-4BAC-9FCB-0FC9CB5EB8D2}.Debug|Win32.ActiveCfg = Debug|Win32 {9E5AB93A-0CCE-4BAC-9FCB-0FC9CB5EB8D2}.Debug|Win32.ActiveCfg = Debug|Win32
{9E5AB93A-0CCE-4BAC-9FCB-0FC9CB5EB8D2}.Debug|Win32.Build.0 = Debug|Win32 {9E5AB93A-0CCE-4BAC-9FCB-0FC9CB5EB8D2}.Debug|Win32.Build.0 = Debug|Win32
{9E5AB93A-0CCE-4BAC-9FCB-0FC9CB5EB8D2}.Release|Win32.ActiveCfg = Release|Win32 {9E5AB93A-0CCE-4BAC-9FCB-0FC9CB5EB8D2}.Release|Win32.ActiveCfg = Release|Win32
{9E5AB93A-0CCE-4BAC-9FCB-0FC9CB5EB8D2}.Release|Win32.Build.0 = Release|Win32 {9E5AB93A-0CCE-4BAC-9FCB-0FC9CB5EB8D2}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

View File

@ -11,8 +11,43 @@
</ProjectConfiguration> </ProjectConfiguration>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\include\spdlog\details\format.cc">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="example.cpp" /> <ClCompile Include="example.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ClInclude Include="..\include\spdlog\async_logger.h" />
<ClInclude Include="..\include\spdlog\common.h" />
<ClInclude Include="..\include\spdlog\details\async_logger_impl.h" />
<ClInclude Include="..\include\spdlog\details\async_log_helper.h" />
<ClInclude Include="..\include\spdlog\details\file_helper.h" />
<ClInclude Include="..\include\spdlog\details\format.h" />
<ClInclude Include="..\include\spdlog\details\logger_impl.h" />
<ClInclude Include="..\include\spdlog\details\log_msg.h" />
<ClInclude Include="..\include\spdlog\details\mpmc_bounded_q.h" />
<ClInclude Include="..\include\spdlog\details\null_mutex.h" />
<ClInclude Include="..\include\spdlog\details\os.h" />
<ClInclude Include="..\include\spdlog\details\pattern_formatter_impl.h" />
<ClInclude Include="..\include\spdlog\details\registry.h" />
<ClInclude Include="..\include\spdlog\details\spdlog_impl.h" />
<ClInclude Include="..\include\spdlog\formatter.h" />
<ClInclude Include="..\include\spdlog\logger.h" />
<ClInclude Include="..\include\spdlog\sinks\android_sink.h" />
<ClInclude Include="..\include\spdlog\sinks\ansicolor_sink.h" />
<ClInclude Include="..\include\spdlog\sinks\base_sink.h" />
<ClInclude Include="..\include\spdlog\sinks\dist_sink.h" />
<ClInclude Include="..\include\spdlog\sinks\file_sinks.h" />
<ClInclude Include="..\include\spdlog\sinks\msvc_sink.h" />
<ClInclude Include="..\include\spdlog\sinks\null_sink.h" />
<ClInclude Include="..\include\spdlog\sinks\ostream_sink.h" />
<ClInclude Include="..\include\spdlog\sinks\sink.h" />
<ClInclude Include="..\include\spdlog\sinks\stdout_sinks.h" />
<ClInclude Include="..\include\spdlog\sinks\syslog_sink.h" />
<ClInclude Include="..\include\spdlog\spdlog.h" />
<ClInclude Include="..\include\spdlog\tweakme.h" />
</ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{9E5AB93A-0CCE-4BAC-9FCB-0FC9CB5EB8D2}</ProjectGuid> <ProjectGuid>{9E5AB93A-0CCE-4BAC-9FCB-0FC9CB5EB8D2}</ProjectGuid>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>

View File

@ -1,2 +0,0 @@
*.txt

View File

@ -63,7 +63,7 @@ public:
void flush() override; void flush() override;
protected: protected:
void _log_msg(details::log_msg& msg) override; void _sink_it(details::log_msg& msg) override;
void _set_formatter(spdlog::formatter_ptr msg_formatter) override; void _set_formatter(spdlog::formatter_ptr msg_formatter) override;
void _set_pattern(const std::string& pattern) override; void _set_pattern(const std::string& pattern) override;

View File

@ -86,21 +86,22 @@ async_msg(async_msg&& other) SPDLOG_NOEXCEPT:
// construct from log_msg // construct from log_msg
async_msg(const details::log_msg& m) : async_msg(const details::log_msg& m) :
logger_name(m.logger_name),
level(m.level), level(m.level),
time(m.time), time(m.time),
thread_id(m.thread_id), thread_id(m.thread_id),
txt(m.raw.data(), m.raw.size()), txt(m.raw.data(), m.raw.size()),
msg_type(async_msg_type::log) msg_type(async_msg_type::log)
{} {
#ifndef SPDLOG_NO_NAME
logger_name = *m.logger_name;
#endif
}
// copy into log_msg // copy into log_msg
void fill_log_msg(log_msg &msg) void fill_log_msg(log_msg &msg)
{ {
msg.clear(); msg.logger_name = &logger_name;
msg.logger_name = logger_name;
msg.level = level; msg.level = level;
msg.time = time; msg.time = time;
msg.thread_id = thread_id; msg.thread_id = thread_id;
@ -278,7 +279,7 @@ inline bool spdlog::details::async_log_helper::process_next_msg(log_clock::time_
{ {
async_msg incoming_async_msg; async_msg incoming_async_msg;
log_msg incoming_log_msg;
if (_q.dequeue(incoming_async_msg)) if (_q.dequeue(incoming_async_msg))
{ {
@ -295,6 +296,7 @@ inline bool spdlog::details::async_log_helper::process_next_msg(log_clock::time_
break; break;
default: default:
log_msg incoming_log_msg;
incoming_async_msg.fill_log_msg(incoming_log_msg); incoming_async_msg.fill_log_msg(incoming_log_msg);
_formatter->format(incoming_log_msg); _formatter->format(incoming_log_msg);
for (auto &s : _sinks) for (auto &s : _sinks)

View File

@ -71,7 +71,7 @@ inline void spdlog::async_logger::_set_pattern(const std::string& pattern)
} }
inline void spdlog::async_logger::_log_msg(details::log_msg& msg) inline void spdlog::async_logger::_sink_it(details::log_msg& msg)
{ {
_async_log_helper->log(msg); _async_log_helper->log(msg);
} }

View File

@ -1,78 +0,0 @@
//
// 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<<
//
DEPRECATED line_logger& operator<<(const char* what);
DEPRECATED line_logger& operator<<(const std::string& what);
DEPRECATED line_logger& operator<<(int what);
DEPRECATED line_logger& operator<<(unsigned int what);
DEPRECATED line_logger& operator<<(long what);
DEPRECATED line_logger& operator<<(unsigned long what);
DEPRECATED line_logger& operator<<(long long what);
DEPRECATED line_logger& operator<<(unsigned long long what);
DEPRECATED line_logger& operator<<(double what);
DEPRECATED line_logger& operator<<(long double what);
DEPRECATED line_logger& operator<<(float what);
DEPRECATED line_logger& operator<<(char what);
//Support user types which implements operator<<
template<typename T>
DEPRECATED 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

View File

@ -1,185 +0,0 @@
//
// 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;
}

View File

@ -7,6 +7,7 @@
#include <spdlog/common.h> #include <spdlog/common.h>
#include <spdlog/details/format.h> #include <spdlog/details/format.h>
#include <spdlog/details/os.h>
#include <string> #include <string>
#include <utility> #include <utility>
@ -18,59 +19,23 @@ namespace details
struct log_msg struct log_msg
{ {
log_msg() = default; log_msg() = default;
log_msg(level::level_enum l): log_msg(std::string *loggers_name, level::level_enum lvl) : logger_name(loggers_name), level(lvl)
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()) #ifndef SPDLOG_NO_DATETIME
raw << fmt::BasicStringRef<char>(other.raw.data(), other.raw.size()); time = os::now();
if (other.formatted.size()) #endif
formatted << fmt::BasicStringRef<char>(other.formatted.data(), other.formatted.size());
#ifndef SPDLOG_NO_THREAD_ID
thread_id = os::thread_id();
#endif
} }
log_msg(log_msg&& other) : log_msg(const log_msg& other) = delete;
logger_name(std::move(other.logger_name)), log_msg& operator=(log_msg&& other) = delete;
level(other.level), log_msg(log_msg&& other) = delete;
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); std::string *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; level::level_enum level;
log_clock::time_point time; log_clock::time_point time;
size_t thread_id; size_t thread_id;

View File

@ -50,210 +50,169 @@ inline void spdlog::logger::set_pattern(const std::string& pattern)
_set_pattern(pattern); _set_pattern(pattern);
} }
//
// log only if given level>=logger's log level
//
template <typename... Args> template <typename... Args>
inline spdlog::details::line_logger spdlog::logger::_log_if_enabled(level::level_enum lvl, const char* fmt, const Args&... args) inline void spdlog::logger::log(level::level_enum lvl, const char* fmt, const Args&... args)
{ {
bool msg_enabled = should_log(lvl); if (!should_log(lvl))
details::line_logger l(this, lvl, msg_enabled); return;
l.write(fmt, args...);
return l; details::log_msg log_msg(&_name, lvl);
try
{
log_msg.raw.write(fmt, args...);
}
catch (fmt::FormatError &ex)
{
throw spdlog::spdlog_ex(std::string("format error in \"") + fmt + "\": " + ex.what());
}
_formatter->format(log_msg);
_sink_it(log_msg);
} }
inline spdlog::details::line_logger spdlog::logger::_log_if_enabled(level::level_enum lvl) template <typename... Args>
inline void spdlog::logger::log(level::level_enum lvl, const char* msg)
{ {
return details::line_logger(this, lvl, should_log(lvl));
if (!should_log(lvl))
return;
details::log_msg log_msg(&_name, lvl);
log_msg.raw << msg;
_formatter->format(log_msg);
_sink_it(log_msg);
} }
template<typename T> template<typename T>
inline spdlog::details::line_logger spdlog::logger::_log_if_enabled(level::level_enum lvl, const T& msg) inline void spdlog::logger::log(level::level_enum lvl, const T& msg)
{ {
bool msg_enabled = should_log(lvl); if (!should_log(lvl))
details::line_logger l(this, lvl, msg_enabled); return;
l.write("{}", msg); details::log_msg log_msg(&_name, lvl);
return l;
log_msg.raw << msg;
_formatter->format(log_msg);
_sink_it(log_msg);
} }
//
// logger.info(cppformat_string, arg1, arg2, arg3, ...) call style
//
template <typename... Args> template <typename... Args>
inline spdlog::details::line_logger spdlog::logger::trace(const char* fmt, const Args&... args) inline void spdlog::logger::trace(const char* fmt, const Args&... args)
{ {
return _log_if_enabled(level::trace, fmt, args...); log(level::trace, fmt, args...);
} }
template <typename... Args> template <typename... Args>
inline spdlog::details::line_logger spdlog::logger::debug(const char* fmt, const Args&... args) inline void spdlog::logger::debug(const char* fmt, const Args&... args)
{ {
return _log_if_enabled(level::debug, fmt, args...); log(level::debug, fmt, args...);
} }
template <typename... Args> template <typename... Args>
inline spdlog::details::line_logger spdlog::logger::info(const char* fmt, const Args&... args) inline void spdlog::logger::info(const char* fmt, const Args&... args)
{ {
return _log_if_enabled(level::info, fmt, args...); log(level::info, fmt, args...);
} }
template <typename... Args> template <typename... Args>
inline spdlog::details::line_logger spdlog::logger::notice(const char* fmt, const Args&... args) inline void spdlog::logger::notice(const char* fmt, const Args&... args)
{ {
return _log_if_enabled(level::notice, fmt, args...); log(level::notice, fmt, args...);
} }
template <typename... Args> template <typename... Args>
inline spdlog::details::line_logger spdlog::logger::warn(const char* fmt, const Args&... args) inline void spdlog::logger::warn(const char* fmt, const Args&... args)
{ {
return _log_if_enabled(level::warn, fmt, args...); log(level::warn, fmt, args...);
} }
template <typename... Args> template <typename... Args>
inline spdlog::details::line_logger spdlog::logger::error(const char* fmt, const Args&... args) inline void spdlog::logger::error(const char* fmt, const Args&... args)
{ {
return _log_if_enabled(level::err, fmt, args...); log(level::err, fmt, args...);
} }
template <typename... Args> template <typename... Args>
inline spdlog::details::line_logger spdlog::logger::critical(const char* fmt, const Args&... args) inline void spdlog::logger::critical(const char* fmt, const Args&... args)
{ {
return _log_if_enabled(level::critical, fmt, args...); log(level::critical, fmt, args...);
} }
template <typename... Args> template <typename... Args>
inline spdlog::details::line_logger spdlog::logger::alert(const char* fmt, const Args&... args) inline void spdlog::logger::alert(const char* fmt, const Args&... args)
{ {
return _log_if_enabled(level::alert, fmt, args...); log(level::alert, fmt, args...);
} }
template <typename... Args> template <typename... Args>
inline spdlog::details::line_logger spdlog::logger::emerg(const char* fmt, const Args&... args) inline void spdlog::logger::emerg(const char* fmt, const Args&... args)
{ {
return _log_if_enabled(level::emerg, fmt, args...); log(level::emerg, fmt, args...);
} }
//
// logger.info(msg) << ".." call style
//
template<typename T> template<typename T>
inline spdlog::details::line_logger spdlog::logger::trace(const T& msg) inline void spdlog::logger::trace(const T& msg)
{ {
return _log_if_enabled(level::trace, msg); log(level::trace, msg);
} }
template<typename T> template<typename T>
inline spdlog::details::line_logger spdlog::logger::debug(const T& msg) inline void spdlog::logger::debug(const T& msg)
{ {
return _log_if_enabled(level::debug, msg); log(level::debug, msg);
} }
template<typename T> template<typename T>
inline spdlog::details::line_logger spdlog::logger::info(const T& msg) inline void spdlog::logger::info(const T& msg)
{ {
return _log_if_enabled(level::info, msg); log(level::info, msg);
} }
template<typename T> template<typename T>
inline spdlog::details::line_logger spdlog::logger::notice(const T& msg) inline void spdlog::logger::notice(const T& msg)
{ {
return _log_if_enabled(level::notice, msg); log(level::notice, msg);
} }
template<typename T> template<typename T>
inline spdlog::details::line_logger spdlog::logger::warn(const T& msg) inline void spdlog::logger::warn(const T& msg)
{ {
return _log_if_enabled(level::warn, msg); log(level::warn, msg);
} }
template<typename T> template<typename T>
inline spdlog::details::line_logger spdlog::logger::error(const T& msg) inline void spdlog::logger::error(const T& msg)
{ {
return _log_if_enabled(level::err, msg); log(level::err, msg);
} }
template<typename T> template<typename T>
inline spdlog::details::line_logger spdlog::logger::critical(const T& msg) inline void spdlog::logger::critical(const T& msg)
{ {
return _log_if_enabled(level::critical, msg); log(level::critical, msg);
} }
template<typename T> template<typename T>
inline spdlog::details::line_logger spdlog::logger::alert(const T& msg) inline void spdlog::logger::alert(const T& msg)
{ {
return _log_if_enabled(level::alert, msg); log(level::alert, msg);
} }
template<typename T> template<typename T>
inline spdlog::details::line_logger spdlog::logger::emerg(const T& msg) inline void spdlog::logger::emerg(const T& msg)
{ {
return _log_if_enabled(level::emerg, msg); log(level::emerg, msg);
} }
//
// logger.info() << ".." call style
//
inline spdlog::details::line_logger spdlog::logger::trace()
{
return _log_if_enabled(level::trace);
}
inline spdlog::details::line_logger spdlog::logger::debug()
{
return _log_if_enabled(level::debug);
}
inline spdlog::details::line_logger spdlog::logger::info()
{
return _log_if_enabled(level::info);
}
inline spdlog::details::line_logger spdlog::logger::notice()
{
return _log_if_enabled(level::notice);
}
inline spdlog::details::line_logger spdlog::logger::warn()
{
return _log_if_enabled(level::warn);
}
inline spdlog::details::line_logger spdlog::logger::error()
{
return _log_if_enabled(level::err);
}
inline spdlog::details::line_logger spdlog::logger::critical()
{
return _log_if_enabled(level::critical);
}
inline spdlog::details::line_logger spdlog::logger::alert()
{
return _log_if_enabled(level::alert);
}
inline spdlog::details::line_logger spdlog::logger::emerg()
{
return _log_if_enabled(level::emerg);
}
// always log, no matter what is the actual logger's log level
template <typename... Args>
inline spdlog::details::line_logger spdlog::logger::force_log(level::level_enum lvl, const char* fmt, const Args&... args)
{
details::line_logger l(this, lvl, true);
l.write(fmt, args...);
return l;
}
// //
// name and level // name and level
// //
@ -285,9 +244,8 @@ inline bool spdlog::logger::should_log(spdlog::level::level_enum msg_level) cons
// //
// protected virtual called at end of each user log call (if enabled) by the line_logger // protected virtual called at end of each user log call (if enabled) by the line_logger
// //
inline void spdlog::logger::_log_msg(details::log_msg& msg) inline void spdlog::logger::_sink_it(details::log_msg& msg)
{ {
_formatter->format(msg);
for (auto &sink : _sinks) for (auto &sink : _sinks)
sink->log(msg); sink->log(msg);

View File

@ -39,7 +39,7 @@ class name_formatter :public flag_formatter
{ {
void format(details::log_msg& msg, const std::tm&) override void format(details::log_msg& msg, const std::tm&) override
{ {
msg.formatted << msg.logger_name; msg.formatted << *msg.logger_name;
} }
}; };
} }
@ -435,7 +435,7 @@ class full_formatter :public flag_formatter
#endif #endif
#ifndef SPDLOG_NO_NAME #ifndef SPDLOG_NO_NAME
msg.formatted << '[' << msg.logger_name << "] "; msg.formatted << '[' << *msg.logger_name << "] ";
#endif #endif
msg.formatted << '[' << level::to_str(msg.level) << "] "; msg.formatted << '[' << level::to_str(msg.level) << "] ";
@ -613,7 +613,11 @@ inline void spdlog::pattern_formatter::format(details::log_msg& msg)
{ {
try try
{ {
#ifndef SPDLOG_NO_DATETIME
auto tm_time = details::os::localtime(log_clock::to_time_t(msg.time)); auto tm_time = details::os::localtime(log_clock::to_time_t(msg.time));
#else
std::tm tm_time;
#endif
for (auto &f : _formatters) for (auto &f : _formatters)
{ {
f->format(msg, tm_time); f->format(msg, tm_time);

View File

@ -14,12 +14,12 @@
#include <spdlog/sinks/base_sink.h> #include <spdlog/sinks/base_sink.h>
#include <spdlog/common.h> #include <spdlog/common.h>
#include <spdlog/details/line_logger_fwd.h>
#include <vector> #include <vector>
#include <memory> #include <memory>
#include <string> #include <string>
namespace spdlog namespace spdlog
{ {
@ -35,74 +35,47 @@ public:
logger(const logger&) = delete; logger(const logger&) = delete;
logger& operator=(const logger&) = delete; logger& operator=(const logger&) = delete;
template <typename... Args> void log(level::level_enum lvl, const char* fmt, const Args&... args);
template <typename... Args> void log(level::level_enum lvl, const char* msg);
template <typename T> void log(level::level_enum lvl, const T&);
template <typename... Args> void trace(const char* fmt, const Args&... args);
template <typename... Args> void debug(const char* fmt, const Args&... args);
template <typename... Args> void info(const char* fmt, const Args&... args);
template <typename... Args> void notice(const char* fmt, const Args&... args);
template <typename... Args> void warn(const char* fmt, const Args&... args);
template <typename... Args> void error(const char* fmt, const Args&... args);
template <typename... Args> void critical(const char* fmt, const Args&... args);
template <typename... Args> void alert(const char* fmt, const Args&... args);
template <typename... Args> void emerg(const char* fmt, const Args&... args);
template <typename T> void trace(const T&);
template <typename T> void debug(const T&);
template <typename T> void info(const T&);
template <typename T> void notice(const T&);
template <typename T> void warn(const T&);
template <typename T> void error(const T&);
template <typename T> void critical(const T&);
template <typename T> void alert(const T&);
template <typename T> void emerg(const T&);
bool should_log(level::level_enum) const;
void set_level(level::level_enum); void set_level(level::level_enum);
level::level_enum level() const; level::level_enum level() const;
const std::string& name() const; const std::string& name() const;
bool should_log(level::level_enum) const;
// automatically call flush() after a message of level log_level or higher is emitted
void flush_on(level::level_enum log_level);
// logger.info(cppformat_string, arg1, arg2, arg3, ...) call style
template <typename... Args> details::line_logger trace(const char* fmt, const Args&... args);
template <typename... Args> details::line_logger debug(const char* fmt, const Args&... args);
template <typename... Args> details::line_logger info(const char* fmt, const Args&... args);
template <typename... Args> details::line_logger notice(const char* fmt, const Args&... args);
template <typename... Args> details::line_logger warn(const char* fmt, const Args&... args);
template <typename... Args> details::line_logger error(const char* fmt, const Args&... args);
template <typename... Args> details::line_logger critical(const char* fmt, const Args&... args);
template <typename... Args> details::line_logger alert(const char* fmt, const Args&... args);
template <typename... Args> details::line_logger emerg(const char* fmt, const Args&... args);
// logger.info(msg) << ".." call style
template <typename T> details::line_logger trace(const T&);
template <typename T> details::line_logger debug(const T&);
template <typename T> details::line_logger info(const T&);
template <typename T> details::line_logger notice(const T&);
template <typename T> details::line_logger warn(const T&);
template <typename T> details::line_logger error(const T&);
template <typename T> details::line_logger critical(const T&);
template <typename T> details::line_logger alert(const T&);
template <typename T> details::line_logger emerg(const T&);
// logger.info() << ".." call style
details::line_logger trace();
details::line_logger debug();
details::line_logger info();
details::line_logger notice();
details::line_logger warn();
details::line_logger error();
details::line_logger critical();
details::line_logger alert();
details::line_logger emerg();
// Create log message with the given level, no matter what is the actual logger's level
template <typename... Args>
details::line_logger force_log(level::level_enum lvl, const char* fmt, const Args&... args);
// Set the format of the log messages from this logger
void set_pattern(const std::string&); void set_pattern(const std::string&);
void set_formatter(formatter_ptr); void set_formatter(formatter_ptr);
// automatically call flush() if message level >= log_level
void flush_on(level::level_enum log_level);
virtual void flush(); virtual void flush();
protected: protected:
virtual void _log_msg(details::log_msg&); virtual void _sink_it(details::log_msg&);
virtual void _set_pattern(const std::string&); virtual void _set_pattern(const std::string&);
virtual void _set_formatter(formatter_ptr); virtual void _set_formatter(formatter_ptr);
details::line_logger _log_if_enabled(level::level_enum lvl);
template <typename... Args>
details::line_logger _log_if_enabled(level::level_enum lvl, const char* fmt, const Args&... args);
template<typename T>
inline details::line_logger _log_if_enabled(level::level_enum lvl, const T& msg);
friend details::line_logger;
std::string _name; std::string _name;
std::vector<sink_ptr> _sinks; std::vector<sink_ptr> _sinks;
formatter_ptr _formatter; formatter_ptr _formatter;
@ -112,5 +85,5 @@ protected:
} }
#include <spdlog/details/logger_impl.h> #include <spdlog/details/logger_impl.h>
#include <spdlog/details/line_logger_impl.h>

View File

@ -91,6 +91,10 @@ inline void ansicolor_sink::log(const details::log_msg& msg)
const std::string& s = msg.formatted.str(); const std::string& s = msg.formatted.str();
const std::string& suffix = reset; const std::string& suffix = reset;
details::log_msg m; details::log_msg m;
m.level = msg.level;
m.logger_name = msg.logger_name;
m.time = msg.time;
m.thread_id = msg.thread_id;
m.formatted << prefix << s << suffix; m.formatted << prefix << s << suffix;
sink_->log(m); sink_->log(m);
} }

View File

@ -5,21 +5,28 @@
#pragma once #pragma once
///////////////////////////////////////////////////////////////////////////////
// //
// Edit this file to squeeze every last drop of performance out of spdlog. // Edit this file to squeeze every last drop of performance out of spdlog.
// //
///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Under Linux, the much faster CLOCK_REALTIME_COARSE clock can be used. // Under Linux, the much faster CLOCK_REALTIME_COARSE clock can be used.
// This clock is less accurate - can be off by dozens of millis - depending on the kernel HZ. // This clock is less accurate - can be off by dozens of millis - depending on the kernel HZ.
// Uncomment to use it instead of the regular (but slower) clock. // Uncomment to use it instead of the regular clock.
//
// #define SPDLOG_CLOCK_COARSE // #define SPDLOG_CLOCK_COARSE
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Uncomment if date/time logging is not needed. // Uncomment if date/time logging is not needed and never appear in the log pattern.
// This will prevent spdlog from quering the clock on each log call. // This will prevent spdlog from quering the clock on each log call.
//
// WARNING: If the log pattern contains any date/time while this flag is on, the result is undefined.
// You must set new pattern(spdlog::set_pattern(..") without any date/time in it
//
// #define SPDLOG_NO_DATETIME // #define SPDLOG_NO_DATETIME
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -27,6 +34,9 @@
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Uncomment if thread id logging is not needed (i.e. no %t in the log pattern). // Uncomment if thread id logging is not needed (i.e. no %t in the log pattern).
// This will prevent spdlog from quering the thread id on each log call. // This will prevent spdlog from quering the thread id on each log call.
//
// WARNING: If the log pattern contains thread id (i.e, %t) while this flag is on, the result is undefined.
//
// #define SPDLOG_NO_THREAD_ID // #define SPDLOG_NO_THREAD_ID
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -34,12 +44,14 @@
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Uncomment if logger name logging is not needed. // Uncomment if logger name logging is not needed.
// This will prevent spdlog from copying the logger name on each log call. // This will prevent spdlog from copying the logger name on each log call.
//
// #define SPDLOG_NO_NAME // #define SPDLOG_NO_NAME
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Uncomment to enable the SPDLOG_DEBUG/SPDLOG_TRACE macros. // Uncomment to enable the SPDLOG_DEBUG/SPDLOG_TRACE macros.
//
// #define SPDLOG_DEBUG_ON // #define SPDLOG_DEBUG_ON
// #define SPDLOG_TRACE_ON // #define SPDLOG_TRACE_ON
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -49,18 +61,21 @@
// Uncomment to avoid locking in the registry operations (spdlog::get(), spdlog::drop() spdlog::register()). // Uncomment to avoid locking in the registry operations (spdlog::get(), spdlog::drop() spdlog::register()).
// Use only if your code never modifes concurrently the registry. // Use only if your code never modifes concurrently the registry.
// Note that upon creating a logger the registry is modified by spdlog.. // Note that upon creating a logger the registry is modified by spdlog..
//
// #define SPDLOG_NO_REGISTRY_MUTEX // #define SPDLOG_NO_REGISTRY_MUTEX
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Uncomment to avoid spdlog's usage of atomic log levels // Uncomment to avoid spdlog's usage of atomic log levels
// Use only if your code never modifies a logger's log levels concurrently. // Use only if your code never modifies a logger's log levels concurrently by different threads.
//
// #define SPDLOG_NO_ATOMIC_LEVELS // #define SPDLOG_NO_ATOMIC_LEVELS
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Uncomment to enable usage of wchar_t for file names on Windows. // Uncomment to enable usage of wchar_t for file names on Windows.
//
// #define SPDLOG_WCHAR_FILENAMES // #define SPDLOG_WCHAR_FILENAMES
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

View File

@ -1,19 +1,19 @@
# #
# Tests # Tests
# #
enable_testing() enable_testing()
find_package(Threads) find_package(Threads)
# Build Catch unit tests # Build Catch unit tests
add_library(catch INTERFACE) add_library(catch INTERFACE)
target_include_directories(catch INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) target_include_directories(catch INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
file(GLOB catch_tests LIST_DIRECTORIES false RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp) file(GLOB catch_tests LIST_DIRECTORIES false RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp)
add_executable(catch_tests ${catch_tests}) add_executable(catch_tests ${catch_tests})
target_link_libraries(catch_tests spdlog ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries(catch_tests spdlog ${CMAKE_THREAD_LIBS_INIT})
add_test(NAME catch_tests COMMAND catch_tests) add_test(NAME catch_tests COMMAND catch_tests)
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/logs") file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/logs")

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,12 @@
#!/bin/bash #!/bin/bash
# #
# Install libc++ under travis # Install libc++ under travis
svn --quiet co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx svn --quiet co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx
mkdir libcxx/build mkdir libcxx/build
(cd libcxx/build && cmake .. -DLIBCXX_CXX_ABI=libstdc++ -DLIBCXX_CXX_ABI_INCLUDE_PATHS="/usr/include/c++/4.6;/usr/include/c++/4.6/x86_64-linux-gnu") (cd libcxx/build && cmake .. -DLIBCXX_CXX_ABI=libstdc++ -DLIBCXX_CXX_ABI_INCLUDE_PATHS="/usr/include/c++/4.6;/usr/include/c++/4.6/x86_64-linux-gnu")
make -C libcxx/build cxx -j2 make -C libcxx/build cxx -j2
sudo cp libcxx/build/lib/libc++.so.1.0 /usr/lib/ sudo cp libcxx/build/lib/libc++.so.1.0 /usr/lib/
sudo cp -r libcxx/build/include/c++/v1 /usr/include/c++/v1/ sudo cp -r libcxx/build/include/c++/v1 /usr/include/c++/v1/
sudo ln -sf /usr/lib/libc++.so.1.0 /usr/lib/libc++.so sudo ln -sf /usr/lib/libc++.so.1.0 /usr/lib/libc++.so
sudo ln -sf /usr/lib/libc++.so.1.0 /usr/lib/libc++.so.1 sudo ln -sf /usr/lib/libc++.so.1.0 /usr/lib/libc++.so.1

View File

@ -1,28 +1,28 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013 # Visual Studio 2013
VisualStudioVersion = 12.0.31101.0 VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests", "tests.vcxproj", "{59A07559-5F38-4DD6-A7FA-DB4153690B42}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests", "tests.vcxproj", "{59A07559-5F38-4DD6-A7FA-DB4153690B42}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32 Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64 Debug|x64 = Debug|x64
Release|Win32 = Release|Win32 Release|Win32 = Release|Win32
Release|x64 = Release|x64 Release|x64 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{59A07559-5F38-4DD6-A7FA-DB4153690B42}.Debug|Win32.ActiveCfg = Debug|Win32 {59A07559-5F38-4DD6-A7FA-DB4153690B42}.Debug|Win32.ActiveCfg = Debug|Win32
{59A07559-5F38-4DD6-A7FA-DB4153690B42}.Debug|Win32.Build.0 = Debug|Win32 {59A07559-5F38-4DD6-A7FA-DB4153690B42}.Debug|Win32.Build.0 = Debug|Win32
{59A07559-5F38-4DD6-A7FA-DB4153690B42}.Debug|x64.ActiveCfg = Debug|x64 {59A07559-5F38-4DD6-A7FA-DB4153690B42}.Debug|x64.ActiveCfg = Debug|x64
{59A07559-5F38-4DD6-A7FA-DB4153690B42}.Debug|x64.Build.0 = Debug|x64 {59A07559-5F38-4DD6-A7FA-DB4153690B42}.Debug|x64.Build.0 = Debug|x64
{59A07559-5F38-4DD6-A7FA-DB4153690B42}.Release|Win32.ActiveCfg = Release|Win32 {59A07559-5F38-4DD6-A7FA-DB4153690B42}.Release|Win32.ActiveCfg = Release|Win32
{59A07559-5F38-4DD6-A7FA-DB4153690B42}.Release|Win32.Build.0 = Release|Win32 {59A07559-5F38-4DD6-A7FA-DB4153690B42}.Release|Win32.Build.0 = Release|Win32
{59A07559-5F38-4DD6-A7FA-DB4153690B42}.Release|x64.ActiveCfg = Release|x64 {59A07559-5F38-4DD6-A7FA-DB4153690B42}.Release|x64.ActiveCfg = Release|x64
{59A07559-5F38-4DD6-A7FA-DB4153690B42}.Release|x64.Build.0 = Release|x64 {59A07559-5F38-4DD6-A7FA-DB4153690B42}.Release|x64.Build.0 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal