mirror of
https://github.com/vgough/encfs.git
synced 2025-02-22 20:51:18 +01:00
Squashed 'vendor/github.com/muflihun/easyloggingpp/' changes from 468597048..49da71da8
49da71da8 Merge pull request #775 from amrayn/develop fa10a7974 Merge branch 'master' into develop 24b0de3d6 Merge pull request #702 from moneromooo-monero/dateIndex 5b55576b7 Merge pull request #647 from agilmor/readme_minor_fix 149000493 Merge pull request #714 from adah1972/typo-change 6cb5e4e52 Merge branch 'master' into typo-change a41864de6 Merge pull request #725 from divinity76/patch-1 a2d78625c Merge pull request #705 from markus-k/qnx-support cc35e9627 Merge pull request #739 from adam1985d/master 75d181c5c Merge pull request #774 from amrayn/develop d3e56c04f Merge pull request #712 from KrusnikViers/remove-unused-variable 83f7b0c03 Merge pull request #735 from ndowens/master 9d35a7e15 Merge pull request #726 from recipe/patch-1 0df4c5ad8 Merge pull request #737 from PhoebeHui/dev/Phoebe/vcpkg_instructions 7f8761b48 Merge pull request #741 from DominionSoftware/add_try_catch e5b4e2d80 Merge pull request #746 from soyoo/patch-1 e6594d8ef Merge pull request #773 from amrayn/develop f68abe86a Merge pull request #757 from jsoref/spelling 769b39d8e Merge pull request #748 from soyoo/patch-2 796565c05 spelling: unknown 84719eef7 spelling: specified 23ff0cbff spelling: situations ee76a6a32 spelling: separator a4d0753f4 spelling: separate 5b522401a spelling: sensitive bea320906 spelling: registries 01a7be37d spelling: program 64856cfd6 spelling: performance 11233adaf spelling: overridden e6f376e10 spelling: original a78650209 spelling: occurred f5bc5df27 spelling: occasional ... ecb10dc07 spelling: javascript fa5148d85 spelling: insensitive 336f3e5e4 spelling: instance e88a535cd spelling: improvement 68bfc9d45 spelling: features 0134dfdf3 spelling: experimental 6df775fbe spelling: ditched 267d90dbc spelling: disabled 66cc3067d spelling: defining 872c0777b spelling: corruption 20a8c30b1 spelling: corresponding f59a4b7f7 spelling: converts 357e5d8dd spelling: configuration 794dd51ef spelling: compliant 66e452eb5 spelling: attempted f316282c0 spelling: assuming 05d596f8e spelling: arithmetic 41b5d377a spelling: april 7bc7d6dea spelling: alpha 210ea0213 Update easylogging++.cc bb0f45c83 Update easyloggingpp.pri 03694bdce Create easyloggingpp.pri 95324817b Merge pull request #743 from benrubson/warn fcf9c6cf2 kSysLogLoggerId defined but not used f18f75cf7 add try catch to handle extremely low memory condition 733d9e749 Merge pull request #1 from amrayn/master 163a8e538 Update README.md 32415d9b3 bug - access attempt to released memory 15e2018ec Add vcpkg installation instructions 60d92a867 Add if defined HAVE_EXECINFO 2a171bc91 Merge pull request #728 from amrayn/develop b7e58d940 Merge branch 'master' into develop 3ec5bb3ae update e00090395 Create FUNDING.yml 2521c4875 typo 8e334dfd5 disable ELPP_STACKTRACE for cygwin a5070d23d Fix two typos that could affect understanding. 438c34cc6 Comment unused variable f5f213459 Disable stacktrace feature on QNX 573a51be4 Add support for QNX a441d4464 Fix using invalid dateIndex (std::string::npos) 20fdea6e1 Merge pull request #689 from zuhd-org/develop ca4f51f39 updated build matrix links bd593b386 Merge pull request #685 from zuhd-org/develop d97dbef47 Update README.md 5181b4039 Merge pull request #684 from muflihun/develop 25ebd5adf Update README.md f3986aaeb Merge pull request #683 from muflihun/develop e4659e547 9.96.7 release ea8e806b9 Merge pull request #642 from SgtCoDFish/develop fd2dda331 Merge branch 'develop' into develop dafba610c Merge pull request #682 from muflihun/develop bbdb96c39 updated release babf11834 updated license ebc066f71 Merge pull request #645 from slaperche-scality/support_pic_code cda4f5346 generate PIC code for the library 72436e541 Fixed unused variable warning while build without performance logging feature 3a832d738 Fix #660 (accessing ELPP before it's initialized) f2f606c41 Merge pull request #677 from moneromooo-monero/foundAt ba629aded Simplify some code based on already checked values a5317986d Merge pull request #668 from muflihun/develop a0e1b5fad release a6477e2bb up 1f78ad898 Merge pull request #667 from muflihun/develop f01c1f8b0 removed message 45b360b20 Ignore sigint 680aeecdd Fixes #666 Set log level from custom message if available d47e10aec Fixing Readme for the right CustomFormatSpecifier signature 7645a4285 Add Emscripten detection, with test modifications 66a3a8741 Merge pull request #630 from muflihun/develop 1ebc9bbc8 update to release 8092189b3 Merge pull request #629 from muflihun/develop 094e4ab92 closes #580 conditional global lock dd8427200 Merge pull request #627 from muflihun/develop 99534e8c3 node binding version 92b81c8df Merge pull request #626 from muflihun/develop f0d0a71b7 Merge pull request #624 from adah1972/file_rolling_at_flush 56876a601 9.96.3 f788ff626 removed attr for gcc b96d4895f closes #620 Unused warnings fixed 2257b7533 null device logging 6af205d56 minor fix demangler 8d30366ec minor fix demangler 8eabcc37f Fix two wrong uses of "it's". 4fd8d92be Update README. 5feb891bf Simplify File::getSizeOfFile. e763286e3 Validate file rolling at flush point. f508c0c21 Merge pull request #619 from muflihun/develop 3e4e2b484 release 430a317c4 Merge pull request #618 from muflihun/develop 9c30e18b9 release 9.96.2 ceae14673 nav to build matrix 2e35613f6 travis fix 044b4f56c updated to use unordered_map closes #611 35eebba97 introduced new constructor for writer and dispatcher update 28612fcda u fd8fc502f updated travis 173358022 travis fix? c03b2c1d8 Merge pull request #616 from muflihun/develop 2ca71dd8e build matrix and sample 162b2ae17 trvis matrix e898d16fe use explicit declr ec43c830d potential wrapper for mutex e9dc1ecdb Merge pull request #615 from muflihun/develop a8b0bb016 update fix a7b9d6533 Merge pull request #614 from muflihun/develop ac1a71c33 9.96.1 release 251daa2e0 Two loggers writing to same file is undefined behaviour #613 89f61e588 Merge pull request #612 from muflihun/develop d40e8a020 Update README.md b443218a7 Update network-logger.cpp f5fe6c5f8 added send to network sample in README 6efc49142 Merge pull request #610 from muflihun/develop ee37c5c64 Update ACKNOWLEDGEMENTS.md 05bdfb0af release 9.96.0 fb67e3a3d Disable log file *initially* when using ELPP_NO_LOG_TO_FILE, to be consistent with documentation c1b128561 Generate and install a pkg-config file 193ea41a0 ack file 0da103b4e ack file 4442da152 respect MaxLogFileSize setting even when ELPP_NO_DEFAULT_LOG_FILE is set see PR #593 96919358c updated changelog 2614f8965 reformatting using astyle 2104884b3 license author joint 7679ace72 Potential deadlocks in extreme edge case - closes #609 5fd54a0dd Merge pull request #607 from muflihun/develop c06db0fa9 release b243df560 v9.95.4 01d12bdf5 made buildTimeInfo for use c6effe23e closes #606 for Writer b218fd3f3 closes #606 reserveCustomFormatSpecifiers e4931683b install cmake on travis ci 717d9607e update readme closes #585 b2ea92809 update changelog eb8ff3047 fix buffer underflow in getBashOutput 32ccda720 Issue #590: clarify usage of configuration macros a58288b4a updated year in license b7b4cbf8d Merge pull request #576 from muflihun/develop e04834d11 update release 049b242d4 Update MESSAGE.md e3f930ce1 Update MESSAGE.md 74ac78557 Update MESSAGE.md 4e5bc7086 Update MESSAGE.md cdf4875c6 Update MESSAGE.md 68b001956 msg 5b98f3ab0 Multithreading issue fixed raised from last release at log builder 11904e5ea Merge pull request #575 from muflihun/develop 5e4566e8b final release for 9.95.2 2990547dc Merge pull request #574 from muflihun/develop f197960e2 refix the failed release ba04082a3 Merge pull request #573 from muflihun/develop 417fa5ed9 9.95.1 release 7dcf83ebc closes #572 fixed printf like logging with thread safety 4286561b9 update e36f8663a fixed msg (see PR #568) 699c12ed9 closes #571 Removed global lock at dispatch 1a3d09bb2 Update README.md 1b515f9e8 up 78d630cbd updated sample 614608af1 Update README.md 3f6dd3e04 old gcc 9a171b4b6 Update README.md 0680b6dbb aix icon 89e37660b another updaet 9d2e024eb Added support for aix (thanks to apollo13) 33bc75ed9 closes #563 kFreeBSD fix c4ec767e6 change cmake to 2.8.7 850ea2a9f Merge pull request #559 from muflihun/develop f33a6239e Update README.md git-subtree-dir: vendor/github.com/muflihun/easyloggingpp git-subtree-split: 49da71da884d1e756a51df617437b87071c2b1a7
This commit is contained in:
parent
e405efee07
commit
b353ce4b9d
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
custom: https://amrayn.com/donate,https://www.paypal.me/mkhan3189
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -6,4 +6,4 @@ release.info
|
|||||||
bin/*
|
bin/*
|
||||||
logs/*
|
logs/*
|
||||||
experiments/*
|
experiments/*
|
||||||
CMakeLists.txt.user
|
CMakeLists.txt.user*
|
||||||
|
71
.travis.yml
71
.travis.yml
@ -1,11 +1,72 @@
|
|||||||
language: cpp
|
language: cpp
|
||||||
compiler:
|
matrix:
|
||||||
- gcc
|
include:
|
||||||
os: linux
|
# - os: linux
|
||||||
dist: trusty
|
# dist: trusty
|
||||||
|
# compiler: clang
|
||||||
|
# before_install:
|
||||||
|
# - sudo add-apt-repository ppa:kubuntu-ppa/backports -y
|
||||||
|
# - sudo apt-get -qq update
|
||||||
|
# - sudo apt-get install -y libgtest-dev valgrind cmake
|
||||||
|
# - sudo apt-get install --only-upgrade cmake
|
||||||
|
# - sudo wget https://github.com/google/googletest/archive/release-1.7.0.tar.gz
|
||||||
|
# - sudo tar xf release-1.7.0.tar.gz
|
||||||
|
# - cd googletest-release-1.7.0
|
||||||
|
# - sudo cmake -DBUILD_SHARED_LIBS=ON .
|
||||||
|
# - sudo make
|
||||||
|
# - sudo cp -a include/gtest /usr/include
|
||||||
|
# - sudo cp -a libgtest_main.so libgtest.so /usr/lib/
|
||||||
|
# - g++ -v
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
dist: trusty
|
||||||
|
compiler: gcc
|
||||||
|
env:
|
||||||
|
- COMPILER=g++-4.8
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources: ['ubuntu-toolchain-r-test']
|
||||||
|
packages: [g++-4.8, valgrind]
|
||||||
|
- os: linux
|
||||||
|
dist: trusty
|
||||||
|
compiler: gcc
|
||||||
|
env:
|
||||||
|
- COMPILER=g++-4.9
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources: ['ubuntu-toolchain-r-test']
|
||||||
|
packages: [g++-4.9, valgrind]
|
||||||
|
- os: linux
|
||||||
|
dist: trusty
|
||||||
|
compiler: gcc
|
||||||
|
env:
|
||||||
|
- COMPILER=g++-5
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources: ['ubuntu-toolchain-r-test']
|
||||||
|
packages: [g++-5, valgrind]
|
||||||
|
- os: linux
|
||||||
|
dist: trusty
|
||||||
|
compiler: gcc
|
||||||
|
env:
|
||||||
|
- COMPILER=g++-6
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources: ['ubuntu-toolchain-r-test']
|
||||||
|
packages: [g++-6, valgrind]
|
||||||
|
- os: linux
|
||||||
|
dist: trusty
|
||||||
|
compiler: gcc
|
||||||
|
env:
|
||||||
|
- COMPILER=g++-7
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
sources: ['ubuntu-toolchain-r-test']
|
||||||
|
packages: [g++-7, valgrind]
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- sudo apt-get -qq update
|
- sudo apt-get -qq update
|
||||||
- sudo apt-get install -y libgtest-dev valgrind
|
- sudo apt-get install -y libgtest-dev valgrind cmake
|
||||||
- sudo wget https://github.com/google/googletest/archive/release-1.7.0.tar.gz
|
- sudo wget https://github.com/google/googletest/archive/release-1.7.0.tar.gz
|
||||||
- sudo tar xf release-1.7.0.tar.gz
|
- sudo tar xf release-1.7.0.tar.gz
|
||||||
- cd googletest-release-1.7.0
|
- cd googletest-release-1.7.0
|
||||||
|
15
ACKNOWLEDGEMENTS.md
Normal file
15
ACKNOWLEDGEMENTS.md
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# 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/amrayn/easyloggingpp/pulls?q=is%3Apr+author%3Aaparajita) |
|
||||||
|
| [@adah1972](https://github.com/adah1972) | [A lot of contributions](https://github.com/amrayn/easyloggingpp/pulls?q=is%3Apr+author%3Aadah1972) |
|
||||||
|
| [@miguelmartin75](https://github.com/miguelmartin75) | [Issue #11](https://github.com/amrayn/easyloggingpp/issues/11), [PR #16](https://github.com/amrayn/easyloggingpp/pull/16) |
|
||||||
|
| [@moneromooo-monero](https://github.com/moneromooo-monero) | [A lot of contributions](https://github.com/amrayn/easyloggingpp/pulls?q=is%3Apr+author%3Amoneromooo-monero)|
|
||||||
|
| [@MonsieurNicolas](https://github.com/MonsieurNicolas) | [PR #593](https://github.com/amrayn/easyloggingpp/pull/593) |
|
||||||
|
| [@acowley](https://github.com/acowley) | [PR #593](https://github.com/amrayn/easyloggingpp/pull/577) |
|
||||||
|
| [@rggjan](https://github.com/rggjan) | [PR 561](https://github.com/amrayn/easyloggingpp/pull/561) |
|
||||||
|
| [@sgtcodfish](https://github.com/sgtcodfish) | Support for emscripten |
|
79
CHANGELOG.md
79
CHANGELOG.md
@ -1,14 +1,83 @@
|
|||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
|
## [9.96.7] - 24-11-2018
|
||||||
|
- Adds support for compiling easyloggingpp using Emscripten. This allows the library to be compiled into JavaScript or WebAssembly and run in the browser while logging to the browser's JavaScript console.
|
||||||
|
|
||||||
|
## [9.96.6] - 24-11-2018
|
||||||
|
- Storage constructor (indirectly) attempts to access elStorage before it's initialized (issue #660) (@Barteks2x)
|
||||||
|
- Fixed unused variable warning while build without performance logging feature (@wrgcpp)
|
||||||
|
- Updated license
|
||||||
|
|
||||||
|
## [9.96.5] - 07-09-2018
|
||||||
|
### Fixes
|
||||||
|
- Check for level enabled when using custom log message (Advanced) (issue #666)
|
||||||
|
- Ignore interruption signal crash log
|
||||||
|
|
||||||
|
## [9.96.4] - 03-04-2018
|
||||||
|
### Fixes
|
||||||
|
- Fixes seg fault with global lock (issue #580)
|
||||||
|
|
||||||
|
## [9.96.3] - 01-04-2018
|
||||||
|
### Fixes
|
||||||
|
- Demangling in GCC fixed
|
||||||
|
- `ELPP_NO_DEFAULT_LOG_FILE` now logs to null device on major platforms (windows and unix)
|
||||||
|
- Fixes unused warnings for constants
|
||||||
|
|
||||||
|
## [9.96.2] - 27-02-2018
|
||||||
|
### Updates
|
||||||
|
- Dispatcher now passes in pointer to log message instead of creating on the fly
|
||||||
|
- Introduced new constructor for `Writer` for advanced usage (see amrayn/residue)
|
||||||
|
- Use `std::unordered_map` for memory management instead of `std::map` issue #611
|
||||||
|
|
||||||
|
## [9.96.1] - 23-02-2018
|
||||||
|
### Fixes
|
||||||
|
- Two loggers writing to same file is undefined behaviour #613
|
||||||
|
|
||||||
|
## [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)
|
||||||
|
- Fix buffer underflow in getBashOutput (see PR#596)
|
||||||
|
|
||||||
|
### Updates
|
||||||
|
- Added new function `Helpers::reserveCustomFormatSpecifier` (see #606)
|
||||||
|
- Made `DateTime::buildTimeInfo` public for use
|
||||||
|
|
||||||
|
## [9.95.3] - 13-10-2017
|
||||||
|
### Fixes
|
||||||
|
- Multithreading issue fixed raised from last release at log builder
|
||||||
|
|
||||||
|
## [9.95.2] - 12-06-2017
|
||||||
|
### Fixes
|
||||||
|
- Build fix for kFreeBSD as suggested in issue #563
|
||||||
|
- Fixed issue with deadlock on dispatch (see #571)
|
||||||
|
- Fixed printf like logging with thread safety (see #572)
|
||||||
|
|
||||||
|
### Updates
|
||||||
|
- Added support for AIX (thanks to @apollo13)
|
||||||
|
|
||||||
## [9.95.0] - 02-08-2017
|
## [9.95.0] - 02-08-2017
|
||||||
### Added
|
### Added
|
||||||
- Added NetBSD as unix [coypoop](https://github.com/muflihun/easyloggingpp/pull/548/commits)
|
- Added NetBSD as unix [coypoop](https://github.com/amrayn/easyloggingpp/pull/548/commits)
|
||||||
- Ignore `NDEBUG` or `_DEBUG` to determine whether debug logs should be enabled or not. Use `ELPP_DISABLE_DEBUG_LOGS`
|
- Ignore `NDEBUG` or `_DEBUG` to determine whether debug logs should be enabled or not. Use `ELPP_DISABLE_DEBUG_LOGS`
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
- Fix compile when `_USE_32_BIT_TIME_T` defined [gggin](https://github.com/muflihun/easyloggingpp/pull/542/files)
|
- Fix compile when `_USE_32_BIT_TIME_T` defined [gggin](https://github.com/amrayn/easyloggingpp/pull/542/files)
|
||||||
- Fix invalid usage of safeDelete which can cause an error with valgrind [Touyote](https://github.com/muflihun/easyloggingpp/pull/544/files)
|
- Fix invalid usage of safeDelete which can cause an error with valgrind [Touyote](https://github.com/amrayn/easyloggingpp/pull/544/files)
|
||||||
- Add code to ensure no nullptr references [tepperly](https://github.com/muflihun/easyloggingpp/pull/512/files)
|
- Add code to ensure no nullptr references [tepperly](https://github.com/amrayn/easyloggingpp/pull/512/files)
|
||||||
|
|
||||||
## [9.94.2] - 12-04-2017
|
## [9.94.2] - 12-04-2017
|
||||||
### Added
|
### Added
|
||||||
@ -42,4 +111,4 @@
|
|||||||
- Custom format specifier now has to return `std::string` instead
|
- Custom format specifier now has to return `std::string` instead
|
||||||
- Merged `thread_name` with `thread` if thread name is available it's used otherwise ID is displayed
|
- Merged `thread_name` with `thread` if thread name is available it's used otherwise ID is displayed
|
||||||
|
|
||||||
For older versions please refer to [https://github.com/muflihun/easyloggingpp/tree/master/doc](https://github.com/muflihun/easyloggingpp/tree/master/doc)
|
For older versions please refer to [https://github.com/amrayn/easyloggingpp/tree/master/doc](https://github.com/amrayn/easyloggingpp/tree/master/doc)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
cmake_minimum_required(VERSION 2.8.12)
|
cmake_minimum_required(VERSION 2.8.7)
|
||||||
|
|
||||||
project(Easyloggingpp CXX)
|
project(Easyloggingpp CXX)
|
||||||
|
|
||||||
@ -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)
|
option(lib_utc_datetime "Build library with UTC date/time logging" OFF)
|
||||||
|
|
||||||
set(ELPP_MAJOR_VERSION "9")
|
set(ELPP_MAJOR_VERSION "9")
|
||||||
set(ELPP_MINOR_VERSION "95")
|
set(ELPP_MINOR_VERSION "96")
|
||||||
set(ELPP_PATCH_VERSION "0")
|
set(ELPP_PATCH_VERSION "7")
|
||||||
set(ELPP_VERSION_STRING "${ELPP_MAJOR_VERSION}.${ELPP_MINOR_VERSION}.${ELPP_PATCH_VERSION}")
|
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_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)
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||||
|
|
||||||
@ -40,6 +41,17 @@ install(FILES
|
|||||||
DESTINATION "${ELPP_INCLUDE_INSTALL_DIR}"
|
DESTINATION "${ELPP_INCLUDE_INSTALL_DIR}"
|
||||||
COMPONENT dev)
|
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}")
|
||||||
|
|
||||||
|
include(CheckIncludeFileCXX)
|
||||||
|
check_include_file_cxx("execinfo.h" HAVE_EXECINFO)
|
||||||
|
if (HAVE_EXECINFO)
|
||||||
|
add_definitions(-DHAVE_EXECINFO)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (build_static_lib)
|
if (build_static_lib)
|
||||||
if (lib_utc_datetime)
|
if (lib_utc_datetime)
|
||||||
add_definitions(-DELPP_UTC_DATETIME)
|
add_definitions(-DELPP_UTC_DATETIME)
|
||||||
@ -47,6 +59,7 @@ if (build_static_lib)
|
|||||||
|
|
||||||
require_cpp11()
|
require_cpp11()
|
||||||
add_library(easyloggingpp STATIC src/easylogging++.cc)
|
add_library(easyloggingpp STATIC src/easylogging++.cc)
|
||||||
|
set_property(TARGET easyloggingpp PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
|
|
||||||
install(TARGETS
|
install(TARGETS
|
||||||
easyloggingpp
|
easyloggingpp
|
||||||
@ -68,6 +81,10 @@ if (test)
|
|||||||
|
|
||||||
enable_testing()
|
enable_testing()
|
||||||
|
|
||||||
|
if (EMSCRIPTEN)
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "-O2 -s TOTAL_MEMORY=134217728")
|
||||||
|
endif()
|
||||||
|
|
||||||
add_executable(easyloggingpp-unit-tests
|
add_executable(easyloggingpp-unit-tests
|
||||||
src/easylogging++.cc
|
src/easylogging++.cc
|
||||||
test/main.cc
|
test/main.cc
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2017 muflihun.com
|
Copyright (c) 2012-2018 Amrayn Web Services
|
||||||
|
Copyright (c) 2012-2018 @abumusamq
|
||||||
|
|
||||||
https://github.com/muflihun/
|
https://github.com/amrayn/
|
||||||
https://muflihun.github.io
|
https://amrayn.com
|
||||||
https://muflihun.com
|
https://muflihun.com
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
282
README.md
282
README.md
@ -1,29 +1,28 @@
|
|||||||
بسم الله الرَّحْمَنِ الرَّحِيمِ
|
<p align="center">
|
||||||
|
﷽
|
||||||
|
</p>
|
||||||
|
|
||||||
![banner]
|
![banner]
|
||||||
|
|
||||||
> **Manual For v9.95.0**
|
> **Manual For v9.96.7**
|
||||||
|
|
||||||
[](https://travis-ci.org/muflihun/easyloggingpp) (`develop`)
|
[](#build-matrix)
|
||||||
|
[](#build-matrix)
|
||||||
|
[](https://ci.appveyor.com/project/abumusamq/easyloggingpp-node)
|
||||||
|
|
||||||
[](https://travis-ci.org/muflihun/easyloggingpp) (`master`)
|
[](https://github.com/amrayn/easyloggingpp-node/releases/latest)
|
||||||
|
[](https://www.npmjs.com/package/easyloggingpp)
|
||||||
|
|
||||||
[](https://github.com/muflihun/easyloggingpp/releases/latest)
|
[](https://github.com/amrayn/easyloggingpp/blob/master/LICENCE)
|
||||||
|
[](https://github.com/amrayn/easyloggingpp/releases/latest)
|
||||||
|
|
||||||
[](http://www.conan.io/source/easyloggingpp/9.95.0/memsharded/testing)
|
[](https://amrayn.com/donate)
|
||||||
|
|
||||||
[](http://melpon.org/wandbox/permlink/rwDXGcnP1IoCKXrJ)
|
#### Looking for maintainers!!
|
||||||
|
|
||||||
[](https://github.com/muflihun/easyloggingpp/blob/master/LICENCE)
|
|
||||||
|
|
||||||
[](https://www.paypal.me/MuflihunDotCom/25)
|
|
||||||
|
|
||||||
[](https://github.com/muflihun/easyloggingpp/releases/latest)
|
|
||||||
|
|
||||||
### Quick Links
|
### Quick Links
|
||||||
|
|
||||||
[![download] Latest Release](https://github.com/muflihun/easyloggingpp/releases/latest)
|
[![download] Latest Release](https://github.com/amrayn/easyloggingpp/releases/latest)
|
||||||
|
|
||||||
[![notes] Changelog](/CHANGELOG.md)
|
[![notes] Changelog](/CHANGELOG.md)
|
||||||
|
|
||||||
@ -33,7 +32,7 @@
|
|||||||
|
|
||||||
### Table of Contents
|
### Table of Contents
|
||||||
<pre>
|
<pre>
|
||||||
<a href="#introduction">Introduction</a>
|
<a href="#overview">Overview</a>
|
||||||
<a href="#why-yet-another-library">Why yet another library</a>
|
<a href="#why-yet-another-library">Why yet another library</a>
|
||||||
<a href="#features-at-a-glance">Features at a glance</a>
|
<a href="#features-at-a-glance">Features at a glance</a>
|
||||||
<a href="#getting-started">Getting Started</a>
|
<a href="#getting-started">Getting Started</a>
|
||||||
@ -64,7 +63,7 @@
|
|||||||
<a href="#network-logging">Network Logging</a>
|
<a href="#network-logging">Network Logging</a>
|
||||||
<a href="#verbose-logging">Verbose Logging</a>
|
<a href="#verbose-logging">Verbose Logging</a>
|
||||||
<a href="#basic-1">Basic</a>
|
<a href="#basic-1">Basic</a>
|
||||||
<a href="#conditional-and-occasional">Conditional and Occasional</a>
|
<a href="#conditional-and-occasional-logging">Conditional and Occasional</a>
|
||||||
<a href="#verbose-level">Verbose Level</a>
|
<a href="#verbose-level">Verbose Level</a>
|
||||||
<a href="#check-if-verbose-logging-is-on">Check If Verbose Logging Is On</a>
|
<a href="#check-if-verbose-logging-is-on">Check If Verbose Logging Is On</a>
|
||||||
<a href="#vmodule">VModule</a>
|
<a href="#vmodule">VModule</a>
|
||||||
@ -101,19 +100,22 @@
|
|||||||
<a href="#submitting-patches">Submitting Patches</a>
|
<a href="#submitting-patches">Submitting Patches</a>
|
||||||
<a href="#reporting-a-bug">Reporting a Bug</a>
|
<a href="#reporting-a-bug">Reporting a Bug</a>
|
||||||
<a href="#compatibility">Compatibility</a>
|
<a href="#compatibility">Compatibility</a>
|
||||||
|
<a href="#build-matrix">Build Matrix</a>
|
||||||
<a href="#licence">Licence</a>
|
<a href="#licence">Licence</a>
|
||||||
<a href="#disclaimer">Disclaimer</a>
|
<a href="#disclaimer">Disclaimer</a>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
# Introduction
|
# 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) (referred to as `LogDispatchCallback`). Currently used by hundreds of open-source projects.
|
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_](/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.0. For other versions please refer to corresponding [release](https://github.com/muflihun/easyloggingpp/releases) on github.
|
This manual is for Easylogging++ v9.96.7. For other versions please refer to corresponding [release](https://github.com/amrayn/easyloggingpp/releases) on github.
|
||||||
|
|
||||||
|
> You may also be interested in [Residue](https://github.com/amrayn/residue/) logging server.
|
||||||
|
|
||||||
[![top] Goto Top](#table-of-contents)
|
[![top] Goto Top](#table-of-contents)
|
||||||
|
|
||||||
### Why yet another library
|
### Why yet another library
|
||||||
If you are working on a small utility or large project in C++, this library can be handy. Its based on single header and only requires to link to single source file. (Originally it was header-only and was changed to use source file in [issue #445](https://github.com/muflihun/easyloggingpp/issues/445). You can still use header-only in [v9.89](https://github.com/muflihun/easyloggingpp/releases/tag/9.89)).
|
If you are working on a small utility or large project in C++, this library can be handy. Its based on single header and only requires to link to single source file. (Originally it was header-only and was changed to use source file in [issue #445](https://github.com/amrayn/easyloggingpp/issues/445). You can still use header-only in [v9.89](https://github.com/amrayn/easyloggingpp/releases/tag/9.89)).
|
||||||
|
|
||||||
This library has been designed with various thoughts in mind (i.e, portability, performance, usability, features and easy to setup).
|
This library has been designed with various thoughts in mind (i.e, portability, performance, usability, features and easy to setup).
|
||||||
|
|
||||||
@ -124,7 +126,7 @@ Why yet another library? Well, answer is pretty straight forward, use it as you
|
|||||||
### Features at a glance
|
### Features at a glance
|
||||||
Easylogging++ is feature-rich containing many features that both typical and advanced developer will require while writing a software;
|
Easylogging++ is feature-rich containing many features that both typical and advanced developer will require while writing a software;
|
||||||
* [Highly configurable](#configuration)
|
* [Highly configurable](#configuration)
|
||||||
* [Extendable](#log-dispatch-callback)
|
* [Extendable](#extending-library)
|
||||||
* Extremely fast
|
* Extremely fast
|
||||||
* [Thread](#multi-threading) and type safe
|
* [Thread](#multi-threading) and type safe
|
||||||
* [Cross-platform](#compatibility)
|
* [Cross-platform](#compatibility)
|
||||||
@ -144,9 +146,9 @@ Easylogging++ is feature-rich containing many features that both typical and adv
|
|||||||
|
|
||||||
# Getting Started
|
# Getting Started
|
||||||
### Download
|
### Download
|
||||||
Download latest version from [Latest Release](https://github.com/muflihun/easyloggingpp/releases/latest)
|
Download latest version from [Latest Release](https://github.com/amrayn/easyloggingpp/releases/latest)
|
||||||
|
|
||||||
For other releases, please visit [releases page](https://github.com/muflihun/easyloggingpp/releases). If you application does not support C++11, please consider using [v8.91](https://github.com/muflihun/easyloggingpp/tree/v8.91). This is stable version for C++98 and C++03, just lack some features.
|
For other releases, please visit [releases page](https://github.com/amrayn/easyloggingpp/releases). If you application does not support C++11, please consider using [v8.91](https://github.com/amrayn/easyloggingpp/tree/v8.91). This is stable version for C++98 and C++03, just lack some features.
|
||||||
|
|
||||||
[![top] Goto Top](#table-of-contents)
|
[![top] Goto Top](#table-of-contents)
|
||||||
|
|
||||||
@ -173,7 +175,7 @@ Now compile using
|
|||||||
g++ main.cc easylogging++.cc -o prog -std=c++11
|
g++ main.cc easylogging++.cc -o prog -std=c++11
|
||||||
```
|
```
|
||||||
|
|
||||||
That simple! Please note that `INITIALIZE_EASYLOGGINGPP` should be used once and once-only otherwise you will end up getting compilation errors. This is definiting several `extern` variables. This means it can be defined only once per application. Best place to put this initialization statement is in file where `int main(int, char**)` function is defined, right after last include statement.
|
That simple! Please note that `INITIALIZE_EASYLOGGINGPP` should be used once and once-only otherwise you will end up getting compilation errors. This is the definition of several `extern` variables. This means it can be defined only once per application. Best place to put this initialization statement is in file where `int main(int, char**)` function is defined, right after last include statement.
|
||||||
|
|
||||||
### Install (Optional)
|
### Install (Optional)
|
||||||
If you want to install this header system-wide, you can do so via:
|
If you want to install this header system-wide, you can do so via:
|
||||||
@ -191,7 +193,18 @@ Following options are supported by Easylogging++ cmake and you can turn these op
|
|||||||
* `lib_utc_datetime` - Defines `ELPP_UTC_DATETIME`
|
* `lib_utc_datetime` - Defines `ELPP_UTC_DATETIME`
|
||||||
* `build_static_lib` - Builds static library for Easylogging++
|
* `build_static_lib` - Builds static library for Easylogging++
|
||||||
|
|
||||||
With that said, you will still need `easylogging++.cc` file in order to compile. For header only, please check [v9.89](https://github.com/muflihun/easyloggingpp/releases/tag/9.89) and lower.
|
With that said, you will still need `easylogging++.cc` file in order to compile. For header only, please check [v9.89](https://github.com/amrayn/easyloggingpp/releases/tag/9.89) and lower.
|
||||||
|
|
||||||
|
Alternatively, you can download and install easyloggingpp using the [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager:
|
||||||
|
|
||||||
|
git clone https://github.com/Microsoft/vcpkg.git
|
||||||
|
cd vcpkg
|
||||||
|
./bootstrap-vcpkg.sh
|
||||||
|
./vcpkg integrate install
|
||||||
|
./vcpkg install easyloggingpp
|
||||||
|
|
||||||
|
The easyloggingpp port in vcpkg is kept up to date by Microsoft team members and community contributors.
|
||||||
|
If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
|
||||||
|
|
||||||
[![top] Goto Top](#table-of-contents)
|
[![top] Goto Top](#table-of-contents)
|
||||||
|
|
||||||
@ -422,7 +435,7 @@ Please note, date/time is limited to `30` characters at most.
|
|||||||
You can also specify your own format specifiers. In order to do that you can use `el::Helpers::installCustomFormatSpecifier`. A perfect example is `%ip_addr` for TCP server application;
|
You can also specify your own format specifiers. In order to do that you can use `el::Helpers::installCustomFormatSpecifier`. A perfect example is `%ip_addr` for TCP server application;
|
||||||
|
|
||||||
```C++
|
```C++
|
||||||
const char* getIp(void) {
|
const char* getIp(const el::LogMessage*) {
|
||||||
return "192.168.1.1";
|
return "192.168.1.1";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,16 +449,16 @@ int main(void) {
|
|||||||
|
|
||||||
[![top] Goto Top](#table-of-contents)
|
[![top] Goto Top](#table-of-contents)
|
||||||
|
|
||||||
###Logging Flags
|
### Logging Flags
|
||||||
Form some parts of logging you can set logging flags; here are flags supported:
|
Form some parts of logging you can set logging flags; here are flags supported:
|
||||||
|
|
||||||
| Flag | Description |
|
| Flag | Description |
|
||||||
|--------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------|
|
|--------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| `NewLineForContainer (1)` | Makes sure we have new line for each container log entry |
|
| `NewLineForContainer (1)` | Makes sure we have new line for each container log entry |
|
||||||
| `AllowVerboseIfModuleNotSpecified (2)` | Makes sure if -vmodule is used and does not specifies a module, then verbose logging is allowed via that module. Say param was -vmodule=main*=3 and a verbose log is being written from a file called something.cpp then if this flag is enabled, log will be written otherwise it will be disallowed. Note: having this defeats purpose of -vmodule |
|
| `AllowVerboseIfModuleNotSpecified (2)` | Makes sure if -vmodule is used and does not specifies a module, then verbose logging is allowed via that module. Say param was -vmodule=main*=3 and a verbose log is being written from a file called something.cpp then if this flag is enabled, log will be written otherwise it will be disallowed. Note: having this defeats purpose of -vmodule |
|
||||||
| `LogDetailedCrashReason (4)` | When handling crashes by default, detailed crash reason will be logged as well (Disabled by default) ([issue #90](https://github.com/muflihun/easyloggingpp/issues/90)) |
|
| `LogDetailedCrashReason (4)` | When handling crashes by default, detailed crash reason will be logged as well (Disabled by default) ([issue #90](https://github.com/amrayn/easyloggingpp/issues/90)) |
|
||||||
| `DisableApplicationAbortOnFatalLog (8)` | Allows to disable application abortion when logged using FATAL level. Note that this does not apply to default crash handlers as application should be aborted after crash signal is handled. (Not added by default) ([issue #119](https://github.com/muflihun/easyloggingpp/issues/119)) |
|
| `DisableApplicationAbortOnFatalLog (8)` | Allows to disable application abortion when logged using FATAL level. Note that this does not apply to default crash handlers as application should be aborted after crash signal is handled. (Not added by default) ([issue #119](https://github.com/amrayn/easyloggingpp/issues/119)) |
|
||||||
| `ImmediateFlush (16)` | Flushes log with every log-entry (performance sensative) - Disabled by default |
|
| `ImmediateFlush (16)` | Flushes log with every log-entry (performance sensitive) - Disabled by default |
|
||||||
| `StrictLogFileSizeCheck (32)` | Makes sure log file size is checked with every log |
|
| `StrictLogFileSizeCheck (32)` | Makes sure log file size is checked with every log |
|
||||||
| `ColoredTerminalOutput (64)` | Terminal output will be colorful if supported by terminal. |
|
| `ColoredTerminalOutput (64)` | Terminal output will be colorful if supported by terminal. |
|
||||||
| `MultiLoggerSupport (128)` | Enables support for using multiple loggers to log single message. (E.g, `CLOG(INFO, "default", "network") << This will be logged using default and network loggers;`) |
|
| `MultiLoggerSupport (128)` | Enables support for using multiple loggers to log single message. (E.g, `CLOG(INFO, "default", "network") << This will be logged using default and network loggers;`) |
|
||||||
@ -455,7 +468,8 @@ Form some parts of logging you can set logging flags; here are flags supported:
|
|||||||
| `HierarchicalLogging (2048)` | Enables hierarchical logging. This is not applicable to verbose logging.|
|
| `HierarchicalLogging (2048)` | Enables hierarchical logging. This is not applicable to verbose logging.|
|
||||||
| `CreateLoggerAutomatically (4096)` | Creates logger automatically when not available. |
|
| `CreateLoggerAutomatically (4096)` | Creates logger automatically when not available. |
|
||||||
| `AutoSpacing (8192)` | Automatically adds spaces. E.g, `LOG(INFO) << "DODGE" << "THIS!";` will output "DODGE THIS!"|
|
| `AutoSpacing (8192)` | Automatically adds spaces. E.g, `LOG(INFO) << "DODGE" << "THIS!";` will output "DODGE THIS!"|
|
||||||
| `FixedTimeFormat (16384)` | Applicable to performace tracking only - this prevents formatting time. E.g, `1001 ms` will be logged as is, instead of formatting it as `1.01 sec`|
|
| `FixedTimeFormat (16384)` | Applicable to performance tracking only - this prevents formatting time. E.g, `1001 ms` will be logged as is, instead of formatting it as `1.01 sec`|
|
||||||
|
| `IgnoreSigInt (32768)` | When application crashes ignore Interruption signal |
|
||||||
|
|
||||||
You can set/unset these flags by using static `el::Loggers::addFlag` and `el::Loggers::removeFlag`. You can check to see if certain flag is available by using `el::Loggers::hasFlag`, all these functions take strongly-typed enum `el::LoggingFlag`
|
You can set/unset these flags by using static `el::Loggers::addFlag` and `el::Loggers::removeFlag`. You can check to see if certain flag is available by using `el::Loggers::hasFlag`, all these functions take strongly-typed enum `el::LoggingFlag`
|
||||||
|
|
||||||
@ -482,7 +496,11 @@ Following table will explain all command line arguments that you may use to defi
|
|||||||
### Configuration Macros
|
### Configuration Macros
|
||||||
Some of logging options can be set by macros, this is a thoughtful decision, for example if we have `ELPP_THREAD_SAFE` defined, all the thread-safe functionalities are enabled otherwise disabled (making sure over-head of thread-safety goes with it). To make it easy to remember and prevent possible conflicts, all the macros start with `ELPP_`
|
Some of logging options can be set by macros, this is a thoughtful decision, for example if we have `ELPP_THREAD_SAFE` defined, all the thread-safe functionalities are enabled otherwise disabled (making sure over-head of thread-safety goes with it). To make it easy to remember and prevent possible conflicts, all the macros start with `ELPP_`
|
||||||
|
|
||||||
NOTE: All the macros either need to be defined before `#include "easylogging++"` - but this gets hard and unreadable if project is getting bigger so we recommend you define all these macros using `-D` option of compiler, for example in case of `g++` you will do `g++ source.cpp ... -DELPP_SYSLOG -DELPP_THREAD_SAFE ...`
|
**NOTE:** All the macros can be defined in one of the following ways:
|
||||||
|
|
||||||
|
1. Define macros using `-D` option of compiler, for example in case of `g++` you will do `g++ source.cpp ... -DELPP_SYSLOG -DELPP_THREAD_SAFE ...` (**recommended way**)
|
||||||
|
|
||||||
|
2. Define macros inside `"easylogging++.h"` ([defining macros in other files won't work](https://github.com/amrayn/easyloggingpp/issues/590#issuecomment-346753951))
|
||||||
|
|
||||||
| Macro Name | Description |
|
| Macro Name | Description |
|
||||||
|------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------|
|
|------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
@ -500,10 +518,10 @@ NOTE: All the macros either need to be defined before `#include "easylogging++"`
|
|||||||
| `ELPP_DISABLE_FATAL_LOGS` | Disables fatal logs - (preprocessing) |
|
| `ELPP_DISABLE_FATAL_LOGS` | Disables fatal logs - (preprocessing) |
|
||||||
| `ELPP_DISABLE_VERBOSE_LOGS` | Disables verbose logs - (preprocessing) |
|
| `ELPP_DISABLE_VERBOSE_LOGS` | Disables verbose logs - (preprocessing) |
|
||||||
| `ELPP_DISABLE_TRACE_LOGS` | Disables trace logs - (preprocessing) |
|
| `ELPP_DISABLE_TRACE_LOGS` | Disables trace logs - (preprocessing) |
|
||||||
| `ELPP_FORCE_ENV_VAR_FROM_BASH` | If environment variable could not be found, force using alternative bash command to find value, e.g, `whoami` for username. (DO NOT USE THIS MACRO WITH `LD_PRELOAD` FOR LIBRARIES THAT ARE ALREADY USING Easylogging++ OR YOU WILL END UP IN STACK OVERFLOW FOR PROCESSES (`popen`) (see [issue #87](https://github.com/muflihun/easyloggingpp/issues/87) for details)) |
|
| `ELPP_FORCE_ENV_VAR_FROM_BASH` | If environment variable could not be found, force using alternative bash command to find value, e.g, `whoami` for username. (DO NOT USE THIS MACRO WITH `LD_PRELOAD` FOR LIBRARIES THAT ARE ALREADY USING Easylogging++ OR YOU WILL END UP IN STACK OVERFLOW FOR PROCESSES (`popen`) (see [issue #87](https://github.com/amrayn/easyloggingpp/issues/87) for details)) |
|
||||||
| `ELPP_DEFAULT_LOG_FILE` | Full filename where you want initial files to be created. You need to embed value of this macro with quotes, e.g, `-DELPP_DEFAULT_LOG_FILE='"logs/el.gtest.log"'` Note the double quotes inside single quotes, double quotes are the values for `const char*` and single quotes specifies value of macro |
|
| `ELPP_DEFAULT_LOG_FILE` | Full filename where you want initial files to be created. You need to embed value of this macro with quotes, e.g, `-DELPP_DEFAULT_LOG_FILE='"logs/el.gtest.log"'` Note the double quotes inside single quotes, double quotes are the values for `const char*` and single quotes specifies value of macro |
|
||||||
| `ELPP_NO_LOG_TO_FILE` | Disable logging to file initially|
|
| `ELPP_NO_LOG_TO_FILE` | Disable logging to file initially|
|
||||||
| `ELPP_NO_DEFAULT_LOG_FILE` | If you dont want to initialize library with default log file, define this macro. But be sure to configure your logger with propery log filename or you will end up getting heaps of errors when trying to log to file (and `TO_FILE` is configured to `true`) |
|
| `ELPP_NO_DEFAULT_LOG_FILE` | If you dont want to initialize library with default log file, define this macro. This will log to null device for unix and windows. In other platforms you may get error and you will need to use `ELPP_DEFAULT_LOG_FILE`. (PR for other platform's null devices are most welcomed) |
|
||||||
| `ELPP_FRESH_LOG_FILE` | Never appends log file whenever log file is created (Use with care as it may cause some unexpected result for some users) |
|
| `ELPP_FRESH_LOG_FILE` | Never appends log file whenever log file is created (Use with care as it may cause some unexpected result for some users) |
|
||||||
| `ELPP_DEBUG_ERRORS` | If you wish to find out internal errors raised by Easylogging++ that can be because of configuration or something else, you can enable them by defining this macro. You will get your errors on standard output i.e, terminal or command prompt. |
|
| `ELPP_DEBUG_ERRORS` | If you wish to find out internal errors raised by Easylogging++ that can be because of configuration or something else, you can enable them by defining this macro. You will get your errors on standard output i.e, terminal or command prompt. |
|
||||||
| `ELPP_DISABLE_CUSTOM_FORMAT_SPECIFIERS` | Forcefully disables custom format specifiers |
|
| `ELPP_DISABLE_CUSTOM_FORMAT_SPECIFIERS` | Forcefully disables custom format specifiers |
|
||||||
@ -515,6 +533,7 @@ NOTE: All the macros either need to be defined before `#include "easylogging++"`
|
|||||||
| `ELPP_NO_CHECK_MACROS` | Do not define the *CHECK* macros |
|
| `ELPP_NO_CHECK_MACROS` | Do not define the *CHECK* macros |
|
||||||
| `ELPP_NO_DEBUG_MACROS` | Do not define the *DEBUG* macros |
|
| `ELPP_NO_DEBUG_MACROS` | Do not define the *DEBUG* macros |
|
||||||
| `ELPP_UTC_DATETIME` | Uses UTC time instead of local time (essentially uses `gmtime` instead of `localtime` and family functions)
|
| `ELPP_UTC_DATETIME` | Uses UTC time instead of local time (essentially uses `gmtime` instead of `localtime` and family functions)
|
||||||
|
| `ELPP_NO_GLOBAL_LOCK` | Do not lock the whole storage on dispatch. This should be used with care. See [issue #580](https://github.com/amrayn/easyloggingpp/issues/580)|
|
||||||
|
|
||||||
[![top] Goto Top](#table-of-contents)
|
[![top] Goto Top](#table-of-contents)
|
||||||
|
|
||||||
@ -763,7 +782,7 @@ Although this is a rare situation but if you wish to get list of all the logger
|
|||||||
### Sharing Logging Repository
|
### Sharing Logging Repository
|
||||||
For advance logging, you can share your logging repositories to shared or static libraries, or even from library to application. This is rare case but a very good example is as follows;
|
For advance logging, you can share your logging repositories to shared or static libraries, or even from library to application. This is rare case but a very good example is as follows;
|
||||||
|
|
||||||
Let's say we have an application that uses easylogging++ and has it's own configuration, now you are importing library that uses easylogging++ and wants to access logging repository of main application. You can do this using two ways;
|
Let's say we have an application that uses easylogging++ and has its own configuration, now you are importing library that uses easylogging++ and wants to access logging repository of main application. You can do this using two ways;
|
||||||
|
|
||||||
* Instead of using `INITIALIZE_EASYLOGGINGPP` you use `SHARE_EASYLOGGINGPP(access-function-to-repository)`
|
* Instead of using `INITIALIZE_EASYLOGGINGPP` you use `SHARE_EASYLOGGINGPP(access-function-to-repository)`
|
||||||
* Instead of using `INITIALIZE_EASYLOGGINGPP` you use `INITIALIZE_NULL_EASYLOGGINGPP` and then `el::Helpers::setStorage(el::base::type::StoragePointer)`
|
* Instead of using `INITIALIZE_EASYLOGGINGPP` you use `INITIALIZE_NULL_EASYLOGGINGPP` and then `el::Helpers::setStorage(el::base::type::StoragePointer)`
|
||||||
@ -891,7 +910,7 @@ Notes:
|
|||||||
|
|
||||||
4. `TIMED_BLOCK` macro resolves to a single-looped for-loop, so be careful where you define `TIMED_BLOCK`, if for-loop is allowed in the line where you use it, you should have no errors.
|
4. `TIMED_BLOCK` macro resolves to a single-looped for-loop, so be careful where you define `TIMED_BLOCK`, if for-loop is allowed in the line where you use it, you should have no errors.
|
||||||
|
|
||||||
> You may be interested in [python script to parse performance logs](https://github.com/muflihun/easyloggingpp/issues/206)
|
> You may be interested in [python script to parse performance logs](https://github.com/amrayn/easyloggingpp/issues/206)
|
||||||
|
|
||||||
[![top] Goto Top](#table-of-contents)
|
[![top] Goto Top](#table-of-contents)
|
||||||
|
|
||||||
@ -922,9 +941,9 @@ In order to install this handler, use `void Helpers::installPerformanceTrackingC
|
|||||||
### Log File Rotating
|
### Log File Rotating
|
||||||
Easylogging++ has ability to roll out (or throw away / rotate) log files if they reach certain limit. You can configure this by setting `Max_Log_File_Size`. See Configuration section above.
|
Easylogging++ has ability to roll out (or throw away / rotate) log files if they reach certain limit. You can configure this by setting `Max_Log_File_Size`. See Configuration section above.
|
||||||
|
|
||||||
If you are having failure in log-rollout, you may have failed to add flag i.e, `el::LoggingFlags::StrictLogFileSizeCheck`.
|
Rollout checking happens when Easylogging++ flushes the log file, or, if you have added the flag `el::LoggingFlags::StrictLogFileSizeCheck`, at each log output.
|
||||||
|
|
||||||
This feature has it's own section in this reference manual because you can do stuffs with the file being thrown away. This is useful, for example if you wish to back this file up etc.
|
This feature has its own section in this reference manual because you can do stuffs with the file being thrown away. This is useful, for example if you wish to back this file up etc.
|
||||||
This can be done by using `el::Helpers::installPreRollOutCallback(const PreRollOutCallback& handler)` where `PreRollOutCallback` is typedef of type `std::function<void(const char*, std::size_t)>`. Please note following if you are using this feature
|
This can be done by using `el::Helpers::installPreRollOutCallback(const PreRollOutCallback& handler)` where `PreRollOutCallback` is typedef of type `std::function<void(const char*, std::size_t)>`. Please note following if you are using this feature
|
||||||
|
|
||||||
There is a [sample](/samples/STL/logrotate.cpp) available that you can use as basis.
|
There is a [sample](/samples/STL/logrotate.cpp) available that you can use as basis.
|
||||||
@ -1021,7 +1040,7 @@ Easylogging++ supports CHECK macros, with these macros you can quickly check whe
|
|||||||
| `CHECK_GT(a, b)` | Greater than e.g, `CHECK_GT(2, 1) << "How 2 is not greater than 1?";` |
|
| `CHECK_GT(a, b)` | Greater than e.g, `CHECK_GT(2, 1) << "How 2 is not greater than 1?";` |
|
||||||
| `CHECK_LE(a, b)` | Less than or equal e.g, `CHECK_LE(1, 1) << "1 is not equal or less than 1";` |
|
| `CHECK_LE(a, b)` | Less than or equal e.g, `CHECK_LE(1, 1) << "1 is not equal or less than 1";` |
|
||||||
| `CHECK_GE(a, b)` | Greater than or equal e.g, `CHECK_GE(1, 1) << "1 is not equal or greater than 1";` |
|
| `CHECK_GE(a, b)` | Greater than or equal e.g, `CHECK_GE(1, 1) << "1 is not equal or greater than 1";` |
|
||||||
| `CHECK_NOTNULL(pointer)` | Ensures pointer is not null - if OK returns pointer e.g, `explicit MyClass(Obj* obj) : m_obj(CHECK_NOT_NULL(obj)) {}` |
|
| `CHECK_NOTNULL(pointer)` | Ensures pointer is not null. This function does not return anything |
|
||||||
| `CHECK_STREQ(str1, str2)` | C-string equality (case-sensitive) e.g, `CHECK_STREQ(argv[1], "0") << "First arg cannot be 0";` |
|
| `CHECK_STREQ(str1, str2)` | C-string equality (case-sensitive) e.g, `CHECK_STREQ(argv[1], "0") << "First arg cannot be 0";` |
|
||||||
| `CHECK_STRNE(str1, str2)` | C-string inequality (case-sensitive) e.g, `CHECK_STRNE(username1, username2) << "Usernames cannot be same";` |
|
| `CHECK_STRNE(str1, str2)` | C-string inequality (case-sensitive) e.g, `CHECK_STRNE(username1, username2) << "Usernames cannot be same";` |
|
||||||
| `CHECK_STRCASEEQ(str1, str2)` | C-string inequality (*case-insensitive*) e.g, `CHECK_CASESTREQ(argv[1], "Z") << "First arg cannot be 'z' or 'Z'";` |
|
| `CHECK_STRCASEEQ(str1, str2)` | C-string inequality (*case-insensitive*) e.g, `CHECK_CASESTREQ(argv[1], "Z") << "First arg cannot be 'z' or 'Z'";` |
|
||||||
@ -1170,6 +1189,10 @@ You may also have a look at wxWidgets sample
|
|||||||
[![top] Goto Top](#table-of-contents)
|
[![top] Goto Top](#table-of-contents)
|
||||||
|
|
||||||
### Extending Library
|
### Extending Library
|
||||||
|
You can extend this library using various callback handlers and inheritable classes.
|
||||||
|
|
||||||
|
A perfect example of using these features is the logging server built with this library. It's called [Residue](https://github.com/amrayn/residue/) that is feature rich. In fact, you may be interested in using that instead of this library for your medium to large sized projects.
|
||||||
|
|
||||||
#### Logging Your Own Class
|
#### Logging Your Own Class
|
||||||
|
|
||||||
You can log your own classes by extending `el::Loggable` class and implementing pure-virtual function `void log(std::ostream& os) const`. Following example shows a good way to extend a class.
|
You can log your own classes by extending `el::Loggable` class and implementing pure-virtual function `void log(std::ostream& os) const`. Following example shows a good way to extend a class.
|
||||||
@ -1266,12 +1289,86 @@ If you have not set flag `LoggingFlag::StrictLogFileSizeCheck` for some reason,
|
|||||||
### Log Dispatch Callback
|
### Log Dispatch Callback
|
||||||
If you wish to capture log message right after it is dispatched, you can do so by having a class that extends `el::LogDispatchCallback` and implement the pure-virtual functions, then install it at anytime using `el::Helpers::installLogDispatchCallback<T>(const std::string&)`. If you wish to uninstall a pre-installed handler with same ID, you can do so by using `el::Helpers::uninstallLogDispatchCallback<T>(const std::string&)`
|
If you wish to capture log message right after it is dispatched, you can do so by having a class that extends `el::LogDispatchCallback` and implement the pure-virtual functions, then install it at anytime using `el::Helpers::installLogDispatchCallback<T>(const std::string&)`. If you wish to uninstall a pre-installed handler with same ID, you can do so by using `el::Helpers::uninstallLogDispatchCallback<T>(const std::string&)`
|
||||||
|
|
||||||
|
You can use this feature to send it to custom destinations e.g, log stash or TCP client etc.
|
||||||
|
|
||||||
|
You can also look at [send-to-network](/samples/send-to-network) sample for practical usage of this.
|
||||||
|
|
||||||
|
```c++
|
||||||
|
// samples/send-to-network/network-logger.cpp
|
||||||
|
|
||||||
|
#include "easylogging++.h"
|
||||||
|
|
||||||
|
#include <boost/asio.hpp>
|
||||||
|
|
||||||
|
INITIALIZE_EASYLOGGINGPP
|
||||||
|
|
||||||
|
|
||||||
|
class Client
|
||||||
|
{
|
||||||
|
boost::asio::io_service* io_service;
|
||||||
|
boost::asio::ip::tcp::socket socket;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Client(boost::asio::io_service* svc, const std::string& host, const std::string& port)
|
||||||
|
: io_service(svc), socket(*io_service)
|
||||||
|
{
|
||||||
|
boost::asio::ip::tcp::resolver resolver(*io_service);
|
||||||
|
boost::asio::ip::tcp::resolver::iterator endpoint = resolver.resolve(boost::asio::ip::tcp::resolver::query(host, port));
|
||||||
|
boost::asio::connect(this->socket, endpoint);
|
||||||
|
};
|
||||||
|
|
||||||
|
void send(std::string const& message) {
|
||||||
|
socket.send(boost::asio::buffer(message));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class NetworkDispatcher : public el::LogDispatchCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void updateServer(const std::string& host, int port) {
|
||||||
|
m_client = std::unique_ptr<Client>(new Client(&m_svc, host, std::to_string(port)));
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
void handle(const el::LogDispatchData* data) noexcept override {
|
||||||
|
m_data = data;
|
||||||
|
// Dispatch using default log builder of logger
|
||||||
|
dispatch(m_data->logMessage()->logger()->logBuilder()->build(m_data->logMessage(),
|
||||||
|
m_data->dispatchAction() == el::base::DispatchAction::NormalLog));
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
const el::LogDispatchData* m_data;
|
||||||
|
boost::asio::io_service m_svc;
|
||||||
|
std::unique_ptr<Client> m_client;
|
||||||
|
|
||||||
|
void dispatch(el::base::type::string_t&& logLine) noexcept
|
||||||
|
{
|
||||||
|
m_client->send(logLine);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
el::Helpers::installLogDispatchCallback<NetworkDispatcher>("NetworkDispatcher");
|
||||||
|
// you can uninstall default one by
|
||||||
|
// el::Helpers::uninstallLogDispatchCallback<el::base::DefaultLogDispatchCallback>("DefaultLogDispatchCallback");
|
||||||
|
// Set server params
|
||||||
|
NetworkDispatcher* dispatcher = el::Helpers::logDispatchCallback<NetworkDispatcher>("NetworkDispatcher");
|
||||||
|
dispatcher->setEnabled(true);
|
||||||
|
dispatcher->updateServer("127.0.0.1", 9090);
|
||||||
|
|
||||||
|
// Start logging and normal program...
|
||||||
|
LOG(INFO) << "First network log";
|
||||||
|
|
||||||
|
// You can even use a different logger, say "network" and send using a different log pattern
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
> DO NOT LOG ANYTHING IN THIS HANDLER OR YOU WILL END UP IN INFINITE-LOOP
|
> DO NOT LOG ANYTHING IN THIS HANDLER OR YOU WILL END UP IN INFINITE-LOOP
|
||||||
|
|
||||||
[![top] Goto Top](#table-of-contents)
|
[![top] Goto Top](#table-of-contents)
|
||||||
|
|
||||||
### Logger Registration Callback
|
### Logger Registration Callback
|
||||||
If you wish to capture event of logger registration (and potentially want to reconfigure this logger without changing default configuration) you can use `el::LoggerRegistrationCallback`. The syntax is similar to [other callbacks](#log-dispatch-callback). You can use [this sample](https://github.com/muflihun/easyloggingpp/blob/master/samples/STL/new-logger-registration-callback.cpp) as basis.
|
If you wish to capture event of logger registration (and potentially want to reconfigure this logger without changing default configuration) you can use `el::LoggerRegistrationCallback`. The syntax is similar to [other callbacks](#log-dispatch-callback). You can use [this sample](https://github.com/amrayn/easyloggingpp/blob/master/samples/STL/new-logger-registration-callback.cpp) as basis.
|
||||||
|
|
||||||
> DO NOT LOG ANYTHING IN THIS HANDLER
|
> DO NOT LOG ANYTHING IN THIS HANDLER
|
||||||
|
|
||||||
@ -1280,12 +1377,12 @@ If you wish to capture event of logger registration (and potentially want to rec
|
|||||||
### Asynchronous Logging
|
### Asynchronous Logging
|
||||||
Prerequisite: Define macro `ELPP_EXPERIMENTAL_ASYNC`
|
Prerequisite: Define macro `ELPP_EXPERIMENTAL_ASYNC`
|
||||||
|
|
||||||
Asynchronous logging is in experimental stages and they are not widely promoted. You may enable and test this feature by defining macro `ELPP_EXPERIMENTAL_ASYNC` and if you find some issue with the feature please report in [this issue](https://github.com/muflihun/easyloggingpp/issues/202). Reporting issues always help for constant improvements.
|
Asynchronous logging is in experimental stages and they are not widely promoted. You may enable and test this feature by defining macro `ELPP_EXPERIMENTAL_ASYNC` and if you find some issue with the feature please report in [this issue](https://github.com/amrayn/easyloggingpp/issues/202). Reporting issues always help for constant improvements.
|
||||||
|
|
||||||
Please note:
|
Please note:
|
||||||
* Asynchronous will only work with few compilers (it purely uses `std::thread`)
|
* Asynchronous will only work with few compilers (it purely uses `std::thread`)
|
||||||
* Compiler should support `std::this_thread::sleep_for`. This restriction may (or may not) be removed in future (stable) version of asynchronous logging.
|
* Compiler should support `std::this_thread::sleep_for`. This restriction may (or may not) be removed in future (stable) version of asynchronous logging.
|
||||||
* You should not rely on asynchronous logging in production, this is because feature is in experiemental stages.
|
* You should not rely on asynchronous logging in production, this is because feature is in experimental stages.
|
||||||
|
|
||||||
[![top] Goto Top](#table-of-contents)
|
[![top] Goto Top](#table-of-contents)
|
||||||
|
|
||||||
@ -1295,7 +1392,7 @@ There are static helper classes available to make it easy to do stuffs;
|
|||||||
* `el::Helpers`
|
* `el::Helpers`
|
||||||
* `el::Loggers`
|
* `el::Loggers`
|
||||||
|
|
||||||
You can do various cool stuffs using functions in these classes, see [this issue](https://github.com/muflihun/easyloggingpp/issues/210) for instance.
|
You can do various cool stuffs using functions in these classes, see [this issue](https://github.com/amrayn/easyloggingpp/issues/210) for instance.
|
||||||
|
|
||||||
[![top] Goto Top](#table-of-contents)
|
[![top] Goto Top](#table-of-contents)
|
||||||
|
|
||||||
@ -1306,7 +1403,7 @@ You can submit patches to `develop` branch and we will try and merge them. Since
|
|||||||
[![top] Goto Top](#table-of-contents)
|
[![top] Goto Top](#table-of-contents)
|
||||||
|
|
||||||
### Reporting a Bug
|
### Reporting a Bug
|
||||||
If you have found a bug and wish to report it, feel free to do so at [github issue tracker](https://github.com/muflihun/easyloggingpp/issues?state=open). I will try to look at it as soon as possible. Some information should be provided to make it easy to reproduce;
|
If you have found a bug and wish to report it, feel free to do so at [github issue tracker](https://github.com/amrayn/easyloggingpp/issues?state=open). I will try to look at it as soon as possible. Some information should be provided to make it easy to reproduce;
|
||||||
* Platform (OS, Compiler)
|
* Platform (OS, Compiler)
|
||||||
* Log file location
|
* Log file location
|
||||||
* Macros defined (on compilation) OR simple compilation
|
* Macros defined (on compilation) OR simple compilation
|
||||||
@ -1318,11 +1415,11 @@ Try to provide as much information as possible. Any bug with no clear informatio
|
|||||||
|
|
||||||
# Compatibility
|
# Compatibility
|
||||||
|
|
||||||
Easylogging++ requires a decent C++0x complient compiler. Some compilers known to work with v9.0+ are shown in table below, for older versions please refer to readme on corresponding release at github
|
Easylogging++ requires a decent C++0x compliant compiler. Some compilers known to work with v9.0+ are shown in table below, for older versions please refer to readme on corresponding release at github
|
||||||
|
|
||||||
| ***** | Compiler/Platform | Notes |
|
| ***** | Compiler/Platform | Notes |
|
||||||
|---------|---------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|---------|---------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
|![gcc] | GCC 4.7+ | Stack trace logging. Very close to support GCC 4.6 if it had supported strong enum types casting to underlying type. It causes internal compiler error. |
|
|![gcc] | GCC 4.6.4+ | Stack trace logging. Very close to support GCC 4.6.0 if it had supported strong enum types casting to underlying type. It causes internal compiler error. |
|
||||||
|![llvm] | Clang++ 3.1+ | Stack trace logging only with gcc compliant. |
|
|![llvm] | Clang++ 3.1+ | Stack trace logging only with gcc compliant. |
|
||||||
|![intel] | Intel C++ 13.0+ | Workarounds to support: Use if instead of switch on strong enum type. No `final` keyword etc. Stack trace logging only with gcc compliant |
|
|![intel] | Intel C++ 13.0+ | Workarounds to support: Use if instead of switch on strong enum type. No `final` keyword etc. Stack trace logging only with gcc compliant |
|
||||||
|![vcpp] | Visual C++ 11.0+ | Tested with VS2012, VS2013; Use of argument templates instead of variadic templates. CRT warnings control. No stack trace logging. |
|
|![vcpp] | Visual C++ 11.0+ | Tested with VS2012, VS2013; Use of argument templates instead of variadic templates. CRT warnings control. No stack trace logging. |
|
||||||
@ -1348,6 +1445,7 @@ Operating systems that have been tested are shown in table below. Easylogging++
|
|||||||
|![android] | Android | Tested with C4droid (g++) on Galaxy Tab 2 |
|
|![android] | Android | Tested with C4droid (g++) on Galaxy Tab 2 |
|
||||||
|![raspberrypi] | RaspberryPi 7.6 | Tested with 7.6.2-1.1 (gcc version 4.9.1 (Raspbian 4.9.1-1)) by contributor |
|
|![raspberrypi] | RaspberryPi 7.6 | Tested with 7.6.2-1.1 (gcc version 4.9.1 (Raspbian 4.9.1-1)) by contributor |
|
||||||
|![solaris] | Solaris i86 | Tested by contributor |
|
|![solaris] | Solaris i86 | Tested by contributor |
|
||||||
|
|![aix] | IBM AIX | Support added by contributor |
|
||||||
|
|
||||||
Easylogging++ has also been tested with following C++ libraries;
|
Easylogging++ has also been tested with following C++ libraries;
|
||||||
|
|
||||||
@ -1360,14 +1458,32 @@ Easylogging++ has also been tested with following C++ libraries;
|
|||||||
|
|
||||||
[![top] Goto Top](#table-of-contents)
|
[![top] Goto Top](#table-of-contents)
|
||||||
|
|
||||||
|
## Build Matrix
|
||||||
|
|
||||||
|
| Branch | Platform | Build Status |
|
||||||
|
| -------- |:------------:|:------------:|
|
||||||
|
| `develop` | GNU/Linux 4.4 / Ubuntu 4.8.4 64-bit / `clang++` | [](https://travis-ci.org/amrayn/easyloggingpp) |
|
||||||
|
| `develop` | GNU/Linux 4.4 / Ubuntu 4.8.4 64-bit / `g++-4.9` | [](https://travis-ci.org/amrayn/easyloggingpp) |
|
||||||
|
| `develop` | GNU/Linux 4.4 / Ubuntu 4.8.4 64-bit / `g++-5` | [](https://travis-ci.org/amrayn/easyloggingpp) |
|
||||||
|
| `develop` | GNU/Linux 4.4 / Ubuntu 4.8.4 64-bit / `g++-6` | [](https://travis-ci.org/amrayn/easyloggingpp) |
|
||||||
|
| `develop` | GNU/Linux 4.4 / Ubuntu 4.8.4 64-bit / `g++-7` | [](https://travis-ci.org/amrayn/easyloggingpp) |
|
||||||
|
| `master` | GNU/Linux 4.4 / Ubuntu 4.8.4 64-bit / `clang++` | [](https://travis-ci.org/amrayn/easyloggingpp) |
|
||||||
|
| `master` | GNU/Linux 4.4 / Ubuntu 4.8.4 64-bit / `g++-4.9` | [](https://travis-ci.org/amrayn/easyloggingpp) |
|
||||||
|
| `master` | GNU/Linux 4.4 / Ubuntu 4.8.4 64-bit / `g++-5` | [](https://travis-ci.org/amrayn/easyloggingpp) |
|
||||||
|
| `master` | GNU/Linux 4.4 / Ubuntu 4.8.4 64-bit / `g++-6` | [](https://travis-ci.org/amrayn/easyloggingpp) |
|
||||||
|
| `master` | GNU/Linux 4.4 / Ubuntu 4.8.4 64-bit / `g++-7` | [](https://travis-ci.org/amrayn/easyloggingpp) |
|
||||||
|
|
||||||
|
[![top] Goto Top](#table-of-contents)
|
||||||
|
|
||||||
# Licence
|
# Licence
|
||||||
```
|
```
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2017 muflihun.com
|
Copyright (c) 2012-2018 Amrayn Web Services
|
||||||
|
Copyright (c) 2012-2018 @abumusamq
|
||||||
|
|
||||||
https://github.com/muflihun/easyloggingpp
|
https://github.com/amrayn/
|
||||||
https://labs.muflihun.com
|
https://amrayn.com
|
||||||
https://muflihun.com
|
https://muflihun.com
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
@ -1398,38 +1514,38 @@ Icons used in this manual (in compatibility section) are solely for information
|
|||||||
|
|
||||||
[![top] Goto Top](#table-of-contents)
|
[![top] Goto Top](#table-of-contents)
|
||||||
|
|
||||||
[banner]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/banner.png?v=4
|
[banner]: https://amrayn.github.io/easyloggingpp/images/banner.png?v=4
|
||||||
[ubuntu]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/icons/ubuntu.png?v=2
|
[ubuntu]: https://amrayn.github.io/easyloggingpp/images/icons/ubuntu.png?v=2
|
||||||
[mint]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/icons/linux-mint.png?v=2
|
[mint]: https://amrayn.github.io/easyloggingpp/images/icons/linux-mint.png?v=2
|
||||||
[freebsd]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/icons/free-bsd.png?v=2
|
[freebsd]: https://amrayn.github.io/easyloggingpp/images/icons/free-bsd.png?v=2
|
||||||
[sl]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/icons/scientific-linux.png?v=2
|
[sl]: https://amrayn.github.io/easyloggingpp/images/icons/scientific-linux.png?v=2
|
||||||
[fedora]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/icons/fedora.png?v=3
|
[fedora]: https://amrayn.github.io/easyloggingpp/images/icons/fedora.png?v=3
|
||||||
[mac]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/icons/mac-osx.png?v=2
|
[mac]: https://amrayn.github.io/easyloggingpp/images/icons/mac-osx.png?v=2
|
||||||
[winxp]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/icons/windowsxp.png?v=2
|
[winxp]: https://amrayn.github.io/easyloggingpp/images/icons/windowsxp.png?v=2
|
||||||
[win7]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/icons/windows7.png?v=2
|
[win7]: https://amrayn.github.io/easyloggingpp/images/icons/windows7.png?v=2
|
||||||
[win8]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/icons/windows8.png?v=2
|
[win8]: https://amrayn.github.io/easyloggingpp/images/icons/windows8.png?v=2
|
||||||
[win10]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/icons/windows10.png?v=2
|
[win10]: https://amrayn.github.io/easyloggingpp/images/icons/windows10.png?v=2
|
||||||
[qt]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/icons/qt.png?v=3
|
[qt]: https://amrayn.github.io/easyloggingpp/images/icons/qt.png?v=3
|
||||||
[boost]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/icons/boost.png?v=3
|
[boost]: https://amrayn.github.io/easyloggingpp/images/icons/boost.png?v=3
|
||||||
[wxwidgets]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/icons/wxwidgets.png?v=3
|
[wxwidgets]: https://amrayn.github.io/easyloggingpp/images/icons/wxwidgets.png?v=3
|
||||||
[devcpp]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/icons/devcpp.png?v=3
|
[devcpp]: https://amrayn.github.io/easyloggingpp/images/icons/devcpp.png?v=3
|
||||||
[gtkmm]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/icons/gtkmm.png?v=3
|
[gtkmm]: https://amrayn.github.io/easyloggingpp/images/icons/gtkmm.png?v=3
|
||||||
[tdm]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/icons/tdm.png?v=3
|
[tdm]: https://amrayn.github.io/easyloggingpp/images/icons/tdm.png?v=3
|
||||||
[raspberrypi]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/icons/raspberry-pi.png?v=3
|
[raspberrypi]: https://amrayn.github.io/easyloggingpp/images/icons/raspberry-pi.png?v=3
|
||||||
[solaris]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/icons/solaris.png?v=3
|
[solaris]: https://amrayn.github.io/easyloggingpp/images/icons/solaris.png?v=3
|
||||||
|
[aix]: https://amrayn.github.io/easyloggingpp/images/icons/aix.png?v=4
|
||||||
|
|
||||||
|
|
||||||
[gcc]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/icons/gcc.png?v=4
|
[gcc]: https://amrayn.github.io/easyloggingpp/images/icons/gcc.png?v=4
|
||||||
[mingw]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/icons/mingw.png?v=2
|
[mingw]: https://amrayn.github.io/easyloggingpp/images/icons/mingw.png?v=2
|
||||||
[cygwin]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/icons/cygwin.png?v=2
|
[cygwin]: https://amrayn.github.io/easyloggingpp/images/icons/cygwin.png?v=2
|
||||||
[vcpp]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/icons/vcpp.png?v=2
|
[vcpp]: https://amrayn.github.io/easyloggingpp/images/icons/vcpp.png?v=2
|
||||||
[llvm]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/icons/llvm.png?v=2
|
[llvm]: https://amrayn.github.io/easyloggingpp/images/icons/llvm.png?v=2
|
||||||
[intel]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/icons/intel.png?v=2
|
[intel]: https://amrayn.github.io/easyloggingpp/images/icons/intel.png?v=2
|
||||||
[android]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/icons/android.png?v=2
|
[android]: https://amrayn.github.io/easyloggingpp/images/icons/android.png?v=2
|
||||||
[manual]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/help.png?v=3
|
[manual]: https://amrayn.github.io/easyloggingpp/images/help.png?v=3
|
||||||
[download]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/download.png?v=2
|
[download]: https://amrayn.github.io/easyloggingpp/images/download.png?v=2
|
||||||
[samples]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/sample.png?v=2
|
[samples]: https://amrayn.github.io/easyloggingpp/images/sample.png?v=2
|
||||||
[notes]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/notes.png?v=4
|
[notes]: https://amrayn.github.io/easyloggingpp/images/notes.png?v=4
|
||||||
[top]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/up.png?v=4
|
[top]: https://amrayn.github.io/easyloggingpp/images/up.png?v=4
|
||||||
[www]: https://raw.githubusercontent.com/muflihun/easyloggingpp.muflihun.com/master/images/logo-www.png?v=6
|
[www]: https://amrayn.github.io/easyloggingpp/images/logo-www.png?v=6
|
||||||
|
|
||||||
|
@ -6,9 +6,10 @@
|
|||||||
# If ${EASYLOGGINGPP_USE_STATIC_LIBS} is ON then static libs are searched.
|
# If ${EASYLOGGINGPP_USE_STATIC_LIBS} is ON then static libs are searched.
|
||||||
# In these cases ${EASYLOGGINGPP_LIBRARY} is also defined
|
# In these cases ${EASYLOGGINGPP_LIBRARY} is also defined
|
||||||
#
|
#
|
||||||
# (c) 2017 Muflihun Labs
|
# (c) 2017-2018 Amrayn Web Services
|
||||||
#
|
#
|
||||||
# https://github.com/muflihun/easyloggingpp
|
# https://github.com/amrayn/easyloggingpp
|
||||||
|
# https://amrayn.com
|
||||||
# https://muflihun.com
|
# https://muflihun.com
|
||||||
#
|
#
|
||||||
|
|
||||||
|
6
cmake/easyloggingpp.pc.cmakein
Normal file
6
cmake/easyloggingpp.pc.cmakein
Normal file
@ -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}
|
@ -18,7 +18,7 @@ Easylogging++ v9.09 RELEASE NOTES
|
|||||||
= REFACTORING =
|
= REFACTORING =
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
- Seperated writer from dispatcher + log class
|
- Separated writer from dispatcher + log class
|
||||||
|
|
||||||
==========================
|
==========================
|
||||||
= NOTES =
|
= NOTES =
|
||||||
|
@ -12,7 +12,7 @@ Easylogging++ v9.17 RELEASE NOTES
|
|||||||
= IMPROVEMENTS =
|
= IMPROVEMENTS =
|
||||||
=============================
|
=============================
|
||||||
|
|
||||||
- Assertion failure and does not process when configuratoin file does not exist
|
- Assertion failure and does not process when configuration file does not exist
|
||||||
|
|
||||||
==========================
|
==========================
|
||||||
= NOTES =
|
= NOTES =
|
||||||
|
@ -6,14 +6,14 @@ Easylogging++ v9.18 RELEASE NOTES
|
|||||||
= FIXES =
|
= FIXES =
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
- Completely dithced away QA logging even macros unusable
|
- Completely ditched away QA logging even macros unusable
|
||||||
- Fixed some of verbose logging macro expansions
|
- Fixed some of verbose logging macro expansions
|
||||||
|
|
||||||
==========================
|
==========================
|
||||||
= NEW FEATURES =
|
= NEW FEATURES =
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
- Only allow aplha-numeric (+ some symbols) for logger names (issue #105)
|
- Only allow alpha-numeric (+ some symbols) for logger names (issue #105)
|
||||||
- Case insensitive app args (issue #106)
|
- Case insensitive app args (issue #106)
|
||||||
- Helper to reconfigure specific level for all loggers (issue #107)
|
- Helper to reconfigure specific level for all loggers (issue #107)
|
||||||
- DCHECK macros for debug mode checks (issue #108)
|
- DCHECK macros for debug mode checks (issue #108)
|
||||||
|
@ -16,7 +16,7 @@ Easylogging++ v9.21 RELEASE NOTES
|
|||||||
- Configuring same logger twice loses some information (issue #116)
|
- Configuring same logger twice loses some information (issue #116)
|
||||||
|
|
||||||
==========================
|
==========================
|
||||||
= NEW FEATRUES =
|
= NEW FEATURES =
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
- Added base configurations pointer to `parseFromText` same as `parseFromFile`
|
- Added base configurations pointer to `parseFromText` same as `parseFromFile`
|
||||||
|
@ -14,7 +14,7 @@ Easylogging++ v9.25 RELEASE NOTES
|
|||||||
==========================
|
==========================
|
||||||
|
|
||||||
- Default log file using command line args (issue #122)
|
- Default log file using command line args (issue #122)
|
||||||
- Introduced `LoggingFlag::ImmediateFlush` for performance imporvement (issue #127)
|
- Introduced `LoggingFlag::ImmediateFlush` for performance improvement (issue #127)
|
||||||
- Introduced `ConfigurationType::LogFlushThreshold` to manually specify log flush threshold (issue #126)
|
- Introduced `ConfigurationType::LogFlushThreshold` to manually specify log flush threshold (issue #126)
|
||||||
- Introduced `Logger::flush` family and `Loggers::flushAll` family of function to manually flush log files (issue #128)
|
- Introduced `Logger::flush` family and `Loggers::flushAll` family of function to manually flush log files (issue #128)
|
||||||
- Introduced command line arg to enable/disable logging flag using `--logging-flags` param (issue #129)
|
- Introduced command line arg to enable/disable logging flag using `--logging-flags` param (issue #129)
|
||||||
|
@ -21,7 +21,7 @@ API changes: No
|
|||||||
= BUG FIXES =
|
= BUG FIXES =
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
- Double free corrpution when sharing storage
|
- Double free corruption when sharing storage
|
||||||
- Unused variable warning on Windows regarding "nextTok_" (issue #161)
|
- Unused variable warning on Windows regarding "nextTok_" (issue #161)
|
||||||
|
|
||||||
==========================
|
==========================
|
||||||
|
@ -10,6 +10,6 @@ Breaking Change: No
|
|||||||
==========================
|
==========================
|
||||||
|
|
||||||
- Updated github repo
|
- Updated github repo
|
||||||
- See https://github.com/muflihun/easyloggingpp/blob/v9.92/README.md for manual for this release
|
- See https://github.com/amrayn/easyloggingpp/blob/v9.92/README.md for manual for this release
|
||||||
- See https://github.com/muflihun/easyloggingpp/tree/master/doc for other release notes
|
- See https://github.com/amrayn/easyloggingpp/tree/master/doc for other release notes
|
||||||
- Closed issues: https://github.com/muflihun/easyloggingpp/issues?page=1&state=closed
|
- Closed issues: https://github.com/amrayn/easyloggingpp/issues?page=1&state=closed
|
||||||
|
@ -23,6 +23,6 @@ Breaking Change: No
|
|||||||
= NOTES =
|
= NOTES =
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
- See https://github.com/muflihun/easyloggingpp/blob/9.93/README.md for manual for this release
|
- See https://github.com/amrayn/easyloggingpp/blob/9.93/README.md for manual for this release
|
||||||
- See https://github.com/muflihun/easyloggingpp/tree/master/doc for other release notes
|
- See https://github.com/amrayn/easyloggingpp/tree/master/doc for other release notes
|
||||||
- Closed issues: https://github.com/muflihun/easyloggingpp/issues?page=1&state=closed
|
- Closed issues: https://github.com/amrayn/easyloggingpp/issues?page=1&state=closed
|
||||||
|
@ -24,6 +24,6 @@ Breaking Change: No
|
|||||||
= NOTES =
|
= NOTES =
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
- See https://github.com/muflihun/easyloggingpp/blob/9.93/README.md for manual for this release
|
- See https://github.com/amrayn/easyloggingpp/blob/9.93/README.md for manual for this release
|
||||||
- See https://github.com/muflihun/easyloggingpp/tree/master/doc for other release notes
|
- See https://github.com/amrayn/easyloggingpp/tree/master/doc for other release notes
|
||||||
- Closed issues: https://github.com/muflihun/easyloggingpp/issues?page=1&state=closed
|
- Closed issues: https://github.com/amrayn/easyloggingpp/issues?page=1&state=closed
|
||||||
|
17
easyloggingpp.pri
Normal file
17
easyloggingpp.pri
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
QT += core
|
||||||
|
|
||||||
|
CONFIG += c++11
|
||||||
|
|
||||||
|
INCLUDEPATH += $$PWD/src
|
||||||
|
|
||||||
|
DEFINES += ELPP_QT_LOGGING \
|
||||||
|
ELPP_STL_LOGGING \
|
||||||
|
ELPP_STRICT_SIZE_CHECK ELPP_UNICODE \
|
||||||
|
ELPP_MULTI_LOGGER_SUPPORT \
|
||||||
|
ELPP_THREAD_SAFE \
|
||||||
|
ELPP_UNICODE \
|
||||||
|
ELPP_NO_DEFAULT_LOG_FILE
|
||||||
|
|
||||||
|
SOURCES += $$PWD/src/easylogging++.cc
|
||||||
|
|
||||||
|
HEADERS += $$PWD/src/easylogging++.h
|
@ -89,7 +89,7 @@ void ListWithSearch::performSearch(void)
|
|||||||
} else {
|
} else {
|
||||||
LOG(INFO) << "Performing search... [" << txtSearchCriteria->text().toStdString() << "]";
|
LOG(INFO) << "Performing search... [" << txtSearchCriteria->text().toStdString() << "]";
|
||||||
for (int i = items.count() - 1; i >= 0; --i) {
|
for (int i = items.count() - 1; i >= 0; --i) {
|
||||||
if (items.at(i)->text().startsWith(txtSearchCriteria->text(), searchBehaviour_ == kCaseSensative ?
|
if (items.at(i)->text().startsWith(txtSearchCriteria->text(), searchBehaviour_ == kCaseSensitive ?
|
||||||
Qt::CaseSensitive : Qt::CaseInsensitive)) {
|
Qt::CaseSensitive : Qt::CaseInsensitive)) {
|
||||||
list->insertItem(i, items.at(i));
|
list->insertItem(i, items.at(i));
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,9 @@ class ListWithSearch : public QWidget
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
static int kSearchBarHeight;
|
static int kSearchBarHeight;
|
||||||
enum kBehaviour { kCaseInsensative, kCaseSensative };
|
enum kBehaviour { kCaseInsensitive, kCaseSensitive };
|
||||||
|
|
||||||
explicit ListWithSearch(int searchBehaviour_ = kCaseSensative, QWidget *parent = 0);
|
explicit ListWithSearch(int searchBehaviour_ = kCaseSensitive, QWidget *parent = 0);
|
||||||
virtual ~ListWithSearch();
|
virtual ~ListWithSearch();
|
||||||
void add(const QString& item);
|
void add(const QString& item);
|
||||||
void resizeEvent(QResizeEvent *);
|
void resizeEvent(QResizeEvent *);
|
||||||
|
@ -34,7 +34,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
this->setWindowTitle("Fast Dictionary Sample - Easylogging++");
|
this->setWindowTitle("Fast Dictionary Sample - Easylogging++");
|
||||||
list = new ListWithSearch(ListWithSearch::kCaseInsensative, this);
|
list = new ListWithSearch(ListWithSearch::kCaseInsensitive, this);
|
||||||
this->setGeometry(0, 0, 800, 600);
|
this->setGeometry(0, 0, 800, 600);
|
||||||
initializeDictionary("words.txt");
|
initializeDictionary("words.txt");
|
||||||
list->setFocus();
|
list->setFocus();
|
||||||
|
@ -56,7 +56,7 @@
|
|||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string><html><head/><body><p><a href="https://github.com/muflihun/easyloggingpp"><span style=" text-decoration: underline; color:#0000ff;">Github</span></a></p></body></html></string>
|
<string><html><head/><body><p><a href="https://github.com/amrayn/easyloggingpp"><span style=" text-decoration: underline; color:#0000ff;">Github</span></a></p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QLabel" name="label_3">
|
<widget class="QLabel" name="label_3">
|
||||||
|
@ -220,6 +220,6 @@ void PartProcessor::run(void) {
|
|||||||
status = merge();
|
status = merge();
|
||||||
}
|
}
|
||||||
if (status == -1) {
|
if (status == -1) {
|
||||||
LOG(ERROR) << "Error occured while " << (processType == kSplit ? "splitting" : "merging");
|
LOG(ERROR) << "Error occurred while " << (processType == kSplit ? "splitting" : "merging");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1
samples/STL/.gitignore
vendored
1
samples/STL/.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
bin/*
|
bin/*
|
||||||
logs/*
|
logs/*
|
||||||
|
myeasylog.log
|
||||||
|
@ -10,6 +10,7 @@ macro="$macro -DELPP_LOG_UNORDERED_MAP"
|
|||||||
macro="$macro -DELPP_FEATURE_CRASH_LOG"
|
macro="$macro -DELPP_FEATURE_CRASH_LOG"
|
||||||
macro="$macro -DELPP_LOGGING_FLAGS_FROM_ARG"
|
macro="$macro -DELPP_LOGGING_FLAGS_FROM_ARG"
|
||||||
macro="$macro -DELPP_FEATURE_ALL"
|
macro="$macro -DELPP_FEATURE_ALL"
|
||||||
|
macro="$macro -DELPP_NO_GLOBAL_LOCK"
|
||||||
# macro="$macro -DELPP_DEFAULT_LOG_FILE=\"/a/path/that/does/not/exist/f.log\""
|
# macro="$macro -DELPP_DEFAULT_LOG_FILE=\"/a/path/that/does/not/exist/f.log\""
|
||||||
|
|
||||||
if [ "$2" = "" ];then
|
if [ "$2" = "" ];then
|
||||||
@ -18,7 +19,7 @@ else
|
|||||||
COMPILER=$2
|
COMPILER=$2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
CXX_STD='-std=c++0x -pthread'
|
CXX_STD='-std=c++11'
|
||||||
|
|
||||||
if [ "$FILE" = "" ]; then
|
if [ "$FILE" = "" ]; then
|
||||||
echo "Please provide filename to compile"
|
echo "Please provide filename to compile"
|
||||||
@ -27,7 +28,7 @@ fi
|
|||||||
|
|
||||||
echo "Compiling... [$FILE]"
|
echo "Compiling... [$FILE]"
|
||||||
|
|
||||||
COMPILE_LINE="$COMPILER $FILE easylogging++.cc -o bin/$FILE.bin $macro $CXX_STD -Wall -Wextra -pedantic -pedantic-errors -Werror -Wfatal-errors -Wundef -Wunused"
|
COMPILE_LINE="$COMPILER $FILE easylogging++.cc -o bin/$FILE.bin $macro $CXX_STD -pthread -Wall -Wextra -pedantic -pedantic-errors -Werror -Wfatal-errors -Wundef -Wunused"
|
||||||
|
|
||||||
echo " $COMPILE_LINE"
|
echo " $COMPILE_LINE"
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//
|
//
|
||||||
// This file is part of Easylogging++ samples
|
// This file is part of Easylogging++ samples
|
||||||
//
|
//
|
||||||
// Demonstration on how crashes are handled. You can set second argument of this progam to `y`
|
// Demonstration on how crashes are handled. You can set second argument of this program to `y`
|
||||||
// and application will not abort before crash is handled
|
// and application will not abort before crash is handled
|
||||||
//
|
//
|
||||||
// Revision 1.1
|
// Revision 1.1
|
||||||
|
@ -16,9 +16,12 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
el::Logger* defaultLogger = el::Loggers::getLogger("default");
|
el::Logger* defaultLogger = el::Loggers::getLogger("default");
|
||||||
|
|
||||||
|
LOG(INFO) << "Blah";
|
||||||
|
|
||||||
std::vector<int> i;
|
std::vector<int> i;
|
||||||
i.push_back(1);
|
i.push_back(1);
|
||||||
i.push_back(2);
|
i.push_back(2);
|
||||||
|
defaultLogger->info("simple %v", "msg");
|
||||||
defaultLogger->warn("My first ultimate log message %v %v %v", 123, 222, i);
|
defaultLogger->warn("My first ultimate log message %v %v %v", 123, 222, i);
|
||||||
|
|
||||||
// Escaping
|
// Escaping
|
||||||
@ -27,5 +30,6 @@ int main(int argc, char** argv) {
|
|||||||
defaultLogger->verbose(1, "test verbose");
|
defaultLogger->verbose(1, "test verbose");
|
||||||
defaultLogger->verbose(1, "test verbose with args %v", 2);
|
defaultLogger->verbose(1, "test verbose with args %v", 2);
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
39
samples/STL/multi-loggers-to-same-file.cpp
Normal file
39
samples/STL/multi-loggers-to-same-file.cpp
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
//
|
||||||
|
// This file is part of Easylogging++ samples
|
||||||
|
//
|
||||||
|
// Revision 1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
#include "easylogging++.h"
|
||||||
|
|
||||||
|
INITIALIZE_EASYLOGGINGPP
|
||||||
|
|
||||||
|
void def() {
|
||||||
|
for (int i = 0; i < 1000; ++i)
|
||||||
|
CLOG(INFO, "first") << "This is from first " << i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void second() {
|
||||||
|
for (int i = 0; i < 1000; ++i)
|
||||||
|
CLOG(INFO, "second") << "This is from second" << i;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int,char**){
|
||||||
|
el::Loggers::addFlag(el::LoggingFlag::CreateLoggerAutomatically);
|
||||||
|
|
||||||
|
el::Configurations confFromFile("../default-logger.conf");
|
||||||
|
|
||||||
|
el::Loggers::setDefaultConfigurations(confFromFile, true);
|
||||||
|
|
||||||
|
LOG(INFO)<<"The program has started!";
|
||||||
|
|
||||||
|
std::thread t1(def);
|
||||||
|
std::thread t2(second);
|
||||||
|
|
||||||
|
t1.join();
|
||||||
|
t2.join();
|
||||||
|
|
||||||
|
LOG(INFO) << "Shutting down.";
|
||||||
|
return 0;
|
||||||
|
}
|
51
samples/STL/multi-loggers-with-async.cpp
Normal file
51
samples/STL/multi-loggers-with-async.cpp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
//
|
||||||
|
// This file is part of Easylogging++ samples
|
||||||
|
//
|
||||||
|
// Revision 1.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <thread>
|
||||||
|
#include <future>
|
||||||
|
#include "easylogging++.h"
|
||||||
|
|
||||||
|
INITIALIZE_EASYLOGGINGPP
|
||||||
|
|
||||||
|
void f() {
|
||||||
|
std::async(std::launch::async, [&]() {
|
||||||
|
std::cout << "[internal] inside async()" << std::endl;
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
|
LOG(INFO) << "This is from async";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyHandler : public el::LogDispatchCallback {
|
||||||
|
public:
|
||||||
|
void handle(const el::LogDispatchData* d) {
|
||||||
|
std::cout << "Message: " << d->logMessage()->message() << " [logger: " << d->logMessage()->logger()->id() << "]" << std::endl;
|
||||||
|
if (d->logMessage()->logger()->id() != "default") {
|
||||||
|
std::cout << "[internal] calling f()" << std::endl;
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main(int,char**){
|
||||||
|
el::Loggers::addFlag(el::LoggingFlag::CreateLoggerAutomatically);
|
||||||
|
// el::Helpers::uninstallLogDispatchCallback<el::base::DefaultLogDispatchCallback>("DefaultLogDispatchCallback");
|
||||||
|
el::Helpers::installLogDispatchCallback<MyHandler>("MyHandler");
|
||||||
|
|
||||||
|
LOG(INFO)<<"The program has started!";
|
||||||
|
CLOG(INFO, "frommain") << "THis is another";
|
||||||
|
|
||||||
|
std::thread t1([](){
|
||||||
|
LOG(INFO) << "This is from thread";
|
||||||
|
});
|
||||||
|
|
||||||
|
t1.join();
|
||||||
|
|
||||||
|
LOG(INFO) << "Shutting down.";
|
||||||
|
return 0;
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
// This file is part of Easylogging++ samples
|
// This file is part of Easylogging++ samples
|
||||||
//
|
//
|
||||||
// Sample to demonstrate using occasionals and other hit counts based logging
|
// Sample to demonstrate using occasional and other hit count based logging
|
||||||
//
|
//
|
||||||
// Revision 1.2
|
// Revision 1.2
|
||||||
// @author mkhan3189
|
// @author mkhan3189
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
* GLOBAL:
|
* GLOBAL:
|
||||||
FORMAT = "%datetime | %level | %msg"
|
FORMAT = "%datetime | %level | %logger | %msg"
|
||||||
FILENAME = "/tmp/logs/myeasylog-configuration.cpp.log"
|
FILENAME = "/tmp/logs/myeasylog-configuration.cpp.log"
|
||||||
ENABLED = true
|
ENABLED = true
|
||||||
TO_FILE = true
|
TO_FILE = true
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
You can use this sample to send your log messages to network as requested by many users. We are not able to add it to the library as this will require some stuffs to choose what network library to use.
|
You can use this sample to send your log messages to network as requested by many users. We are not able to add it to the library as this will require some stuffs to choose what network library to use.
|
||||||
|
|
||||||
This sample uses `asio` in `boost_system`
|
This sample uses `boost::asio`
|
||||||
|
|
||||||
## Run
|
## Run
|
||||||
|
|
||||||
@ -13,17 +13,15 @@ mkdir bin
|
|||||||
sh compile.sh network-logger.sh
|
sh compile.sh network-logger.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
Run a server (we are using netcat on mac for test purposes) on a different terminal
|
Run a server (we are using netcat on mac for demo) on a new tab in your terminal
|
||||||
|
|
||||||
```
|
```
|
||||||
nc -l 9090
|
nc -k -l 9090
|
||||||
```
|
```
|
||||||
|
|
||||||
Now run `./bin/network-logger`
|
Now run `./bin/network-logger`
|
||||||
|
|
||||||
|
|
||||||
## More
|
## More
|
||||||
|
|
||||||
You may need `ELPP_NO_LOG_TO_FILE` and `ELPP_NO_DEFAULT_LOG_FILE` depending on your needs.
|
Please refer to [doc](https://github.com/amrayn/easyloggingpp#configuration-macros) for further details on macros
|
||||||
|
|
||||||
Please refer to [doc](https://github.com/muflihun/easyloggingpp#configuration-macros) for further details on macros
|
|
||||||
|
@ -17,7 +17,11 @@ fi
|
|||||||
|
|
||||||
echo "Compiling... [$FILE]"
|
echo "Compiling... [$FILE]"
|
||||||
|
|
||||||
COMPILE_LINE="$COMPILER $FILE easylogging++.cc -o bin/$FILE.bin $CXX_STD -std=c++11 -pthread -I /opt/local/include -L/opt/local/lib -lboost_system -Wno-deprecated-declarations"
|
if [ ! -d "bin" ];then
|
||||||
|
mkdir bin
|
||||||
|
fi;
|
||||||
|
|
||||||
|
COMPILE_LINE="$COMPILER $FILE easylogging++.cc -o bin/$FILE.bin $CXX_STD -pthread -lboost_system"
|
||||||
|
|
||||||
echo " $COMPILE_LINE"
|
echo " $COMPILE_LINE"
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
// Revision 1.0
|
// Revision 1.0
|
||||||
// @author mkhan3189
|
// @author mkhan3189
|
||||||
//
|
//
|
||||||
// Compile: g++ network-logger.cpp easylogging++.cc -o bin/network-logger.cpp.bin -std=c++11 -pthread -I /opt/local/include -L/opt/local/lib -lboost_system -Wno-deprecated-declarations
|
// Compile: sh compile.sh network-logger.cpp
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "easylogging++.h"
|
#include "easylogging++.h"
|
||||||
@ -16,16 +16,16 @@
|
|||||||
INITIALIZE_EASYLOGGINGPP
|
INITIALIZE_EASYLOGGINGPP
|
||||||
|
|
||||||
|
|
||||||
// Following Client struct adapted from http://stackoverflow.com/questions/27672591/boost-asio-send-and-receive-messages
|
class Client
|
||||||
struct Client
|
|
||||||
{
|
{
|
||||||
boost::asio::io_service& io_service;
|
boost::asio::io_service* io_service;
|
||||||
boost::asio::ip::tcp::socket socket;
|
boost::asio::ip::tcp::socket socket;
|
||||||
|
|
||||||
Client(boost::asio::io_service& svc, std::string const& host, std::string const& port)
|
public:
|
||||||
: io_service(svc), socket(io_service)
|
Client(boost::asio::io_service* svc, const std::string& host, const std::string& port)
|
||||||
|
: io_service(svc), socket(*io_service)
|
||||||
{
|
{
|
||||||
boost::asio::ip::tcp::resolver resolver(io_service);
|
boost::asio::ip::tcp::resolver resolver(*io_service);
|
||||||
boost::asio::ip::tcp::resolver::iterator endpoint = resolver.resolve(boost::asio::ip::tcp::resolver::query(host, port));
|
boost::asio::ip::tcp::resolver::iterator endpoint = resolver.resolve(boost::asio::ip::tcp::resolver::query(host, port));
|
||||||
boost::asio::connect(this->socket, endpoint);
|
boost::asio::connect(this->socket, endpoint);
|
||||||
};
|
};
|
||||||
@ -38,46 +38,39 @@ struct Client
|
|||||||
class NetworkDispatcher : public el::LogDispatchCallback
|
class NetworkDispatcher : public el::LogDispatchCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Setters
|
void updateServer(const std::string& host, int port) {
|
||||||
void setHost(const std::string& host) {
|
m_client = std::unique_ptr<Client>(new Client(&m_svc, host, std::to_string(port)));
|
||||||
m_host = host;
|
}
|
||||||
}
|
|
||||||
void setPort(int port) {
|
|
||||||
m_port = port;
|
|
||||||
}
|
|
||||||
protected:
|
protected:
|
||||||
void handle(const el::LogDispatchData* data) noexcept override
|
void handle(const el::LogDispatchData* data) noexcept override {
|
||||||
{
|
m_data = data;
|
||||||
m_data = data;
|
// Dispatch using default log builder of logger
|
||||||
// Dispatch using default log builder of logger
|
dispatch(m_data->logMessage()->logger()->logBuilder()->build(m_data->logMessage(),
|
||||||
dispatch(m_data->logMessage()->logger()->logBuilder()->build(m_data->logMessage(),
|
m_data->dispatchAction() == el::base::DispatchAction::NormalLog));
|
||||||
m_data->dispatchAction() == el::base::DispatchAction::NormalLog));
|
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
const el::LogDispatchData* m_data;
|
const el::LogDispatchData* m_data;
|
||||||
std::string m_host;
|
boost::asio::io_service m_svc;
|
||||||
int m_port;
|
std::unique_ptr<Client> m_client;
|
||||||
|
|
||||||
void dispatch(el::base::type::string_t&& logLine) noexcept
|
void dispatch(el::base::type::string_t&& logLine) noexcept
|
||||||
{
|
{
|
||||||
boost::asio::io_service svc;
|
m_client->send(logLine);
|
||||||
Client client(svc, m_host, std::to_string(m_port));
|
|
||||||
|
|
||||||
client.send(logLine);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
el::Helpers::installLogDispatchCallback<NetworkDispatcher>("NetworkDispatcher");
|
el::Helpers::installLogDispatchCallback<NetworkDispatcher>("NetworkDispatcher");
|
||||||
// Set server params
|
// you can uninstall default one by
|
||||||
NetworkDispatcher* dispatcher = el::Helpers::logDispatchCallback<NetworkDispatcher>("NetworkDispatcher");
|
// el::Helpers::uninstallLogDispatchCallback<el::base::DefaultLogDispatchCallback>("DefaultLogDispatchCallback");
|
||||||
dispatcher->setEnabled(true);
|
// Set server params
|
||||||
dispatcher->setHost("127.0.0.1");
|
NetworkDispatcher* dispatcher = el::Helpers::logDispatchCallback<NetworkDispatcher>("NetworkDispatcher");
|
||||||
dispatcher->setPort(9090);
|
dispatcher->setEnabled(true);
|
||||||
|
dispatcher->updateServer("127.0.0.1", 9090);
|
||||||
|
|
||||||
// Start logging and normal program...
|
// Start logging and normal program...
|
||||||
LOG(INFO) << "First network log";
|
LOG(INFO) << "First network log";
|
||||||
|
|
||||||
// You can even use a different logger, say "network" and send using a different log pattern
|
// You can even use a different logger, say "network" and send using a different log pattern
|
||||||
}
|
}
|
@ -1,16 +1,16 @@
|
|||||||
//
|
//
|
||||||
// Bismillah ar-Rahmaan ar-Raheem
|
// Bismillah ar-Rahmaan ar-Raheem
|
||||||
//
|
//
|
||||||
// Easylogging++ v9.95.0
|
// Easylogging++ v9.96.7
|
||||||
// Cross-platform logging library for C++ applications
|
// Cross-platform logging library for C++ applications
|
||||||
//
|
//
|
||||||
// Copyright (c) 2017 muflihun.com
|
// Copyright (c) 2012-2018 Amrayn Web Services
|
||||||
|
// Copyright (c) 2012-2018 @abumusamq
|
||||||
//
|
//
|
||||||
// This library is released under the MIT Licence.
|
// This library is released under the MIT Licence.
|
||||||
// http://labs.muflihun.com/easyloggingpp/licence.php
|
// https://github.com/amrayn/easyloggingpp/blob/master/LICENSE
|
||||||
//
|
//
|
||||||
// https://github.com/muflihun/easyloggingpp
|
// https://amrayn.com
|
||||||
// https://muflihun.github.io/easyloggingpp
|
|
||||||
// http://muflihun.com
|
// http://muflihun.com
|
||||||
//
|
//
|
||||||
|
|
||||||
@ -22,8 +22,95 @@ INITIALIZE_EASYLOGGINGPP
|
|||||||
|
|
||||||
namespace el {
|
namespace el {
|
||||||
|
|
||||||
// el::base::utils
|
// el::base
|
||||||
namespace base {
|
namespace base {
|
||||||
|
// el::base::consts
|
||||||
|
namespace consts {
|
||||||
|
|
||||||
|
// Level log values - These are values that are replaced in place of %level format specifier
|
||||||
|
// Extra spaces after format specifiers are only for readability purposes in log files
|
||||||
|
static const base::type::char_t* kInfoLevelLogValue = ELPP_LITERAL("INFO");
|
||||||
|
static const base::type::char_t* kDebugLevelLogValue = ELPP_LITERAL("DEBUG");
|
||||||
|
static const base::type::char_t* kWarningLevelLogValue = ELPP_LITERAL("WARNING");
|
||||||
|
static const base::type::char_t* kErrorLevelLogValue = ELPP_LITERAL("ERROR");
|
||||||
|
static const base::type::char_t* kFatalLevelLogValue = ELPP_LITERAL("FATAL");
|
||||||
|
static const base::type::char_t* kVerboseLevelLogValue =
|
||||||
|
ELPP_LITERAL("VERBOSE"); // will become VERBOSE-x where x = verbose level
|
||||||
|
static const base::type::char_t* kTraceLevelLogValue = ELPP_LITERAL("TRACE");
|
||||||
|
static const base::type::char_t* kInfoLevelShortLogValue = ELPP_LITERAL("I");
|
||||||
|
static const base::type::char_t* kDebugLevelShortLogValue = ELPP_LITERAL("D");
|
||||||
|
static const base::type::char_t* kWarningLevelShortLogValue = ELPP_LITERAL("W");
|
||||||
|
static const base::type::char_t* kErrorLevelShortLogValue = ELPP_LITERAL("E");
|
||||||
|
static const base::type::char_t* kFatalLevelShortLogValue = ELPP_LITERAL("F");
|
||||||
|
static const base::type::char_t* kVerboseLevelShortLogValue = ELPP_LITERAL("V");
|
||||||
|
static const base::type::char_t* kTraceLevelShortLogValue = ELPP_LITERAL("T");
|
||||||
|
// Format specifiers - These are used to define log format
|
||||||
|
static const base::type::char_t* kAppNameFormatSpecifier = ELPP_LITERAL("%app");
|
||||||
|
static const base::type::char_t* kLoggerIdFormatSpecifier = ELPP_LITERAL("%logger");
|
||||||
|
static const base::type::char_t* kThreadIdFormatSpecifier = ELPP_LITERAL("%thread");
|
||||||
|
static const base::type::char_t* kSeverityLevelFormatSpecifier = ELPP_LITERAL("%level");
|
||||||
|
static const base::type::char_t* kSeverityLevelShortFormatSpecifier = ELPP_LITERAL("%levshort");
|
||||||
|
static const base::type::char_t* kDateTimeFormatSpecifier = ELPP_LITERAL("%datetime");
|
||||||
|
static const base::type::char_t* kLogFileFormatSpecifier = ELPP_LITERAL("%file");
|
||||||
|
static const base::type::char_t* kLogFileBaseFormatSpecifier = ELPP_LITERAL("%fbase");
|
||||||
|
static const base::type::char_t* kLogLineFormatSpecifier = ELPP_LITERAL("%line");
|
||||||
|
static const base::type::char_t* kLogLocationFormatSpecifier = ELPP_LITERAL("%loc");
|
||||||
|
static const base::type::char_t* kLogFunctionFormatSpecifier = ELPP_LITERAL("%func");
|
||||||
|
static const base::type::char_t* kCurrentUserFormatSpecifier = ELPP_LITERAL("%user");
|
||||||
|
static const base::type::char_t* kCurrentHostFormatSpecifier = ELPP_LITERAL("%host");
|
||||||
|
static const base::type::char_t* kMessageFormatSpecifier = ELPP_LITERAL("%msg");
|
||||||
|
static const base::type::char_t* kVerboseLevelFormatSpecifier = ELPP_LITERAL("%vlevel");
|
||||||
|
static const char* kDateTimeFormatSpecifierForFilename = "%datetime";
|
||||||
|
// Date/time
|
||||||
|
static const char* kDays[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
|
||||||
|
static const char* kDaysAbbrev[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
|
||||||
|
static const char* kMonths[12] = { "January", "February", "March", "April", "May", "June", "July", "August",
|
||||||
|
"September", "October", "November", "December"
|
||||||
|
};
|
||||||
|
static const char* kMonthsAbbrev[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
||||||
|
static const char* kDefaultDateTimeFormat = "%Y-%M-%d %H:%m:%s,%g";
|
||||||
|
static const char* kDefaultDateTimeFormatInFilename = "%Y-%M-%d_%H-%m";
|
||||||
|
static const int kYearBase = 1900;
|
||||||
|
static const char* kAm = "AM";
|
||||||
|
static const char* kPm = "PM";
|
||||||
|
// Miscellaneous constants
|
||||||
|
|
||||||
|
static const char* kNullPointer = "nullptr";
|
||||||
|
#if ELPP_VARIADIC_TEMPLATES_SUPPORTED
|
||||||
|
#endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED
|
||||||
|
static const base::type::VerboseLevel kMaxVerboseLevel = 9;
|
||||||
|
static const char* kUnknownUser = "unknown-user";
|
||||||
|
static const char* kUnknownHost = "unknown-host";
|
||||||
|
|
||||||
|
|
||||||
|
//---------------- DEFAULT LOG FILE -----------------------
|
||||||
|
|
||||||
|
#if defined(ELPP_NO_DEFAULT_LOG_FILE)
|
||||||
|
# if ELPP_OS_UNIX
|
||||||
|
static const char* kDefaultLogFile = "/dev/null";
|
||||||
|
# elif ELPP_OS_WINDOWS
|
||||||
|
static const char* kDefaultLogFile = "nul";
|
||||||
|
# endif // ELPP_OS_UNIX
|
||||||
|
#elif defined(ELPP_DEFAULT_LOG_FILE)
|
||||||
|
static const char* kDefaultLogFile = ELPP_DEFAULT_LOG_FILE;
|
||||||
|
#else
|
||||||
|
static const char* kDefaultLogFile = "myeasylog.log";
|
||||||
|
#endif // defined(ELPP_NO_DEFAULT_LOG_FILE)
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG)
|
||||||
|
static const char* kDefaultLogFileParam = "--default-log-file";
|
||||||
|
#endif // !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG)
|
||||||
|
#if defined(ELPP_LOGGING_FLAGS_FROM_ARG)
|
||||||
|
static const char* kLoggingFlagsParam = "--logging-flags";
|
||||||
|
#endif // defined(ELPP_LOGGING_FLAGS_FROM_ARG)
|
||||||
|
static const char* kValidLoggerIdSymbols =
|
||||||
|
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._";
|
||||||
|
static const char* kConfigurationComment = "##";
|
||||||
|
static const char* kConfigurationLevel = "*";
|
||||||
|
static const char* kConfigurationLoggerId = "--";
|
||||||
|
}
|
||||||
|
// el::base::utils
|
||||||
namespace utils {
|
namespace utils {
|
||||||
|
|
||||||
/// @brief Aborts application due with user-defined status
|
/// @brief Aborts application due with user-defined status
|
||||||
@ -205,7 +292,7 @@ Configurations::Configurations(const std::string& configurationFile, bool useDef
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Configurations::parseFromFile(const std::string& configurationFile, Configurations* base) {
|
bool Configurations::parseFromFile(const std::string& configurationFile, Configurations* base) {
|
||||||
// We initial assertion with true because if we have assertion diabled, we want to pass this
|
// We initial assertion with true because if we have assertion disabled, we want to pass this
|
||||||
// check and if assertion is enabled we will have values re-assigned any way.
|
// check and if assertion is enabled we will have values re-assigned any way.
|
||||||
bool assertionPassed = true;
|
bool assertionPassed = true;
|
||||||
ELPP_ASSERT((assertionPassed = base::utils::File::pathExists(configurationFile.c_str(), true)) == true,
|
ELPP_ASSERT((assertionPassed = base::utils::File::pathExists(configurationFile.c_str(), true)) == true,
|
||||||
@ -276,11 +363,7 @@ void Configurations::set(Configuration* conf) {
|
|||||||
|
|
||||||
void Configurations::setToDefault(void) {
|
void Configurations::setToDefault(void) {
|
||||||
setGlobally(ConfigurationType::Enabled, std::string("true"), true);
|
setGlobally(ConfigurationType::Enabled, std::string("true"), true);
|
||||||
#if !defined(ELPP_NO_DEFAULT_LOG_FILE)
|
|
||||||
setGlobally(ConfigurationType::Filename, std::string(base::consts::kDefaultLogFile), true);
|
setGlobally(ConfigurationType::Filename, std::string(base::consts::kDefaultLogFile), true);
|
||||||
#else
|
|
||||||
ELPP_UNUSED(base::consts::kDefaultLogFile);
|
|
||||||
#endif // !defined(ELPP_NO_DEFAULT_LOG_FILE)
|
|
||||||
#if defined(ELPP_NO_LOG_TO_FILE)
|
#if defined(ELPP_NO_LOG_TO_FILE)
|
||||||
setGlobally(ConfigurationType::ToFile, std::string("false"), true);
|
setGlobally(ConfigurationType::ToFile, std::string("false"), true);
|
||||||
#else
|
#else
|
||||||
@ -309,9 +392,7 @@ void Configurations::setRemainingToDefault(void) {
|
|||||||
#else
|
#else
|
||||||
unsafeSetIfNotExist(Level::Global, ConfigurationType::Enabled, std::string("true"));
|
unsafeSetIfNotExist(Level::Global, ConfigurationType::Enabled, std::string("true"));
|
||||||
#endif // defined(ELPP_NO_LOG_TO_FILE)
|
#endif // defined(ELPP_NO_LOG_TO_FILE)
|
||||||
#if !defined(ELPP_NO_DEFAULT_LOG_FILE)
|
|
||||||
unsafeSetIfNotExist(Level::Global, ConfigurationType::Filename, std::string(base::consts::kDefaultLogFile));
|
unsafeSetIfNotExist(Level::Global, ConfigurationType::Filename, std::string(base::consts::kDefaultLogFile));
|
||||||
#endif // !defined(ELPP_NO_DEFAULT_LOG_FILE)
|
|
||||||
unsafeSetIfNotExist(Level::Global, ConfigurationType::ToStandardOutput, std::string("true"));
|
unsafeSetIfNotExist(Level::Global, ConfigurationType::ToStandardOutput, std::string("true"));
|
||||||
unsafeSetIfNotExist(Level::Global, ConfigurationType::SubsecondPrecision, std::string("3"));
|
unsafeSetIfNotExist(Level::Global, ConfigurationType::SubsecondPrecision, std::string("3"));
|
||||||
unsafeSetIfNotExist(Level::Global, ConfigurationType::PerformanceTracking, std::string("true"));
|
unsafeSetIfNotExist(Level::Global, ConfigurationType::PerformanceTracking, std::string("true"));
|
||||||
@ -518,7 +599,7 @@ void LogBuilder::convertToColoredOutput(base::type::string_t* logLine, Level lev
|
|||||||
|
|
||||||
// Logger
|
// Logger
|
||||||
|
|
||||||
Logger::Logger(const std::string& id, base::LogStreamsReferenceMap* logStreamsReference) :
|
Logger::Logger(const std::string& id, base::LogStreamsReferenceMapPtr logStreamsReference) :
|
||||||
m_id(id),
|
m_id(id),
|
||||||
m_typedConfigurations(nullptr),
|
m_typedConfigurations(nullptr),
|
||||||
m_parentApplicationName(std::string()),
|
m_parentApplicationName(std::string()),
|
||||||
@ -528,7 +609,7 @@ Logger::Logger(const std::string& id, base::LogStreamsReferenceMap* logStreamsRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
Logger::Logger(const std::string& id, const Configurations& configurations,
|
Logger::Logger(const std::string& id, const Configurations& configurations,
|
||||||
base::LogStreamsReferenceMap* logStreamsReference) :
|
base::LogStreamsReferenceMapPtr logStreamsReference) :
|
||||||
m_id(id),
|
m_id(id),
|
||||||
m_typedConfigurations(nullptr),
|
m_typedConfigurations(nullptr),
|
||||||
m_parentApplicationName(std::string()),
|
m_parentApplicationName(std::string()),
|
||||||
@ -569,7 +650,6 @@ void Logger::configure(const Configurations& configurations) {
|
|||||||
if (m_typedConfigurations != nullptr) {
|
if (m_typedConfigurations != nullptr) {
|
||||||
Configurations* c = const_cast<Configurations*>(m_typedConfigurations->configurations());
|
Configurations* c = const_cast<Configurations*>(m_typedConfigurations->configurations());
|
||||||
if (c->hasConfiguration(Level::Global, ConfigurationType::Filename)) {
|
if (c->hasConfiguration(Level::Global, ConfigurationType::Filename)) {
|
||||||
// This check is definitely needed for cases like ELPP_NO_DEFAULT_LOG_FILE
|
|
||||||
flush();
|
flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -613,10 +693,11 @@ void Logger::flush(Level level, base::type::fstream_t* fs) {
|
|||||||
}
|
}
|
||||||
if (fs != nullptr) {
|
if (fs != nullptr) {
|
||||||
fs->flush();
|
fs->flush();
|
||||||
std::map<Level, unsigned int>::iterator iter = m_unflushedCount.find(level);
|
std::unordered_map<Level, unsigned int>::iterator iter = m_unflushedCount.find(level);
|
||||||
if (iter != m_unflushedCount.end()) {
|
if (iter != m_unflushedCount.end()) {
|
||||||
iter->second = 0;
|
iter->second = 0;
|
||||||
}
|
}
|
||||||
|
Helpers::validateFileRolling(this, level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -675,10 +756,9 @@ std::size_t File::getSizeOfFile(base::type::fstream_t* fs) {
|
|||||||
if (fs == nullptr) {
|
if (fs == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
std::streampos currPos = fs->tellg();
|
// Since the file stream is appended to or truncated, the current
|
||||||
fs->seekg(0, fs->end);
|
// offset is the file size.
|
||||||
std::size_t size = static_cast<std::size_t>(fs->tellg());
|
std::size_t size = static_cast<std::size_t>(fs->tellg());
|
||||||
fs->seekg(currPos);
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -714,22 +794,22 @@ bool File::createPath(const std::string& path) {
|
|||||||
if (path[0] == '/') {
|
if (path[0] == '/') {
|
||||||
builtPath = "/";
|
builtPath = "/";
|
||||||
}
|
}
|
||||||
currPath = STRTOK(currPath, base::consts::kFilePathSeperator, 0);
|
currPath = STRTOK(currPath, base::consts::kFilePathSeparator, 0);
|
||||||
#elif ELPP_OS_WINDOWS
|
#elif ELPP_OS_WINDOWS
|
||||||
// Use secure functions API
|
// Use secure functions API
|
||||||
char* nextTok_ = nullptr;
|
char* nextTok_ = nullptr;
|
||||||
currPath = STRTOK(currPath, base::consts::kFilePathSeperator, &nextTok_);
|
currPath = STRTOK(currPath, base::consts::kFilePathSeparator, &nextTok_);
|
||||||
ELPP_UNUSED(nextTok_);
|
ELPP_UNUSED(nextTok_);
|
||||||
#endif // ELPP_OS_UNIX
|
#endif // ELPP_OS_UNIX
|
||||||
while (currPath != nullptr) {
|
while (currPath != nullptr) {
|
||||||
builtPath.append(currPath);
|
builtPath.append(currPath);
|
||||||
builtPath.append(base::consts::kFilePathSeperator);
|
builtPath.append(base::consts::kFilePathSeparator);
|
||||||
#if ELPP_OS_UNIX
|
#if ELPP_OS_UNIX
|
||||||
status = mkdir(builtPath.c_str(), ELPP_LOG_PERMS);
|
status = mkdir(builtPath.c_str(), ELPP_LOG_PERMS);
|
||||||
currPath = STRTOK(nullptr, base::consts::kFilePathSeperator, 0);
|
currPath = STRTOK(nullptr, base::consts::kFilePathSeparator, 0);
|
||||||
#elif ELPP_OS_WINDOWS
|
#elif ELPP_OS_WINDOWS
|
||||||
status = _mkdir(builtPath.c_str());
|
status = _mkdir(builtPath.c_str());
|
||||||
currPath = STRTOK(nullptr, base::consts::kFilePathSeperator, &nextTok_);
|
currPath = STRTOK(nullptr, base::consts::kFilePathSeparator, &nextTok_);
|
||||||
#endif // ELPP_OS_UNIX
|
#endif // ELPP_OS_UNIX
|
||||||
}
|
}
|
||||||
if (status == -1) {
|
if (status == -1) {
|
||||||
@ -850,7 +930,7 @@ void Str::replaceFirstWithEscape(base::type::string_t& str, const base::type::st
|
|||||||
std::size_t foundAt = base::type::string_t::npos;
|
std::size_t foundAt = base::type::string_t::npos;
|
||||||
while ((foundAt = str.find(replaceWhat, foundAt + 1)) != base::type::string_t::npos) {
|
while ((foundAt = str.find(replaceWhat, foundAt + 1)) != base::type::string_t::npos) {
|
||||||
if (foundAt > 0 && str[foundAt - 1] == base::consts::kFormatSpecifierChar) {
|
if (foundAt > 0 && str[foundAt - 1] == base::consts::kFormatSpecifierChar) {
|
||||||
str.erase(foundAt > 0 ? foundAt - 1 : 0, 1);
|
str.erase(foundAt - 1, 1);
|
||||||
++foundAt;
|
++foundAt;
|
||||||
} else {
|
} else {
|
||||||
str.replace(foundAt, replaceWhat.length(), replaceWith);
|
str.replace(foundAt, replaceWhat.length(), replaceWith);
|
||||||
@ -933,7 +1013,7 @@ char* Str::clearBuff(char buff[], std::size_t lim) {
|
|||||||
return buff;
|
return buff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Converst wchar* to char*
|
/// @brief Converts wchar* to char*
|
||||||
/// NOTE: Need to free return value after use!
|
/// NOTE: Need to free return value after use!
|
||||||
char* Str::wcharPtrToCharPtr(const wchar_t* line) {
|
char* Str::wcharPtrToCharPtr(const wchar_t* line) {
|
||||||
std::size_t len_ = wcslen(line) + 1;
|
std::size_t len_ = wcslen(line) + 1;
|
||||||
@ -997,8 +1077,9 @@ const std::string OS::getBashOutput(const char* command) {
|
|||||||
char hBuff[4096];
|
char hBuff[4096];
|
||||||
if (fgets(hBuff, sizeof(hBuff), proc) != nullptr) {
|
if (fgets(hBuff, sizeof(hBuff), proc) != nullptr) {
|
||||||
pclose(proc);
|
pclose(proc);
|
||||||
if (hBuff[strlen(hBuff) - 1] == '\n') {
|
const std::size_t buffLen = strlen(hBuff);
|
||||||
hBuff[strlen(hBuff) - 1] = '\0';
|
if (buffLen > 0 && hBuff[buffLen - 1] == '\n') {
|
||||||
|
hBuff[buffLen - 1] = '\0';
|
||||||
}
|
}
|
||||||
return std::string(hBuff);
|
return std::string(hBuff);
|
||||||
} else {
|
} else {
|
||||||
@ -1272,7 +1353,7 @@ bool CommandLineArgs::hasParamWithValue(const char* paramKey) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char* CommandLineArgs::getParamValue(const char* paramKey) const {
|
const char* CommandLineArgs::getParamValue(const char* paramKey) const {
|
||||||
std::map<std::string, std::string>::const_iterator iter = m_paramsWithValue.find(std::string(paramKey));
|
std::unordered_map<std::string, std::string>::const_iterator iter = m_paramsWithValue.find(std::string(paramKey));
|
||||||
return iter != m_paramsWithValue.end() ? iter->second.c_str() : "";
|
return iter != m_paramsWithValue.end() ? iter->second.c_str() : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1418,7 +1499,7 @@ void LogFormat::parseFromFormat(const base::type::string_t& userFormat) {
|
|||||||
if (hasFlag(flag)) {
|
if (hasFlag(flag)) {
|
||||||
// If we already have flag we remove the escape chars so that '%%' is turned to '%'
|
// If we already have flag we remove the escape chars so that '%%' is turned to '%'
|
||||||
// even after specifier resolution - this is because we only replaceFirst specifier
|
// even after specifier resolution - this is because we only replaceFirst specifier
|
||||||
formatCopy.erase(foundAt > 0 ? foundAt - 1 : 0, 1);
|
formatCopy.erase(foundAt - 1, 1);
|
||||||
++foundAt;
|
++foundAt;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1443,7 +1524,7 @@ void LogFormat::parseFromFormat(const base::type::string_t& userFormat) {
|
|||||||
// For date/time we need to extract user's date format first
|
// For date/time we need to extract user's date format first
|
||||||
std::size_t dateIndex = std::string::npos;
|
std::size_t dateIndex = std::string::npos;
|
||||||
if ((dateIndex = formatCopy.find(base::consts::kDateTimeFormatSpecifier)) != std::string::npos) {
|
if ((dateIndex = formatCopy.find(base::consts::kDateTimeFormatSpecifier)) != std::string::npos) {
|
||||||
while (dateIndex > 0 && formatCopy[dateIndex - 1] == base::consts::kFormatSpecifierChar) {
|
while (dateIndex != std::string::npos && dateIndex > 0 && formatCopy[dateIndex - 1] == base::consts::kFormatSpecifierChar) {
|
||||||
dateIndex = formatCopy.find(base::consts::kDateTimeFormatSpecifier, dateIndex + 1);
|
dateIndex = formatCopy.find(base::consts::kDateTimeFormatSpecifier, dateIndex + 1);
|
||||||
}
|
}
|
||||||
if (dateIndex != std::string::npos) {
|
if (dateIndex != std::string::npos) {
|
||||||
@ -1534,7 +1615,7 @@ void LogFormat::updateFormatSpec(void) {
|
|||||||
// TypedConfigurations
|
// TypedConfigurations
|
||||||
|
|
||||||
TypedConfigurations::TypedConfigurations(Configurations* configurations,
|
TypedConfigurations::TypedConfigurations(Configurations* configurations,
|
||||||
base::LogStreamsReferenceMap* logStreamsReference) {
|
LogStreamsReferenceMapPtr logStreamsReference) {
|
||||||
m_configurations = configurations;
|
m_configurations = configurations;
|
||||||
m_logStreamsReference = logStreamsReference;
|
m_logStreamsReference = logStreamsReference;
|
||||||
build(m_configurations);
|
build(m_configurations);
|
||||||
@ -1610,7 +1691,7 @@ void TypedConfigurations::build(Configurations* configurations) {
|
|||||||
// We do not yet configure filename but we will configure in another
|
// We do not yet configure filename but we will configure in another
|
||||||
// loop. This is because if file cannot be created, we will force ToFile
|
// loop. This is because if file cannot be created, we will force ToFile
|
||||||
// to be false. Because configuring logger is not necessarily performance
|
// to be false. Because configuring logger is not necessarily performance
|
||||||
// sensative operation, we can live with another loop; (by the way this loop
|
// sensitive operation, we can live with another loop; (by the way this loop
|
||||||
// is not very heavy either)
|
// is not very heavy either)
|
||||||
} else if (conf->configurationType() == ConfigurationType::Format) {
|
} else if (conf->configurationType() == ConfigurationType::Format) {
|
||||||
setValue(conf->level(), base::LogFormat(conf->level(),
|
setValue(conf->level(), base::LogFormat(conf->level(),
|
||||||
@ -1621,10 +1702,11 @@ void TypedConfigurations::build(Configurations* configurations) {
|
|||||||
} else if (conf->configurationType() == ConfigurationType::PerformanceTracking) {
|
} else if (conf->configurationType() == ConfigurationType::PerformanceTracking) {
|
||||||
setValue(Level::Global, getBool(conf->value()), &m_performanceTrackingMap);
|
setValue(Level::Global, getBool(conf->value()), &m_performanceTrackingMap);
|
||||||
} else if (conf->configurationType() == ConfigurationType::MaxLogFileSize) {
|
} else if (conf->configurationType() == ConfigurationType::MaxLogFileSize) {
|
||||||
setValue(conf->level(), static_cast<std::size_t>(getULong(conf->value())), &m_maxLogFileSizeMap);
|
auto v = getULong(conf->value());
|
||||||
#if !defined(ELPP_NO_DEFAULT_LOG_FILE)
|
setValue(conf->level(), static_cast<std::size_t>(v), &m_maxLogFileSizeMap);
|
||||||
withFileSizeLimit.push_back(conf);
|
if (v != 0) {
|
||||||
#endif // !defined(ELPP_NO_DEFAULT_LOG_FILE)
|
withFileSizeLimit.push_back(conf);
|
||||||
|
}
|
||||||
} else if (conf->configurationType() == ConfigurationType::LogFlushThreshold) {
|
} else if (conf->configurationType() == ConfigurationType::LogFlushThreshold) {
|
||||||
setValue(conf->level(), static_cast<std::size_t>(getULong(conf->value())), &m_logFlushThresholdMap);
|
setValue(conf->level(), static_cast<std::size_t>(getULong(conf->value())), &m_logFlushThresholdMap);
|
||||||
}
|
}
|
||||||
@ -1698,18 +1780,12 @@ std::string TypedConfigurations::resolveFilename(const std::string& filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TypedConfigurations::insertFile(Level level, const std::string& fullFilename) {
|
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);
|
std::string resolvedFilename = resolveFilename(fullFilename);
|
||||||
if (resolvedFilename.empty()) {
|
if (resolvedFilename.empty()) {
|
||||||
std::cerr << "Could not load empty file for logging, please re-check your configurations for level ["
|
std::cerr << "Could not load empty file for logging, please re-check your configurations for level ["
|
||||||
<< LevelHelper::convertToString(level) << "]";
|
<< LevelHelper::convertToString(level) << "]";
|
||||||
}
|
}
|
||||||
std::string filePath = base::utils::File::extractPathFromFilename(resolvedFilename, base::consts::kFilePathSeperator);
|
std::string filePath = base::utils::File::extractPathFromFilename(resolvedFilename, base::consts::kFilePathSeparator);
|
||||||
if (filePath.size() < resolvedFilename.size()) {
|
if (filePath.size() < resolvedFilename.size()) {
|
||||||
base::utils::File::createPath(filePath);
|
base::utils::File::createPath(filePath);
|
||||||
}
|
}
|
||||||
@ -1809,6 +1885,7 @@ bool RegisteredHitCounters::validateNTimes(const char* filename, base::type::Lin
|
|||||||
RegisteredLoggers::RegisteredLoggers(const LogBuilderPtr& defaultLogBuilder) :
|
RegisteredLoggers::RegisteredLoggers(const LogBuilderPtr& defaultLogBuilder) :
|
||||||
m_defaultLogBuilder(defaultLogBuilder) {
|
m_defaultLogBuilder(defaultLogBuilder) {
|
||||||
m_defaultConfigurations.setToDefault();
|
m_defaultConfigurations.setToDefault();
|
||||||
|
m_logStreamsReference = std::make_shared<base::LogStreamsReferenceMap>();
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger* RegisteredLoggers::get(const std::string& id, bool forceCreation) {
|
Logger* RegisteredLoggers::get(const std::string& id, bool forceCreation) {
|
||||||
@ -1820,7 +1897,7 @@ Logger* RegisteredLoggers::get(const std::string& id, bool forceCreation) {
|
|||||||
ELPP_ASSERT(validId, "Invalid logger ID [" << id << "]. Not registering this logger.");
|
ELPP_ASSERT(validId, "Invalid logger ID [" << id << "]. Not registering this logger.");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
logger_ = new Logger(id, m_defaultConfigurations, &m_logStreamsReference);
|
logger_ = new Logger(id, m_defaultConfigurations, m_logStreamsReference);
|
||||||
logger_->m_logBuilder = m_defaultLogBuilder;
|
logger_->m_logBuilder = m_defaultLogBuilder;
|
||||||
registerNew(id, logger_);
|
registerNew(id, logger_);
|
||||||
LoggerRegistrationCallback* callback = nullptr;
|
LoggerRegistrationCallback* callback = nullptr;
|
||||||
@ -1839,8 +1916,10 @@ bool RegisteredLoggers::remove(const std::string& id) {
|
|||||||
if (id == base::consts::kDefaultLoggerId) {
|
if (id == base::consts::kDefaultLoggerId) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// get has internal lock
|
||||||
Logger* logger = base::utils::Registry<Logger, std::string>::get(id);
|
Logger* logger = base::utils::Registry<Logger, std::string>::get(id);
|
||||||
if (logger != nullptr) {
|
if (logger != nullptr) {
|
||||||
|
// unregister has internal lock
|
||||||
unregister(logger);
|
unregister(logger);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -1848,8 +1927,8 @@ bool RegisteredLoggers::remove(const std::string& id) {
|
|||||||
|
|
||||||
void RegisteredLoggers::unsafeFlushAll(void) {
|
void RegisteredLoggers::unsafeFlushAll(void) {
|
||||||
ELPP_INTERNAL_INFO(1, "Flushing all log files");
|
ELPP_INTERNAL_INFO(1, "Flushing all log files");
|
||||||
for (base::LogStreamsReferenceMap::iterator it = m_logStreamsReference.begin();
|
for (base::LogStreamsReferenceMap::iterator it = m_logStreamsReference->begin();
|
||||||
it != m_logStreamsReference.end(); ++it) {
|
it != m_logStreamsReference->end(); ++it) {
|
||||||
if (it->second.get() == nullptr) continue;
|
if (it->second.get() == nullptr) continue;
|
||||||
it->second->flush();
|
it->second->flush();
|
||||||
}
|
}
|
||||||
@ -1948,7 +2027,7 @@ bool VRegistry::allowed(base::type::VerboseLevel vlevel, const char* file) {
|
|||||||
} else {
|
} else {
|
||||||
char baseFilename[base::consts::kSourceFilenameMaxLength] = "";
|
char baseFilename[base::consts::kSourceFilenameMaxLength] = "";
|
||||||
base::utils::File::buildBaseFilename(file, baseFilename);
|
base::utils::File::buildBaseFilename(file, baseFilename);
|
||||||
std::map<std::string, base::type::VerboseLevel>::iterator it = m_modules.begin();
|
std::unordered_map<std::string, base::type::VerboseLevel>::iterator it = m_modules.begin();
|
||||||
for (; it != m_modules.end(); ++it) {
|
for (; it != m_modules.end(); ++it) {
|
||||||
if (base::utils::Str::wildCardMatch(baseFilename, it->first.c_str())) {
|
if (base::utils::Str::wildCardMatch(baseFilename, it->first.c_str())) {
|
||||||
return vlevel <= it->second;
|
return vlevel <= it->second;
|
||||||
@ -1989,20 +2068,26 @@ Storage::Storage(const LogBuilderPtr& defaultLogBuilder) :
|
|||||||
m_registeredLoggers(new base::RegisteredLoggers(defaultLogBuilder)),
|
m_registeredLoggers(new base::RegisteredLoggers(defaultLogBuilder)),
|
||||||
m_flags(ELPP_DEFAULT_LOGGING_FLAGS),
|
m_flags(ELPP_DEFAULT_LOGGING_FLAGS),
|
||||||
m_vRegistry(new base::VRegistry(0, &m_flags)),
|
m_vRegistry(new base::VRegistry(0, &m_flags)),
|
||||||
|
|
||||||
#if ELPP_ASYNC_LOGGING
|
#if ELPP_ASYNC_LOGGING
|
||||||
m_asyncLogQueue(new base::AsyncLogQueue()),
|
m_asyncLogQueue(new base::AsyncLogQueue()),
|
||||||
m_asyncDispatchWorker(asyncDispatchWorker),
|
m_asyncDispatchWorker(asyncDispatchWorker),
|
||||||
#endif // ELPP_ASYNC_LOGGING
|
#endif // ELPP_ASYNC_LOGGING
|
||||||
|
|
||||||
m_preRollOutCallback(base::defaultPreRollOutCallback) {
|
m_preRollOutCallback(base::defaultPreRollOutCallback) {
|
||||||
// Register default logger
|
// Register default logger
|
||||||
m_registeredLoggers->get(std::string(base::consts::kDefaultLoggerId));
|
m_registeredLoggers->get(std::string(base::consts::kDefaultLoggerId));
|
||||||
// We register default logger anyway (worse case it's not going to register) just in case
|
// We register default logger anyway (worse case it's not going to register) just in case
|
||||||
m_registeredLoggers->get("default");
|
m_registeredLoggers->get("default");
|
||||||
|
|
||||||
|
#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING)
|
||||||
// Register performance logger and reconfigure format
|
// Register performance logger and reconfigure format
|
||||||
Logger* performanceLogger = m_registeredLoggers->get(std::string(base::consts::kPerformanceLoggerId));
|
Logger* performanceLogger = m_registeredLoggers->get(std::string(base::consts::kPerformanceLoggerId));
|
||||||
m_registeredLoggers->get("performance");
|
m_registeredLoggers->get("performance");
|
||||||
performanceLogger->configurations()->setGlobally(ConfigurationType::Format, std::string("%datetime %level %msg"));
|
performanceLogger->configurations()->setGlobally(ConfigurationType::Format, std::string("%datetime %level %msg"));
|
||||||
performanceLogger->reconfigure();
|
performanceLogger->reconfigure();
|
||||||
|
#endif // defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING)
|
||||||
|
|
||||||
#if defined(ELPP_SYSLOG)
|
#if defined(ELPP_SYSLOG)
|
||||||
// Register syslog logger and reconfigure format
|
// Register syslog logger and reconfigure format
|
||||||
Logger* sysLogLogger = m_registeredLoggers->get(std::string(base::consts::kSysLogLoggerId));
|
Logger* sysLogLogger = m_registeredLoggers->get(std::string(base::consts::kSysLogLoggerId));
|
||||||
@ -2045,7 +2130,7 @@ Storage::~Storage(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Storage::hasCustomFormatSpecifier(const char* formatSpecifier) {
|
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(),
|
return std::find(m_customFormatSpecifiers.begin(), m_customFormatSpecifiers.end(),
|
||||||
formatSpecifier) != m_customFormatSpecifiers.end();
|
formatSpecifier) != m_customFormatSpecifiers.end();
|
||||||
}
|
}
|
||||||
@ -2054,12 +2139,12 @@ void Storage::installCustomFormatSpecifier(const CustomFormatSpecifier& customFo
|
|||||||
if (hasCustomFormatSpecifier(customFormatSpecifier.formatSpecifier())) {
|
if (hasCustomFormatSpecifier(customFormatSpecifier.formatSpecifier())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
base::threading::ScopedLock scopedLock(lock());
|
base::threading::ScopedLock scopedLock(customFormatSpecifiersLock());
|
||||||
m_customFormatSpecifiers.push_back(customFormatSpecifier);
|
m_customFormatSpecifiers.push_back(customFormatSpecifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Storage::uninstallCustomFormatSpecifier(const char* formatSpecifier) {
|
bool Storage::uninstallCustomFormatSpecifier(const char* formatSpecifier) {
|
||||||
base::threading::ScopedLock scopedLock(lock());
|
base::threading::ScopedLock scopedLock(customFormatSpecifiersLock());
|
||||||
std::vector<CustomFormatSpecifier>::iterator it = std::find(m_customFormatSpecifiers.begin(),
|
std::vector<CustomFormatSpecifier>::iterator it = std::find(m_customFormatSpecifiers.begin(),
|
||||||
m_customFormatSpecifiers.end(), formatSpecifier);
|
m_customFormatSpecifiers.end(), formatSpecifier);
|
||||||
if (it != m_customFormatSpecifiers.end() && strcmp(formatSpecifier, it->formatSpecifier()) == 0) {
|
if (it != m_customFormatSpecifiers.end() && strcmp(formatSpecifier, it->formatSpecifier()) == 0) {
|
||||||
@ -2097,9 +2182,35 @@ void Storage::setApplicationArguments(int argc, char** argv) {
|
|||||||
#endif // defined(ELPP_LOGGING_FLAGS_FROM_ARG)
|
#endif // defined(ELPP_LOGGING_FLAGS_FROM_ARG)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace base
|
||||||
|
|
||||||
|
// LogDispatchCallback
|
||||||
|
#if defined(ELPP_THREAD_SAFE)
|
||||||
|
void LogDispatchCallback::handle(const LogDispatchData* data) {
|
||||||
|
base::threading::ScopedLock scopedLock(m_fileLocksMapLock);
|
||||||
|
std::string filename = data->logMessage()->logger()->typedConfigurations()->filename(data->logMessage()->level());
|
||||||
|
auto lock = m_fileLocks.find(filename);
|
||||||
|
if (lock == m_fileLocks.end()) {
|
||||||
|
m_fileLocks.emplace(std::make_pair(filename, std::unique_ptr<base::threading::Mutex>(new base::threading::Mutex)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void LogDispatchCallback::handle(const LogDispatchData* /*data*/) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
base::threading::Mutex& LogDispatchCallback::fileHandle(const LogDispatchData* data) {
|
||||||
|
auto it = m_fileLocks.find(data->logMessage()->logger()->typedConfigurations()->filename(data->logMessage()->level()));
|
||||||
|
return *(it->second.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace base {
|
||||||
// DefaultLogDispatchCallback
|
// DefaultLogDispatchCallback
|
||||||
|
|
||||||
void DefaultLogDispatchCallback::handle(const LogDispatchData* data) {
|
void DefaultLogDispatchCallback::handle(const LogDispatchData* data) {
|
||||||
|
#if defined(ELPP_THREAD_SAFE)
|
||||||
|
LogDispatchCallback::handle(data);
|
||||||
|
base::threading::ScopedLock scopedLock(fileHandle(data));
|
||||||
|
#endif
|
||||||
m_data = data;
|
m_data = data;
|
||||||
dispatch(m_data->logMessage()->logger()->logBuilder()->build(m_data->logMessage(),
|
dispatch(m_data->logMessage()->logger()->logBuilder()->build(m_data->logMessage(),
|
||||||
m_data->dispatchAction() == base::DispatchAction::NormalLog));
|
m_data->dispatchAction() == base::DispatchAction::NormalLog));
|
||||||
@ -2348,6 +2459,8 @@ base::type::string_t DefaultLogBuilder::build(const LogMessage* logMessage, bool
|
|||||||
base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kMessageFormatSpecifier, logMessage->message());
|
base::utils::Str::replaceFirstWithEscape(logLine, base::consts::kMessageFormatSpecifier, logMessage->message());
|
||||||
}
|
}
|
||||||
#if !defined(ELPP_DISABLE_CUSTOM_FORMAT_SPECIFIERS)
|
#if !defined(ELPP_DISABLE_CUSTOM_FORMAT_SPECIFIERS)
|
||||||
|
el::base::threading::ScopedLock lock_(ELPP->customFormatSpecifiersLock());
|
||||||
|
ELPP_UNUSED(lock_);
|
||||||
for (std::vector<CustomFormatSpecifier>::const_iterator it = ELPP->customFormatSpecifiers()->begin();
|
for (std::vector<CustomFormatSpecifier>::const_iterator it = ELPP->customFormatSpecifiers()->begin();
|
||||||
it != ELPP->customFormatSpecifiers()->end(); ++it) {
|
it != ELPP->customFormatSpecifiers()->end(); ++it) {
|
||||||
std::string fs(it->formatSpecifier());
|
std::string fs(it->formatSpecifier());
|
||||||
@ -2368,10 +2481,15 @@ void LogDispatcher::dispatch(void) {
|
|||||||
if (!m_proceed) {
|
if (!m_proceed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#ifndef ELPP_NO_GLOBAL_LOCK
|
||||||
|
// see https://github.com/muflihun/easyloggingpp/issues/580
|
||||||
|
// global lock is turned on by default unless
|
||||||
|
// ELPP_NO_GLOBAL_LOCK is defined
|
||||||
base::threading::ScopedLock scopedLock(ELPP->lock());
|
base::threading::ScopedLock scopedLock(ELPP->lock());
|
||||||
base::TypedConfigurations* tc = m_logMessage.logger()->m_typedConfigurations;
|
#endif
|
||||||
|
base::TypedConfigurations* tc = m_logMessage->logger()->m_typedConfigurations;
|
||||||
if (ELPP->hasFlag(LoggingFlag::StrictLogFileSizeCheck)) {
|
if (ELPP->hasFlag(LoggingFlag::StrictLogFileSizeCheck)) {
|
||||||
tc->validateFileRolling(m_logMessage.level(), ELPP->preRollOutCallback());
|
tc->validateFileRolling(m_logMessage->level(), ELPP->preRollOutCallback());
|
||||||
}
|
}
|
||||||
LogDispatchCallback* callback = nullptr;
|
LogDispatchCallback* callback = nullptr;
|
||||||
LogDispatchData data;
|
LogDispatchData data;
|
||||||
@ -2379,7 +2497,7 @@ void LogDispatcher::dispatch(void) {
|
|||||||
: ELPP->m_logDispatchCallbacks) {
|
: ELPP->m_logDispatchCallbacks) {
|
||||||
callback = h.second.get();
|
callback = h.second.get();
|
||||||
if (callback != nullptr && callback->enabled()) {
|
if (callback != nullptr && callback->enabled()) {
|
||||||
data.setLogMessage(&m_logMessage);
|
data.setLogMessage(m_logMessage);
|
||||||
data.setDispatchAction(m_dispatchAction);
|
data.setDispatchAction(m_dispatchAction);
|
||||||
callback->handle(&data);
|
callback->handle(&data);
|
||||||
}
|
}
|
||||||
@ -2390,7 +2508,7 @@ void LogDispatcher::dispatch(void) {
|
|||||||
|
|
||||||
void MessageBuilder::initialize(Logger* logger) {
|
void MessageBuilder::initialize(Logger* logger) {
|
||||||
m_logger = logger;
|
m_logger = logger;
|
||||||
m_containerLogSeperator = ELPP->hasFlag(LoggingFlag::NewLineForContainer) ?
|
m_containerLogSeparator = ELPP->hasFlag(LoggingFlag::NewLineForContainer) ?
|
||||||
ELPP_LITERAL("\n ") : ELPP_LITERAL(", ");
|
ELPP_LITERAL("\n ") : ELPP_LITERAL(", ");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2426,6 +2544,7 @@ Writer& Writer::construct(int count, const char* loggerIds, ...) {
|
|||||||
va_list loggersList;
|
va_list loggersList;
|
||||||
va_start(loggersList, loggerIds);
|
va_start(loggersList, loggerIds);
|
||||||
const char* id = loggerIds;
|
const char* id = loggerIds;
|
||||||
|
m_loggerIds.reserve(count);
|
||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
m_loggerIds.push_back(std::string(id));
|
m_loggerIds.push_back(std::string(id));
|
||||||
id = va_arg(loggersList, const char*);
|
id = va_arg(loggersList, const char*);
|
||||||
@ -2444,12 +2563,12 @@ void Writer::initializeLogger(const std::string& loggerId, bool lookup, bool nee
|
|||||||
m_logger = ELPP->registeredLoggers()->get(loggerId, ELPP->hasFlag(LoggingFlag::CreateLoggerAutomatically));
|
m_logger = ELPP->registeredLoggers()->get(loggerId, ELPP->hasFlag(LoggingFlag::CreateLoggerAutomatically));
|
||||||
}
|
}
|
||||||
if (m_logger == nullptr) {
|
if (m_logger == nullptr) {
|
||||||
ELPP->acquireLock();
|
{
|
||||||
if (!ELPP->registeredLoggers()->has(std::string(base::consts::kDefaultLoggerId))) {
|
if (!ELPP->registeredLoggers()->has(std::string(base::consts::kDefaultLoggerId))) {
|
||||||
// Somehow default logger has been unregistered. Not good! Register again
|
// Somehow default logger has been unregistered. Not good! Register again
|
||||||
ELPP->registeredLoggers()->get(std::string(base::consts::kDefaultLoggerId));
|
ELPP->registeredLoggers()->get(std::string(base::consts::kDefaultLoggerId));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ELPP->releaseLock(); // Need to unlock it for next writer
|
|
||||||
Writer(Level::Debug, m_file, m_line, m_func).construct(1, base::consts::kDefaultLoggerId)
|
Writer(Level::Debug, m_file, m_line, m_func).construct(1, base::consts::kDefaultLoggerId)
|
||||||
<< "Logger [" << loggerId << "] is not registered yet!";
|
<< "Logger [" << loggerId << "] is not registered yet!";
|
||||||
m_proceed = false;
|
m_proceed = false;
|
||||||
@ -2509,25 +2628,35 @@ void Writer::processDispatch() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Writer::triggerDispatch(void) {
|
void Writer::triggerDispatch(void) {
|
||||||
if (m_proceed) {
|
try {
|
||||||
base::LogDispatcher(m_proceed, LogMessage(m_level, m_file, m_line, m_func, m_verboseLevel,
|
if (m_proceed) {
|
||||||
m_logger), m_dispatchAction).dispatch();
|
if (m_msg == nullptr) {
|
||||||
}
|
LogMessage msg(m_level, m_file, m_line, m_func, m_verboseLevel,
|
||||||
if (m_logger != nullptr) {
|
m_logger);
|
||||||
m_logger->stream().str(ELPP_LITERAL(""));
|
base::LogDispatcher(m_proceed, &msg, m_dispatchAction).dispatch();
|
||||||
m_logger->releaseLock();
|
} else {
|
||||||
}
|
base::LogDispatcher(m_proceed, m_msg, m_dispatchAction).dispatch();
|
||||||
if (m_proceed && m_level == Level::Fatal
|
}
|
||||||
&& !ELPP->hasFlag(LoggingFlag::DisableApplicationAbortOnFatalLog)) {
|
}
|
||||||
base::Writer(Level::Warning, m_file, m_line, m_func).construct(1, base::consts::kDefaultLoggerId)
|
if (m_logger != nullptr) {
|
||||||
<< "Aborting application. Reason: Fatal log at [" << m_file << ":" << m_line << "]";
|
m_logger->stream().str(ELPP_LITERAL(""));
|
||||||
std::stringstream reasonStream;
|
m_logger->releaseLock();
|
||||||
reasonStream << "Fatal log at [" << m_file << ":" << m_line << "]"
|
}
|
||||||
<< " If you wish to disable 'abort on fatal log' please use "
|
if (m_proceed && m_level == Level::Fatal
|
||||||
<< "el::Helpers::addFlag(el::LoggingFlag::DisableApplicationAbortOnFatalLog)";
|
&& !ELPP->hasFlag(LoggingFlag::DisableApplicationAbortOnFatalLog)) {
|
||||||
base::utils::abort(1, reasonStream.str());
|
base::Writer(Level::Warning, m_file, m_line, m_func).construct(1, base::consts::kDefaultLoggerId)
|
||||||
}
|
<< "Aborting application. Reason: Fatal log at [" << m_file << ":" << m_line << "]";
|
||||||
m_proceed = false;
|
std::stringstream reasonStream;
|
||||||
|
reasonStream << "Fatal log at [" << m_file << ":" << m_line << "]"
|
||||||
|
<< " If you wish to disable 'abort on fatal log' please use "
|
||||||
|
<< "el::Loggers::addFlag(el::LoggingFlag::DisableApplicationAbortOnFatalLog)";
|
||||||
|
base::utils::abort(1, reasonStream.str());
|
||||||
|
}
|
||||||
|
m_proceed = false;
|
||||||
|
}
|
||||||
|
catch(std::exception & ex){
|
||||||
|
// Extremely low memory situation; don't let exception be unhandled.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PErrorWriter
|
// PErrorWriter
|
||||||
@ -2556,7 +2685,7 @@ PerformanceTracker::PerformanceTracker(const std::string& blockName,
|
|||||||
m_level(level), m_hasChecked(false), m_lastCheckpointId(std::string()), m_enabled(false) {
|
m_level(level), m_hasChecked(false), m_lastCheckpointId(std::string()), m_enabled(false) {
|
||||||
#if !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED
|
#if !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED
|
||||||
// We store it locally so that if user happen to change configuration by the end of scope
|
// We store it locally so that if user happen to change configuration by the end of scope
|
||||||
// or before calling checkpoint, we still depend on state of configuraton at time of construction
|
// or before calling checkpoint, we still depend on state of configuration at time of construction
|
||||||
el::Logger* loggerPtr = ELPP->registeredLoggers()->get(loggerId, false);
|
el::Logger* loggerPtr = ELPP->registeredLoggers()->get(loggerId, false);
|
||||||
m_enabled = loggerPtr != nullptr && loggerPtr->m_typedConfigurations->performanceTracking(m_level);
|
m_enabled = loggerPtr != nullptr && loggerPtr->m_typedConfigurations->performanceTracking(m_level);
|
||||||
if (m_enabled) {
|
if (m_enabled) {
|
||||||
@ -2640,18 +2769,19 @@ namespace debug {
|
|||||||
|
|
||||||
// StackTrace
|
// StackTrace
|
||||||
|
|
||||||
StackTrace::StackTraceEntry::StackTraceEntry(std::size_t index, const char* loc, const char* demang, const char* hex,
|
StackTrace::StackTraceEntry::StackTraceEntry(std::size_t index, const std::string& loc, const std::string& demang,
|
||||||
const char* addr) {
|
const std::string& hex,
|
||||||
m_index = index;
|
const std::string& addr) :
|
||||||
m_location = std::string(loc);
|
m_index(index),
|
||||||
m_demangled = std::string(demang);
|
m_location(loc),
|
||||||
m_hex = std::string(hex);
|
m_demangled(demang),
|
||||||
m_addr = std::string(addr);
|
m_hex(hex),
|
||||||
|
m_addr(addr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& ss, const StackTrace::StackTraceEntry& si) {
|
std::ostream& operator<<(std::ostream& ss, const StackTrace::StackTraceEntry& si) {
|
||||||
ss << "[" << si.m_index << "] " << si.m_location << (si.m_demangled.empty() ? "" : ":") << si.m_demangled
|
ss << "[" << si.m_index << "] " << si.m_location << (si.m_hex.empty() ? "" : "+") << si.m_hex << " " << si.m_addr <<
|
||||||
<< (si.m_hex.empty() ? "" : "+") << si.m_hex << si.m_addr;
|
(si.m_demangled.empty() ? "" : ":") << si.m_demangled;
|
||||||
return ss;
|
return ss;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2664,51 +2794,47 @@ std::ostream& operator<<(std::ostream& os, const StackTrace& st) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void StackTrace::generateNew(void) {
|
void StackTrace::generateNew(void) {
|
||||||
#if ELPP_STACKTRACE
|
#ifdef HAVE_EXECINFO
|
||||||
m_stack.clear();
|
m_stack.clear();
|
||||||
void* stack[kMaxStack];
|
void* stack[kMaxStack];
|
||||||
unsigned int size = backtrace(stack, kMaxStack);
|
unsigned int size = backtrace(stack, kMaxStack);
|
||||||
char** strings = backtrace_symbols(stack, size);
|
char** strings = backtrace_symbols(stack, size);
|
||||||
if (size > kStackStart) { // Skip StackTrace c'tor and generateNew
|
if (size > kStackStart) { // Skip StackTrace c'tor and generateNew
|
||||||
for (std::size_t i = kStackStart; i < size; ++i) {
|
for (std::size_t i = kStackStart; i < size; ++i) {
|
||||||
char* mangName = nullptr;
|
std::string mangName;
|
||||||
char* hex = nullptr;
|
std::string location;
|
||||||
char* addr = nullptr;
|
std::string hex;
|
||||||
for (char* c = strings[i]; *c; ++c) {
|
std::string addr;
|
||||||
switch (*c) {
|
|
||||||
case '(':
|
// entry: 2 crash.cpp.bin 0x0000000101552be5 _ZN2el4base5debug10StackTraceC1Ev + 21
|
||||||
mangName = c;
|
const std::string line(strings[i]);
|
||||||
break;
|
auto p = line.find("_");
|
||||||
case '+':
|
if (p != std::string::npos) {
|
||||||
hex = c;
|
mangName = line.substr(p);
|
||||||
break;
|
mangName = mangName.substr(0, mangName.find(" +"));
|
||||||
case ')':
|
}
|
||||||
addr = c;
|
p = line.find("0x");
|
||||||
break;
|
if (p != std::string::npos) {
|
||||||
default:
|
addr = line.substr(p);
|
||||||
break;
|
addr = addr.substr(0, addr.find("_"));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Perform demangling if parsed properly
|
// Perform demangling if parsed properly
|
||||||
if (mangName != nullptr && hex != nullptr && addr != nullptr && mangName < hex) {
|
if (!mangName.empty()) {
|
||||||
*mangName++ = '\0';
|
|
||||||
*hex++ = '\0';
|
|
||||||
*addr++ = '\0';
|
|
||||||
int status = 0;
|
int status = 0;
|
||||||
char* demangName = abi::__cxa_demangle(mangName, 0, 0, &status);
|
char* demangName = abi::__cxa_demangle(mangName.data(), 0, 0, &status);
|
||||||
// if demangling is successful, output the demangled function name
|
// if demangling is successful, output the demangled function name
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
// Success (see http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.3/a01696.html)
|
// Success (see http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.3/a01696.html)
|
||||||
StackTraceEntry entry(i - 1, strings[i], demangName, hex, addr);
|
StackTraceEntry entry(i - 1, location, demangName, hex, addr);
|
||||||
m_stack.push_back(entry);
|
m_stack.push_back(entry);
|
||||||
} else {
|
} else {
|
||||||
// Not successful - we will use mangled name
|
// Not successful - we will use mangled name
|
||||||
StackTraceEntry entry(i - 1, strings[i], mangName, hex, addr);
|
StackTraceEntry entry(i - 1, location, mangName, hex, addr);
|
||||||
m_stack.push_back(entry);
|
m_stack.push_back(entry);
|
||||||
}
|
}
|
||||||
free(demangName);
|
free(demangName);
|
||||||
} else {
|
} else {
|
||||||
StackTraceEntry entry(i - 1, strings[i]);
|
StackTraceEntry entry(i - 1, line);
|
||||||
m_stack.push_back(entry);
|
m_stack.push_back(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2742,6 +2868,9 @@ static std::string crashReason(int sig) {
|
|||||||
}
|
}
|
||||||
/// @brief Logs reason of crash from sig
|
/// @brief Logs reason of crash from sig
|
||||||
static void logCrashReason(int sig, bool stackTraceIfAvailable, Level level, const char* logger) {
|
static void logCrashReason(int sig, bool stackTraceIfAvailable, Level level, const char* logger) {
|
||||||
|
if (sig == SIGINT && ELPP->hasFlag(el::LoggingFlag::IgnoreSigInt)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "CRASH HANDLED; ";
|
ss << "CRASH HANDLED; ";
|
||||||
ss << crashReason(sig);
|
ss << crashReason(sig);
|
||||||
@ -2820,7 +2949,6 @@ void Helpers::logCrashReason(int sig, bool stackTraceIfAvailable, Level level, c
|
|||||||
// Loggers
|
// Loggers
|
||||||
|
|
||||||
Logger* Loggers::getLogger(const std::string& identity, bool registerIfNotAvailable) {
|
Logger* Loggers::getLogger(const std::string& identity, bool registerIfNotAvailable) {
|
||||||
base::threading::ScopedLock scopedLock(ELPP->lock());
|
|
||||||
return ELPP->registeredLoggers()->get(identity, registerIfNotAvailable);
|
return ELPP->registeredLoggers()->get(identity, registerIfNotAvailable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2829,12 +2957,10 @@ void Loggers::setDefaultLogBuilder(el::LogBuilderPtr& logBuilderPtr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Loggers::unregisterLogger(const std::string& identity) {
|
bool Loggers::unregisterLogger(const std::string& identity) {
|
||||||
base::threading::ScopedLock scopedLock(ELPP->lock());
|
|
||||||
return ELPP->registeredLoggers()->remove(identity);
|
return ELPP->registeredLoggers()->remove(identity);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Loggers::hasLogger(const std::string& identity) {
|
bool Loggers::hasLogger(const std::string& identity) {
|
||||||
base::threading::ScopedLock scopedLock(ELPP->lock());
|
|
||||||
return ELPP->registeredLoggers()->has(identity);
|
return ELPP->registeredLoggers()->has(identity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2887,7 +3013,7 @@ const Configurations* Loggers::defaultConfigurations(void) {
|
|||||||
return ELPP->registeredLoggers()->defaultConfigurations();
|
return ELPP->registeredLoggers()->defaultConfigurations();
|
||||||
}
|
}
|
||||||
|
|
||||||
const base::LogStreamsReferenceMap* Loggers::logStreamsReference(void) {
|
const base::LogStreamsReferenceMapPtr Loggers::logStreamsReference(void) {
|
||||||
return ELPP->registeredLoggers()->logStreamsReference();
|
return ELPP->registeredLoggers()->logStreamsReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2984,11 +3110,11 @@ void Loggers::clearVModules(void) {
|
|||||||
// VersionInfo
|
// VersionInfo
|
||||||
|
|
||||||
const std::string VersionInfo::version(void) {
|
const std::string VersionInfo::version(void) {
|
||||||
return std::string("9.95.0");
|
return std::string("9.96.7");
|
||||||
}
|
}
|
||||||
/// @brief Release date of current version
|
/// @brief Release date of current version
|
||||||
const std::string VersionInfo::releaseDate(void) {
|
const std::string VersionInfo::releaseDate(void) {
|
||||||
return std::string("02-08-2017 2312hrs");
|
return std::string("24-11-2018 0728hrs");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace el
|
} // namespace el
|
||||||
|
@ -1,18 +1,19 @@
|
|||||||
//
|
//
|
||||||
// Bismillah ar-Rahmaan ar-Raheem
|
// Bismillah ar-Rahmaan ar-Raheem
|
||||||
//
|
//
|
||||||
// Easylogging++ v9.95.0
|
// Easylogging++ v9.96.7
|
||||||
// Single-header only, cross-platform logging library for C++ applications
|
// Single-header only, cross-platform logging library for C++ applications
|
||||||
//
|
//
|
||||||
// Copyright (c) 2017 muflihun.com
|
// Copyright (c) 2012-2018 Amrayn Web Services
|
||||||
|
// Copyright (c) 2012-2018 @abumusamq
|
||||||
//
|
//
|
||||||
// This library is released under the MIT Licence.
|
// This library is released under the MIT Licence.
|
||||||
// http://labs.muflihun.com/easyloggingpp/licence.php
|
// https://github.com/amrayn/easyloggingpp/blob/master/LICENSE
|
||||||
//
|
//
|
||||||
// https://github.com/muflihun/easyloggingpp
|
// https://amrayn.com
|
||||||
// https://muflihun.github.io/easyloggingpp
|
|
||||||
// http://muflihun.com
|
// http://muflihun.com
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef EASYLOGGINGPP_H
|
#ifndef EASYLOGGINGPP_H
|
||||||
#define EASYLOGGINGPP_H
|
#define EASYLOGGINGPP_H
|
||||||
// Compilers and C++0x/C++11 Evaluation
|
// Compilers and C++0x/C++11 Evaluation
|
||||||
@ -93,7 +94,7 @@
|
|||||||
#else
|
#else
|
||||||
# define ELPP_OS_MAC 0
|
# define ELPP_OS_MAC 0
|
||||||
#endif
|
#endif
|
||||||
#if (defined(__FreeBSD__))
|
#if (defined(__FreeBSD__) || defined(__FreeBSD_kernel__))
|
||||||
# define ELPP_OS_FREEBSD 1
|
# define ELPP_OS_FREEBSD 1
|
||||||
#else
|
#else
|
||||||
# define ELPP_OS_FREEBSD 0
|
# define ELPP_OS_FREEBSD 0
|
||||||
@ -103,13 +104,28 @@
|
|||||||
#else
|
#else
|
||||||
# define ELPP_OS_SOLARIS 0
|
# define ELPP_OS_SOLARIS 0
|
||||||
#endif
|
#endif
|
||||||
|
#if (defined(_AIX))
|
||||||
|
# define ELPP_OS_AIX 1
|
||||||
|
#else
|
||||||
|
# define ELPP_OS_AIX 0
|
||||||
|
#endif
|
||||||
#if (defined(__NetBSD__))
|
#if (defined(__NetBSD__))
|
||||||
# define ELPP_OS_NETBSD 1
|
# define ELPP_OS_NETBSD 1
|
||||||
#else
|
#else
|
||||||
# define ELPP_OS_NETBSD 0
|
# define ELPP_OS_NETBSD 0
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(__EMSCRIPTEN__)
|
||||||
|
# define ELPP_OS_EMSCRIPTEN 1
|
||||||
|
#else
|
||||||
|
# define ELPP_OS_EMSCRIPTEN 0
|
||||||
|
#endif
|
||||||
|
#if (defined(__QNX__) || defined(__QNXNTO__))
|
||||||
|
# define ELPP_OS_QNX 1
|
||||||
|
#else
|
||||||
|
# define ELPP_OS_QNX 0
|
||||||
|
#endif
|
||||||
// Unix
|
// Unix
|
||||||
#if ((ELPP_OS_LINUX || ELPP_OS_MAC || ELPP_OS_FREEBSD || ELPP_OS_NETBSD || ELPP_OS_SOLARIS) && (!ELPP_OS_WINDOWS))
|
#if ((ELPP_OS_LINUX || ELPP_OS_MAC || ELPP_OS_FREEBSD || ELPP_OS_NETBSD || ELPP_OS_SOLARIS || ELPP_OS_AIX || ELPP_OS_EMSCRIPTEN || ELPP_OS_QNX) && (!ELPP_OS_WINDOWS))
|
||||||
# define ELPP_OS_UNIX 1
|
# define ELPP_OS_UNIX 1
|
||||||
#else
|
#else
|
||||||
# define ELPP_OS_UNIX 0
|
# define ELPP_OS_UNIX 0
|
||||||
@ -194,7 +210,7 @@ ELPP_INTERNAL_DEBUGGING_OUT_INFO << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStre
|
|||||||
# define ELPP_INTERNAL_INFO(lvl, msg)
|
# define ELPP_INTERNAL_INFO(lvl, msg)
|
||||||
#endif // (defined(ELPP_DEBUG_INFO))
|
#endif // (defined(ELPP_DEBUG_INFO))
|
||||||
#if (defined(ELPP_FEATURE_ALL)) || (defined(ELPP_FEATURE_CRASH_LOG))
|
#if (defined(ELPP_FEATURE_ALL)) || (defined(ELPP_FEATURE_CRASH_LOG))
|
||||||
# if (ELPP_COMPILER_GCC && !ELPP_MINGW && !ELPP_OS_ANDROID)
|
# if (ELPP_COMPILER_GCC && !ELPP_MINGW && !ELPP_CYGWIN && !ELPP_OS_ANDROID && !ELPP_OS_EMSCRIPTEN && !ELPP_OS_QNX)
|
||||||
# define ELPP_STACKTRACE 1
|
# define ELPP_STACKTRACE 1
|
||||||
# else
|
# else
|
||||||
# if ELPP_COMPILER_MSVC
|
# if ELPP_COMPILER_MSVC
|
||||||
@ -349,10 +365,10 @@ ELPP_INTERNAL_DEBUGGING_OUT_INFO << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStre
|
|||||||
# include <codecvt>
|
# include <codecvt>
|
||||||
# endif // ELPP_OS_WINDOWS
|
# endif // ELPP_OS_WINDOWS
|
||||||
#endif // defined(ELPP_UNICODE)
|
#endif // defined(ELPP_UNICODE)
|
||||||
#if ELPP_STACKTRACE
|
#ifdef HAVE_EXECINFO
|
||||||
# include <cxxabi.h>
|
# include <cxxabi.h>
|
||||||
# include <execinfo.h>
|
# include <execinfo.h>
|
||||||
#endif // ELPP_STACKTRACE
|
#endif // ENABLE_EXECINFO
|
||||||
#if ELPP_OS_ANDROID
|
#if ELPP_OS_ANDROID
|
||||||
# include <sys/system_properties.h>
|
# include <sys/system_properties.h>
|
||||||
#endif // ELPP_OS_ANDROID
|
#endif // ELPP_OS_ANDROID
|
||||||
@ -373,6 +389,7 @@ ELPP_INTERNAL_DEBUGGING_OUT_INFO << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStre
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -410,9 +427,6 @@ ELPP_INTERNAL_DEBUGGING_OUT_INFO << ELPP_INTERNAL_DEBUGGING_MSG(internalInfoStre
|
|||||||
# if defined(ELPP_LOG_STD_ARRAY)
|
# if defined(ELPP_LOG_STD_ARRAY)
|
||||||
# include <array>
|
# include <array>
|
||||||
# endif // defined(ELPP_LOG_STD_ARRAY)
|
# endif // defined(ELPP_LOG_STD_ARRAY)
|
||||||
# if defined(ELPP_LOG_UNORDERED_MAP)
|
|
||||||
# include <unordered_map>
|
|
||||||
# endif // defined(ELPP_LOG_UNORDERED_MAP)
|
|
||||||
# if defined(ELPP_LOG_UNORDERED_SET)
|
# if defined(ELPP_LOG_UNORDERED_SET)
|
||||||
# include <unordered_set>
|
# include <unordered_set>
|
||||||
# endif // defined(ELPP_UNORDERED_SET)
|
# endif // defined(ELPP_UNORDERED_SET)
|
||||||
@ -571,7 +585,7 @@ enum class Level : base::type::EnumType {
|
|||||||
Fatal = 8,
|
Fatal = 8,
|
||||||
/// @brief Information representing errors in application but application will keep running
|
/// @brief Information representing errors in application but application will keep running
|
||||||
Error = 16,
|
Error = 16,
|
||||||
/// @brief Useful when application has potentially harmful situtaions
|
/// @brief Useful when application has potentially harmful situations
|
||||||
Warning = 32,
|
Warning = 32,
|
||||||
/// @brief Information that can be highly useful and vary with verbose logging level.
|
/// @brief Information that can be highly useful and vary with verbose logging level.
|
||||||
Verbose = 64,
|
Verbose = 64,
|
||||||
@ -580,6 +594,16 @@ enum class Level : base::type::EnumType {
|
|||||||
/// @brief Represents unknown level
|
/// @brief Represents unknown level
|
||||||
Unknown = 1010
|
Unknown = 1010
|
||||||
};
|
};
|
||||||
|
} // namespace el
|
||||||
|
namespace std {
|
||||||
|
template<> struct hash<el::Level> {
|
||||||
|
public:
|
||||||
|
std::size_t operator()(const el::Level& l) const {
|
||||||
|
return hash<el::base::type::EnumType> {}(static_cast<el::base::type::EnumType>(l));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
namespace el {
|
||||||
/// @brief Static class that contains helper functions for el::Level
|
/// @brief Static class that contains helper functions for el::Level
|
||||||
class LevelHelper : base::StaticClass {
|
class LevelHelper : base::StaticClass {
|
||||||
public:
|
public:
|
||||||
@ -621,7 +645,7 @@ enum class ConfigurationType : base::type::EnumType {
|
|||||||
ToStandardOutput = 4,
|
ToStandardOutput = 4,
|
||||||
/// @brief Determines format of logging corresponding level and logger.
|
/// @brief Determines format of logging corresponding level and logger.
|
||||||
Format = 8,
|
Format = 8,
|
||||||
/// @brief Determines log file (full path) to write logs to for correponding level and logger
|
/// @brief Determines log file (full path) to write logs to for corresponding level and logger
|
||||||
Filename = 16,
|
Filename = 16,
|
||||||
/// @brief Specifies precision of the subsecond part. It should be within range (1-6).
|
/// @brief Specifies precision of the subsecond part. It should be within range (1-6).
|
||||||
SubsecondPrecision = 32,
|
SubsecondPrecision = 32,
|
||||||
@ -652,7 +676,7 @@ class ConfigurationTypeHelper : base::StaticClass {
|
|||||||
static base::type::EnumType castToInt(ConfigurationType configurationType) {
|
static base::type::EnumType castToInt(ConfigurationType configurationType) {
|
||||||
return static_cast<base::type::EnumType>(configurationType);
|
return static_cast<base::type::EnumType>(configurationType);
|
||||||
}
|
}
|
||||||
/// @brief Casts int(ushort) to configurationt type, useful for iterating through enum.
|
/// @brief Casts int(ushort) to configuration type, useful for iterating through enum.
|
||||||
static ConfigurationType castFromInt(base::type::EnumType c) {
|
static ConfigurationType castFromInt(base::type::EnumType c) {
|
||||||
return static_cast<ConfigurationType>(c);
|
return static_cast<ConfigurationType>(c);
|
||||||
}
|
}
|
||||||
@ -681,7 +705,7 @@ enum class LoggingFlag : base::type::EnumType {
|
|||||||
LogDetailedCrashReason = 4,
|
LogDetailedCrashReason = 4,
|
||||||
/// @brief Allows to disable application abortion when logged using FATAL level
|
/// @brief Allows to disable application abortion when logged using FATAL level
|
||||||
DisableApplicationAbortOnFatalLog = 8,
|
DisableApplicationAbortOnFatalLog = 8,
|
||||||
/// @brief Flushes log with every log-entry (performance sensative) - Disabled by default
|
/// @brief Flushes log with every log-entry (performance sensitive) - Disabled by default
|
||||||
ImmediateFlush = 16,
|
ImmediateFlush = 16,
|
||||||
/// @brief Enables strict file rolling
|
/// @brief Enables strict file rolling
|
||||||
StrictLogFileSizeCheck = 32,
|
StrictLogFileSizeCheck = 32,
|
||||||
@ -702,115 +726,43 @@ enum class LoggingFlag : base::type::EnumType {
|
|||||||
/// @brief Adds spaces b/w logs that separated by left-shift operator
|
/// @brief Adds spaces b/w logs that separated by left-shift operator
|
||||||
AutoSpacing = 8192,
|
AutoSpacing = 8192,
|
||||||
/// @brief Preserves time format and does not convert it to sec, hour etc (performance tracking only)
|
/// @brief Preserves time format and does not convert it to sec, hour etc (performance tracking only)
|
||||||
FixedTimeFormat = 16384
|
FixedTimeFormat = 16384,
|
||||||
|
// @brief Ignore SIGINT or crash
|
||||||
|
IgnoreSigInt = 32768,
|
||||||
};
|
};
|
||||||
namespace base {
|
namespace base {
|
||||||
/// @brief Namespace containing constants used internally.
|
/// @brief Namespace containing constants used internally.
|
||||||
namespace consts {
|
namespace consts {
|
||||||
#if defined(__GNUC__) && !defined(__clang__)
|
static const char kFormatSpecifierCharValue = 'v';
|
||||||
#pragma GCC diagnostic push
|
static const char kFormatSpecifierChar = '%';
|
||||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
static const unsigned int kMaxLogPerCounter = 100000;
|
||||||
#endif
|
static const unsigned int kMaxLogPerContainer = 100;
|
||||||
// Level log values - These are values that are replaced in place of %level format specifier
|
static const unsigned int kDefaultSubsecondPrecision = 3;
|
||||||
// Extra spaces after format specifiers are only for readability purposes in log files
|
|
||||||
static const base::type::char_t* kInfoLevelLogValue = ELPP_LITERAL("INFO");
|
|
||||||
static const base::type::char_t* kDebugLevelLogValue = ELPP_LITERAL("DEBUG");
|
|
||||||
static const base::type::char_t* kWarningLevelLogValue = ELPP_LITERAL("WARNING");
|
|
||||||
static const base::type::char_t* kErrorLevelLogValue = ELPP_LITERAL("ERROR");
|
|
||||||
static const base::type::char_t* kFatalLevelLogValue = ELPP_LITERAL("FATAL");
|
|
||||||
static const base::type::char_t* kVerboseLevelLogValue =
|
|
||||||
ELPP_LITERAL("VERBOSE"); // will become VERBOSE-x where x = verbose level
|
|
||||||
static const base::type::char_t* kTraceLevelLogValue = ELPP_LITERAL("TRACE");
|
|
||||||
static const base::type::char_t* kInfoLevelShortLogValue = ELPP_LITERAL("I");
|
|
||||||
static const base::type::char_t* kDebugLevelShortLogValue = ELPP_LITERAL("D");
|
|
||||||
static const base::type::char_t* kWarningLevelShortLogValue = ELPP_LITERAL("W");
|
|
||||||
static const base::type::char_t* kErrorLevelShortLogValue = ELPP_LITERAL("E");
|
|
||||||
static const base::type::char_t* kFatalLevelShortLogValue = ELPP_LITERAL("F");
|
|
||||||
static const base::type::char_t* kVerboseLevelShortLogValue = ELPP_LITERAL("V");
|
|
||||||
static const base::type::char_t* kTraceLevelShortLogValue = ELPP_LITERAL("T");
|
|
||||||
// Format specifiers - These are used to define log format
|
|
||||||
static const base::type::char_t* kAppNameFormatSpecifier = ELPP_LITERAL("%app");
|
|
||||||
static const base::type::char_t* kLoggerIdFormatSpecifier = ELPP_LITERAL("%logger");
|
|
||||||
static const base::type::char_t* kThreadIdFormatSpecifier = ELPP_LITERAL("%thread");
|
|
||||||
static const base::type::char_t* kSeverityLevelFormatSpecifier = ELPP_LITERAL("%level");
|
|
||||||
static const base::type::char_t* kSeverityLevelShortFormatSpecifier = ELPP_LITERAL("%levshort");
|
|
||||||
static const base::type::char_t* kDateTimeFormatSpecifier = ELPP_LITERAL("%datetime");
|
|
||||||
static const base::type::char_t* kLogFileFormatSpecifier = ELPP_LITERAL("%file");
|
|
||||||
static const base::type::char_t* kLogFileBaseFormatSpecifier = ELPP_LITERAL("%fbase");
|
|
||||||
static const base::type::char_t* kLogLineFormatSpecifier = ELPP_LITERAL("%line");
|
|
||||||
static const base::type::char_t* kLogLocationFormatSpecifier = ELPP_LITERAL("%loc");
|
|
||||||
static const base::type::char_t* kLogFunctionFormatSpecifier = ELPP_LITERAL("%func");
|
|
||||||
static const base::type::char_t* kCurrentUserFormatSpecifier = ELPP_LITERAL("%user");
|
|
||||||
static const base::type::char_t* kCurrentHostFormatSpecifier = ELPP_LITERAL("%host");
|
|
||||||
static const base::type::char_t* kMessageFormatSpecifier = ELPP_LITERAL("%msg");
|
|
||||||
static const base::type::char_t* kVerboseLevelFormatSpecifier = ELPP_LITERAL("%vlevel");
|
|
||||||
static const char* kDateTimeFormatSpecifierForFilename = "%datetime";
|
|
||||||
// Date/time
|
|
||||||
static const char* kDays[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
|
|
||||||
static const char* kDaysAbbrev[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
|
|
||||||
static const char* kMonths[12] = { "January", "February", "March", "Apri", "May", "June", "July", "August",
|
|
||||||
"September", "October", "November", "December"
|
|
||||||
};
|
|
||||||
static const char* kMonthsAbbrev[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
|
||||||
static const char* kDefaultDateTimeFormat = "%Y-%M-%d %H:%m:%s,%g";
|
|
||||||
static const char* kDefaultDateTimeFormatInFilename = "%Y-%M-%d_%H-%m";
|
|
||||||
static const int kYearBase = 1900;
|
|
||||||
static const char* kAm = "AM";
|
|
||||||
static const char* kPm = "PM";
|
|
||||||
// Miscellaneous constants
|
|
||||||
#ifdef ELPP_DEFAULT_LOGGER
|
#ifdef ELPP_DEFAULT_LOGGER
|
||||||
static const char* kDefaultLoggerId = ELPP_DEFAULT_LOGGER;
|
static const char* kDefaultLoggerId = ELPP_DEFAULT_LOGGER;
|
||||||
#else
|
#else
|
||||||
static const char* kDefaultLoggerId = "default";
|
static const char* kDefaultLoggerId = "default";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING)
|
||||||
#ifdef ELPP_DEFAULT_PERFORMANCE_LOGGER
|
#ifdef ELPP_DEFAULT_PERFORMANCE_LOGGER
|
||||||
static const char* kPerformanceLoggerId = ELPP_DEFAULT_PERFORMANCE_LOGGER;
|
static const char* kPerformanceLoggerId = ELPP_DEFAULT_PERFORMANCE_LOGGER;
|
||||||
#else
|
#else
|
||||||
static const char* kPerformanceLoggerId = "performance";
|
static const char* kPerformanceLoggerId = "performance";
|
||||||
|
#endif // ELPP_DEFAULT_PERFORMANCE_LOGGER
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(ELPP_SYSLOG)
|
#if defined(ELPP_SYSLOG)
|
||||||
static const char* kSysLogLoggerId = "syslog";
|
static const char* kSysLogLoggerId = "syslog";
|
||||||
#endif // defined(ELPP_SYSLOG)
|
#endif // defined(ELPP_SYSLOG)
|
||||||
static const char* kNullPointer = "nullptr";
|
|
||||||
static const char kFormatSpecifierChar = '%';
|
|
||||||
#if ELPP_VARIADIC_TEMPLATES_SUPPORTED
|
|
||||||
static const char kFormatSpecifierCharValue = 'v';
|
|
||||||
#endif // ELPP_VARIADIC_TEMPLATES_SUPPORTED
|
|
||||||
static const unsigned int kMaxLogPerContainer = 100;
|
|
||||||
static const unsigned int kMaxLogPerCounter = 100000;
|
|
||||||
static const unsigned int kDefaultSubsecondPrecision = 3;
|
|
||||||
static const base::type::VerboseLevel kMaxVerboseLevel = 9;
|
|
||||||
static const char* kUnknownUser = "user";
|
|
||||||
static const char* kUnknownHost = "unknown-host";
|
|
||||||
#if defined(ELPP_DEFAULT_LOG_FILE)
|
|
||||||
static const char* kDefaultLogFile = ELPP_DEFAULT_LOG_FILE;
|
|
||||||
#else
|
|
||||||
# if ELPP_OS_UNIX
|
|
||||||
# if ELPP_OS_ANDROID
|
|
||||||
static const char* kDefaultLogFile = "logs/myeasylog.log";
|
|
||||||
# else
|
|
||||||
static const char* kDefaultLogFile = "logs/myeasylog.log";
|
|
||||||
# endif // ELPP_OS_ANDROID
|
|
||||||
# elif ELPP_OS_WINDOWS
|
|
||||||
static const char* kDefaultLogFile = "logs\\myeasylog.log";
|
|
||||||
# endif // ELPP_OS_UNIX
|
|
||||||
#endif // defined(ELPP_DEFAULT_LOG_FILE)
|
|
||||||
#if !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG)
|
|
||||||
static const char* kDefaultLogFileParam = "--default-log-file";
|
|
||||||
#endif // !defined(ELPP_DISABLE_LOG_FILE_FROM_ARG)
|
|
||||||
#if defined(ELPP_LOGGING_FLAGS_FROM_ARG)
|
|
||||||
static const char* kLoggingFlagsParam = "--logging-flags";
|
|
||||||
#endif // defined(ELPP_LOGGING_FLAGS_FROM_ARG)
|
|
||||||
#if ELPP_OS_WINDOWS
|
#if ELPP_OS_WINDOWS
|
||||||
static const char* kFilePathSeperator = "\\";
|
static const char* kFilePathSeparator = "\\";
|
||||||
#else
|
#else
|
||||||
static const char* kFilePathSeperator = "/";
|
static const char* kFilePathSeparator = "/";
|
||||||
#endif // ELPP_OS_WINDOWS
|
#endif // ELPP_OS_WINDOWS
|
||||||
static const char* kValidLoggerIdSymbols =
|
|
||||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._";
|
|
||||||
static const char* kConfigurationComment = "##";
|
|
||||||
static const char* kConfigurationLevel = "*";
|
|
||||||
static const char* kConfigurationLoggerId = "--";
|
|
||||||
static const std::size_t kSourceFilenameMaxLength = 100;
|
static const std::size_t kSourceFilenameMaxLength = 100;
|
||||||
static const std::size_t kSourceLineMaxLength = 10;
|
static const std::size_t kSourceLineMaxLength = 10;
|
||||||
static const Level kPerformanceTrackerDefaultLevel = Level::Info;
|
static const Level kPerformanceTrackerDefaultLevel = Level::Info;
|
||||||
@ -839,7 +791,7 @@ const struct {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
SIGFPE, "SIGFPE", "Erroneous arithmetic operation",
|
SIGFPE, "SIGFPE", "Erroneous arithmetic operation",
|
||||||
"Arithemetic operation issue such as division by zero or operation resulting in overflow."
|
"Arithmetic operation issue such as division by zero or operation resulting in overflow."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
SIGILL, "SIGILL", "Illegal instruction",
|
SIGILL, "SIGILL", "Illegal instruction",
|
||||||
@ -855,9 +807,6 @@ const struct {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
static const int kCrashSignalsCount = sizeof(kCrashSignals) / sizeof(kCrashSignals[0]);
|
static const int kCrashSignalsCount = sizeof(kCrashSignals) / sizeof(kCrashSignals[0]);
|
||||||
#if defined(__GNUC__) && !defined(__clang__)
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
#endif
|
|
||||||
} // namespace consts
|
} // namespace consts
|
||||||
} // namespace base
|
} // namespace base
|
||||||
typedef std::function<void(const char*, std::size_t)> PreRollOutCallback;
|
typedef std::function<void(const char*, std::size_t)> PreRollOutCallback;
|
||||||
@ -1108,14 +1057,14 @@ class File : base::StaticClass {
|
|||||||
static bool createPath(const std::string& path);
|
static bool createPath(const std::string& path);
|
||||||
/// @brief Extracts path of filename with leading slash
|
/// @brief Extracts path of filename with leading slash
|
||||||
static std::string extractPathFromFilename(const std::string& fullPath,
|
static std::string extractPathFromFilename(const std::string& fullPath,
|
||||||
const char* seperator = base::consts::kFilePathSeperator);
|
const char* separator = base::consts::kFilePathSeparator);
|
||||||
/// @brief builds stripped filename and puts it in buff
|
/// @brief builds stripped filename and puts it in buff
|
||||||
static void buildStrippedFilename(const char* filename, char buff[],
|
static void buildStrippedFilename(const char* filename, char buff[],
|
||||||
std::size_t limit = base::consts::kSourceFilenameMaxLength);
|
std::size_t limit = base::consts::kSourceFilenameMaxLength);
|
||||||
/// @brief builds base filename and puts it in buff
|
/// @brief builds base filename and puts it in buff
|
||||||
static void buildBaseFilename(const std::string& fullPath, char buff[],
|
static void buildBaseFilename(const std::string& fullPath, char buff[],
|
||||||
std::size_t limit = base::consts::kSourceFilenameMaxLength,
|
std::size_t limit = base::consts::kSourceFilenameMaxLength,
|
||||||
const char* seperator = base::consts::kFilePathSeperator);
|
const char* separator = base::consts::kFilePathSeparator);
|
||||||
};
|
};
|
||||||
/// @brief String utilities helper class used internally. You should not use it.
|
/// @brief String utilities helper class used internally. You should not use it.
|
||||||
class Str : base::StaticClass {
|
class Str : base::StaticClass {
|
||||||
@ -1184,7 +1133,7 @@ class Str : base::StaticClass {
|
|||||||
static char* addToBuff(const char* str, char* buf, const char* bufLim);
|
static char* addToBuff(const char* str, char* buf, const char* bufLim);
|
||||||
static char* clearBuff(char buff[], std::size_t lim);
|
static char* clearBuff(char buff[], std::size_t lim);
|
||||||
|
|
||||||
/// @brief Converst wchar* to char*
|
/// @brief Converts wchar* to char*
|
||||||
/// NOTE: Need to free return value after use!
|
/// NOTE: Need to free return value after use!
|
||||||
static char* wcharPtrToCharPtr(const wchar_t* line);
|
static char* wcharPtrToCharPtr(const wchar_t* line);
|
||||||
};
|
};
|
||||||
@ -1225,7 +1174,7 @@ class OS : base::StaticClass {
|
|||||||
|
|
||||||
/// @brief Gets current host name or computer name.
|
/// @brief Gets current host name or computer name.
|
||||||
///
|
///
|
||||||
/// @detail For android systems this is device name with its manufacturer and model seperated by hyphen
|
/// @detail For android systems this is device name with its manufacturer and model separated by hyphen
|
||||||
static std::string currentHost(void);
|
static std::string currentHost(void);
|
||||||
/// @brief Whether or not terminal supports colors
|
/// @brief Whether or not terminal supports colors
|
||||||
static bool termSupportsColor(void);
|
static bool termSupportsColor(void);
|
||||||
@ -1235,7 +1184,7 @@ class DateTime : base::StaticClass {
|
|||||||
public:
|
public:
|
||||||
/// @brief Cross platform gettimeofday for Windows and unix platform. This can be used to determine current microsecond.
|
/// @brief Cross platform gettimeofday for Windows and unix platform. This can be used to determine current microsecond.
|
||||||
///
|
///
|
||||||
/// @detail For unix system it uses gettimeofday(timeval*, timezone*) and for Windows, a seperate implementation is provided
|
/// @detail For unix system it uses gettimeofday(timeval*, timezone*) and for Windows, a separate implementation is provided
|
||||||
/// @param [in,out] tv Pointer that gets updated
|
/// @param [in,out] tv Pointer that gets updated
|
||||||
static void gettimeofday(struct timeval* tv);
|
static void gettimeofday(struct timeval* tv);
|
||||||
|
|
||||||
@ -1257,8 +1206,8 @@ class DateTime : base::StaticClass {
|
|||||||
base::TimestampUnit timestampUnit);
|
base::TimestampUnit timestampUnit);
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
static struct ::tm* buildTimeInfo(struct timeval* currTime, struct ::tm* timeInfo);
|
static struct ::tm* buildTimeInfo(struct timeval* currTime, struct ::tm* timeInfo);
|
||||||
|
private:
|
||||||
static char* parseFormat(char* buf, std::size_t bufSz, const char* format, const struct tm* tInfo,
|
static char* parseFormat(char* buf, std::size_t bufSz, const char* format, const struct tm* tInfo,
|
||||||
std::size_t msec, const base::SubsecondPrecision* ssPrec);
|
std::size_t msec, const base::SubsecondPrecision* ssPrec);
|
||||||
};
|
};
|
||||||
@ -1281,7 +1230,7 @@ class CommandLineArgs {
|
|||||||
}
|
}
|
||||||
/// @brief Sets arguments and parses them
|
/// @brief Sets arguments and parses them
|
||||||
void setArgs(int argc, char** argv);
|
void setArgs(int argc, char** argv);
|
||||||
/// @brief Returns true if arguments contain paramKey with a value (seperated by '=')
|
/// @brief Returns true if arguments contain paramKey with a value (separated by '=')
|
||||||
bool hasParamWithValue(const char* paramKey) const;
|
bool hasParamWithValue(const char* paramKey) const;
|
||||||
/// @brief Returns value of arguments
|
/// @brief Returns value of arguments
|
||||||
/// @see hasParamWithValue(const char*)
|
/// @see hasParamWithValue(const char*)
|
||||||
@ -1297,7 +1246,7 @@ class CommandLineArgs {
|
|||||||
private:
|
private:
|
||||||
int m_argc;
|
int m_argc;
|
||||||
char** m_argv;
|
char** m_argv;
|
||||||
std::map<std::string, std::string> m_paramsWithValue;
|
std::unordered_map<std::string, std::string> m_paramsWithValue;
|
||||||
std::vector<std::string> m_params;
|
std::vector<std::string> m_params;
|
||||||
};
|
};
|
||||||
/// @brief Abstract registry (aka repository) that provides basic interface for pointer repository specified by T_Ptr type.
|
/// @brief Abstract registry (aka repository) that provides basic interface for pointer repository specified by T_Ptr type.
|
||||||
@ -1422,7 +1371,7 @@ class AbstractRegistry : public base::threading::ThreadSafe {
|
|||||||
/// of AbstractRegistry<T_Ptr, Container>. Any implementation of this class should be
|
/// of AbstractRegistry<T_Ptr, Container>. Any implementation of this class should be
|
||||||
/// explicitly (by using lock functions)
|
/// explicitly (by using lock functions)
|
||||||
template <typename T_Ptr, typename T_Key = const char*>
|
template <typename T_Ptr, typename T_Key = const char*>
|
||||||
class Registry : public AbstractRegistry<T_Ptr, std::map<T_Key, T_Ptr*>> {
|
class Registry : public AbstractRegistry<T_Ptr, std::unordered_map<T_Key, T_Ptr*>> {
|
||||||
public:
|
public:
|
||||||
typedef typename Registry<T_Ptr, T_Key>::iterator iterator;
|
typedef typename Registry<T_Ptr, T_Key>::iterator iterator;
|
||||||
typedef typename Registry<T_Ptr, T_Key>::const_iterator const_iterator;
|
typedef typename Registry<T_Ptr, T_Key>::const_iterator const_iterator;
|
||||||
@ -1437,7 +1386,7 @@ class Registry : public AbstractRegistry<T_Ptr, std::map<T_Key, T_Ptr*>> {
|
|||||||
this->reinitDeepCopy(sr);
|
this->reinitDeepCopy(sr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Assignment operator that unregisters all the existing registeries and deeply copies each of repo element
|
/// @brief Assignment operator that unregisters all the existing registries and deeply copies each of repo element
|
||||||
/// @see unregisterAll()
|
/// @see unregisterAll()
|
||||||
/// @see deepCopy(const AbstractRegistry&)
|
/// @see deepCopy(const AbstractRegistry&)
|
||||||
Registry& operator=(const Registry& sr) {
|
Registry& operator=(const Registry& sr) {
|
||||||
@ -1486,7 +1435,7 @@ class Registry : public AbstractRegistry<T_Ptr, std::map<T_Key, T_Ptr*>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void deepCopy(const AbstractRegistry<T_Ptr, std::map<T_Key, T_Ptr*>>& sr) ELPP_FINAL {
|
virtual void deepCopy(const AbstractRegistry<T_Ptr, std::unordered_map<T_Key, T_Ptr*>>& sr) ELPP_FINAL {
|
||||||
for (const_iterator it = sr.cbegin(); it != sr.cend(); ++it) {
|
for (const_iterator it = sr.cbegin(); it != sr.cend(); ++it) {
|
||||||
registerNew(it->first, new T_Ptr(*it->second));
|
registerNew(it->first, new T_Ptr(*it->second));
|
||||||
}
|
}
|
||||||
@ -1518,7 +1467,7 @@ class RegistryWithPred : public AbstractRegistry<T_Ptr, std::vector<T_Ptr*>> {
|
|||||||
this->reinitDeepCopy(sr);
|
this->reinitDeepCopy(sr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Assignment operator that unregisters all the existing registeries and deeply copies each of repo element
|
/// @brief Assignment operator that unregisters all the existing registries and deeply copies each of repo element
|
||||||
/// @see unregisterAll()
|
/// @see unregisterAll()
|
||||||
/// @see deepCopy(const AbstractRegistry&)
|
/// @see deepCopy(const AbstractRegistry&)
|
||||||
RegistryWithPred& operator=(const RegistryWithPred& sr) {
|
RegistryWithPred& operator=(const RegistryWithPred& sr) {
|
||||||
@ -1565,7 +1514,7 @@ class RegistryWithPred : public AbstractRegistry<T_Ptr, std::vector<T_Ptr*>> {
|
|||||||
this->list().push_back(ptr);
|
this->list().push_back(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Gets pointer from repository with speicifed arguments. Arguments are passed to predicate
|
/// @brief Gets pointer from repository with specified arguments. Arguments are passed to predicate
|
||||||
/// in order to validate pointer.
|
/// in order to validate pointer.
|
||||||
template <typename T, typename T2>
|
template <typename T, typename T2>
|
||||||
T_Ptr* get(const T& arg1, const T2 arg2) {
|
T_Ptr* get(const T& arg1, const T2 arg2) {
|
||||||
@ -1586,7 +1535,7 @@ class RegistryWithPred : public AbstractRegistry<T_Ptr, std::vector<T_Ptr*>> {
|
|||||||
class Utils {
|
class Utils {
|
||||||
public:
|
public:
|
||||||
template <typename T, typename TPtr>
|
template <typename T, typename TPtr>
|
||||||
static bool installCallback(const std::string& id, std::map<std::string, TPtr>* mapT) {
|
static bool installCallback(const std::string& id, std::unordered_map<std::string, TPtr>* mapT) {
|
||||||
if (mapT->find(id) == mapT->end()) {
|
if (mapT->find(id) == mapT->end()) {
|
||||||
mapT->insert(std::make_pair(id, TPtr(new T())));
|
mapT->insert(std::make_pair(id, TPtr(new T())));
|
||||||
return true;
|
return true;
|
||||||
@ -1595,15 +1544,15 @@ class Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename TPtr>
|
template <typename T, typename TPtr>
|
||||||
static void uninstallCallback(const std::string& id, std::map<std::string, TPtr>* mapT) {
|
static void uninstallCallback(const std::string& id, std::unordered_map<std::string, TPtr>* mapT) {
|
||||||
if (mapT->find(id) != mapT->end()) {
|
if (mapT->find(id) != mapT->end()) {
|
||||||
mapT->erase(id);
|
mapT->erase(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename TPtr>
|
template <typename T, typename TPtr>
|
||||||
static T* callback(const std::string& id, std::map<std::string, TPtr>* mapT) {
|
static T* callback(const std::string& id, std::unordered_map<std::string, TPtr>* mapT) {
|
||||||
typename std::map<std::string, TPtr>::iterator iter = mapT->find(id);
|
typename std::unordered_map<std::string, TPtr>::iterator iter = mapT->find(id);
|
||||||
if (iter != mapT->end()) {
|
if (iter != mapT->end()) {
|
||||||
return static_cast<T*>(iter->second.get());
|
return static_cast<T*>(iter->second.get());
|
||||||
}
|
}
|
||||||
@ -1948,7 +1897,8 @@ class Configurations : public base::utils::RegistryWithPred<Configuration, Confi
|
|||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
typedef std::shared_ptr<base::type::fstream_t> FileStreamPtr;
|
typedef std::shared_ptr<base::type::fstream_t> FileStreamPtr;
|
||||||
typedef std::map<std::string, FileStreamPtr> LogStreamsReferenceMap;
|
typedef std::unordered_map<std::string, FileStreamPtr> LogStreamsReferenceMap;
|
||||||
|
typedef std::shared_ptr<base::LogStreamsReferenceMap> LogStreamsReferenceMapPtr;
|
||||||
/// @brief Configurations with data types.
|
/// @brief Configurations with data types.
|
||||||
///
|
///
|
||||||
/// @detail el::Configurations have string based values. This is whats used internally in order to read correct configurations.
|
/// @detail el::Configurations have string based values. This is whats used internally in order to read correct configurations.
|
||||||
@ -1960,7 +1910,7 @@ class TypedConfigurations : public base::threading::ThreadSafe {
|
|||||||
/// @brief Constructor to initialize (construct) the object off el::Configurations
|
/// @brief Constructor to initialize (construct) the object off el::Configurations
|
||||||
/// @param configurations Configurations pointer/reference to base this typed configurations off.
|
/// @param configurations Configurations pointer/reference to base this typed configurations off.
|
||||||
/// @param logStreamsReference Use ELPP->registeredLoggers()->logStreamsReference()
|
/// @param logStreamsReference Use ELPP->registeredLoggers()->logStreamsReference()
|
||||||
TypedConfigurations(Configurations* configurations, base::LogStreamsReferenceMap* logStreamsReference);
|
TypedConfigurations(Configurations* configurations, LogStreamsReferenceMapPtr logStreamsReference);
|
||||||
|
|
||||||
TypedConfigurations(const TypedConfigurations& other);
|
TypedConfigurations(const TypedConfigurations& other);
|
||||||
|
|
||||||
@ -1985,17 +1935,17 @@ class TypedConfigurations : public base::threading::ThreadSafe {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Configurations* m_configurations;
|
Configurations* m_configurations;
|
||||||
std::map<Level, bool> m_enabledMap;
|
std::unordered_map<Level, bool> m_enabledMap;
|
||||||
std::map<Level, bool> m_toFileMap;
|
std::unordered_map<Level, bool> m_toFileMap;
|
||||||
std::map<Level, std::string> m_filenameMap;
|
std::unordered_map<Level, std::string> m_filenameMap;
|
||||||
std::map<Level, bool> m_toStandardOutputMap;
|
std::unordered_map<Level, bool> m_toStandardOutputMap;
|
||||||
std::map<Level, base::LogFormat> m_logFormatMap;
|
std::unordered_map<Level, base::LogFormat> m_logFormatMap;
|
||||||
std::map<Level, base::SubsecondPrecision> m_subsecondPrecisionMap;
|
std::unordered_map<Level, base::SubsecondPrecision> m_subsecondPrecisionMap;
|
||||||
std::map<Level, bool> m_performanceTrackingMap;
|
std::unordered_map<Level, bool> m_performanceTrackingMap;
|
||||||
std::map<Level, base::FileStreamPtr> m_fileStreamMap;
|
std::unordered_map<Level, base::FileStreamPtr> m_fileStreamMap;
|
||||||
std::map<Level, std::size_t> m_maxLogFileSizeMap;
|
std::unordered_map<Level, std::size_t> m_maxLogFileSizeMap;
|
||||||
std::map<Level, std::size_t> m_logFlushThresholdMap;
|
std::unordered_map<Level, std::size_t> m_logFlushThresholdMap;
|
||||||
base::LogStreamsReferenceMap* m_logStreamsReference;
|
LogStreamsReferenceMapPtr m_logStreamsReference = nullptr;
|
||||||
|
|
||||||
friend class el::Helpers;
|
friend class el::Helpers;
|
||||||
friend class el::base::MessageBuilder;
|
friend class el::base::MessageBuilder;
|
||||||
@ -2004,21 +1954,21 @@ class TypedConfigurations : public base::threading::ThreadSafe {
|
|||||||
friend class el::base::LogDispatcher;
|
friend class el::base::LogDispatcher;
|
||||||
|
|
||||||
template <typename Conf_T>
|
template <typename Conf_T>
|
||||||
inline Conf_T getConfigByVal(Level level, const std::map<Level, Conf_T>* confMap, const char* confName) {
|
inline Conf_T getConfigByVal(Level level, const std::unordered_map<Level, Conf_T>* confMap, const char* confName) {
|
||||||
base::threading::ScopedLock scopedLock(lock());
|
base::threading::ScopedLock scopedLock(lock());
|
||||||
return unsafeGetConfigByVal(level, confMap, confName); // This is not unsafe anymore - mutex locked in scope
|
return unsafeGetConfigByVal(level, confMap, confName); // This is not unsafe anymore - mutex locked in scope
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Conf_T>
|
template <typename Conf_T>
|
||||||
inline Conf_T& getConfigByRef(Level level, std::map<Level, Conf_T>* confMap, const char* confName) {
|
inline Conf_T& getConfigByRef(Level level, std::unordered_map<Level, Conf_T>* confMap, const char* confName) {
|
||||||
base::threading::ScopedLock scopedLock(lock());
|
base::threading::ScopedLock scopedLock(lock());
|
||||||
return unsafeGetConfigByRef(level, confMap, confName); // This is not unsafe anymore - mutex locked in scope
|
return unsafeGetConfigByRef(level, confMap, confName); // This is not unsafe anymore - mutex locked in scope
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Conf_T>
|
template <typename Conf_T>
|
||||||
Conf_T unsafeGetConfigByVal(Level level, const std::map<Level, Conf_T>* confMap, const char* confName) {
|
Conf_T unsafeGetConfigByVal(Level level, const std::unordered_map<Level, Conf_T>* confMap, const char* confName) {
|
||||||
ELPP_UNUSED(confName);
|
ELPP_UNUSED(confName);
|
||||||
typename std::map<Level, Conf_T>::const_iterator it = confMap->find(level);
|
typename std::unordered_map<Level, Conf_T>::const_iterator it = confMap->find(level);
|
||||||
if (it == confMap->end()) {
|
if (it == confMap->end()) {
|
||||||
try {
|
try {
|
||||||
return confMap->at(Level::Global);
|
return confMap->at(Level::Global);
|
||||||
@ -2033,9 +1983,9 @@ class TypedConfigurations : public base::threading::ThreadSafe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename Conf_T>
|
template <typename Conf_T>
|
||||||
Conf_T& unsafeGetConfigByRef(Level level, std::map<Level, Conf_T>* confMap, const char* confName) {
|
Conf_T& unsafeGetConfigByRef(Level level, std::unordered_map<Level, Conf_T>* confMap, const char* confName) {
|
||||||
ELPP_UNUSED(confName);
|
ELPP_UNUSED(confName);
|
||||||
typename std::map<Level, Conf_T>::iterator it = confMap->find(level);
|
typename std::unordered_map<Level, Conf_T>::iterator it = confMap->find(level);
|
||||||
if (it == confMap->end()) {
|
if (it == confMap->end()) {
|
||||||
try {
|
try {
|
||||||
return confMap->at(Level::Global);
|
return confMap->at(Level::Global);
|
||||||
@ -2049,14 +1999,15 @@ class TypedConfigurations : public base::threading::ThreadSafe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename Conf_T>
|
template <typename Conf_T>
|
||||||
void setValue(Level level, const Conf_T& value, std::map<Level, Conf_T>* confMap, bool includeGlobalLevel = true) {
|
void setValue(Level level, const Conf_T& value, std::unordered_map<Level, Conf_T>* confMap,
|
||||||
|
bool includeGlobalLevel = true) {
|
||||||
// If map is empty and we are allowed to add into generic level (Level::Global), do it!
|
// If map is empty and we are allowed to add into generic level (Level::Global), do it!
|
||||||
if (confMap->empty() && includeGlobalLevel) {
|
if (confMap->empty() && includeGlobalLevel) {
|
||||||
confMap->insert(std::make_pair(Level::Global, value));
|
confMap->insert(std::make_pair(Level::Global, value));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// If same value exist in generic level already, dont add it to explicit level
|
// If same value exist in generic level already, dont add it to explicit level
|
||||||
typename std::map<Level, Conf_T>::iterator it = confMap->find(Level::Global);
|
typename std::unordered_map<Level, Conf_T>::iterator it = confMap->find(Level::Global);
|
||||||
if (it != confMap->end() && it->second == value) {
|
if (it != confMap->end() && it->second == value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2218,21 +2169,26 @@ class LogDispatchData {
|
|||||||
inline base::DispatchAction dispatchAction(void) const {
|
inline base::DispatchAction dispatchAction(void) const {
|
||||||
return m_dispatchAction;
|
return m_dispatchAction;
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
LogMessage* m_logMessage;
|
|
||||||
base::DispatchAction m_dispatchAction;
|
|
||||||
friend class base::LogDispatcher;
|
|
||||||
|
|
||||||
inline void setLogMessage(LogMessage* logMessage) {
|
inline void setLogMessage(LogMessage* logMessage) {
|
||||||
m_logMessage = logMessage;
|
m_logMessage = logMessage;
|
||||||
}
|
}
|
||||||
inline void setDispatchAction(base::DispatchAction dispatchAction) {
|
inline void setDispatchAction(base::DispatchAction dispatchAction) {
|
||||||
m_dispatchAction = dispatchAction;
|
m_dispatchAction = dispatchAction;
|
||||||
}
|
}
|
||||||
|
private:
|
||||||
|
LogMessage* m_logMessage;
|
||||||
|
base::DispatchAction m_dispatchAction;
|
||||||
|
friend class base::LogDispatcher;
|
||||||
|
|
||||||
};
|
};
|
||||||
class LogDispatchCallback : public Callback<LogDispatchData> {
|
class LogDispatchCallback : public Callback<LogDispatchData> {
|
||||||
|
protected:
|
||||||
|
virtual void handle(const LogDispatchData* data);
|
||||||
|
base::threading::Mutex& fileHandle(const LogDispatchData* data);
|
||||||
private:
|
private:
|
||||||
friend class base::LogDispatcher;
|
friend class base::LogDispatcher;
|
||||||
|
std::unordered_map<std::string, std::unique_ptr<base::threading::Mutex>> m_fileLocks;
|
||||||
|
base::threading::Mutex m_fileLocksMapLock;
|
||||||
};
|
};
|
||||||
class PerformanceTrackingCallback : public Callback<PerformanceTrackingData> {
|
class PerformanceTrackingCallback : public Callback<PerformanceTrackingData> {
|
||||||
private:
|
private:
|
||||||
@ -2257,11 +2213,11 @@ class LogBuilder : base::NoCopy {
|
|||||||
typedef std::shared_ptr<LogBuilder> LogBuilderPtr;
|
typedef std::shared_ptr<LogBuilder> LogBuilderPtr;
|
||||||
/// @brief Represents a logger holding ID and configurations we need to write logs
|
/// @brief Represents a logger holding ID and configurations we need to write logs
|
||||||
///
|
///
|
||||||
/// @detail This class does not write logs itself instead its used by writer to read configuations from.
|
/// @detail This class does not write logs itself instead its used by writer to read configurations from.
|
||||||
class Logger : public base::threading::ThreadSafe, public Loggable {
|
class Logger : public base::threading::ThreadSafe, public Loggable {
|
||||||
public:
|
public:
|
||||||
Logger(const std::string& id, base::LogStreamsReferenceMap* logStreamsReference);
|
Logger(const std::string& id, base::LogStreamsReferenceMapPtr logStreamsReference);
|
||||||
Logger(const std::string& id, const Configurations& configurations, base::LogStreamsReferenceMap* logStreamsReference);
|
Logger(const std::string& id, const Configurations& configurations, base::LogStreamsReferenceMapPtr logStreamsReference);
|
||||||
Logger(const Logger& logger);
|
Logger(const Logger& logger);
|
||||||
Logger& operator=(const Logger& logger);
|
Logger& operator=(const Logger& logger);
|
||||||
|
|
||||||
@ -2350,8 +2306,8 @@ inline void FUNCTION_NAME(const T&);
|
|||||||
std::string m_parentApplicationName;
|
std::string m_parentApplicationName;
|
||||||
bool m_isConfigured;
|
bool m_isConfigured;
|
||||||
Configurations m_configurations;
|
Configurations m_configurations;
|
||||||
std::map<Level, unsigned int> m_unflushedCount;
|
std::unordered_map<Level, unsigned int> m_unflushedCount;
|
||||||
base::LogStreamsReferenceMap* m_logStreamsReference;
|
base::LogStreamsReferenceMapPtr m_logStreamsReference = nullptr;
|
||||||
LogBuilderPtr m_logBuilder;
|
LogBuilderPtr m_logBuilder;
|
||||||
|
|
||||||
friend class el::LogMessage;
|
friend class el::LogMessage;
|
||||||
@ -2438,8 +2394,8 @@ class RegisteredLoggers : public base::utils::Registry<Logger, std::string> {
|
|||||||
base::utils::Registry<Logger, std::string>::unregister(logger->id());
|
base::utils::Registry<Logger, std::string>::unregister(logger->id());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline base::LogStreamsReferenceMap* logStreamsReference(void) {
|
inline LogStreamsReferenceMapPtr logStreamsReference(void) {
|
||||||
return &m_logStreamsReference;
|
return m_logStreamsReference;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void flushAll(void) {
|
inline void flushAll(void) {
|
||||||
@ -2455,8 +2411,8 @@ class RegisteredLoggers : public base::utils::Registry<Logger, std::string> {
|
|||||||
private:
|
private:
|
||||||
LogBuilderPtr m_defaultLogBuilder;
|
LogBuilderPtr m_defaultLogBuilder;
|
||||||
Configurations m_defaultConfigurations;
|
Configurations m_defaultConfigurations;
|
||||||
base::LogStreamsReferenceMap m_logStreamsReference;
|
base::LogStreamsReferenceMapPtr m_logStreamsReference = nullptr;
|
||||||
std::map<std::string, base::type::LoggerRegistrationCallbackPtr> m_loggerRegistrationCallbacks;
|
std::unordered_map<std::string, base::type::LoggerRegistrationCallbackPtr> m_loggerRegistrationCallbacks;
|
||||||
friend class el::base::Storage;
|
friend class el::base::Storage;
|
||||||
|
|
||||||
void unsafeFlushAll(void);
|
void unsafeFlushAll(void);
|
||||||
@ -2482,7 +2438,7 @@ class VRegistry : base::NoCopy, public base::threading::ThreadSafe {
|
|||||||
|
|
||||||
bool allowed(base::type::VerboseLevel vlevel, const char* file);
|
bool allowed(base::type::VerboseLevel vlevel, const char* file);
|
||||||
|
|
||||||
inline const std::map<std::string, base::type::VerboseLevel>& modules(void) const {
|
inline const std::unordered_map<std::string, base::type::VerboseLevel>& modules(void) const {
|
||||||
return m_modules;
|
return m_modules;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2496,7 +2452,7 @@ class VRegistry : base::NoCopy, public base::threading::ThreadSafe {
|
|||||||
private:
|
private:
|
||||||
base::type::VerboseLevel m_level;
|
base::type::VerboseLevel m_level;
|
||||||
base::type::EnumType* m_pFlags;
|
base::type::EnumType* m_pFlags;
|
||||||
std::map<std::string, base::type::VerboseLevel> m_modules;
|
std::unordered_map<std::string, base::type::VerboseLevel> m_modules;
|
||||||
};
|
};
|
||||||
} // namespace base
|
} // namespace base
|
||||||
class LogMessage {
|
class LogMessage {
|
||||||
@ -2680,6 +2636,10 @@ class Storage : base::NoCopy, public base::threading::ThreadSafe {
|
|||||||
return &m_customFormatSpecifiers;
|
return &m_customFormatSpecifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
base::threading::Mutex& customFormatSpecifiersLock() {
|
||||||
|
return m_customFormatSpecifiersLock;
|
||||||
|
}
|
||||||
|
|
||||||
inline void setLoggingLevel(Level level) {
|
inline void setLoggingLevel(Level level) {
|
||||||
m_loggingLevel = level;
|
m_loggingLevel = level;
|
||||||
}
|
}
|
||||||
@ -2720,12 +2680,13 @@ class Storage : base::NoCopy, public base::threading::ThreadSafe {
|
|||||||
/// @brief Sets thread name for current thread. Requires std::thread
|
/// @brief Sets thread name for current thread. Requires std::thread
|
||||||
inline void setThreadName(const std::string& name) {
|
inline void setThreadName(const std::string& name) {
|
||||||
if (name.empty()) return;
|
if (name.empty()) return;
|
||||||
base::threading::ScopedLock scopedLock(lock());
|
base::threading::ScopedLock scopedLock(m_threadNamesLock);
|
||||||
m_threadNames[base::threading::getCurrentThreadId()] = name;
|
m_threadNames[base::threading::getCurrentThreadId()] = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string getThreadName(const std::string& threadId) {
|
inline std::string getThreadName(const std::string& threadId) {
|
||||||
std::map<std::string, std::string>::const_iterator it = m_threadNames.find(threadId);
|
base::threading::ScopedLock scopedLock(m_threadNamesLock);
|
||||||
|
std::unordered_map<std::string, std::string>::const_iterator it = m_threadNames.find(threadId);
|
||||||
if (it == m_threadNames.end()) {
|
if (it == m_threadNames.end()) {
|
||||||
return threadId;
|
return threadId;
|
||||||
}
|
}
|
||||||
@ -2742,10 +2703,12 @@ class Storage : base::NoCopy, public base::threading::ThreadSafe {
|
|||||||
#endif // ELPP_ASYNC_LOGGING
|
#endif // ELPP_ASYNC_LOGGING
|
||||||
base::utils::CommandLineArgs m_commandLineArgs;
|
base::utils::CommandLineArgs m_commandLineArgs;
|
||||||
PreRollOutCallback m_preRollOutCallback;
|
PreRollOutCallback m_preRollOutCallback;
|
||||||
std::map<std::string, base::type::LogDispatchCallbackPtr> m_logDispatchCallbacks;
|
std::unordered_map<std::string, base::type::LogDispatchCallbackPtr> m_logDispatchCallbacks;
|
||||||
std::map<std::string, base::type::PerformanceTrackingCallbackPtr> m_performanceTrackingCallbacks;
|
std::unordered_map<std::string, base::type::PerformanceTrackingCallbackPtr> m_performanceTrackingCallbacks;
|
||||||
std::map<std::string, std::string> m_threadNames;
|
std::unordered_map<std::string, std::string> m_threadNames;
|
||||||
std::vector<CustomFormatSpecifier> m_customFormatSpecifiers;
|
std::vector<CustomFormatSpecifier> m_customFormatSpecifiers;
|
||||||
|
base::threading::Mutex m_customFormatSpecifiersLock;
|
||||||
|
base::threading::Mutex m_threadNamesLock;
|
||||||
Level m_loggingLevel;
|
Level m_loggingLevel;
|
||||||
|
|
||||||
friend class el::Helpers;
|
friend class el::Helpers;
|
||||||
@ -2788,7 +2751,7 @@ class AsyncDispatchWorker : public base::IWorker, public base::threading::Thread
|
|||||||
void run(void);
|
void run(void);
|
||||||
|
|
||||||
void setContinueRunning(bool value) {
|
void setContinueRunning(bool value) {
|
||||||
base::threading::ScopedLock scopedLock(m_continueRunningMutex);
|
base::threading::ScopedLock scopedLock(m_continueRunningLock);
|
||||||
m_continueRunning = value;
|
m_continueRunning = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2798,7 +2761,7 @@ class AsyncDispatchWorker : public base::IWorker, public base::threading::Thread
|
|||||||
private:
|
private:
|
||||||
std::condition_variable cv;
|
std::condition_variable cv;
|
||||||
bool m_continueRunning;
|
bool m_continueRunning;
|
||||||
base::threading::Mutex m_continueRunningMutex;
|
base::threading::Mutex m_continueRunningLock;
|
||||||
};
|
};
|
||||||
#endif // ELPP_ASYNC_LOGGING
|
#endif // ELPP_ASYNC_LOGGING
|
||||||
} // namespace base
|
} // namespace base
|
||||||
@ -2810,9 +2773,9 @@ class DefaultLogBuilder : public LogBuilder {
|
|||||||
/// @brief Dispatches log messages
|
/// @brief Dispatches log messages
|
||||||
class LogDispatcher : base::NoCopy {
|
class LogDispatcher : base::NoCopy {
|
||||||
public:
|
public:
|
||||||
LogDispatcher(bool proceed, LogMessage&& logMessage, base::DispatchAction dispatchAction) :
|
LogDispatcher(bool proceed, LogMessage* logMessage, base::DispatchAction dispatchAction) :
|
||||||
m_proceed(proceed),
|
m_proceed(proceed),
|
||||||
m_logMessage(std::move(logMessage)),
|
m_logMessage(logMessage),
|
||||||
m_dispatchAction(std::move(dispatchAction)) {
|
m_dispatchAction(std::move(dispatchAction)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2820,7 +2783,7 @@ class LogDispatcher : base::NoCopy {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_proceed;
|
bool m_proceed;
|
||||||
LogMessage m_logMessage;
|
LogMessage* m_logMessage;
|
||||||
base::DispatchAction m_dispatchAction;
|
base::DispatchAction m_dispatchAction;
|
||||||
};
|
};
|
||||||
#if defined(ELPP_STL_LOGGING)
|
#if defined(ELPP_STL_LOGGING)
|
||||||
@ -2902,7 +2865,7 @@ class IterableStack : public IterableContainer<T, Container>, public std::stack<
|
|||||||
// Log message builder
|
// Log message builder
|
||||||
class MessageBuilder {
|
class MessageBuilder {
|
||||||
public:
|
public:
|
||||||
MessageBuilder(void) : m_logger(nullptr), m_containerLogSeperator(ELPP_LITERAL("")) {}
|
MessageBuilder(void) : m_logger(nullptr), m_containerLogSeparator(ELPP_LITERAL("")) {}
|
||||||
void initialize(Logger* logger);
|
void initialize(Logger* logger);
|
||||||
|
|
||||||
# define ELPP_SIMPLE_LOG(LOG_TYPE)\
|
# define ELPP_SIMPLE_LOG(LOG_TYPE)\
|
||||||
@ -3090,7 +3053,7 @@ return writeIterator(template_inst.begin(), template_inst.end(), template_inst.s
|
|||||||
m_logger->stream() << ELPP_LITERAL(", ");
|
m_logger->stream() << ELPP_LITERAL(", ");
|
||||||
operator << (static_cast<V>(map_.value(*begin)));
|
operator << (static_cast<V>(map_.value(*begin)));
|
||||||
m_logger->stream() << ELPP_LITERAL(")");
|
m_logger->stream() << ELPP_LITERAL(")");
|
||||||
m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeperator : ELPP_LITERAL(""));
|
m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeparator : ELPP_LITERAL(""));
|
||||||
}
|
}
|
||||||
if (begin != end) {
|
if (begin != end) {
|
||||||
m_logger->stream() << ELPP_LITERAL("...");
|
m_logger->stream() << ELPP_LITERAL("...");
|
||||||
@ -3116,7 +3079,7 @@ return writeIterator(template_inst.begin(), template_inst.end(), template_inst.s
|
|||||||
m_logger->stream() << ELPP_LITERAL(", ");
|
m_logger->stream() << ELPP_LITERAL(", ");
|
||||||
operator << (static_cast<V>(hash_.value(*begin)));
|
operator << (static_cast<V>(hash_.value(*begin)));
|
||||||
m_logger->stream() << ELPP_LITERAL(")");
|
m_logger->stream() << ELPP_LITERAL(")");
|
||||||
m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeperator : ELPP_LITERAL(""));
|
m_logger->stream() << ((index_ < keys.size() -1) ? m_containerLogSeparator : ELPP_LITERAL(""));
|
||||||
}
|
}
|
||||||
if (begin != end) {
|
if (begin != end) {
|
||||||
m_logger->stream() << ELPP_LITERAL("...");
|
m_logger->stream() << ELPP_LITERAL("...");
|
||||||
@ -3147,7 +3110,7 @@ return writeIterator(template_inst.begin(), template_inst.end(), template_inst.s
|
|||||||
/// have begin() and end() methods that return respective iterators
|
/// have begin() and end() methods that return respective iterators
|
||||||
/// @param ContainerType Type of container e.g, MyList from WX_DECLARE_LIST(int, MyList); in wxwidgets
|
/// @param ContainerType Type of container e.g, MyList from WX_DECLARE_LIST(int, MyList); in wxwidgets
|
||||||
/// @param SizeMethod Method used to get size of container.
|
/// @param SizeMethod Method used to get size of container.
|
||||||
/// @param ElementInstance Instance of element to be fed out. Insance name is "elem". See WXELPP_ENABLED macro
|
/// @param ElementInstance Instance of element to be fed out. Instance name is "elem". See WXELPP_ENABLED macro
|
||||||
/// for an example usage
|
/// for an example usage
|
||||||
#define MAKE_CONTAINERELPP_FRIENDLY(ContainerType, SizeMethod, ElementInstance) \
|
#define MAKE_CONTAINERELPP_FRIENDLY(ContainerType, SizeMethod, ElementInstance) \
|
||||||
el::base::type::ostream_t& operator<<(el::base::type::ostream_t& ss, const ContainerType& container) {\
|
el::base::type::ostream_t& operator<<(el::base::type::ostream_t& ss, const ContainerType& container) {\
|
||||||
@ -3189,14 +3152,14 @@ ELPP_LITERAL("(") << elem->first << ELPP_LITERAL(", ") << elem->second << ELPP_L
|
|||||||
#undef ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG
|
#undef ELPP_ITERATOR_CONTAINER_LOG_FIVE_ARG
|
||||||
private:
|
private:
|
||||||
Logger* m_logger;
|
Logger* m_logger;
|
||||||
const base::type::char_t* m_containerLogSeperator;
|
const base::type::char_t* m_containerLogSeparator;
|
||||||
|
|
||||||
template<class Iterator>
|
template<class Iterator>
|
||||||
MessageBuilder& writeIterator(Iterator begin_, Iterator end_, std::size_t size_) {
|
MessageBuilder& writeIterator(Iterator begin_, Iterator end_, std::size_t size_) {
|
||||||
m_logger->stream() << ELPP_LITERAL("[");
|
m_logger->stream() << ELPP_LITERAL("[");
|
||||||
for (std::size_t i = 0; begin_ != end_ && i < base::consts::kMaxLogPerContainer; ++i, ++begin_) {
|
for (std::size_t i = 0; begin_ != end_ && i < base::consts::kMaxLogPerContainer; ++i, ++begin_) {
|
||||||
operator << (*begin_);
|
operator << (*begin_);
|
||||||
m_logger->stream() << ((i < size_ - 1) ? m_containerLogSeperator : ELPP_LITERAL(""));
|
m_logger->stream() << ((i < size_ - 1) ? m_containerLogSeparator : ELPP_LITERAL(""));
|
||||||
}
|
}
|
||||||
if (begin_ != end_) {
|
if (begin_ != end_) {
|
||||||
m_logger->stream() << ELPP_LITERAL("...");
|
m_logger->stream() << ELPP_LITERAL("...");
|
||||||
@ -3233,10 +3196,15 @@ class Writer : base::NoCopy {
|
|||||||
Writer(Level level, const char* file, base::type::LineNumber line,
|
Writer(Level level, const char* file, base::type::LineNumber line,
|
||||||
const char* func, base::DispatchAction dispatchAction = base::DispatchAction::NormalLog,
|
const char* func, base::DispatchAction dispatchAction = base::DispatchAction::NormalLog,
|
||||||
base::type::VerboseLevel verboseLevel = 0) :
|
base::type::VerboseLevel verboseLevel = 0) :
|
||||||
m_level(level), m_file(file), m_line(line), m_func(func), m_verboseLevel(verboseLevel),
|
m_msg(nullptr), m_level(level), m_file(file), m_line(line), m_func(func), m_verboseLevel(verboseLevel),
|
||||||
m_logger(nullptr), m_proceed(false), m_dispatchAction(dispatchAction) {
|
m_logger(nullptr), m_proceed(false), m_dispatchAction(dispatchAction) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Writer(LogMessage* msg, base::DispatchAction dispatchAction = base::DispatchAction::NormalLog) :
|
||||||
|
m_msg(msg), m_level(msg != nullptr ? msg->level() : Level::Unknown),
|
||||||
|
m_line(0), m_logger(nullptr), m_proceed(false), m_dispatchAction(dispatchAction) {
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~Writer(void) {
|
virtual ~Writer(void) {
|
||||||
processDispatch();
|
processDispatch();
|
||||||
}
|
}
|
||||||
@ -3267,6 +3235,7 @@ class Writer : base::NoCopy {
|
|||||||
Writer& construct(Logger* logger, bool needLock = true);
|
Writer& construct(Logger* logger, bool needLock = true);
|
||||||
Writer& construct(int count, const char* loggerIds, ...);
|
Writer& construct(int count, const char* loggerIds, ...);
|
||||||
protected:
|
protected:
|
||||||
|
LogMessage* m_msg;
|
||||||
Level m_level;
|
Level m_level;
|
||||||
const char* m_file;
|
const char* m_file;
|
||||||
const base::type::LineNumber m_line;
|
const base::type::LineNumber m_line;
|
||||||
@ -3325,6 +3294,7 @@ void Logger::log_(Level level, int vlevel, const T& log) {
|
|||||||
base::DispatchAction::NormalLog, vlevel).construct(this, false) << log;
|
base::DispatchAction::NormalLog, vlevel).construct(this, false) << log;
|
||||||
} else {
|
} else {
|
||||||
stream().str(ELPP_LITERAL(""));
|
stream().str(ELPP_LITERAL(""));
|
||||||
|
releaseLock();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
base::Writer(level, "FILE", 0, "FUNCTION").construct(this, false) << log;
|
base::Writer(level, "FILE", 0, "FUNCTION").construct(this, false) << log;
|
||||||
@ -3332,23 +3302,23 @@ void Logger::log_(Level level, int vlevel, const T& log) {
|
|||||||
}
|
}
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
inline void Logger::log(Level level, const char* s, const T& value, const Args&... args) {
|
inline void Logger::log(Level level, const char* s, const T& value, const Args&... args) {
|
||||||
base::threading::ScopedLock scopedLock(lock());
|
acquireLock(); // released in Writer!
|
||||||
log_(level, 0, s, value, args...);
|
log_(level, 0, s, value, args...);
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void Logger::log(Level level, const T& log) {
|
inline void Logger::log(Level level, const T& log) {
|
||||||
base::threading::ScopedLock scopedLock(lock());
|
acquireLock(); // released in Writer!
|
||||||
log_(level, 0, log);
|
log_(level, 0, log);
|
||||||
}
|
}
|
||||||
# if ELPP_VERBOSE_LOG
|
# if ELPP_VERBOSE_LOG
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
inline void Logger::verbose(int vlevel, const char* s, const T& value, const Args&... args) {
|
inline void Logger::verbose(int vlevel, const char* s, const T& value, const Args&... args) {
|
||||||
base::threading::ScopedLock scopedLock(lock());
|
acquireLock(); // released in Writer!
|
||||||
log_(el::Level::Verbose, vlevel, s, value, args...);
|
log_(el::Level::Verbose, vlevel, s, value, args...);
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void Logger::verbose(int vlevel, const T& log) {
|
inline void Logger::verbose(int vlevel, const T& log) {
|
||||||
base::threading::ScopedLock scopedLock(lock());
|
acquireLock(); // released in Writer!
|
||||||
log_(el::Level::Verbose, vlevel, log);
|
log_(el::Level::Verbose, vlevel, log);
|
||||||
}
|
}
|
||||||
# else
|
# else
|
||||||
@ -3603,8 +3573,9 @@ class StackTrace : base::NoCopy {
|
|||||||
static const unsigned int kStackStart = 2; // We want to skip c'tor and StackTrace::generateNew()
|
static const unsigned int kStackStart = 2; // We want to skip c'tor and StackTrace::generateNew()
|
||||||
class StackTraceEntry {
|
class StackTraceEntry {
|
||||||
public:
|
public:
|
||||||
StackTraceEntry(std::size_t index, const char* loc, const char* demang, const char* hex, const char* addr);
|
StackTraceEntry(std::size_t index, const std::string& loc, const std::string& demang, const std::string& hex,
|
||||||
StackTraceEntry(std::size_t index, char* loc) :
|
const std::string& addr);
|
||||||
|
StackTraceEntry(std::size_t index, const std::string& loc) :
|
||||||
m_index(index),
|
m_index(index),
|
||||||
m_location(loc) {
|
m_location(loc) {
|
||||||
}
|
}
|
||||||
@ -3667,6 +3638,7 @@ class SysLogInitializer {
|
|||||||
public:
|
public:
|
||||||
SysLogInitializer(const char* processIdent, int options = 0, int facility = 0) {
|
SysLogInitializer(const char* processIdent, int options = 0, int facility = 0) {
|
||||||
#if defined(ELPP_SYSLOG)
|
#if defined(ELPP_SYSLOG)
|
||||||
|
(void)base::consts::kSysLogLoggerId;
|
||||||
openlog(processIdent, options, facility);
|
openlog(processIdent, options, facility);
|
||||||
#else
|
#else
|
||||||
ELPP_UNUSED(processIdent);
|
ELPP_UNUSED(processIdent);
|
||||||
@ -3789,6 +3761,11 @@ class Helpers : base::StaticClass {
|
|||||||
static inline const el::base::utils::CommandLineArgs* commandLineArgs(void) {
|
static inline const el::base::utils::CommandLineArgs* commandLineArgs(void) {
|
||||||
return ELPP->commandLineArgs();
|
return ELPP->commandLineArgs();
|
||||||
}
|
}
|
||||||
|
/// @brief Reserve space for custom format specifiers for performance
|
||||||
|
/// @see std::vector::reserve
|
||||||
|
static inline void reserveCustomFormatSpecifiers(std::size_t size) {
|
||||||
|
ELPP->m_customFormatSpecifiers.reserve(size);
|
||||||
|
}
|
||||||
/// @brief Installs user defined format specifier and handler
|
/// @brief Installs user defined format specifier and handler
|
||||||
static inline void installCustomFormatSpecifier(const CustomFormatSpecifier& customFormatSpecifier) {
|
static inline void installCustomFormatSpecifier(const CustomFormatSpecifier& customFormatSpecifier) {
|
||||||
ELPP->installCustomFormatSpecifier(customFormatSpecifier);
|
ELPP->installCustomFormatSpecifier(customFormatSpecifier);
|
||||||
@ -3802,7 +3779,7 @@ class Helpers : base::StaticClass {
|
|||||||
return ELPP->hasCustomFormatSpecifier(formatSpecifier);
|
return ELPP->hasCustomFormatSpecifier(formatSpecifier);
|
||||||
}
|
}
|
||||||
static inline void validateFileRolling(Logger* logger, Level level) {
|
static inline void validateFileRolling(Logger* logger, Level level) {
|
||||||
if (logger == nullptr) return;
|
if (ELPP == nullptr || logger == nullptr) return;
|
||||||
logger->m_typedConfigurations->validateFileRolling(level, ELPP->preRollOutCallback());
|
logger->m_typedConfigurations->validateFileRolling(level, ELPP->preRollOutCallback());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -3854,7 +3831,7 @@ class Loggers : base::StaticClass {
|
|||||||
/// @brief Returns current default
|
/// @brief Returns current default
|
||||||
static const Configurations* defaultConfigurations(void);
|
static const Configurations* defaultConfigurations(void);
|
||||||
/// @brief Returns log stream reference pointer if needed by user
|
/// @brief Returns log stream reference pointer if needed by user
|
||||||
static const base::LogStreamsReferenceMap* logStreamsReference(void);
|
static const base::LogStreamsReferenceMapPtr logStreamsReference(void);
|
||||||
/// @brief Default typed configuration based on existing defaultConf
|
/// @brief Default typed configuration based on existing defaultConf
|
||||||
static base::TypedConfigurations defaultTypedConfigurations(void);
|
static base::TypedConfigurations defaultTypedConfigurations(void);
|
||||||
/// @brief Populates all logger IDs in current repository.
|
/// @brief Populates all logger IDs in current repository.
|
||||||
@ -3865,7 +3842,7 @@ class Loggers : base::StaticClass {
|
|||||||
/// @brief Configures loggers using command line arg. Ensure you have already set command line args,
|
/// @brief Configures loggers using command line arg. Ensure you have already set command line args,
|
||||||
/// @return False if invalid argument or argument with no value provided, true if attempted to configure logger.
|
/// @return False if invalid argument or argument with no value provided, true if attempted to configure logger.
|
||||||
/// If true is returned that does not mean it has been configured successfully, it only means that it
|
/// If true is returned that does not mean it has been configured successfully, it only means that it
|
||||||
/// has attempeted to configure logger using configuration file provided in argument
|
/// has attempted to configure logger using configuration file provided in argument
|
||||||
static bool configureFromArg(const char* argKey);
|
static bool configureFromArg(const char* argKey);
|
||||||
/// @brief Flushes all loggers for all levels - Be careful if you dont know how many loggers are registered
|
/// @brief Flushes all loggers for all levels - Be careful if you dont know how many loggers are registered
|
||||||
static void flushAll(void);
|
static void flushAll(void);
|
||||||
|
@ -21,11 +21,14 @@ TEST(FileUtilsTest, GetSizeOfFile) {
|
|||||||
EXPECT_EQ(File::getSizeOfFile(fs), strlen(data));
|
EXPECT_EQ(File::getSizeOfFile(fs), strlen(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !ELPP_OS_EMSCRIPTEN
|
||||||
|
// this doesn't work as expected under emscripten's filesystem emulation
|
||||||
TEST(FileUtilsTest, PathExists) {
|
TEST(FileUtilsTest, PathExists) {
|
||||||
EXPECT_TRUE(File::pathExists(filename));
|
EXPECT_TRUE(File::pathExists(filename));
|
||||||
removeFile(filename);
|
removeFile(filename);
|
||||||
EXPECT_FALSE(File::pathExists(filename));
|
EXPECT_FALSE(File::pathExists(filename));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
TEST(FileUtilsTest, ExtractPathFromFilename) {
|
TEST(FileUtilsTest, ExtractPathFromFilename) {
|
||||||
EXPECT_EQ("/this/is/path/on/unix/", File::extractPathFromFilename("/this/is/path/on/unix/file.txt"));
|
EXPECT_EQ("/this/is/path/on/unix/", File::extractPathFromFilename("/this/is/path/on/unix/file.txt"));
|
||||||
@ -34,11 +37,17 @@ TEST(FileUtilsTest, ExtractPathFromFilename) {
|
|||||||
|
|
||||||
TEST(FileUtilsTest, CreatePath) {
|
TEST(FileUtilsTest, CreatePath) {
|
||||||
const char* path = "/tmp/my/one/long/path";
|
const char* path = "/tmp/my/one/long/path";
|
||||||
|
#if !ELPP_OS_EMSCRIPTEN
|
||||||
|
// it'll be reported as existing in emscripten
|
||||||
EXPECT_FALSE(File::pathExists(path));
|
EXPECT_FALSE(File::pathExists(path));
|
||||||
|
#endif
|
||||||
EXPECT_TRUE(File::createPath(path));
|
EXPECT_TRUE(File::createPath(path));
|
||||||
EXPECT_TRUE(File::pathExists(path));
|
EXPECT_TRUE(File::pathExists(path));
|
||||||
removeFile(path);
|
removeFile(path);
|
||||||
|
|
||||||
|
#if !ELPP_OS_EMSCRIPTEN
|
||||||
EXPECT_FALSE(File::pathExists(path));
|
EXPECT_FALSE(File::pathExists(path));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ TEST(FormatSpecifierTest, TestLevShortSpecifier) {
|
|||||||
el::Helpers::setArgs(2, param);
|
el::Helpers::setArgs(2, param);
|
||||||
|
|
||||||
|
|
||||||
// Regression origional %level still correct
|
// Regression original %level still correct
|
||||||
Configurations c;
|
Configurations c;
|
||||||
c.setGlobally(el::ConfigurationType::Format, "%level %msg");
|
c.setGlobally(el::ConfigurationType::Format, "%level %msg");
|
||||||
c.set(el::Level::Verbose, el::ConfigurationType::Format, "%level-%vlevel %msg");
|
c.set(el::Level::Verbose, el::ConfigurationType::Format, "%level-%vlevel %msg");
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
|
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
|
|
||||||
#if ELPP_OS_UNIX
|
#if ELPP_OS_UNIX && !ELPP_OS_EMSCRIPTEN
|
||||||
|
// this doesn't make any sense under emscripten; you can't shell out
|
||||||
TEST(OSUtilsTest, GetBashOutput) {
|
TEST(OSUtilsTest, GetBashOutput) {
|
||||||
const char* bashCommand = "echo 'test'";
|
const char* bashCommand = "echo 'test'";
|
||||||
std::string bashResult = OS::getBashOutput(bashCommand);
|
std::string bashResult = OS::getBashOutput(bashCommand);
|
||||||
|
@ -101,9 +101,17 @@ TEST(TypedConfigurationsTest, NonExistentFileCreation) {
|
|||||||
c.set(Level::Error, ConfigurationType::Filename, "/tmp/logs/el.gtest.log");
|
c.set(Level::Error, ConfigurationType::Filename, "/tmp/logs/el.gtest.log");
|
||||||
TypedConfigurations tConf(&c, ELPP->registeredLoggers()->logStreamsReference());
|
TypedConfigurations tConf(&c, ELPP->registeredLoggers()->logStreamsReference());
|
||||||
EXPECT_TRUE(tConf.toFile(Level::Global));
|
EXPECT_TRUE(tConf.toFile(Level::Global));
|
||||||
EXPECT_FALSE(tConf.toFile(Level::Info));
|
|
||||||
EXPECT_TRUE(tConf.toFile(Level::Error));
|
#if ELPP_OS_EMSCRIPTEN == 1
|
||||||
|
// On Emscripten, all files can be created; we actually expect success here
|
||||||
|
EXPECT_TRUE(tConf.toFile(Level::Info));
|
||||||
|
EXPECT_NE(nullptr, tConf.fileStream(Level::Info)); // not nullptr (emulated fs)
|
||||||
|
#else
|
||||||
EXPECT_EQ(nullptr, tConf.fileStream(Level::Info)); // nullptr
|
EXPECT_EQ(nullptr, tConf.fileStream(Level::Info)); // nullptr
|
||||||
|
EXPECT_FALSE(tConf.toFile(Level::Info));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EXPECT_TRUE(tConf.toFile(Level::Error));
|
||||||
EXPECT_NE(nullptr, tConf.fileStream(Level::Error)); // Not null
|
EXPECT_NE(nullptr, tConf.fileStream(Level::Error)); // Not null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
6
tools/cpplint.py
vendored
6
tools/cpplint.py
vendored
@ -113,7 +113,7 @@ Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
|
|||||||
ignored.
|
ignored.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
Assuing that src/.git exists, the header guard CPP variables for
|
Assuming that src/.git exists, the header guard CPP variables for
|
||||||
src/chrome/browser/ui/browser.h are:
|
src/chrome/browser/ui/browser.h are:
|
||||||
|
|
||||||
No flag => CHROME_BROWSER_UI_BROWSER_H_
|
No flag => CHROME_BROWSER_UI_BROWSER_H_
|
||||||
@ -196,7 +196,7 @@ _ERROR_CATEGORIES = [
|
|||||||
'whitespace/todo'
|
'whitespace/todo'
|
||||||
]
|
]
|
||||||
|
|
||||||
# The default state of the category filter. This is overrided by the --filter=
|
# The default state of the category filter. This is overridden by the --filter=
|
||||||
# flag. By default all errors are on, so only add here categories that should be
|
# flag. By default all errors are on, so only add here categories that should be
|
||||||
# off by default (i.e., categories that must be enabled by the --filter= flags).
|
# off by default (i.e., categories that must be enabled by the --filter= flags).
|
||||||
# All entries here should start with a '-' or '+', as in the --filter= flag.
|
# All entries here should start with a '-' or '+', as in the --filter= flag.
|
||||||
@ -4076,7 +4076,7 @@ def CheckForNonConstReference(filename, clean_lines, linenum,
|
|||||||
# inside declarators: reference parameter
|
# inside declarators: reference parameter
|
||||||
# We will exclude the first two cases by checking that we are not inside a
|
# We will exclude the first two cases by checking that we are not inside a
|
||||||
# function body, including one that was just introduced by a trailing '{'.
|
# function body, including one that was just introduced by a trailing '{'.
|
||||||
# TODO(unknwon): Doesn't account for preprocessor directives.
|
# TODO(unknown): Doesn't account for preprocessor directives.
|
||||||
# TODO(unknown): Doesn't account for 'catch(Exception& e)' [rare].
|
# TODO(unknown): Doesn't account for 'catch(Exception& e)' [rare].
|
||||||
check_params = False
|
check_params = False
|
||||||
if not nesting_state.stack:
|
if not nesting_state.stack:
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Bash script that helps with releasing new versions of EasyLogging++
|
# Bash script that helps with releasing new versions of Easylogging++
|
||||||
# Revision: 1.4
|
# Revision: 1.5
|
||||||
# @author mkhan3189
|
# author @abumusamq
|
||||||
#
|
#
|
||||||
# Usage:
|
# Usage:
|
||||||
# ./release.sh [repo-root] [homepage-repo-root] [curr-version] [new-version] [do-not-ask]
|
# ./release.sh [repo-root] [homepage-repo-root] [curr-version] [new-version] [do-not-ask]
|
||||||
@ -69,11 +69,12 @@ if [ "$confirm" = "y" ]; then
|
|||||||
cp $1/src/easylogging++.h .
|
cp $1/src/easylogging++.h .
|
||||||
cp $1/src/easylogging++.cc .
|
cp $1/src/easylogging++.cc .
|
||||||
cp $1/CHANGELOG.md CHANGELOG.txt
|
cp $1/CHANGELOG.md CHANGELOG.txt
|
||||||
cp $1/LICENCE LICENCE.txt
|
cp $1/README.md README.txt
|
||||||
zip easyloggingpp_v$NEW_VERSION.zip easylogging++.h easylogging++.cc LICENCE.txt CHANGELOG.txt
|
cp $1/LICENSE LICENSE.txt
|
||||||
tar -pczf easyloggingpp_v$NEW_VERSION.tar.gz easylogging++.h easylogging++.cc LICENCE.txt CHANGELOG.txt
|
zip easyloggingpp_v$NEW_VERSION.zip easylogging++.h easylogging++.cc LICENSE.txt CHANGELOG.txt README.txt
|
||||||
|
tar -pczf easyloggingpp_v$NEW_VERSION.tar.gz easylogging++.h easylogging++.cc LICENSE.txt CHANGELOG.txt README.txt
|
||||||
mv easyloggingpp_v$NEW_VERSION.zip $2/
|
mv easyloggingpp_v$NEW_VERSION.zip $2/
|
||||||
mv easyloggingpp_v$NEW_VERSION.tar.gz $2/
|
mv easyloggingpp_v$NEW_VERSION.tar.gz $2/
|
||||||
rm easylogging++.h easylogging++.cc CHANGELOG.txt LICENCE.txt
|
rm easylogging++.h easylogging++.cc CHANGELOG.txt LICENSE.txt README.txt
|
||||||
echo "\n---------- PLEASE CHANGE CMakeLists.txt MANUALLY ----------- \n"
|
echo "\n---------- PLEASE CHANGE CMakeLists.txt MANUALLY ----------- \n"
|
||||||
fi
|
fi
|
||||||
|
Loading…
Reference in New Issue
Block a user