diff --git a/CMakeLists.txt b/CMakeLists.txt index 843a522f..20669a00 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,3 +1,4 @@ + # # Copyright(c) 2015 Ruslan Baratov. # Distributed under the MIT License (http://opensource.org/licenses/MIT) @@ -6,7 +7,6 @@ cmake_minimum_required(VERSION 3.1) project(spdlog VERSION 1.3.1 LANGUAGES CXX) include(CMakeDependentOption) -include(GNUInstallDirs) #--------------------------------------------------------------------------------------- # set default build to release @@ -40,8 +40,6 @@ include(cmake/sanitizers.cmake) #--------------------------------------------------------------------------------------- # spdlog target #--------------------------------------------------------------------------------------- -add_library(spdlog INTERFACE) -add_library(spdlog::spdlog ALIAS spdlog) # Check if spdlog is being used directly or via add_subdirectory set(SPDLOG_MASTER_PROJECT OFF) @@ -49,12 +47,24 @@ if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) set(SPDLOG_MASTER_PROJECT ON) endif() +option(SPDLOG_HEADER_ONLY "Header only version. Turn OFF to build as static lib" OFF) option(SPDLOG_BUILD_EXAMPLES "Build examples" ${SPDLOG_MASTER_PROJECT}) option(SPDLOG_BUILD_BENCH "Build benchmarks (Requires https://github.com/google/benchmark.git to be installed)" OFF) option(SPDLOG_BUILD_TESTS "Build tests" ${SPDLOG_MASTER_PROJECT}) option(SPDLOG_FMT_EXTERNAL "Use external fmt library instead of bundled" OFF) option(SPDLOG_INSTALL "Generate the install target." ${SPDLOG_MASTER_PROJECT}) +if(SPDLOG_HEADER_ONLY) + add_definitions(-DSPDLOG_HEADER_ONLY) + add_library(spdlog INTERFACE) + add_library(spdlog::spdlog ALIAS spdlog) + +else() + remove_definitions(-DSPDLOG_HEADER_ONLY) + file(GLOB SRC_FILES ${PROJECT_SOURCE_DIR}/src/*.cpp) + add_library(spdlog ${SRC_FILES} ) + add_library(spdlog::spdlog ALIAS spdlog) +endif() if(SPDLOG_FMT_EXTERNAL AND NOT TARGET fmt::fmt) find_package(fmt REQUIRED CONFIG) @@ -62,9 +72,8 @@ endif() target_include_directories( spdlog - INTERFACE + PUBLIC "$" - "$" ) if(SPDLOG_FMT_EXTERNAL) @@ -86,76 +95,3 @@ endif() if(SPDLOG_BUILD_BENCH) add_subdirectory(bench) endif() - -#--------------------------------------------------------------------------------------- -# Install/export targets and files -#--------------------------------------------------------------------------------------- -if(SPDLOG_INSTALL) - # set files and directories - set(config_install_dir "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") - set(include_install_dir "${CMAKE_INSTALL_INCLUDEDIR}") - set(pkgconfig_install_dir "${CMAKE_INSTALL_LIBDIR}/pkgconfig") - set(version_config "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake") - set(project_config "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake") - set(targets_config "${PROJECT_NAME}Targets.cmake") - set(pkg_config "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc") - set(targets_export_name "${PROJECT_NAME}Targets") - set(namespace "${PROJECT_NAME}::") - - # generate package version file - include(CMakePackageConfigHelpers) - write_basic_package_version_file( - "${version_config}" COMPATIBILITY SameMajorVersion - ) - - # configure pkg config file - configure_file("cmake/spdlog.pc.in" "${pkg_config}" @ONLY) - # configure spdlogConfig.cmake file - configure_file("cmake/Config.cmake.in" "${project_config}" @ONLY) - - # install targets - install( - TARGETS spdlog - EXPORT "${targets_export_name}" - ) - - # install headers - install( - DIRECTORY "${HEADER_BASE}/${PROJECT_NAME}" - DESTINATION "${include_install_dir}" - ) - - # install project config and version file - install( - FILES "${project_config}" "${version_config}" - DESTINATION "${config_install_dir}" - ) - - # install pkg config file - install( - FILES "${pkg_config}" - DESTINATION "${pkgconfig_install_dir}" - ) - - # install targets config file - install( - EXPORT "${targets_export_name}" - NAMESPACE "${namespace}" - DESTINATION "${config_install_dir}" - FILE ${targets_config} - ) - -# export build directory targets file -export( - EXPORT ${targets_export_name} - NAMESPACE "${namespace}" - FILE ${targets_config} -) - -# register project in CMake user registry -export(PACKAGE ${PROJECT_NAME}) - -endif() - -file(GLOB_RECURSE spdlog_include_SRCS "${HEADER_BASE}/*.h") -add_custom_target(spdlog_headers_for_ide SOURCES ${spdlog_include_SRCS}) diff --git a/example/example.cpp b/example/example.cpp index e740afb6..616a4d20 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -7,15 +7,16 @@ // // -#include "spdlog/spdlog.h" -#include "spdlog/logger.h" -spdlog::logger *get_logger(); +#include "spdlog/spdlog.h" +#include "spdlog/async.h" +#include "spdlog/sinks/stdout_color_sinks.h" + int main(int, char *[]) -{ - int x = 4; - - auto *l = get_logger(); - l->info("HEllo { }", "HG FS"); -} \ No newline at end of file +{ + using spdlog::sinks::stderr_color_sink_mt; + auto logger = spdlog::create_async("async"); + logger->info("HEllo xsdsdfs {}", 123); + //spdlog::error("HEllo err {}", "HG FS"); +} diff --git a/include/spdlog/async_logger.h b/include/spdlog/async_logger.h index a7ecb787..3d1c9578 100644 --- a/include/spdlog/async_logger.h +++ b/include/spdlog/async_logger.h @@ -19,12 +19,8 @@ // Upon destruction, logs all remaining messages in the queue before // destructing.. -#include "spdlog/common.h" -#include "spdlog/logger.h" -#include -#include -#include +#include "spdlog/logger.h" namespace spdlog { @@ -70,4 +66,8 @@ private: }; } // namespace spdlog -#include "details/async_logger_impl.h" +#ifdef SPDLOG_HEADER_ONLY +#include "../src/async_logger.cpp" +#endif // SPDLOG_HEADER_ONLY + + diff --git a/src/async_logger.cpp b/src/async_logger.cpp new file mode 100644 index 00000000..94e8e546 --- /dev/null +++ b/src/async_logger.cpp @@ -0,0 +1,123 @@ +#ifndef SPDLOG_HEADER_ONLY +#include "spdlog/async_logger.h" +#endif + + +// async logger implementation +// uses a thread pool to perform the actual logging + +#include "spdlog/sinks/sink.h" +#include "spdlog/details/thread_pool.h" + +#include +#include +#include + +template +SPDLOG_INLINE spdlog::async_logger::async_logger( + std::string logger_name, It begin, It end, std::weak_ptr tp, async_overflow_policy overflow_policy) + : logger(std::move(logger_name), begin, end) + , thread_pool_(std::move(tp)) + , overflow_policy_(overflow_policy) +{ +} + +SPDLOG_INLINE spdlog::async_logger::async_logger( + std::string logger_name, sinks_init_list sinks_list, std::weak_ptr tp, async_overflow_policy overflow_policy) + : async_logger(std::move(logger_name), sinks_list.begin(), sinks_list.end(), std::move(tp), overflow_policy) +{ +} + +SPDLOG_INLINE spdlog::async_logger::async_logger( + std::string logger_name, sink_ptr single_sink, std::weak_ptr tp, async_overflow_policy overflow_policy) + : async_logger(std::move(logger_name), {std::move(single_sink)}, std::move(tp), overflow_policy) +{ +} + +// send the log message to the thread pool +SPDLOG_INLINE void spdlog::async_logger::sink_it_(details::log_msg &msg) +{ + if (auto pool_ptr = thread_pool_.lock()) + { + pool_ptr->post_log(shared_from_this(), msg, overflow_policy_); + } + else + { + throw spdlog_ex("async log: thread pool doesn't exist anymore"); + } +} + +// send flush request to the thread pool +SPDLOG_INLINE void spdlog::async_logger::flush_() +{ + if (auto pool_ptr = thread_pool_.lock()) + { + pool_ptr->post_flush(shared_from_this(), overflow_policy_); + } + else + { + throw spdlog_ex("async flush: thread pool doesn't exist anymore"); + } +} + +// +// backend functions - called from the thread pool to do the actual job +// +SPDLOG_INLINE void spdlog::async_logger::backend_log_(const details::log_msg &incoming_log_msg) +{ + try + { + for (auto &s : sinks_) + { + if (s->should_log(incoming_log_msg.level)) + { + s->log(incoming_log_msg); + } + } + } + catch (const std::exception &ex) + { + err_handler_(ex.what()); + } + catch (...) + { + err_handler_("Unknown exception in logger"); + } + + if (should_flush_(incoming_log_msg)) + { + backend_flush_(); + } +} + +SPDLOG_INLINE void spdlog::async_logger::backend_flush_() +{ + try + { + for (auto &sink : sinks_) + { + sink->flush(); + } + } + catch (const std::exception &ex) + { + err_handler_(ex.what()); + } + catch (...) + { + err_handler_("Unknown exception in logger"); + } +} + +SPDLOG_INLINE std::shared_ptr spdlog::async_logger::clone(std::string new_name) +{ + auto cloned = std::make_shared(std::move(new_name), sinks_.begin(), sinks_.end(), thread_pool_, overflow_policy_); + + cloned->set_level(this->level()); + cloned->flush_on(this->flush_level()); + cloned->set_error_handler(this->custom_err_handler_); + return std::move(cloned); +} + + + diff --git a/src/os.cpp b/src/os.cpp index 93738cb0..ecd5a611 100644 --- a/src/os.cpp +++ b/src/os.cpp @@ -2,8 +2,6 @@ // Copyright(c) 2015 Gabi Melman. // Distributed under the MIT License (http://opensource.org/licenses/MIT) // -#pragma once - #ifndef SPDLOG_HEADER_ONLY #include "spdlog/details/os.h" #endif diff --git a/tests/test_errors.cpp b/tests/test_errors.cpp index e675cfd3..f2d69777 100644 --- a/tests/test_errors.cpp +++ b/tests/test_errors.cpp @@ -42,7 +42,7 @@ struct custom_ex { }; -static void custom_handler(const std::string &msg) +static void custom_handler(const std::string &) { throw custom_ex(); }