diff --git a/ACKNOWLEDGEMENTS.md b/ACKNOWLEDGEMENTS.md new file mode 100644 index 000000000..49f58b45f --- /dev/null +++ b/ACKNOWLEDGEMENTS.md @@ -0,0 +1,14 @@ +# Acknowledgements +This file contains list of contributors and acknowledgement of their efforts in making this library better especially by making acceptable code changes. + +If we have missed your name please feel free to add it with contribution link. + +| **Github User** | **Contribution** | +|--------------------------------------|----------------------------------| +| [@aparajita](https://github.com/aparajita) | [Separated out .h and .cc file](https://github.com/muflihun/easyloggingpp/pulls?q=is%3Apr+author%3Aaparajita) | +| [@adah1972](https://github.com/adah1972) | [A lot of contributions](https://github.com/muflihun/easyloggingpp/pulls?q=is%3Apr+author%3Aadah1972) | +| [@miguelmartin75](https://github.com/miguelmartin75) | [Issue #11](https://github.com/muflihun/easyloggingpp/issues/11), [PR #16](https://github.com/muflihun/easyloggingpp/pull/16) | +| [@moneromooo-monero](https://github.com/moneromooo-monero) | [A lot of contributions](https://github.com/muflihun/easyloggingpp/pulls?q=is%3Apr+author%3Amoneromooo-monero)| +| [@MonsieurNicolas](https://github.com/MonsieurNicolas) | [PR #593](https://github.com/muflihun/easyloggingpp/pull/593) | +| [@acowley](https://github.com/acowley) | [PR #593](https://github.com/muflihun/easyloggingpp/pull/577) | +| [@rggjan](https://github.com/rggjan) | [PR 561](https://github.com/muflihun/easyloggingpp/pull/561) | diff --git a/CHANGELOG.md b/CHANGELOG.md index fbe418a3c..df68c5db3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Change Log +## [9.96.0] - 14-02-2018 +### Fixes +- Potential deadlocks in extreme edge case #609 +- Respect `MaxLogFileSize` setting even when `ELPP_NO_DEFAULT_LOG_FILE` is set (@MonsieurNicolas) +- Disable log file **initially** when using `ELPP_NO_LOG_TO_FILE`, to be consistent with documentation (@rggjan) + +### Updates +- `el::Storage` no longer contains locks as it should be +- Reformatted both files with `astyle` +- License text updated + +### Added +- Install a pkg-config `.pc` file (@acowley) + ## [9.95.4] - 10-02-2018 ### Fixes - Fix documentation (see PR#597) diff --git a/CMakeLists.txt b/CMakeLists.txt index 27038eb75..e422a0baf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,11 +26,12 @@ option(build_static_lib "Build easyloggingpp as a static library" OFF) option(lib_utc_datetime "Build library with UTC date/time logging" OFF) set(ELPP_MAJOR_VERSION "9") -set(ELPP_MINOR_VERSION "95") -set(ELPP_PATCH_VERSION "4") +set(ELPP_MINOR_VERSION "96") +set(ELPP_PATCH_VERSION "0") set(ELPP_VERSION_STRING "${ELPP_MAJOR_VERSION}.${ELPP_MINOR_VERSION}.${ELPP_PATCH_VERSION}") set(ELPP_INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "The directory the headers are installed in") +set(ELPP_PKGCONFIG_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files") include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) @@ -40,6 +41,11 @@ install(FILES DESTINATION "${ELPP_INCLUDE_INSTALL_DIR}" COMPONENT dev) +configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/easyloggingpp.pc.cmakein + ${CMAKE_CURRENT_BINARY_DIR}/easyloggingpp.pc @ONLY) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/easyloggingpp.pc DESTINATION "${ELPP_PKGCONFIG_INSTALL_DIR}") + if (build_static_lib) if (lib_utc_datetime) add_definitions(-DELPP_UTC_DATETIME) diff --git a/LICENSE b/LICENSE index 3f97e0924..2f047afa8 100644 --- a/LICENSE +++ b/LICENSE @@ -1,10 +1,11 @@ The MIT License (MIT) Copyright (c) 2012-2018 Muflihun Labs +Copyright (c) 2012-2018 @abumusamq https://github.com/muflihun/ -https://muflihun.com -https://muflihun.github.io +https://muflihun.com/ +https://muflihun.github.io/ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/README.md b/README.md index d1680808f..937cbd508 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ![banner] -> **Manual For v9.95.4** +> **Manual For v9.96.0** [![Build Status (Master)](https://img.shields.io/travis/muflihun/easyloggingpp/master.svg)](https://travis-ci.org/muflihun/easyloggingpp) [![Build Status (Develop)](https://img.shields.io/travis/muflihun/easyloggingpp/develop.svg)](https://travis-ci.org/muflihun/easyloggingpp) [![Version](https://img.shields.io/github/release/muflihun/easyloggingpp.svg)](https://github.com/muflihun/easyloggingpp/releases/latest) @@ -100,7 +100,7 @@ # Overview Easylogging++ is single header efficient logging library for C++ applications. It is extremely powerful, highly extendable and configurable to user's requirements. It provides ability to [write your own _sinks_](https://github.com/muflihun/easyloggingpp/tree/master/samples/send-to-network) (via featured referred as `LogDispatchCallback`). This library is currently used by [hundreds of open-source projects on github](https://github.com/search?q=%22easylogging%2B%2B.h%22&type=Code&utf8=%E2%9C%93) and other open-source source control management sites. -This manual is for Easylogging++ v9.95.4. For other versions please refer to corresponding [release](https://github.com/muflihun/easyloggingpp/releases) on github. +This manual is for Easylogging++ v9.96.0. For other versions please refer to corresponding [release](https://github.com/muflihun/easyloggingpp/releases) on github. > You may also be interested in [Residue](https://github.com/muflihun/residue/) logging server. diff --git a/cmake/easyloggingpp.pc.cmakein b/cmake/easyloggingpp.pc.cmakein new file mode 100644 index 000000000..61000ce4e --- /dev/null +++ b/cmake/easyloggingpp.pc.cmakein @@ -0,0 +1,6 @@ +Name: easyloggingpp +Description: Feature-rich single header C++ logging library +Version: @ELPP_VERSION_STRING@ +prefix=@CMAKE_INSTALL_PREFIX@ +includedir=@ELPP_INCLUDE_INSTALL_DIR@ +Cflags: -I${includedir} diff --git a/src/easylogging++.cc b/src/easylogging++.cc index 620921454..c58a733d0 100644 --- a/src/easylogging++.cc +++ b/src/easylogging++.cc @@ -1,13 +1,14 @@ // // Bismillah ar-Rahmaan ar-Raheem // -// Easylogging++ v9.95.4 +// Easylogging++ v9.96.0 // Cross-platform logging library for C++ applications // // Copyright (c) 2012-2018 Muflihun Labs +// Copyright (c) 2012-2018 @abumusamq // // This library is released under the MIT Licence. -// http://labs.muflihun.com/easyloggingpp/licence.php +// https://github.com/muflihun/easyloggingpp/blob/master/LICENSE // // https://github.com/muflihun/easyloggingpp // https://muflihun.github.io/easyloggingpp @@ -1622,10 +1623,11 @@ void TypedConfigurations::build(Configurations* configurations) { } else if (conf->configurationType() == ConfigurationType::PerformanceTracking) { setValue(Level::Global, getBool(conf->value()), &m_performanceTrackingMap); } else if (conf->configurationType() == ConfigurationType::MaxLogFileSize) { - setValue(conf->level(), static_cast(getULong(conf->value())), &m_maxLogFileSizeMap); -#if !defined(ELPP_NO_DEFAULT_LOG_FILE) - withFileSizeLimit.push_back(conf); -#endif // !defined(ELPP_NO_DEFAULT_LOG_FILE) + auto v = getULong(conf->value()); + setValue(conf->level(), static_cast(v), &m_maxLogFileSizeMap); + if (v != 0) { + withFileSizeLimit.push_back(conf); + } } else if (conf->configurationType() == ConfigurationType::LogFlushThreshold) { setValue(conf->level(), static_cast(getULong(conf->value())), &m_logFlushThresholdMap); } @@ -1699,12 +1701,6 @@ std::string TypedConfigurations::resolveFilename(const std::string& filename) { } void TypedConfigurations::insertFile(Level level, const std::string& fullFilename) { -#if defined(ELPP_NO_LOG_TO_FILE) - setValue(level, false, &m_toFileMap); - ELPP_UNUSED(fullFilename); - m_fileStreamMap.insert(std::make_pair(level, base::FileStreamPtr(nullptr))); - return; -#endif std::string resolvedFilename = resolveFilename(fullFilename); if (resolvedFilename.empty()) { std::cerr << "Could not load empty file for logging, please re-check your configurations for level [" @@ -1840,8 +1836,10 @@ bool RegisteredLoggers::remove(const std::string& id) { if (id == base::consts::kDefaultLoggerId) { return false; } + // get has internal lock Logger* logger = base::utils::Registry::get(id); if (logger != nullptr) { + // unregister has internal lock unregister(logger); } return true; @@ -2046,7 +2044,7 @@ Storage::~Storage(void) { } bool Storage::hasCustomFormatSpecifier(const char* formatSpecifier) { - base::threading::ScopedLock scopedLock(lock()); + base::threading::ScopedLock scopedLock(customFormatSpecifiersLock()); return std::find(m_customFormatSpecifiers.begin(), m_customFormatSpecifiers.end(), formatSpecifier) != m_customFormatSpecifiers.end(); } @@ -2055,12 +2053,12 @@ void Storage::installCustomFormatSpecifier(const CustomFormatSpecifier& customFo if (hasCustomFormatSpecifier(customFormatSpecifier.formatSpecifier())) { return; } - base::threading::ScopedLock scopedLock(lock()); + base::threading::ScopedLock scopedLock(customFormatSpecifiersLock()); m_customFormatSpecifiers.push_back(customFormatSpecifier); } bool Storage::uninstallCustomFormatSpecifier(const char* formatSpecifier) { - base::threading::ScopedLock scopedLock(lock()); + base::threading::ScopedLock scopedLock(customFormatSpecifiersLock()); std::vector::iterator it = std::find(m_customFormatSpecifiers.begin(), m_customFormatSpecifiers.end(), formatSpecifier); if (it != m_customFormatSpecifiers.end() && strcmp(formatSpecifier, it->formatSpecifier()) == 0) { @@ -2349,7 +2347,7 @@ base::type::string_t DefaultLogBuilder::build(const LogMessage* logMessage, bool base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kMessageFormatSpecifier, logMessage->message()); } #if !defined(ELPP_DISABLE_CUSTOM_FORMAT_SPECIFIERS) - el::base::threading::ScopedLock lock_(ELPP->lock()); + el::base::threading::ScopedLock lock_(ELPP->customFormatSpecifiersLock()); ELPP_UNUSED(lock_); for (std::vector::const_iterator it = ELPP->customFormatSpecifiers()->begin(); it != ELPP->customFormatSpecifiers()->end(); ++it) { @@ -2448,7 +2446,6 @@ void Writer::initializeLogger(const std::string& loggerId, bool lookup, bool nee } if (m_logger == nullptr) { { - base::threading::ScopedLock scopedLock(ELPP->lock()); if (!ELPP->registeredLoggers()->has(std::string(base::consts::kDefaultLoggerId))) { // Somehow default logger has been unregistered. Not good! Register again ELPP->registeredLoggers()->get(std::string(base::consts::kDefaultLoggerId)); @@ -2824,7 +2821,6 @@ void Helpers::logCrashReason(int sig, bool stackTraceIfAvailable, Level level, c // Loggers Logger* Loggers::getLogger(const std::string& identity, bool registerIfNotAvailable) { - base::threading::ScopedLock scopedLock(ELPP->lock()); return ELPP->registeredLoggers()->get(identity, registerIfNotAvailable); } @@ -2833,12 +2829,10 @@ void Loggers::setDefaultLogBuilder(el::LogBuilderPtr& logBuilderPtr) { } bool Loggers::unregisterLogger(const std::string& identity) { - base::threading::ScopedLock scopedLock(ELPP->lock()); return ELPP->registeredLoggers()->remove(identity); } bool Loggers::hasLogger(const std::string& identity) { - base::threading::ScopedLock scopedLock(ELPP->lock()); return ELPP->registeredLoggers()->has(identity); } @@ -2988,11 +2982,11 @@ void Loggers::clearVModules(void) { // VersionInfo const std::string VersionInfo::version(void) { - return std::string("9.95.4"); + return std::string("9.96.0"); } /// @brief Release date of current version const std::string VersionInfo::releaseDate(void) { - return std::string("10-02-2018 1109hrs"); + return std::string("14-02-2018 1629hrs"); } } // namespace el diff --git a/src/easylogging++.h b/src/easylogging++.h index 921dfa90c..8a54ab0d5 100644 --- a/src/easylogging++.h +++ b/src/easylogging++.h @@ -1,18 +1,20 @@ // // Bismillah ar-Rahmaan ar-Raheem // -// Easylogging++ v9.95.4 +// Easylogging++ v9.96.0 // Single-header only, cross-platform logging library for C++ applications // // Copyright (c) 2012-2018 Muflihun Labs +// Copyright (c) 2012-2018 @abumusamq // // This library is released under the MIT Licence. -// http://labs.muflihun.com/easyloggingpp/licence.php +// https://github.com/muflihun/easyloggingpp/blob/master/LICENSE // // https://github.com/muflihun/easyloggingpp // https://muflihun.github.io/easyloggingpp // http://muflihun.com // + #ifndef EASYLOGGINGPP_H #define EASYLOGGINGPP_H // Compilers and C++0x/C++11 Evaluation @@ -2601,7 +2603,7 @@ class IWorker { }; #endif // ELPP_ASYNC_LOGGING /// @brief Easylogging++ management storage -class Storage : base::NoCopy, public base::threading::ThreadSafe { +class Storage : base::NoCopy { public: #if ELPP_ASYNC_LOGGING Storage(const LogBuilderPtr& defaultLogBuilder, base::IWorker* asyncDispatchWorker); @@ -2685,6 +2687,10 @@ class Storage : base::NoCopy, public base::threading::ThreadSafe { return &m_customFormatSpecifiers; } + base::threading::Mutex& customFormatSpecifiersLock() { + return m_customFormatSpecifiersLock; + } + inline void setLoggingLevel(Level level) { m_loggingLevel = level; } @@ -2725,11 +2731,12 @@ class Storage : base::NoCopy, public base::threading::ThreadSafe { /// @brief Sets thread name for current thread. Requires std::thread inline void setThreadName(const std::string& name) { if (name.empty()) return; - base::threading::ScopedLock scopedLock(lock()); + base::threading::ScopedLock scopedLock(m_threadNamesLock); m_threadNames[base::threading::getCurrentThreadId()] = name; } inline std::string getThreadName(const std::string& threadId) { + base::threading::ScopedLock scopedLock(m_threadNamesLock); std::map::const_iterator it = m_threadNames.find(threadId); if (it == m_threadNames.end()) { return threadId; @@ -2751,6 +2758,8 @@ class Storage : base::NoCopy, public base::threading::ThreadSafe { std::map m_performanceTrackingCallbacks; std::map m_threadNames; std::vector m_customFormatSpecifiers; + base::threading::Mutex m_customFormatSpecifiersLock; + base::threading::Mutex m_threadNamesLock; Level m_loggingLevel; friend class el::Helpers; @@ -2793,7 +2802,7 @@ class AsyncDispatchWorker : public base::IWorker, public base::threading::Thread void run(void); void setContinueRunning(bool value) { - base::threading::ScopedLock scopedLock(m_continueRunningMutex); + base::threading::ScopedLock scopedLock(m_continueRunningLock); m_continueRunning = value; } @@ -2803,7 +2812,7 @@ class AsyncDispatchWorker : public base::IWorker, public base::threading::Thread private: std::condition_variable cv; bool m_continueRunning; - base::threading::Mutex m_continueRunningMutex; + base::threading::Mutex m_continueRunningLock; }; #endif // ELPP_ASYNC_LOGGING } // namespace base