mirror of
https://github.com/FairRootGroup/FairLogger.git
synced 2025-10-13 16:46:46 +00:00
Compare commits
49 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
71aac1199a | ||
|
2a4be75246 | ||
|
290070cbcf | ||
|
832376101d | ||
|
cd9e392ce0 | ||
|
27527ad87b | ||
|
f3d68fb4ba | ||
|
0ae9a697b4 | ||
|
fdbc047591 | ||
|
ea4067c474 | ||
|
067dcc0e26 | ||
|
0ab390c465 | ||
|
56b90a7445 | ||
|
7fc05f3808 | ||
|
d93fb0870b | ||
|
953eac19c8 | ||
|
9a6644c931 | ||
|
27040ea292 | ||
|
6545d0efa2 | ||
|
159a21c24b | ||
|
2494a9e85a | ||
|
d0b109015d | ||
|
ba7da2f79a | ||
|
1c7e7f566a | ||
|
b2dfdd1768 | ||
|
13ebedca3d | ||
|
1c43450582 | ||
|
f9af3a7269 | ||
|
064e034d25 | ||
|
3f55a16850 | ||
|
340b005997 | ||
|
f012a870e7 | ||
|
bcfe438862 | ||
|
4b3e6d3837 | ||
|
b30cacab12 | ||
|
c8d59d11fb | ||
|
a737a1de9c | ||
|
1cb941021c | ||
|
de1014dabb | ||
|
ce64f628b0 | ||
|
35ebc10204 | ||
|
1253bbbac8 | ||
|
e9bd3f2b62 | ||
|
1f3b2a2c82 | ||
|
2b37d0147e | ||
|
f0cbe0bd47 | ||
|
5f7197d987 | ||
|
b1cb6f8a99 | ||
|
56780689fc |
85
.github/workflows/ci.yml
vendored
Normal file
85
.github/workflows/ci.yml
vendored
Normal file
|
@ -0,0 +1,85 @@
|
|||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master, dev ]
|
||||
pull_request:
|
||||
branches: [ master, dev ]
|
||||
|
||||
jobs:
|
||||
build-linux:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
fedora: [38, 39, 40]
|
||||
include:
|
||||
- fedora: 38
|
||||
gcc: 13
|
||||
- fedora: 39
|
||||
gcc: 13
|
||||
- fedora: 40
|
||||
gcc: 14
|
||||
|
||||
container: ghcr.io/fairrootgroup/fairmq-dev/fedora-${{ matrix.fedora }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install additional dependencies
|
||||
run: |
|
||||
dnf install -y fmt-devel || true
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
cmake -B build -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DDISABLE_COLOR=ON \
|
||||
-DUSE_EXTERNAL_FMT=ON \
|
||||
-DUSE_BOOST_PRETTY_FUNCTION=ON
|
||||
|
||||
- name: Build
|
||||
run: cmake --build build
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
cd build
|
||||
ctest -V --output-on-failure
|
||||
|
||||
build-macos:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [macos-13, macos-14, macos-15]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Cache Homebrew packages
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/Library/Caches/Homebrew
|
||||
/usr/local/Homebrew/Library/Taps
|
||||
key: ${{ runner.os }}-${{ matrix.os }}-brew-${{ hashFiles('.github/workflows/ci.yml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-${{ matrix.os }}-brew-
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
brew install cmake ninja boost fmt
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
cmake -B build -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DDISABLE_COLOR=ON \
|
||||
-DUSE_EXTERNAL_FMT=ON \
|
||||
-DUSE_BOOST_PRETTY_FUNCTION=ON
|
||||
|
||||
- name: Build
|
||||
run: cmake --build build
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
cd build
|
||||
ctest -V --output-on-failure
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
|||
build/
|
||||
.vscode
|
||||
install/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
################################################################################
|
||||
# Copyright (C) 2018-2019 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||
# Copyright (C) 2018-2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||
# #
|
||||
# This software is distributed under the terms of the #
|
||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||
|
@ -7,15 +7,16 @@
|
|||
################################################################################
|
||||
|
||||
cmake_minimum_required(VERSION 3.9.4 FATAL_ERROR)
|
||||
cmake_policy(VERSION 3.9...3.15)
|
||||
cmake_policy(VERSION 3.9...3.30)
|
||||
|
||||
# Project ######################################################################
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
|
||||
include(FairLoggerLib)
|
||||
include(FairFindPackage2)
|
||||
|
||||
get_git_version()
|
||||
|
||||
project(FairLogger VERSION ${PROJECT_VERSION} LANGUAGES C CXX)
|
||||
project(FairLogger VERSION ${PROJECT_VERSION} LANGUAGES CXX)
|
||||
message(STATUS "${BWhite}${PROJECT_NAME}${CR} ${PROJECT_GIT_VERSION} from ${PROJECT_DATE}")
|
||||
|
||||
set_fairlogger_defaults()
|
||||
|
@ -53,32 +54,34 @@ add_library(FairLogger
|
|||
logger/Logger.cxx
|
||||
logger/Logger.h
|
||||
)
|
||||
target_compile_features(FairLogger PUBLIC cxx_std_17)
|
||||
|
||||
if(USE_BOOST_PRETTY_FUNCTION)
|
||||
target_link_libraries(FairLogger PUBLIC Boost::boost)
|
||||
target_compile_definitions(FairLogger PUBLIC FAIRLOGGER_USE_BOOST_PRETTY_FUNCTION)
|
||||
endif()
|
||||
|
||||
# legacy paths
|
||||
list(APPEND FAIRLOGGER_INSTALL_INCLUDE_DIRS ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR})
|
||||
|
||||
if(USE_EXTERNAL_FMT)
|
||||
target_link_libraries(FairLogger PUBLIC fmt::fmt)
|
||||
else()
|
||||
add_library(fmt INTERFACE)
|
||||
target_include_directories(fmt INTERFACE
|
||||
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/logger/bundled>
|
||||
$<INSTALL_INTERFACE:${PROJECT_INSTALL_INCDIR}/bundled>
|
||||
$<INSTALL_INTERFACE:${PROJECT_INSTALL_BUNDLEDINCDIR}>
|
||||
)
|
||||
target_compile_features(fmt INTERFACE cxx_std_11)
|
||||
target_compile_definitions(fmt INTERFACE FMT_HEADER_ONLY)
|
||||
target_link_libraries(FairLogger PUBLIC fmt)
|
||||
list(APPEND FAIRLOGGER_INSTALL_INCLUDE_DIRS ${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_INCDIR}/bundled)
|
||||
endif()
|
||||
|
||||
if(DEFINED FAIR_MIN_SEVERITY)
|
||||
target_compile_definitions(FairLogger PUBLIC "FAIR_MIN_SEVERITY=${FAIR_MIN_SEVERITY}")
|
||||
endif()
|
||||
|
||||
target_include_directories(FairLogger
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/logger>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/logger>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
)
|
||||
set_target_properties(FairLogger PROPERTIES
|
||||
VERSION ${PROJECT_GIT_VERSION}
|
||||
|
@ -86,8 +89,22 @@ set_target_properties(FairLogger PROPERTIES
|
|||
)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_executable(loggerTest test/loggerTest.cxx)
|
||||
target_link_libraries(loggerTest FairLogger pthread)
|
||||
add_executable(cycleTest test/cycle.cxx)
|
||||
target_link_libraries(cycleTest FairLogger)
|
||||
add_executable(loggerTest test/logger.cxx)
|
||||
target_link_libraries(loggerTest FairLogger)
|
||||
add_executable(macrosTest test/macros.cxx)
|
||||
target_link_libraries(macrosTest FairLogger)
|
||||
add_executable(nologTest test/nolog.cxx)
|
||||
target_link_libraries(nologTest FairLogger)
|
||||
add_executable(severityTest test/severity.cxx)
|
||||
target_link_libraries(severityTest FairLogger)
|
||||
add_executable(sinksTest test/sinks.cxx)
|
||||
target_link_libraries(sinksTest FairLogger)
|
||||
add_executable(threadsTest test/threads.cxx)
|
||||
target_link_libraries(threadsTest FairLogger pthread)
|
||||
add_executable(verbosityTest test/verbosity.cxx)
|
||||
target_link_libraries(verbosityTest FairLogger)
|
||||
endif()
|
||||
################################################################################
|
||||
|
||||
|
@ -127,7 +144,22 @@ install_cmake_package()
|
|||
|
||||
# Testing ######################################################################
|
||||
if(BUILD_TESTING)
|
||||
add_test(NAME loggerTest COMMAND $<TARGET_FILE:loggerTest>)
|
||||
add_test(NAME cycle COMMAND $<TARGET_FILE:cycleTest>)
|
||||
add_test(NAME logger COMMAND $<TARGET_FILE:loggerTest>)
|
||||
add_test(NAME macros COMMAND $<TARGET_FILE:macrosTest>)
|
||||
add_test(NAME nolog COMMAND $<TARGET_FILE:nologTest>)
|
||||
add_test(NAME severity COMMAND $<TARGET_FILE:severityTest>)
|
||||
add_test(NAME sinks COMMAND $<TARGET_FILE:sinksTest>)
|
||||
add_test(NAME threads COMMAND $<TARGET_FILE:threadsTest>)
|
||||
add_test(NAME verbosity COMMAND $<TARGET_FILE:verbosityTest>)
|
||||
endif()
|
||||
################################################################################
|
||||
|
||||
# Utils ########################################################################
|
||||
find_program(BASH bash HINTS "/bin")
|
||||
find_program(SINGULARITY singularity)
|
||||
if(BASH AND SINGULARITY)
|
||||
add_subdirectory(test/ci)
|
||||
endif()
|
||||
################################################################################
|
||||
|
||||
|
@ -212,6 +244,12 @@ else()
|
|||
endif()
|
||||
message(STATUS " ${BWhite}tests${CR} ${testing_summary}")
|
||||
message(STATUS " ")
|
||||
if(DEFINED FAIR_MIN_SEVERITY)
|
||||
message(STATUS " ${Cyan}FAIR_MIN_SEVERITY${CR} ${BGreen}${FAIR_MIN_SEVERITY}${CR} (change with ${BMagenta}-DFAIR_MIN_SEVERITY=...${CR})")
|
||||
else()
|
||||
message(STATUS " ${Cyan}FAIR_MIN_SEVERITY${CR} not defined${CR}, enabling all severities (change with ${BMagenta}-DFAIR_MIN_SEVERITY=...${CR})")
|
||||
endif()
|
||||
message(STATUS " ")
|
||||
message(STATUS " ${Cyan}INSTALL PREFIX${CR} ${BGreen}${CMAKE_INSTALL_PREFIX}${CR} (change with ${BMagenta}-DCMAKE_INSTALL_PREFIX=...${CR})")
|
||||
message(STATUS " ")
|
||||
################################################################################
|
||||
|
|
133
Dart.sh
133
Dart.sh
|
@ -1,133 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
|
||||
function print_example(){
|
||||
echo "##################################################################"
|
||||
echo "# To set the required parameters as source and the build #"
|
||||
echo "# directory for ctest, the linux flavour and the SIMPATH #"
|
||||
echo "# put the export commands below to a separate file which is read #"
|
||||
echo "# during execution and which is defined on the command line. #"
|
||||
echo "# Set all parameters according to your needs. #"
|
||||
echo "# LINUX_FLAVOUR should be set to the distribution you are using #"
|
||||
echo "# eg Debian, SuSe etc. #"
|
||||
echo "# An additional varibale NCPU can overwrite the default number #"
|
||||
echo "# of parallel processes used to compile the project. #"
|
||||
echo "# This can be usefull if one can use a distributed build system #"
|
||||
echo "# like icecream. #"
|
||||
echo "# For example #"
|
||||
echo "#!/bin/bash #"
|
||||
echo "export LINUX_FLAVOUR=<your linux flavour> #"
|
||||
echo "export FAIRSOFT_VERSION=<version of FairSoft> #"
|
||||
echo "export SIMPATH=<path to your FairSoft version> #"
|
||||
echo "export GIT_BRANCH=< master or dev> #"
|
||||
echo "export BUILDDIR=<dir where the build files go> #"
|
||||
echo "export SOURCEDIR=<location of the FairRoot sources> #"
|
||||
echo "#export NCPU=100 #"
|
||||
echo "##################################################################"
|
||||
}
|
||||
|
||||
if [ "$#" -lt "2" ]; then
|
||||
echo ""
|
||||
echo "-- Error -- Please start script with two parameters"
|
||||
echo "-- Error -- The first parameter is the ctest model."
|
||||
echo "-- Error -- Possible arguments are Nightly, Experimental, "
|
||||
echo "-- Error -- Continuous or Profile."
|
||||
echo "-- Error -- The second parameter is the file containg the"
|
||||
echo "-- Error -- Information about the setup at the client"
|
||||
echo "-- Error -- installation (see example below)."
|
||||
echo ""
|
||||
print_example
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# test if a valid ctest model is defined
|
||||
if [ "$1" == "Experimental" -o "$1" == "Nightly" -o "$1" == "Continuous" -o "$1" == "Profile" -o "$1" == "alfa_ci" ]; then
|
||||
echo ""
|
||||
else
|
||||
echo "-- Error -- This ctest model is not supported."
|
||||
echo "-- Error -- Possible arguments are Nightly, Experimental, Continuous or Profile."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# test if the input file exists and execute it
|
||||
if [ -e "$2" ];then
|
||||
source $2
|
||||
else
|
||||
echo "-- Error -- Input file does not exist."
|
||||
echo "-- Error -- Please choose existing input file."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# set the ctest model to command line parameter
|
||||
if [ "$1" == "alfa_ci" ]; then
|
||||
export ctest_model=Experimental
|
||||
else
|
||||
export ctest_model=$1
|
||||
fi
|
||||
|
||||
|
||||
# test for architecture
|
||||
arch=$(uname -s | tr '[A-Z]' '[a-z]')
|
||||
chip=$(uname -m | tr '[A-Z]' '[a-z]')
|
||||
|
||||
# extract information about the system and the machine and set
|
||||
# environment variables used by ctest
|
||||
SYSTEM=$arch-$chip
|
||||
if test -z $CXX ; then
|
||||
if [ "$arch" == "darwin" ]; then
|
||||
COMPILER=$(clang --version | head -n 1 | cut -d' ' -f1,2,4 | tr -d ' ')
|
||||
else
|
||||
COMPILER=gcc$(gcc -dumpversion)
|
||||
fi
|
||||
else
|
||||
COMPILER=$CXX$($CXX -dumpversion)
|
||||
fi
|
||||
|
||||
if [ "$1" == "alfa_ci" ]; then
|
||||
export LABEL1=alfa_ci-$COMPILER-FairLogger_$GIT_BRANCH
|
||||
export LABEL=$(echo $LABEL1 | sed -e 's#/#_#g')
|
||||
else
|
||||
export LABEL1=${LINUX_FLAVOUR}-$chip-$COMPILER-FairLogger_$GIT_BRANCH
|
||||
export LABEL=$(echo $LABEL1 | sed -e 's#/#_#g')
|
||||
fi
|
||||
|
||||
# get the number of processors
|
||||
# and information about the host
|
||||
if [ "$arch" = "linux" ];
|
||||
then
|
||||
if [ "$NCPU" != "" ];
|
||||
then
|
||||
export number_of_processors=$NCPU
|
||||
else
|
||||
export number_of_processors=$(cat /proc/cpuinfo | grep processor | wc -l)
|
||||
fi
|
||||
if [ -z "$SITE" ]; then
|
||||
export SITE=$(hostname -f)
|
||||
if [ -z "$SITE" ]; then
|
||||
export SITE=$(uname -n)
|
||||
fi
|
||||
fi
|
||||
elif [ "$arch" = "darwin" ];
|
||||
then
|
||||
if [ "$NCPU" != "" ];
|
||||
then
|
||||
export number_of_processors=$NCPU
|
||||
else
|
||||
export number_of_processors=$(sysctl -n hw.ncpu)
|
||||
fi
|
||||
if [ -z "$SITE" ]; then
|
||||
export SITE=$(hostname -s)
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "************************"
|
||||
date
|
||||
echo "LABEL: " $LABEL
|
||||
echo "SITE: " $SITE
|
||||
echo "Model: " ${ctest_model}
|
||||
echo "Nr. of processes: " $number_of_processors
|
||||
echo "************************"
|
||||
|
||||
cd $SOURCEDIR
|
||||
|
||||
ctest -S FairLoggerTest.cmake -V --VV
|
|
@ -1,69 +1,58 @@
|
|||
################################################################################
|
||||
# Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||
# Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||
# #
|
||||
# This software is distributed under the terms of the #
|
||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||
# copied verbatim in the file "LICENSE" #
|
||||
################################################################################
|
||||
Set(CTEST_SOURCE_DIRECTORY $ENV{SOURCEDIR})
|
||||
Set(CTEST_BINARY_DIRECTORY $ENV{BUILDDIR})
|
||||
Set(CTEST_SITE $ENV{SITE})
|
||||
Set(CTEST_BUILD_NAME $ENV{LABEL})
|
||||
Set(CTEST_CMAKE_GENERATOR "Unix Makefiles")
|
||||
Set(CTEST_PROJECT_NAME "FairLogger")
|
||||
|
||||
Find_Program(CTEST_GIT_COMMAND NAMES git)
|
||||
Set(CTEST_UPDATE_COMMAND "${CTEST_GIT_COMMAND}")
|
||||
cmake_host_system_information(RESULT fqdn QUERY FQDN)
|
||||
|
||||
Set(BUILD_COMMAND "make")
|
||||
Set(CTEST_BUILD_COMMAND "${BUILD_COMMAND} -j$ENV{number_of_processors}")
|
||||
set(CTEST_SOURCE_DIRECTORY .)
|
||||
set(CTEST_BINARY_DIRECTORY build)
|
||||
set(CTEST_CMAKE_GENERATOR "Ninja")
|
||||
set(CTEST_USE_LAUNCHERS ON)
|
||||
set(CTEST_CONFIGURATION_TYPE "RelWithDebInfo")
|
||||
|
||||
String(TOUPPER $ENV{ctest_model} _Model)
|
||||
Set(configure_options "-DCMAKE_BUILD_TYPE=${_Model}")
|
||||
if(NOT NCPUS)
|
||||
include(ProcessorCount)
|
||||
ProcessorCount(NCPUS)
|
||||
if(NCPUS EQUAL 0)
|
||||
set(NCPUS 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
Set(CTEST_USE_LAUNCHERS 1)
|
||||
Set(configure_options "${configure_options};-DCTEST_USE_LAUNCHERS=${CTEST_USE_LAUNCHERS}")
|
||||
if ("$ENV{CTEST_SITE}" STREQUAL "")
|
||||
set(CTEST_SITE "${fqdn}")
|
||||
else()
|
||||
set(CTEST_SITE $ENV{CTEST_SITE})
|
||||
endif()
|
||||
|
||||
Set(configure_options "${configure_options};-DDISABLE_COLOR=ON")
|
||||
if ("$ENV{CTEST_BUILD_NAME}" STREQUAL "")
|
||||
set(CTEST_BUILD_NAME "build")
|
||||
else()
|
||||
set(CTEST_BUILD_NAME $ENV{CTEST_BUILD_NAME})
|
||||
endif()
|
||||
|
||||
Set(EXTRA_FLAGS $ENV{EXTRA_FLAGS})
|
||||
If(EXTRA_FLAGS)
|
||||
Set(configure_options "${configure_options};${EXTRA_FLAGS}")
|
||||
EndIf()
|
||||
ctest_start(Continuous)
|
||||
|
||||
If($ENV{ctest_model} MATCHES Nightly OR $ENV{ctest_model} MATCHES Profile)
|
||||
list(APPEND options
|
||||
"-DDISABLE_COLOR=ON"
|
||||
"-DUSE_EXTERNAL_FMT=ON"
|
||||
"-DUSE_BOOST_PRETTY_FUNCTION=ON"
|
||||
)
|
||||
list(JOIN options ";" optionsstr)
|
||||
ctest_configure(OPTIONS "${optionsstr}")
|
||||
|
||||
Find_Program(GCOV_COMMAND gcov)
|
||||
If(GCOV_COMMAND)
|
||||
Message("Found GCOV: ${GCOV_COMMAND}")
|
||||
Set(CTEST_COVERAGE_COMMAND ${GCOV_COMMAND})
|
||||
EndIf(GCOV_COMMAND)
|
||||
ctest_build(FLAGS "-j${NCPUS}")
|
||||
|
||||
Set(ENV{ctest_model} Nightly)
|
||||
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}"
|
||||
PARALLEL_LEVEL 1
|
||||
SCHEDULE_RANDOM ON
|
||||
RETURN_VALUE _ctest_test_ret_val)
|
||||
|
||||
CTEST_EMPTY_BINARY_DIRECTORY(${CTEST_BINARY_DIRECTORY})
|
||||
ctest_submit()
|
||||
|
||||
EndIf()
|
||||
|
||||
Ctest_Start($ENV{ctest_model})
|
||||
|
||||
Ctest_Configure(BUILD "${CTEST_BINARY_DIRECTORY}"
|
||||
OPTIONS "${configure_options}"
|
||||
)
|
||||
|
||||
Ctest_Build(BUILD "${CTEST_BINARY_DIRECTORY}")
|
||||
|
||||
Ctest_Test(BUILD "${CTEST_BINARY_DIRECTORY}"
|
||||
PARALLEL_LEVEL $ENV{number_of_processors}
|
||||
RETURN_VALUE _ctest_test_ret_val
|
||||
)
|
||||
|
||||
If(GCOV_COMMAND)
|
||||
Ctest_Coverage(BUILD "${CTEST_BINARY_DIRECTORY}")
|
||||
EndIf()
|
||||
|
||||
Ctest_Submit()
|
||||
|
||||
if (_ctest_test_ret_val)
|
||||
if(_ctest_test_ret_val)
|
||||
Message(FATAL_ERROR "Some tests failed.")
|
||||
endif()
|
||||
|
|
79
Jenkinsfile
vendored
79
Jenkinsfile
vendored
|
@ -1,79 +0,0 @@
|
|||
#!groovy
|
||||
|
||||
def specToLabel(Map spec) {
|
||||
return "${spec.os}-${spec.arch}-${spec.compiler}-FairSoft_${spec.fairsoft}"
|
||||
}
|
||||
|
||||
def jobMatrix(String prefix, List specs, Closure callback) {
|
||||
def nodes = [:]
|
||||
for (spec in specs) {
|
||||
def label = specToLabel(spec)
|
||||
def fairsoft = spec.fairsoft
|
||||
def os = spec.os
|
||||
def compiler = spec.compiler
|
||||
nodes["${prefix}/${label}"] = {
|
||||
node(label) {
|
||||
githubNotify(context: "${prefix}/${label}", description: 'Building ...', status: 'PENDING')
|
||||
try {
|
||||
deleteDir()
|
||||
checkout scm
|
||||
|
||||
sh """\
|
||||
echo "export SIMPATH=\${SIMPATH_PREFIX}${fairsoft}" >> Dart.cfg
|
||||
echo "export FAIRSOFT_VERSION=${fairsoft}" >> Dart.cfg
|
||||
"""
|
||||
if (os =~ /Debian/ && compiler =~ /gcc9/) {
|
||||
sh '''\
|
||||
echo "source /etc/profile.d/modules.sh" >> Dart.cfg
|
||||
echo "module use /cvmfs/it.gsi.de/modulefiles" >> Dart.cfg
|
||||
echo "module load compiler/gcc/9.1.0" >> Dart.cfg
|
||||
'''
|
||||
}
|
||||
if (os =~ /MacOS/) {
|
||||
sh "echo \"export EXTRA_FLAGS='-DCMAKE_CXX_COMPILER=clang++'\" >> Dart.cfg"
|
||||
} else {
|
||||
sh "echo \"export EXTRA_FLAGS='-DCMAKE_CXX_COMPILER=g++'\" >> Dart.cfg"
|
||||
}
|
||||
|
||||
sh '''\
|
||||
echo "export BUILDDIR=$PWD/build" >> Dart.cfg
|
||||
echo "export SOURCEDIR=$PWD" >> Dart.cfg
|
||||
echo "export PATH=\\\$SIMPATH/bin:\\\$PATH" >> Dart.cfg
|
||||
echo "export GIT_BRANCH=$JOB_BASE_NAME" >> Dart.cfg
|
||||
echo "echo \\\$PATH" >> Dart.cfg
|
||||
'''
|
||||
sh 'cat Dart.cfg'
|
||||
|
||||
callback.call(spec, label)
|
||||
|
||||
deleteDir()
|
||||
githubNotify(context: "${prefix}/${label}", description: 'Success', status: 'SUCCESS')
|
||||
} catch (e) {
|
||||
deleteDir()
|
||||
githubNotify(context: "${prefix}/${label}", description: 'Error', status: 'ERROR')
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nodes
|
||||
}
|
||||
|
||||
pipeline{
|
||||
agent none
|
||||
stages {
|
||||
stage("Run CI Matrix") {
|
||||
steps{
|
||||
script {
|
||||
parallel(jobMatrix('alfa-ci/build', [
|
||||
[os: 'Debian8', arch: 'x86_64', compiler: 'gcc9.1.0', fairsoft: 'fairmq_dev'],
|
||||
[os: 'MacOS10.13', arch: 'x86_64', compiler: 'AppleLLVM10.0.0', fairsoft: 'fairmq_dev'],
|
||||
[os: 'MacOS10.14', arch: 'x86_64', compiler: 'AppleLLVM10.0.0', fairsoft: 'fairmq_dev'],
|
||||
]) { spec, label ->
|
||||
sh './Dart.sh alfa_ci Dart.cfg'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
#!groovy
|
||||
|
||||
def specToLabel(Map spec) {
|
||||
return "${spec.os}-${spec.arch}-${spec.compiler}-FairSoft_${spec.fairsoft}"
|
||||
}
|
||||
|
||||
def buildMatrix(List specs, Closure callback) {
|
||||
def nodes = [:]
|
||||
for (spec in specs) {
|
||||
def label = specToLabel(spec)
|
||||
def fairsoft = spec.fairsoft
|
||||
def os = spec.os
|
||||
def compiler = spec.compiler
|
||||
nodes[label] = {
|
||||
node(label) {
|
||||
try {
|
||||
deleteDir()
|
||||
checkout scm
|
||||
|
||||
sh """\
|
||||
echo "export SIMPATH=\${SIMPATH_PREFIX}${fairsoft}" >> Dart.cfg
|
||||
echo "export FAIRSOFT_VERSION=${fairsoft}" >> Dart.cfg
|
||||
"""
|
||||
if (os =~ /Debian/ && compiler =~ /gcc9/) {
|
||||
sh '''\
|
||||
echo "source /etc/profile.d/modules.sh" >> Dart.cfg
|
||||
echo "module use /cvmfs/it.gsi.de/modulefiles" >> Dart.cfg
|
||||
echo "module load compiler/gcc/9.1.0" >> Dart.cfg
|
||||
'''
|
||||
}
|
||||
if (os =~ /MacOS/) {
|
||||
sh "echo \"export EXTRA_FLAGS='-DCMAKE_CXX_COMPILER=clang++'\" >> Dart.cfg"
|
||||
} else {
|
||||
sh "echo \"export EXTRA_FLAGS='-DCMAKE_CXX_COMPILER=g++'\" >> Dart.cfg"
|
||||
}
|
||||
sh '''\
|
||||
echo "export BUILDDIR=$PWD/build" >> Dart.cfg
|
||||
echo "export SOURCEDIR=$PWD" >> Dart.cfg
|
||||
echo "export PATH=\\\$SIMPATH/bin:\\\$PATH" >> Dart.cfg
|
||||
echo "export GIT_BRANCH=dev" >> Dart.cfg
|
||||
echo "echo \\\$PATH" >> Dart.cfg
|
||||
'''
|
||||
sh 'cat Dart.cfg'
|
||||
|
||||
callback.call(spec, label)
|
||||
|
||||
deleteDir()
|
||||
} catch (e) {
|
||||
deleteDir()
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nodes
|
||||
}
|
||||
|
||||
pipeline{
|
||||
agent none
|
||||
triggers { cron('H 2 * * *') }
|
||||
stages {
|
||||
stage("Run Nightly Build/Test Matrix") {
|
||||
steps{
|
||||
script {
|
||||
parallel(buildMatrix([
|
||||
[os: 'Debian8', arch: 'x86_64', compiler: 'gcc9.1.0', fairsoft: 'fairmq_dev'],
|
||||
[os: 'MacOS10.13', arch: 'x86_64', compiler: 'AppleLLVM10.0.0', fairsoft: 'fairmq_dev'],
|
||||
[os: 'MacOS10.14', arch: 'x86_64', compiler: 'AppleLLVM10.0.0', fairsoft: 'fairmq_dev'],
|
||||
]) { spec, label ->
|
||||
sh './Dart.sh Nightly Dart.cfg'
|
||||
sh './Dart.sh Profile Dart.cfg'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
32
README.md
32
README.md
|
@ -66,11 +66,13 @@ All log calls go through the provided LOG(severity) macro. Output through this m
|
|||
A number of additional logging macros are provided:
|
||||
|
||||
- `LOGV(severity, verbosity)` Log the line with the provided verbosity, e.g. `LOG(info, veryhigh) << "abcd";`
|
||||
- `LOGF(severity, ...)` The arguments are given to `fmt::format` and the result is logged, e.g. `LOGF(info, "Hello {}!", "world");`
|
||||
- `LOGP(severity, ...)` The arguments are given to `fmt::printf` and the result is logged, e.g. `LOGP(info, "Hello %s!", "world");`
|
||||
- `LOGF(severity, ...)` The arguments are given to `fmt::printf`, which formats the string using a [printf syntax](https://fmt.dev/dev/api.html#printf-formatting) and the result is logged, e.g. `LOGF(info, "Hello %s!", "world");`
|
||||
- `LOGP(severity, ...)` The arguments are given to `fmt::format`, which formats the string using a [Python-like syntax](https://fmt.dev/dev/syntax.html) and the result is logged, e.g. `LOGP(info, "Hello {}!", "world");`
|
||||
- `LOGPD(severity, ...)` Same as `LOGP`, but accepts dynamic severity (runtime variable), e.g. `LOGPD(dynamicSeverity, "Hello {}!", "world");`
|
||||
- `LOGFD(severity, ...)` Same as `LOGF`, but accepts dynamic severity (runtime variable), e.g. `LOGFD(dynamicSeverity, "Hello %s!", "world");`
|
||||
- `LOGN(severity)` Logs an empty line, e.g. `LOGN(info);`
|
||||
- `LOG_IF(severity, condition)` Logs the line if the provided condition if true
|
||||
- `LOGD(severity, file, line, f)` Logs the line with the provided file, line and function parameters (only if the active verbosity allows it).
|
||||
- `LOGD(severity, file, line, f)` Logs the line with the provided file, line and function parameters (accepts severity as a variable), e.g. `LOGD(dynamicSeverity, "main.cpp", "42", "main");`
|
||||
|
||||
## 3. Severity
|
||||
|
||||
|
@ -93,10 +95,14 @@ where severity level is one of the following:
|
|||
"debug2",
|
||||
"debug1",
|
||||
"debug",
|
||||
"detail",
|
||||
"info",
|
||||
"state",
|
||||
"warn",
|
||||
"important",
|
||||
"alarm",
|
||||
"error",
|
||||
"critical",
|
||||
"fatal",
|
||||
```
|
||||
|
||||
|
@ -106,12 +112,12 @@ Logger will log the chosen severity and all above it (except "nolog", which deac
|
|||
|
||||
The minimum severity level can be configured at compile time via definition of `FAIR_MIN_SEVERITY`:
|
||||
|
||||
```C++
|
||||
#define FAIR_MIN_SEVERITY warn // only allow severities >= warn
|
||||
#include <fairlogger/Logger.h>
|
||||
```
|
||||
cmake -DFAIR_MIN_SEVERITY=warn ..
|
||||
```
|
||||
The above would only log severities equal to or above `warn`.
|
||||
|
||||
When `FAIR_MIN_SEVERITY` is not provided, it will be set to `info` if `NDEBUG` is defined, otherwise all severities will be enabled.
|
||||
When `FAIR_MIN_SEVERITY` is not provided all severities are enabled.
|
||||
|
||||
## 4. Verbosity
|
||||
|
||||
|
@ -126,8 +132,8 @@ it is same for all sinks, and is one of the following values: `verylow`, `low`,
|
|||
verylow: message
|
||||
low: [severity] message
|
||||
medium: [HH:MM:SS][severity] message
|
||||
high: [process name][HH:MM:SS][severity] message
|
||||
veryhigh: [process name][HH:MM:SS:µS][severity][file:line:function] message
|
||||
high: [process_name][HH:MM:SS][severity] message
|
||||
veryhigh: [process_name][HH:MM:SS:µS][severity][file:line:function] message
|
||||
user1: [severity] message
|
||||
user2: [severity] message
|
||||
user3: [severity] message
|
||||
|
@ -146,12 +152,12 @@ The `fair::Logger::VerbositySpec` object can e.g. be created like this:
|
|||
```C++
|
||||
auto spec = fair::VerbositySpec::Make(VerbositySpec::Info::timestamp_s,
|
||||
VerbositySpec::Info::process_name);
|
||||
// results in [HH:MM:SS][process name] message
|
||||
// results in [HH:MM:SS][process_name] message
|
||||
```
|
||||
|
||||
| **Argument** | **Result** |
|
||||
| --- | --- |
|
||||
| `fair::VerbositySpec::Info::process_name` | `[process name]` |
|
||||
| `fair::VerbositySpec::Info::process_name` | `[process_name]` |
|
||||
| `fair::VerbositySpec::Info::timestamp_s` | `[HH:MM:SS]` |
|
||||
| `fair::VerbositySpec::Info::timestamp_us` | `[HH:MM:SS:µS]` |
|
||||
| `fair::VerbositySpec::Info::severity` | `[severity]` |
|
||||
|
@ -220,7 +226,7 @@ If only output from custom sinks is desirable, console/file sinks must be deacti
|
|||
|
||||
## Naming conflicts?
|
||||
|
||||
By default, `<fairlogger/Logger.h>` defines unprefixed macros: `LOG`, `LOGV`, `LOGF`, `LOGP`, `LOGN`, `LOGD`, `LOG_IF`.
|
||||
By default, `<fairlogger/Logger.h>` defines unprefixed macros: `LOG`, `LOGV`, `LOGF`, `LOGP`, `LOGPD`, `LOGFD`, `LOGN`, `LOGD`, `LOG_IF`.
|
||||
|
||||
Define an option `FAIR_NO_LOG*` to prevent the above unprefixed macros to be defined, e.g.
|
||||
|
||||
|
@ -234,4 +240,4 @@ Define an option `FAIR_NO_LOG*` to prevent the above unprefixed macros to be def
|
|||
|
||||
GNU Lesser General Public Licence (LGPL) version 3, see [LICENSE](LICENSE).
|
||||
|
||||
Copyright (C) 2017-2020 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
|
||||
Copyright (C) 2017-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
|
||||
|
|
102
cmake/FairFindPackage2.cmake
Normal file
102
cmake/FairFindPackage2.cmake
Normal file
|
@ -0,0 +1,102 @@
|
|||
################################################################################
|
||||
# Copyright (C) 2018-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||
# #
|
||||
# This software is distributed under the terms of the #
|
||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||
# copied verbatim in the file "LICENSE" #
|
||||
################################################################################
|
||||
|
||||
#
|
||||
# find_package2(PRIVATE|PUBLIC|INTERFACE <pkgname>
|
||||
# [VERSION <version>]
|
||||
# [COMPONENTS <list of components>]
|
||||
# [ADD_REQUIREMENTS_OF <list of dep_pgkname>]
|
||||
# [any other option the native find_package supports]...)
|
||||
#
|
||||
# Wrapper around CMake's native find_package command to add some features and bookkeeping.
|
||||
#
|
||||
# The qualifier (PRIVATE|PUBLIC|INTERFACE) to the package to populate
|
||||
# the variables PROJECT_[INTERFACE]_<pkgname>_([VERSION]|[COMPONENTS]|PACKAGE_DEPENDENCIES)
|
||||
# accordingly. This bookkeeping information is used to print our dependency found summary
|
||||
# table and to generate a part of our CMake package.
|
||||
#
|
||||
# When a dependending package is listed with ADD_REQUIREMENTS_OF the variables
|
||||
# <dep_pkgname>_<pkgname>_VERSION|COMPONENTS are looked up to and added to the native
|
||||
# VERSION (selected highest version) and COMPONENTS (deduplicated) args.
|
||||
#
|
||||
# COMPONENTS and VERSION args are then just passed to the native find_package.
|
||||
#
|
||||
macro(find_package2 qualifier pkgname)
|
||||
cmake_parse_arguments(ARGS "" "VERSION" "COMPONENTS;ADD_REQUIREMENTS_OF" ${ARGN})
|
||||
|
||||
string(TOUPPER ${pkgname} pkgname_upper)
|
||||
set(__old_cpp__ ${CMAKE_PREFIX_PATH})
|
||||
set(CMAKE_PREFIX_PATH ${${pkgname_upper}_ROOT} $ENV{${pkgname_upper}_ROOT} ${CMAKE_PREFIX_PATH})
|
||||
|
||||
# build lists of required versions and components
|
||||
unset(__required_versions__)
|
||||
unset(__components__)
|
||||
if(ARGS_VERSION)
|
||||
list(APPEND __required_versions__ ${ARGS_VERSION})
|
||||
endif()
|
||||
if(ARGS_COMPONENTS)
|
||||
list(APPEND __components__ ${ARGS_COMPONENTS})
|
||||
endif()
|
||||
if(ARGS_ADD_REQUIREMENTS_OF)
|
||||
foreach(dep_pkgname IN LISTS ARGS_ADD_REQUIREMENTS_OF)
|
||||
if(${dep_pkgname}_${pkgname}_VERSION)
|
||||
list(APPEND __required_versions__ ${${dep_pkgname}_${pkgname}_VERSION})
|
||||
endif()
|
||||
if(${dep_pkgname}_${pkgname}_COMPONENTS)
|
||||
list(APPEND __components__ ${${dep_pkgname}_${pkgname}_COMPONENTS})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# select highest required version
|
||||
unset(__version__)
|
||||
if(__required_versions__)
|
||||
list(GET __required_versions__ 0 __version__)
|
||||
foreach(v IN LISTS __required_versions__)
|
||||
if(${v} VERSION_GREATER ${__version__})
|
||||
set(__version__ ${v})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
# deduplicate required component list
|
||||
if(__components__)
|
||||
list(REMOVE_DUPLICATES ARGS_COMPONENTS)
|
||||
endif()
|
||||
|
||||
# call native find_package
|
||||
if(__components__)
|
||||
find_package(${pkgname} ${__version__} QUIET COMPONENTS ${__components__} ${ARGS_UNPARSED_ARGUMENTS})
|
||||
else()
|
||||
find_package(${pkgname} ${__version__} QUIET ${ARGS_UNPARSED_ARGUMENTS})
|
||||
endif()
|
||||
|
||||
if(${pkgname}_FOUND)
|
||||
if(${qualifier} STREQUAL PRIVATE)
|
||||
set(PROJECT_${pkgname}_VERSION ${__version__})
|
||||
set(PROJECT_${pkgname}_COMPONENTS ${ARGS_COMPONENTS})
|
||||
set(PROJECT_PACKAGE_DEPENDENCIES ${PROJECT_PACKAGE_DEPENDENCIES} ${pkgname})
|
||||
elseif(${qualifier} STREQUAL PUBLIC)
|
||||
set(PROJECT_${pkgname}_VERSION ${__version__})
|
||||
set(PROJECT_${pkgname}_COMPONENTS ${ARGS_COMPONENTS})
|
||||
set(PROJECT_PACKAGE_DEPENDENCIES ${PROJECT_PACKAGE_DEPENDENCIES} ${pkgname})
|
||||
set(PROJECT_INTERFACE_${pkgname}_VERSION ${__version__})
|
||||
set(PROJECT_INTERFACE_${pkgname}_COMPONENTS ${ARGS_COMPONENTS})
|
||||
set(PROJECT_INTERFACE_PACKAGE_DEPENDENCIES ${PROJECT_INTERFACE_PACKAGE_DEPENDENCIES} ${pkgname})
|
||||
elseif(${qualifier} STREQUAL INTERFACE)
|
||||
set(PROJECT_INTERFACE_${pkgname}_VERSION ${__version__})
|
||||
set(PROJECT_INTERFACE_${pkgname}_COMPONENTS ${ARGS_COMPONENTS})
|
||||
set(PROJECT_INTERFACE_PACKAGE_DEPENDENCIES ${PROJECT_INTERFACE_PACKAGE_DEPENDENCIES} ${pkgname})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
unset(__version__)
|
||||
unset(__components__)
|
||||
unset(__required_versions__)
|
||||
set(CMAKE_PREFIX_PATH ${__old_cpp__})
|
||||
unset(__old_cpp__)
|
||||
endmacro()
|
|
@ -1,5 +1,5 @@
|
|||
################################################################################
|
||||
# Copyright (C) 2018-2019 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||
# Copyright (C) 2018-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||
# #
|
||||
# This software is distributed under the terms of the #
|
||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||
|
@ -15,8 +15,8 @@ set(@PROJECT_NAME@_GIT_DATE @PROJECT_GIT_DATE@)
|
|||
|
||||
set_and_check(@PROJECT_NAME@_PREFIX @PACKAGE_CMAKE_INSTALL_PREFIX@)
|
||||
set(@PROJECT_NAME@_BINDIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@PROJECT_INSTALL_BINDIR@)
|
||||
set(@PROJECT_NAME@_INCDIR @FAIRLOGGER_INSTALL_INCLUDE_DIRS@)
|
||||
set(@PROJECT_NAME@_INCDIRS @FAIRLOGGER_INSTALL_INCLUDE_DIRS@)
|
||||
set(@PROJECT_NAME@_INCDIR @PACKAGE_INSTALL_INCDIRS@)
|
||||
set(@PROJECT_NAME@_INCDIRS @PACKAGE_INSTALL_INCDIRS@)
|
||||
set_and_check(@PROJECT_NAME@_LIBDIR @PACKAGE_CMAKE_INSTALL_PREFIX@/@PROJECT_INSTALL_LIBDIR@)
|
||||
|
||||
set(@PROJECT_NAME@_CXX_STANDARD_REQUIRED @CMAKE_CXX_STANDARD_REQUIRED@)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
################################################################################
|
||||
# Copyright (C) 2018-2019 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||
# Copyright (C) 2018-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||
# #
|
||||
# This software is distributed under the terms of the #
|
||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||
|
@ -94,24 +94,22 @@ macro(set_fairlogger_defaults)
|
|||
endif()
|
||||
|
||||
# Handle C++ standard level
|
||||
set(PROJECT_MIN_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
if(NOT CMAKE_CXX_STANDARD)
|
||||
set(CMAKE_CXX_STANDARD ${PROJECT_MIN_CXX_STANDARD})
|
||||
elseif(${CMAKE_CXX_STANDARD} LESS ${PROJECT_MIN_CXX_STANDARD})
|
||||
set(PROJECT_MIN_CXX_STANDARD 17)
|
||||
if(CMAKE_CXX_STANDARD LESS PROJECT_MIN_CXX_STANDARD)
|
||||
message(FATAL_ERROR "A minimum CMAKE_CXX_STANDARD of ${PROJECT_MIN_CXX_STANDARD} is required.")
|
||||
endif()
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
# Generate compile_commands.json file (https://clang.llvm.org/docs/JSONCompilationDatabase.html)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
if(NOT DEFINED CMAKE_EXPORT_COMPILE_COMMANDS)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
endif()
|
||||
|
||||
if(NOT BUILD_SHARED_LIBS)
|
||||
if(NOT DEFINED BUILD_SHARED_LIBS)
|
||||
set(BUILD_SHARED_LIBS ON CACHE BOOL "Whether to build shared libraries or static archives")
|
||||
endif()
|
||||
|
||||
# Set -fPIC as default for all library types
|
||||
if(NOT CMAKE_POSITION_INDEPENDENT_CODE)
|
||||
if(NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
endif()
|
||||
|
||||
|
@ -122,6 +120,7 @@ macro(set_fairlogger_defaults)
|
|||
set(PROJECT_INSTALL_BINDIR ${CMAKE_INSTALL_BINDIR})
|
||||
set(PROJECT_INSTALL_LIBDIR ${CMAKE_INSTALL_LIBDIR})
|
||||
set(PROJECT_INSTALL_INCDIR ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME_LOWER})
|
||||
set(PROJECT_INSTALL_BUNDLEDINCDIR ${PROJECT_INSTALL_INCDIR}/bundled)
|
||||
set(PROJECT_INSTALL_DATADIR ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME_LOWER})
|
||||
|
||||
# https://cmake.org/Wiki/CMake_RPATH_handling
|
||||
|
@ -129,13 +128,13 @@ macro(set_fairlogger_defaults)
|
|||
list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_LIBDIR}" isSystemDir)
|
||||
if("${isSystemDir}" STREQUAL "-1")
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} "-Wl,--enable-new-dtags")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} "-Wl,--enable-new-dtags")
|
||||
set(CMAKE_INSTALL_RPATH "$ORIGIN/../${PROJECT_INSTALL_LIBDIR}")
|
||||
string(APPEND CMAKE_EXE_LINKER_FLAGS " -Wl,--enable-new-dtags")
|
||||
string(APPEND CMAKE_SHARED_LINKER_FLAGS " -Wl,--enable-new-dtags")
|
||||
list(APPEND CMAKE_INSTALL_RPATH "$ORIGIN/../${PROJECT_INSTALL_LIBDIR}")
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
set(CMAKE_INSTALL_RPATH "@loader_path/../${PROJECT_INSTALL_LIBDIR}")
|
||||
list(APPEND CMAKE_INSTALL_RPATH "@loader_path/../${PROJECT_INSTALL_LIBDIR}")
|
||||
else()
|
||||
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_LIBDIR}")
|
||||
list(APPEND CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${PROJECT_INSTALL_LIBDIR}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@ -227,6 +226,13 @@ macro(install_cmake_package)
|
|||
VERSION ${PROJECT_VERSION}
|
||||
COMPATIBILITY AnyNewerVersion
|
||||
)
|
||||
unset(PACKAGE_INSTALL_INCDIRS)
|
||||
list(APPEND PACKAGE_INSTALL_INCDIRS
|
||||
\$\{PACKAGE_PREFIX_DIR\}/${CMAKE_INSTALL_INCLUDEDIR})
|
||||
if(NOT USE_EXTERNAL_FMT)
|
||||
list(APPEND PACKAGE_INSTALL_INCDIRS
|
||||
\$\{PACKAGE_PREFIX_DIR\}/${PROJECT_INSTALL_BUNDLEDINCDIR})
|
||||
endif()
|
||||
generate_package_dependencies() # fills ${PACKAGE_DEPENDENCIES}
|
||||
string(TOUPPER ${CMAKE_BUILD_TYPE} PROJECT_BUILD_TYPE_UPPER)
|
||||
set(PROJECT_CXX_FLAGS ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${PROJECT_BUILD_TYPE_UPPER}})
|
||||
|
@ -242,98 +248,3 @@ macro(install_cmake_package)
|
|||
DESTINATION ${PACKAGE_INSTALL_DESTINATION}
|
||||
)
|
||||
endmacro()
|
||||
|
||||
#
|
||||
# find_package2(PRIVATE|PUBLIC|INTERFACE <pkgname>
|
||||
# [VERSION <version>]
|
||||
# [COMPONENTS <list of components>]
|
||||
# [ADD_REQUIREMENTS_OF <list of dep_pgkname>]
|
||||
# [any other option the native find_package supports]...)
|
||||
#
|
||||
# Wrapper around CMake's native find_package command to add some features and bookkeeping.
|
||||
#
|
||||
# The qualifier (PRIVATE|PUBLIC|INTERFACE) to the package to populate
|
||||
# the variables PROJECT_[INTERFACE]_<pkgname>_([VERSION]|[COMPONENTS]|PACKAGE_DEPENDENCIES)
|
||||
# accordingly. This bookkeeping information is used to print our dependency found summary
|
||||
# table and to generate a part of our CMake package.
|
||||
#
|
||||
# When a dependending package is listed with ADD_REQUIREMENTS_OF the variables
|
||||
# <dep_pkgname>_<pkgname>_VERSION|COMPONENTS are looked up to and added to the native
|
||||
# VERSION (selected highest version) and COMPONENTS (deduplicated) args.
|
||||
#
|
||||
# COMPONENTS and VERSION args are then just passed to the native find_package.
|
||||
#
|
||||
macro(find_package2 qualifier pkgname)
|
||||
cmake_parse_arguments(ARGS "" "VERSION" "COMPONENTS;ADD_REQUIREMENTS_OF" ${ARGN})
|
||||
|
||||
string(TOUPPER ${pkgname} pkgname_upper)
|
||||
set(__old_cpp__ ${CMAKE_PREFIX_PATH})
|
||||
set(CMAKE_PREFIX_PATH ${${pkgname_upper}_ROOT} $ENV{${pkgname_upper}_ROOT} ${CMAKE_PREFIX_PATH})
|
||||
|
||||
# build lists of required versions and components
|
||||
unset(__required_versions__)
|
||||
unset(__components__)
|
||||
if(ARGS_VERSION)
|
||||
list(APPEND __required_versions__ ${ARGS_VERSION})
|
||||
endif()
|
||||
if(ARGS_COMPONENTS)
|
||||
list(APPEND __components__ ${ARGS_COMPONENTS})
|
||||
endif()
|
||||
if(ARGS_ADD_REQUIREMENTS_OF)
|
||||
foreach(dep_pkgname IN LISTS ARGS_ADD_REQUIREMENTS_OF)
|
||||
if(${dep_pkgname}_${pkgname}_VERSION)
|
||||
list(APPEND __required_versions__ ${${dep_pkgname}_${pkgname}_VERSION})
|
||||
endif()
|
||||
if(${dep_pkgname}_${pkgname}_COMPONENTS)
|
||||
list(APPEND __components__ ${${dep_pkgname}_${pkgname}_COMPONENTS})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
# select highest required version
|
||||
unset(__version__)
|
||||
if(__required_versions__)
|
||||
list(GET __required_versions__ 0 __version__)
|
||||
foreach(v IN LISTS __required_versions__)
|
||||
if(${v} VERSION_GREATER ${__version__})
|
||||
set(__version__ ${v})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
# deduplicate required component list
|
||||
if(__components__)
|
||||
list(REMOVE_DUPLICATES ARGS_COMPONENTS)
|
||||
endif()
|
||||
|
||||
# call native find_package
|
||||
if(__components__)
|
||||
find_package(${pkgname} ${__version__} QUIET COMPONENTS ${__components__} ${ARGS_UNPARSED_ARGUMENTS})
|
||||
else()
|
||||
find_package(${pkgname} ${__version__} QUIET ${ARGS_UNPARSED_ARGUMENTS})
|
||||
endif()
|
||||
|
||||
if(${pkgname}_FOUND)
|
||||
if(${qualifier} STREQUAL PRIVATE)
|
||||
set(PROJECT_${pkgname}_VERSION ${__version__})
|
||||
set(PROJECT_${pkgname}_COMPONENTS ${ARGS_COMPONENTS})
|
||||
set(PROJECT_PACKAGE_DEPENDENCIES ${PROJECT_PACKAGE_DEPENDENCIES} ${pkgname})
|
||||
elseif(${qualifier} STREQUAL PUBLIC)
|
||||
set(PROJECT_${pkgname}_VERSION ${__version__})
|
||||
set(PROJECT_${pkgname}_COMPONENTS ${ARGS_COMPONENTS})
|
||||
set(PROJECT_PACKAGE_DEPENDENCIES ${PROJECT_PACKAGE_DEPENDENCIES} ${pkgname})
|
||||
set(PROJECT_INTERFACE_${pkgname}_VERSION ${__version__})
|
||||
set(PROJECT_INTERFACE_${pkgname}_COMPONENTS ${ARGS_COMPONENTS})
|
||||
set(PROJECT_INTERFACE_PACKAGE_DEPENDENCIES ${PROJECT_INTERFACE_PACKAGE_DEPENDENCIES} ${pkgname})
|
||||
elseif(${qualifier} STREQUAL INTERFACE)
|
||||
set(PROJECT_INTERFACE_${pkgname}_VERSION ${__version__})
|
||||
set(PROJECT_INTERFACE_${pkgname}_COMPONENTS ${ARGS_COMPONENTS})
|
||||
set(PROJECT_INTERFACE_PACKAGE_DEPENDENCIES ${PROJECT_INTERFACE_PACKAGE_DEPENDENCIES} ${pkgname})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
unset(__version__)
|
||||
unset(__components__)
|
||||
unset(__required_versions__)
|
||||
set(CMAKE_PREFIX_PATH ${__old_cpp__})
|
||||
unset(__old_cpp__)
|
||||
endmacro()
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
/********************************************************************************
|
||||
* Copyright (C) 2014-2019 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* Copyright (C) 2014-2025 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
#include "Logger.h"
|
||||
#include <string_view>
|
||||
|
||||
#if FMT_VERSION < 60000
|
||||
#include <fmt/time.h>
|
||||
|
@ -15,6 +16,7 @@
|
|||
|
||||
#include <cstdio> // printf
|
||||
#include <iostream>
|
||||
#include <iterator> // std::back_inserter
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -23,31 +25,12 @@ namespace fair
|
|||
|
||||
using VSpec = VerbositySpec;
|
||||
|
||||
string GetColoredSeverityString(Severity severity)
|
||||
{
|
||||
switch (severity) {
|
||||
case Severity::nolog: return "\033[01;39mNOLOG\033[0m"; break;
|
||||
case Severity::fatal: return "\033[01;31mFATAL\033[0m"; break;
|
||||
case Severity::error: return "\033[01;31mERROR\033[0m"; break;
|
||||
case Severity::warn: return "\033[01;33mWARN\033[0m"; break;
|
||||
case Severity::state: return "\033[01;35mSTATE\033[0m"; break;
|
||||
case Severity::info: return "\033[01;32mINFO\033[0m"; break;
|
||||
case Severity::debug: return "\033[01;34mDEBUG\033[0m"; break;
|
||||
case Severity::debug1: return "\033[01;34mDEBUG1\033[0m"; break;
|
||||
case Severity::debug2: return "\033[01;34mDEBUG2\033[0m"; break;
|
||||
case Severity::debug3: return "\033[01;34mDEBUG3\033[0m"; break;
|
||||
case Severity::debug4: return "\033[01;34mDEBUG4\033[0m"; break;
|
||||
case Severity::trace: return "\033[01;36mTRACE\033[0m"; break;
|
||||
default: return "UNKNOWN"; break;
|
||||
}
|
||||
}
|
||||
|
||||
bool Logger::fColored = false;
|
||||
fstream Logger::fFileStream;
|
||||
Verbosity Logger::fVerbosity = Verbosity::low;
|
||||
Severity Logger::fConsoleSeverity = Severity::info;
|
||||
Severity Logger::fConsoleSeverity = Severity::FAIR_MIN_SEVERITY > Severity::info ? Severity::FAIR_MIN_SEVERITY : Severity::info;
|
||||
Severity Logger::fMinSeverity = Severity::FAIR_MIN_SEVERITY > Severity::info ? Severity::FAIR_MIN_SEVERITY : Severity::info;
|
||||
Severity Logger::fFileSeverity = Severity::nolog;
|
||||
Severity Logger::fMinSeverity = Severity::info;
|
||||
function<void()> Logger::fFatalCallback;
|
||||
unordered_map<string, pair<Severity, function<void(const string& content, const LogMetaData& metadata)>>> Logger::fCustomSinks;
|
||||
mutex Logger::fMtx;
|
||||
|
@ -62,53 +45,59 @@ const string Logger::fProcessName = program_invocation_short_name;
|
|||
const string Logger::fProcessName = "?";
|
||||
#endif
|
||||
|
||||
const unordered_map<string, Verbosity> Logger::fVerbosityMap =
|
||||
const unordered_map<string_view, Verbosity> Logger::fVerbosityMap =
|
||||
{
|
||||
{ "veryhigh", Verbosity::veryhigh },
|
||||
{ "high", Verbosity::high },
|
||||
{ "medium", Verbosity::medium },
|
||||
{ "low", Verbosity::low },
|
||||
{ "verylow", Verbosity::verylow },
|
||||
{ "VERYHIGH", Verbosity::veryhigh },
|
||||
{ "HIGH", Verbosity::high },
|
||||
{ "MEDIUM", Verbosity::medium },
|
||||
{ "LOW", Verbosity::low },
|
||||
{ "VERYLOW", Verbosity::verylow },
|
||||
{ "user1", Verbosity::user1 },
|
||||
{ "user2", Verbosity::user2 },
|
||||
{ "user3", Verbosity::user3 },
|
||||
{ "user4", Verbosity::user4 }
|
||||
{ {"veryhigh"}, Verbosity::veryhigh },
|
||||
{ {"high"}, Verbosity::high },
|
||||
{ {"medium"}, Verbosity::medium },
|
||||
{ {"low"}, Verbosity::low },
|
||||
{ {"verylow"}, Verbosity::verylow },
|
||||
{ {"VERYHIGH"}, Verbosity::veryhigh },
|
||||
{ {"HIGH"}, Verbosity::high },
|
||||
{ {"MEDIUM"}, Verbosity::medium },
|
||||
{ {"LOW"}, Verbosity::low },
|
||||
{ {"VERYLOW"}, Verbosity::verylow },
|
||||
{ {"user1"}, Verbosity::user1 },
|
||||
{ {"user2"}, Verbosity::user2 },
|
||||
{ {"user3"}, Verbosity::user3 },
|
||||
{ {"user4"}, Verbosity::user4 }
|
||||
};
|
||||
|
||||
const unordered_map<string, Severity> Logger::fSeverityMap =
|
||||
const unordered_map<string_view, Severity> Logger::fSeverityMap =
|
||||
{
|
||||
{ "nolog", Severity::nolog },
|
||||
{ "NOLOG", Severity::nolog },
|
||||
{ "error", Severity::error },
|
||||
{ "ERROR", Severity::error },
|
||||
{ "warn", Severity::warn },
|
||||
{ "WARN", Severity::warn },
|
||||
{ "warning", Severity::warn },
|
||||
{ "WARNING", Severity::warn },
|
||||
{ "state", Severity::state },
|
||||
{ "STATE", Severity::state },
|
||||
{ "info", Severity::info },
|
||||
{ "INFO", Severity::info },
|
||||
{ "debug", Severity::debug },
|
||||
{ "DEBUG", Severity::debug },
|
||||
{ "debug1", Severity::debug1 },
|
||||
{ "DEBUG1", Severity::debug1 },
|
||||
{ "debug2", Severity::debug2 },
|
||||
{ "DEBUG2", Severity::debug2 },
|
||||
{ "debug3", Severity::debug3 },
|
||||
{ "DEBUG3", Severity::debug3 },
|
||||
{ "debug4", Severity::debug4 },
|
||||
{ "DEBUG4", Severity::debug4 },
|
||||
{ "trace", Severity::trace },
|
||||
{ "TRACE", Severity::trace }
|
||||
{ {"nolog"}, Severity::nolog },
|
||||
{ {"NOLOG"}, Severity::nolog },
|
||||
{ {"fatal"}, Severity::fatal },
|
||||
{ {"FATAL"}, Severity::fatal },
|
||||
{ {"critical"}, Severity::critical },
|
||||
{ {"error"}, Severity::error },
|
||||
{ {"ERROR"}, Severity::error },
|
||||
{ {"alarm"}, Severity::alarm },
|
||||
{ {"important"}, Severity::important },
|
||||
{ {"warn"}, Severity::warn },
|
||||
{ {"WARN"}, Severity::warn },
|
||||
{ {"warning"}, Severity::warn },
|
||||
{ {"WARNING"}, Severity::warn },
|
||||
{ {"state"}, Severity::state },
|
||||
{ {"STATE"}, Severity::state },
|
||||
{ {"info"}, Severity::info },
|
||||
{ {"INFO"}, Severity::info },
|
||||
{ {"detail"}, Severity::detail },
|
||||
{ {"debug"}, Severity::debug },
|
||||
{ {"DEBUG"}, Severity::debug },
|
||||
{ {"debug1"}, Severity::debug1 },
|
||||
{ {"DEBUG1"}, Severity::debug1 },
|
||||
{ {"debug2"}, Severity::debug2 },
|
||||
{ {"DEBUG2"}, Severity::debug2 },
|
||||
{ {"debug3"}, Severity::debug3 },
|
||||
{ {"DEBUG3"}, Severity::debug3 },
|
||||
{ {"debug4"}, Severity::debug4 },
|
||||
{ {"DEBUG4"}, Severity::debug4 },
|
||||
{ {"trace"}, Severity::trace },
|
||||
{ {"TRACE"}, Severity::trace }
|
||||
};
|
||||
|
||||
const array<string, 12> Logger::fSeverityNames =
|
||||
const array<string_view, 16> Logger::fSeverityNames =
|
||||
{
|
||||
{
|
||||
"NOLOG",
|
||||
|
@ -118,15 +107,19 @@ const array<string, 12> Logger::fSeverityNames =
|
|||
"DEBUG2",
|
||||
"DEBUG1",
|
||||
"DEBUG",
|
||||
"DETAIL",
|
||||
"INFO",
|
||||
"STATE",
|
||||
"WARN",
|
||||
"IMPORTANT",
|
||||
"ALARM",
|
||||
"ERROR",
|
||||
"CRITICAL",
|
||||
"FATAL"
|
||||
}
|
||||
};
|
||||
|
||||
const array<string, 9> Logger::fVerbosityNames =
|
||||
const array<string_view, 9> Logger::fVerbosityNames =
|
||||
{
|
||||
{
|
||||
"verylow",
|
||||
|
@ -154,12 +147,11 @@ map<Verbosity, VSpec> Logger::fVerbosities =
|
|||
{ Verbosity::user4, VSpec::Make(VSpec::Info::severity) }
|
||||
};
|
||||
|
||||
Logger::Logger(Severity severity, Verbosity verbosity, const string& file, const string& line, const string& func)
|
||||
Logger::Logger(Severity severity, Verbosity verbosity, std::string_view file, std::string_view line, std::string_view func)
|
||||
: fTimeCalculated(false)
|
||||
{
|
||||
if (!fIsDestructed) {
|
||||
size_t pos = file.rfind("/");
|
||||
|
||||
// fInfos.timestamp is filled conditionally
|
||||
// fInfos.us is filled conditionally
|
||||
fInfos.process_name = fProcessName;
|
||||
|
@ -175,27 +167,27 @@ Logger::Logger(Severity severity, Verbosity verbosity, const string& file, const
|
|||
for (const auto info : spec.fInfos) {
|
||||
switch (info) {
|
||||
case VSpec::Info::process_name:
|
||||
fmt::format_to(fBWPrefix, "[{}]", fInfos.process_name);
|
||||
fmt::format_to(std::back_inserter(fBWPrefix), "[{}]", fInfos.process_name);
|
||||
break;
|
||||
case VSpec::Info::timestamp_us:
|
||||
FillTimeInfos();
|
||||
fmt::format_to(fBWPrefix, "[{:%H:%M:%S}.{:06}]", fmt::localtime(fInfos.timestamp), fInfos.us.count());
|
||||
fmt::format_to(std::back_inserter(fBWPrefix), "[{:%H:%M:%S}.{:06}]", fmt::localtime(fInfos.timestamp), fInfos.us.count());
|
||||
break;
|
||||
case VSpec::Info::timestamp_s:
|
||||
FillTimeInfos();
|
||||
fmt::format_to(fBWPrefix, "[{:%H:%M:%S}]", fmt::localtime(fInfos.timestamp));
|
||||
fmt::format_to(std::back_inserter(fBWPrefix), "[{:%H:%M:%S}]", fmt::localtime(fInfos.timestamp));
|
||||
break;
|
||||
case VSpec::Info::severity:
|
||||
fmt::format_to(fBWPrefix, "[{}]", fInfos.severity_name);
|
||||
fmt::format_to(std::back_inserter(fBWPrefix), "[{}]", fInfos.severity_name);
|
||||
break;
|
||||
case VSpec::Info::file_line_function:
|
||||
fmt::format_to(fBWPrefix, "[{}:{}:{}]", fInfos.file, fInfos.line, fInfos.func);
|
||||
fmt::format_to(std::back_inserter(fBWPrefix), "[{}:{}:{}]", fInfos.file, fInfos.line, fInfos.func);
|
||||
break;
|
||||
case VSpec::Info::file_line:
|
||||
fmt::format_to(fBWPrefix, "[{}:{}]", fInfos.file, fInfos.line);
|
||||
fmt::format_to(std::back_inserter(fBWPrefix), "[{}:{}]", fInfos.file, fInfos.line);
|
||||
break;
|
||||
case VSpec::Info::file:
|
||||
fmt::format_to(fBWPrefix, "[{}]", fInfos.file);
|
||||
fmt::format_to(std::back_inserter(fBWPrefix), "[{}]", fInfos.file);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -203,7 +195,7 @@ Logger::Logger(Severity severity, Verbosity verbosity, const string& file, const
|
|||
}
|
||||
|
||||
if (spec.fSize > 0) {
|
||||
fmt::format_to(fBWPrefix, " ");
|
||||
fmt::format_to(std::back_inserter(fBWPrefix), " ");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -211,27 +203,27 @@ Logger::Logger(Severity severity, Verbosity verbosity, const string& file, const
|
|||
for (const auto info : spec.fInfos) {
|
||||
switch (info) {
|
||||
case VSpec::Info::process_name:
|
||||
fmt::format_to(fColorPrefix, "[{}]", ColorOut(Color::fgBlue, fInfos.process_name));
|
||||
fmt::format_to(std::back_inserter(fColorPrefix), "[{}]", ColorOut(Color::fgBlue, fInfos.process_name));
|
||||
break;
|
||||
case VSpec::Info::timestamp_us:
|
||||
FillTimeInfos();
|
||||
fmt::format_to(fColorPrefix, "[{}{:%H:%M:%S}.{:06}{}]", startColor(Color::fgCyan), fmt::localtime(fInfos.timestamp), fInfos.us.count(), endColor());
|
||||
fmt::format_to(std::back_inserter(fColorPrefix), "[{}{:%H:%M:%S}.{:06}{}]", startColor(Color::fgCyan), fmt::localtime(fInfos.timestamp), fInfos.us.count(), endColor());
|
||||
break;
|
||||
case VSpec::Info::timestamp_s:
|
||||
FillTimeInfos();
|
||||
fmt::format_to(fColorPrefix, "[{}{:%H:%M:%S}{}]", startColor(Color::fgCyan), fmt::localtime(fInfos.timestamp), endColor());
|
||||
fmt::format_to(std::back_inserter(fColorPrefix), "[{}{:%H:%M:%S}{}]", startColor(Color::fgCyan), fmt::localtime(fInfos.timestamp), endColor());
|
||||
break;
|
||||
case VSpec::Info::severity:
|
||||
fmt::format_to(fColorPrefix, "[{}]", GetColoredSeverityString(fInfos.severity));
|
||||
fmt::format_to(std::back_inserter(fColorPrefix), "[{}]", GetColoredSeverityString(fInfos.severity));
|
||||
break;
|
||||
case VSpec::Info::file_line_function:
|
||||
fmt::format_to(fColorPrefix, "[{}:{}:{}]", ColorOut(Color::fgBlue, fInfos.file), ColorOut(Color::fgYellow, fInfos.line), ColorOut(Color::fgBlue, fInfos.func));
|
||||
fmt::format_to(std::back_inserter(fColorPrefix), "[{}:{}:{}]", ColorOut(Color::fgBlue, fInfos.file), ColorOut(Color::fgYellow, fInfos.line), ColorOut(Color::fgBlue, fInfos.func));
|
||||
break;
|
||||
case VSpec::Info::file_line:
|
||||
fmt::format_to(fColorPrefix, "[{}:{}]", ColorOut(Color::fgBlue, fInfos.file), ColorOut(Color::fgYellow, fInfos.line));
|
||||
fmt::format_to(std::back_inserter(fColorPrefix), "[{}:{}]", ColorOut(Color::fgBlue, fInfos.file), ColorOut(Color::fgYellow, fInfos.line));
|
||||
break;
|
||||
case VSpec::Info::file:
|
||||
fmt::format_to(fColorPrefix, "[{}]", ColorOut(Color::fgBlue, fInfos.file));
|
||||
fmt::format_to(std::back_inserter(fColorPrefix), "[{}]", ColorOut(Color::fgBlue, fInfos.file));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -239,7 +231,7 @@ Logger::Logger(Severity severity, Verbosity verbosity, const string& file, const
|
|||
}
|
||||
|
||||
if (spec.fSize > 0) {
|
||||
fmt::format_to(fColorPrefix, " ");
|
||||
fmt::format_to(std::back_inserter(fColorPrefix), " ");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -294,8 +286,35 @@ void Logger::LogEmptyLine()
|
|||
// this call just to prevent any output to be added to the logger object
|
||||
}
|
||||
|
||||
string Logger::GetColoredSeverityString(Severity severity)
|
||||
{
|
||||
switch (severity) {
|
||||
case Severity::nolog: return "\033[01;39mNOLOG\033[0m"; break;
|
||||
case Severity::fatal: return "\033[01;31mFATAL\033[0m"; break;
|
||||
case Severity::critical: return "\033[01;31mCRITICAL\033[0m"; break;
|
||||
case Severity::error: return "\033[01;31mERROR\033[0m"; break;
|
||||
case Severity::alarm: return "\033[01;33mALARM\033[0m"; break;
|
||||
case Severity::important: return "\033[01;32mIMPORTANT\033[0m"; break;
|
||||
case Severity::warn: return "\033[01;33mWARN\033[0m"; break;
|
||||
case Severity::state: return "\033[01;35mSTATE\033[0m"; break;
|
||||
case Severity::info: return "\033[01;32mINFO\033[0m"; break;
|
||||
case Severity::detail: return "\033[01;32mDETAIL\033[0m"; break;
|
||||
case Severity::debug: return "\033[01;34mDEBUG\033[0m"; break;
|
||||
case Severity::debug1: return "\033[01;34mDEBUG1\033[0m"; break;
|
||||
case Severity::debug2: return "\033[01;34mDEBUG2\033[0m"; break;
|
||||
case Severity::debug3: return "\033[01;34mDEBUG3\033[0m"; break;
|
||||
case Severity::debug4: return "\033[01;34mDEBUG4\033[0m"; break;
|
||||
case Severity::trace: return "\033[01;36mTRACE\033[0m"; break;
|
||||
default: return "UNKNOWN"; break;
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::SetConsoleSeverity(const Severity severity)
|
||||
{
|
||||
if (severity < Severity::FAIR_MIN_SEVERITY && severity != Severity::nolog) {
|
||||
cout << "Requested severity is higher than the enabled compile-time FAIR_MIN_SEVERITY (" << Severity::FAIR_MIN_SEVERITY << "), ignoring" << endl;
|
||||
return;
|
||||
}
|
||||
fConsoleSeverity = severity;
|
||||
UpdateMinSeverity();
|
||||
}
|
||||
|
@ -317,6 +336,10 @@ Severity Logger::GetConsoleSeverity()
|
|||
|
||||
void Logger::SetFileSeverity(const Severity severity)
|
||||
{
|
||||
if (severity < Severity::FAIR_MIN_SEVERITY && severity != Severity::nolog) {
|
||||
cout << "Requested severity is higher than the enabled compile-time FAIR_MIN_SEVERITY (" << Severity::FAIR_MIN_SEVERITY << "), ignoring" << endl;
|
||||
return;
|
||||
}
|
||||
fFileSeverity = severity;
|
||||
UpdateMinSeverity();
|
||||
}
|
||||
|
@ -333,8 +356,17 @@ void Logger::SetFileSeverity(const string& severityStr)
|
|||
|
||||
void Logger::SetCustomSeverity(const string& key, const Severity severity)
|
||||
{
|
||||
fCustomSinks.at(key).first = severity; // TODO: range checks
|
||||
UpdateMinSeverity();
|
||||
try {
|
||||
if (severity < Severity::FAIR_MIN_SEVERITY && severity != Severity::nolog) {
|
||||
cout << "Requested severity is higher than the enabled compile-time FAIR_MIN_SEVERITY (" << Severity::FAIR_MIN_SEVERITY << "), ignoring" << endl;
|
||||
return;
|
||||
}
|
||||
fCustomSinks.at(key).first = severity;
|
||||
UpdateMinSeverity();
|
||||
} catch (const out_of_range& oor) {
|
||||
LOG(error) << "No custom sink with id '" << key << "' found";
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::SetCustomSeverity(const string& key, const string& severityStr)
|
||||
|
@ -347,11 +379,21 @@ void Logger::SetCustomSeverity(const string& key, const string& severityStr)
|
|||
}
|
||||
}
|
||||
|
||||
Severity Logger::GetCustomSeverity(const std::string& key)
|
||||
{
|
||||
try {
|
||||
return fCustomSinks.at(key).first;
|
||||
} catch (const out_of_range& oor) {
|
||||
LOG(error) << "No custom sink with id '" << key << "' found";
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::CycleConsoleSeverityUp()
|
||||
{
|
||||
int current = static_cast<int>(fConsoleSeverity);
|
||||
if (current == static_cast<int>(fSeverityNames.size()) - 1) {
|
||||
SetConsoleSeverity(static_cast<Severity>(0));
|
||||
SetConsoleSeverity(Severity::FAIR_MIN_SEVERITY);
|
||||
} else {
|
||||
SetConsoleSeverity(static_cast<Severity>(current + 1));
|
||||
}
|
||||
|
@ -359,7 +401,7 @@ void Logger::CycleConsoleSeverityUp()
|
|||
stringstream ss;
|
||||
|
||||
for (int i = 0; i < static_cast<int>(fSeverityNames.size()); ++i) {
|
||||
ss << (i == newCurrent ? ">" : " ") << fSeverityNames.at(i) << (i == newCurrent ? "<" : " ");
|
||||
ss << (i == newCurrent ? "<" : " ") << fSeverityNames.at(i) << (i == newCurrent ? ">" : " ");
|
||||
}
|
||||
|
||||
ss << "\n\n";
|
||||
|
@ -369,7 +411,7 @@ void Logger::CycleConsoleSeverityUp()
|
|||
void Logger::CycleConsoleSeverityDown()
|
||||
{
|
||||
int current = static_cast<int>(fConsoleSeverity);
|
||||
if (current == 0) {
|
||||
if (current == static_cast<int>(Severity::FAIR_MIN_SEVERITY)) {
|
||||
SetConsoleSeverity(static_cast<Severity>(fSeverityNames.size() - 1));
|
||||
} else {
|
||||
SetConsoleSeverity(static_cast<Severity>(current - 1));
|
||||
|
@ -378,7 +420,7 @@ void Logger::CycleConsoleSeverityDown()
|
|||
stringstream ss;
|
||||
|
||||
for (int i = 0; i < static_cast<int>(fSeverityNames.size()); ++i) {
|
||||
ss << (i == newCurrent ? ">" : " ") << fSeverityNames.at(i) << (i == newCurrent ? "<" : " ");
|
||||
ss << (i == newCurrent ? "<" : " ") << fSeverityNames.at(i) << (i == newCurrent ? ">" : " ");
|
||||
}
|
||||
|
||||
ss << "\n\n";
|
||||
|
@ -397,7 +439,7 @@ void Logger::CycleVerbosityUp()
|
|||
stringstream ss;
|
||||
|
||||
for (int i = 0; i < static_cast<int>(fVerbosityNames.size()); ++i) {
|
||||
ss << (i == newCurrent ? ">" : " ") << fVerbosityNames.at(i) << (i == newCurrent ? "<" : " ");
|
||||
ss << (i == newCurrent ? "<" : " ") << fVerbosityNames.at(i) << (i == newCurrent ? ">" : " ");
|
||||
}
|
||||
|
||||
ss << "\n\n";
|
||||
|
@ -416,7 +458,7 @@ void Logger::CycleVerbosityDown()
|
|||
stringstream ss;
|
||||
|
||||
for (int i = 0; i < static_cast<int>(fVerbosityNames.size()); ++i) {
|
||||
ss << (i == newCurrent ? ">" : " ") << fVerbosityNames.at(i) << (i == newCurrent ? "<" : " ");
|
||||
ss << (i == newCurrent ? "<" : " ") << fVerbosityNames.at(i) << (i == newCurrent ? ">" : " ");
|
||||
}
|
||||
|
||||
ss << "\n\n";
|
||||
|
@ -428,7 +470,7 @@ void Logger::UpdateMinSeverity()
|
|||
if (fFileSeverity == Severity::nolog) {
|
||||
fMinSeverity = fConsoleSeverity;
|
||||
} else {
|
||||
fMinSeverity = std::min(fConsoleSeverity, fFileSeverity);
|
||||
fMinSeverity = std::max(fConsoleSeverity, fFileSeverity);
|
||||
}
|
||||
|
||||
for (auto& it : fCustomSinks) {
|
||||
|
@ -440,13 +482,6 @@ void Logger::UpdateMinSeverity()
|
|||
}
|
||||
}
|
||||
|
||||
bool Logger::Logging(Severity severity)
|
||||
{
|
||||
return (severity >= fMinSeverity &&
|
||||
fMinSeverity > Severity::nolog) ||
|
||||
severity == Severity::fatal;
|
||||
}
|
||||
|
||||
bool Logger::Logging(const string& severityStr)
|
||||
{
|
||||
if (fSeverityMap.count(severityStr)) {
|
||||
|
@ -496,7 +531,7 @@ void Logger::SetConsoleColor(const bool colored)
|
|||
fColored = colored;
|
||||
}
|
||||
|
||||
void Logger::InitFileSink(const Severity severity, const string& filename, bool customizeName)
|
||||
string Logger::InitFileSink(const Severity severity, const string& filename, bool customizeName)
|
||||
{
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
if (fFileStream.is_open()) {
|
||||
|
@ -521,21 +556,27 @@ void Logger::InitFileSink(const Severity severity, const string& filename, bool
|
|||
fFileStream.open(fullName, fstream::out | fstream::app);
|
||||
|
||||
if (fFileStream.is_open()) {
|
||||
fFileSeverity = severity;
|
||||
if (severity < Severity::FAIR_MIN_SEVERITY && severity != Severity::nolog) {
|
||||
cout << "Requested file sink severity is higher than the enabled compile-time FAIR_MIN_SEVERITY (" << Severity::FAIR_MIN_SEVERITY << "), setting to " << Severity::FAIR_MIN_SEVERITY << endl;
|
||||
fFileSeverity = Severity::FAIR_MIN_SEVERITY;
|
||||
} else {
|
||||
fFileSeverity = severity;
|
||||
}
|
||||
UpdateMinSeverity();
|
||||
} else {
|
||||
cout << "Error opening file: " << fullName;
|
||||
}
|
||||
|
||||
return fullName;
|
||||
}
|
||||
|
||||
void Logger::InitFileSink(const string& severityStr, const string& filename, bool customizeName)
|
||||
string Logger::InitFileSink(const string& severityStr, const string& filename, bool customizeName)
|
||||
{
|
||||
if (fSeverityMap.count(severityStr)) {
|
||||
InitFileSink(fSeverityMap.at(severityStr), filename, customizeName);
|
||||
return InitFileSink(fSeverityMap.at(severityStr), filename, customizeName);
|
||||
} else {
|
||||
LOG(error) << "Unknown severity setting: '" << severityStr << "', setting to default 'info'.";
|
||||
InitFileSink(Severity::info, filename);
|
||||
return InitFileSink(Severity::info, filename);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -544,6 +585,8 @@ void Logger::RemoveFileSink()
|
|||
lock_guard<mutex> lock(fMtx);
|
||||
if (fFileStream.is_open()) {
|
||||
fFileStream.close();
|
||||
fFileSeverity = Severity::nolog;
|
||||
UpdateMinSeverity();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -577,10 +620,16 @@ void Logger::AddCustomSink(const string& key, Severity severity, function<void(c
|
|||
{
|
||||
lock_guard<mutex> lock(fMtx);
|
||||
if (fCustomSinks.count(key) == 0) {
|
||||
fCustomSinks.insert(make_pair(key, make_pair(severity, func)));
|
||||
if (severity < Severity::FAIR_MIN_SEVERITY && severity != Severity::nolog) {
|
||||
cout << "Requested custom sink severity is higher than the enabled compile-time FAIR_MIN_SEVERITY (" << Severity::FAIR_MIN_SEVERITY << "), setting to " << Severity::FAIR_MIN_SEVERITY << endl;
|
||||
fCustomSinks.insert(make_pair(key, make_pair(Severity::FAIR_MIN_SEVERITY, func)));
|
||||
} else {
|
||||
fCustomSinks.insert(make_pair(key, make_pair(severity, func)));
|
||||
}
|
||||
UpdateMinSeverity();
|
||||
} else {
|
||||
cout << "Logger::AddCustomSink: sink '" << key << "' already exists, will not add again. Remove first with Logger::RemoveCustomSink(const string& key)" << endl;
|
||||
throw runtime_error("Adding a sink with a key that already exists. Remove first.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -601,6 +650,7 @@ void Logger::RemoveCustomSink(const string& key)
|
|||
UpdateMinSeverity();
|
||||
} else {
|
||||
cout << "Logger::RemoveCustomSink: sink '" << key << "' doesn't exists, will not remove." << endl;
|
||||
throw runtime_error("Trying to remove a sink with a key that does not exist.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
170
logger/Logger.h
170
logger/Logger.h
|
@ -1,5 +1,5 @@
|
|||
/********************************************************************************
|
||||
* Copyright (C) 2014-2019 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* Copyright (C) 2014-2025 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
|
@ -13,8 +13,8 @@
|
|||
#warning "The symbol 'DEBUG' is used in FairRoot Logger. undefining..."
|
||||
#endif
|
||||
|
||||
#if !defined(FAIR_MIN_SEVERITY) && defined(NDEBUG)
|
||||
#define FAIR_MIN_SEVERITY info
|
||||
#ifndef FAIR_MIN_SEVERITY
|
||||
#define FAIR_MIN_SEVERITY nolog
|
||||
#endif
|
||||
|
||||
#ifdef FAIRLOGGER_USE_BOOST_PRETTY_FUNCTION
|
||||
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/printf.h>
|
||||
#include <fmt/ostream.h>
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
|
@ -39,10 +40,12 @@
|
|||
#include <mutex>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <time.h> // time_t
|
||||
#include <type_traits>
|
||||
#include <type_traits> // is_same
|
||||
#include <unordered_map>
|
||||
#include <string_view>
|
||||
#include <utility> // pair
|
||||
|
||||
namespace fair
|
||||
|
@ -57,52 +60,57 @@ enum class Severity : int
|
|||
debug2 = 4,
|
||||
debug1 = 5,
|
||||
debug = 6,
|
||||
info = 7,
|
||||
state = 8,
|
||||
warn = 9,
|
||||
error = 10,
|
||||
fatal = 11,
|
||||
// backwards-compatibility:
|
||||
NOLOG = nolog,
|
||||
TRACE = trace,
|
||||
DEBUG4 = debug4,
|
||||
DEBUG3 = debug3,
|
||||
DEBUG2 = debug2,
|
||||
DEBUG1 = debug1,
|
||||
DEBUG = debug,
|
||||
INFO = info,
|
||||
STATE = state,
|
||||
WARNING = warn,
|
||||
detail = 7,
|
||||
info = 8,
|
||||
state = 9,
|
||||
warn = 10,
|
||||
important = 11,
|
||||
alarm = 12,
|
||||
error = 13,
|
||||
critical = 14,
|
||||
fatal = 15,
|
||||
// aliases
|
||||
warning = warn,
|
||||
WARN = warn,
|
||||
ERROR = error,
|
||||
FATAL = fatal
|
||||
// backwards-compatibility
|
||||
NOLOG __attribute__((deprecated("Use LOG(nolog) instead (lowercase severity name)."))) = nolog,
|
||||
FATAL __attribute__((deprecated("Use LOG(fatal) instead (lowercase severity name)."))) = fatal,
|
||||
ERROR __attribute__((deprecated("Use LOG(error) instead (lowercase severity name)."))) = error,
|
||||
WARN __attribute__((deprecated("Use LOG(warn) instead (lowercase severity name)."))) = warn,
|
||||
WARNING __attribute__((deprecated("Use LOG(warning) instead (lowercase severity name)."))) = warn,
|
||||
STATE __attribute__((deprecated("Use LOG(state) instead (lowercase severity name)."))) = state,
|
||||
INFO __attribute__((deprecated("Use LOG(info) instead (lowercase severity name)."))) = info,
|
||||
DEBUG __attribute__((deprecated("Use LOG(debug) instead (lowercase severity name)."))) = debug,
|
||||
DEBUG1 __attribute__((deprecated("Use LOG(debug1) instead (lowercase severity name)."))) = debug1,
|
||||
DEBUG2 __attribute__((deprecated("Use LOG(debug2) instead (lowercase severity name)."))) = debug2,
|
||||
DEBUG3 __attribute__((deprecated("Use LOG(debug3) instead (lowercase severity name)."))) = debug3,
|
||||
DEBUG4 __attribute__((deprecated("Use LOG(debug4) instead (lowercase severity name)."))) = debug4,
|
||||
TRACE __attribute__((deprecated("Use LOG(trace) instead (lowercase severity name)."))) = trace
|
||||
};
|
||||
|
||||
// verbosity levels:
|
||||
// verylow: message
|
||||
// low: [severity] message
|
||||
// medium: [HH:MM:SS][severity] message
|
||||
// high: [process name][HH:MM:SS][severity] message
|
||||
// veryhigh: [process name][HH:MM:SS:µS][severity][file:line:function] message
|
||||
// high: [process_name][HH:MM:SS][severity] message
|
||||
// veryhigh: [process_name][HH:MM:SS:µS][severity][file:line:function] message
|
||||
enum class Verbosity : int
|
||||
{
|
||||
verylow,
|
||||
verylow = 0,
|
||||
low,
|
||||
medium,
|
||||
high,
|
||||
veryhigh,
|
||||
// backwards-compatibility:
|
||||
VERYLOW = verylow,
|
||||
LOW = low,
|
||||
MEDIUM = medium,
|
||||
HIGH = high,
|
||||
VERYHIGH = veryhigh,
|
||||
// extra slots for user-defined verbosities:
|
||||
user1,
|
||||
user2,
|
||||
user3,
|
||||
user4,
|
||||
// backwards-compatibility:
|
||||
VERYLOW = verylow,
|
||||
LOW = low,
|
||||
MEDIUM = medium,
|
||||
HIGH = high,
|
||||
VERYHIGH = veryhigh
|
||||
};
|
||||
|
||||
struct VerbositySpec
|
||||
|
@ -110,7 +118,7 @@ struct VerbositySpec
|
|||
enum class Info : int
|
||||
{
|
||||
__empty__ = 0, // used to initialize order array
|
||||
process_name, // [process name]
|
||||
process_name, // [process_name]
|
||||
timestamp_s, // [HH:MM:SS]
|
||||
timestamp_us, // [HH:MM:SS:µS]
|
||||
severity, // [severity]
|
||||
|
@ -169,19 +177,19 @@ struct LogMetaData
|
|||
{
|
||||
std::time_t timestamp;
|
||||
std::chrono::microseconds us;
|
||||
std::string process_name;
|
||||
std::string file;
|
||||
std::string line;
|
||||
std::string func;
|
||||
std::string severity_name;
|
||||
std::string_view process_name;
|
||||
std::string_view file;
|
||||
std::string_view line;
|
||||
std::string_view func;
|
||||
std::string_view severity_name;
|
||||
fair::Severity severity;
|
||||
};
|
||||
|
||||
class Logger
|
||||
{
|
||||
public:
|
||||
Logger(Severity severity, Verbosity verbosity, const std::string& file, const std::string& line, const std::string& func);
|
||||
Logger(Severity severity, const std::string& file, const std::string& line, const std::string& func)
|
||||
Logger(Severity severity, Verbosity verbosity, std::string_view file, std::string_view line, std::string_view func);
|
||||
Logger(Severity severity, std::string_view file, std::string_view line, std::string_view func)
|
||||
: Logger(severity, fVerbosity, file, line, func)
|
||||
{}
|
||||
virtual ~Logger() noexcept(false);
|
||||
|
@ -238,7 +246,8 @@ class Logger
|
|||
|
||||
static std::string startColor(Color color) { return fmt::format("\033[01;{}m", static_cast<int>(color)); }
|
||||
static std::string endColor() { return "\033[0m"; }
|
||||
static std::string ColorOut(Color c, const std::string& s) { return fmt::format("\033[01;{}m{}\033[0m", static_cast<int>(c), s); }
|
||||
static std::string ColorOut(Color c, std::string_view s) { return fmt::format("\033[01;{}m{}\033[0m", static_cast<int>(c), s); }
|
||||
static std::string GetColoredSeverityString(Severity severity);
|
||||
|
||||
static void SetConsoleSeverity(const Severity severity);
|
||||
static void SetConsoleSeverity(const std::string& severityStr);
|
||||
|
@ -246,16 +255,23 @@ class Logger
|
|||
|
||||
static void SetFileSeverity(const Severity severity);
|
||||
static void SetFileSeverity(const std::string& severityStr);
|
||||
static Severity GetFileSeverity() { return fFileSeverity; }
|
||||
|
||||
static void SetCustomSeverity(const std::string& key, const Severity severity);
|
||||
static void SetCustomSeverity(const std::string& key, const std::string& severityStr);
|
||||
static Severity GetCustomSeverity(const std::string& key);
|
||||
|
||||
static void CycleConsoleSeverityUp();
|
||||
static void CycleConsoleSeverityDown();
|
||||
static void CycleVerbosityUp();
|
||||
static void CycleVerbosityDown();
|
||||
|
||||
static bool Logging(const Severity severity);
|
||||
static bool Logging(const Severity severity)
|
||||
{
|
||||
return (severity >= fMinSeverity &&
|
||||
fMinSeverity > Severity::nolog) ||
|
||||
severity == Severity::fatal;
|
||||
}
|
||||
static bool Logging(const std::string& severityStr);
|
||||
|
||||
static void SetVerbosity(const Verbosity verbosity);
|
||||
|
@ -266,13 +282,13 @@ class Logger
|
|||
|
||||
static void SetConsoleColor(const bool colored = true);
|
||||
|
||||
static void InitFileSink(const Severity severity, const std::string& filename, bool customizeName = true);
|
||||
static void InitFileSink(const std::string& severityStr, const std::string& filename, bool customizeName = true);
|
||||
static std::string InitFileSink(const Severity severity, const std::string& filename, bool customizeName = true);
|
||||
static std::string InitFileSink(const std::string& severityStr, const std::string& filename, bool customizeName = true);
|
||||
|
||||
static void RemoveFileSink();
|
||||
|
||||
static std::string SeverityName(Severity s) { return fSeverityNames.at(static_cast<size_t>(s)); }
|
||||
static std::string VerbosityName(Verbosity v) { return fVerbosityNames.at(static_cast<size_t>(v)); }
|
||||
static std::string_view SeverityName(Severity s) { return fSeverityNames.at(static_cast<size_t>(s)); }
|
||||
static std::string_view VerbosityName(Verbosity v) { return fVerbosityNames.at(static_cast<size_t>(v)); }
|
||||
|
||||
static void OnFatal(std::function<void()> func);
|
||||
|
||||
|
@ -308,10 +324,10 @@ class Logger
|
|||
Logger& operator<<(std::ios_base& (*manip) (std::ios_base&));
|
||||
Logger& operator<<(std::ostream& (*manip) (std::ostream&));
|
||||
|
||||
static const std::unordered_map<std::string, Verbosity> fVerbosityMap;
|
||||
static const std::unordered_map<std::string, Severity> fSeverityMap;
|
||||
static const std::array<std::string, 12> fSeverityNames;
|
||||
static const std::array<std::string, 9> fVerbosityNames;
|
||||
static const std::unordered_map<std::string_view, Verbosity> fVerbosityMap;
|
||||
static const std::unordered_map<std::string_view, Severity> fSeverityMap;
|
||||
static const std::array<std::string_view, 16> fSeverityNames;
|
||||
static const std::array<std::string_view, 9> fVerbosityNames;
|
||||
|
||||
// protection for use after static destruction took place
|
||||
static bool fIsDestructed;
|
||||
|
@ -319,11 +335,7 @@ class Logger
|
|||
|
||||
static bool constexpr SuppressSeverity(Severity sev)
|
||||
{
|
||||
#ifdef FAIR_MIN_SEVERITY
|
||||
return sev < Severity::FAIR_MIN_SEVERITY;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -358,6 +370,9 @@ class Logger
|
|||
static std::map<Verbosity, VerbositySpec> fVerbosities;
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, const Severity& s) { return os << Logger::SeverityName(s); }
|
||||
inline std::ostream& operator<<(std::ostream& os, const Verbosity& v) { return os << Logger::VerbosityName(v); }
|
||||
|
||||
} // namespace fair
|
||||
|
||||
#define IMP_CONVERTTOSTRING(s) # s
|
||||
|
@ -379,16 +394,16 @@ class Logger
|
|||
#undef LOGV
|
||||
#define LOGV FAIR_LOGV
|
||||
#endif
|
||||
// allow user of this header file to prevent definition of the LOGF macro, by defining FAIR_NO_LOGF before including this header
|
||||
#ifndef FAIR_NO_LOGF
|
||||
#undef LOGF
|
||||
#define LOGF FAIR_LOGF
|
||||
#endif
|
||||
// allow user of this header file to prevent definition of the LOGP macro, by defining FAIR_NO_LOGP before including this header
|
||||
#ifndef FAIR_NO_LOGP
|
||||
#undef LOGP
|
||||
#define LOGP FAIR_LOGP
|
||||
#endif
|
||||
// allow user of this header file to prevent definition of the LOGF macro, by defining FAIR_NO_LOGF before including this header
|
||||
#ifndef FAIR_NO_LOGF
|
||||
#undef LOGF
|
||||
#define LOGF FAIR_LOGF
|
||||
#endif
|
||||
// allow user of this header file to prevent definition of the LOGN macro, by defining FAIR_NO_LOGN before including this header
|
||||
#ifndef FAIR_NO_LOGN
|
||||
#undef LOGN
|
||||
|
@ -404,38 +419,59 @@ class Logger
|
|||
#undef LOG_IF
|
||||
#define LOG_IF FAIR_LOG_IF
|
||||
#endif
|
||||
// allow user of this header file to prevent definition of the LOGPD macro, by defining FAIR_NO_LOGPD before including this header
|
||||
#ifndef FAIR_NO_LOGPD
|
||||
#undef LOGPD
|
||||
#define LOGPD FAIR_LOGPD
|
||||
#endif
|
||||
// allow user of this header file to prevent definition of the LOGFD macro, by defining FAIR_NO_LOGFD before including this header
|
||||
#ifndef FAIR_NO_LOGFD
|
||||
#undef LOGFD
|
||||
#define LOGFD FAIR_LOGFD
|
||||
#endif
|
||||
|
||||
// Log line if the provided severity is below or equals the configured one
|
||||
#define FAIR_LOG(severity) \
|
||||
if (fair::Logger::SuppressSeverity(fair::Severity::severity)) ; else \
|
||||
for (bool fairLOggerunLikelyvariable3 = false; !fair::Logger::SuppressSeverity(fair::Severity::severity) && !fairLOggerunLikelyvariable3; fairLOggerunLikelyvariable3 = true) \
|
||||
for (bool fairLOggerunLikelyvariable = false; fair::Logger::Logging(fair::Severity::severity) && !fairLOggerunLikelyvariable; fairLOggerunLikelyvariable = true) \
|
||||
fair::Logger(fair::Severity::severity, MSG_ORIGIN)
|
||||
|
||||
// Log line with the given verbosity if the provided severity is below or equals the configured one
|
||||
#define FAIR_LOGV(severity, verbosity) \
|
||||
if (fair::Logger::SuppressSeverity(fair::Severity::severity)) ; else \
|
||||
for (bool fairLOggerunLikelyvariable3 = false; !fair::Logger::SuppressSeverity(fair::Severity::severity) && !fairLOggerunLikelyvariable3; fairLOggerunLikelyvariable3 = true) \
|
||||
for (bool fairLOggerunLikelyvariable = false; fair::Logger::Logging(fair::Severity::severity) && !fairLOggerunLikelyvariable; fairLOggerunLikelyvariable = true) \
|
||||
fair::Logger(fair::Severity::severity, fair::Verbosity::verbosity, MSG_ORIGIN)
|
||||
|
||||
// Log with fmt- or printf-like formatting
|
||||
#define FAIR_LOGF(severity, ...) LOG(severity) << fmt::format(__VA_ARGS__)
|
||||
#define FAIR_LOGP(severity, ...) LOG(severity) << fmt::sprintf(__VA_ARGS__)
|
||||
#define FAIR_LOGP(severity, ...) FAIR_LOG(severity) << fmt::format(__VA_ARGS__)
|
||||
#define FAIR_LOGF(severity, ...) FAIR_LOG(severity) << fmt::sprintf(__VA_ARGS__)
|
||||
|
||||
// Log with fmt- or printf-like formatting (dynamic severity)
|
||||
#define FAIR_LOGPD(severity, ...) \
|
||||
for (bool fairLOggerunLikelyvariable3 = false; !fair::Logger::SuppressSeverity(severity) && !fairLOggerunLikelyvariable3; fairLOggerunLikelyvariable3 = true) \
|
||||
for (bool fairLOggerunLikelyvariable = false; fair::Logger::Logging(severity) && !fairLOggerunLikelyvariable; fairLOggerunLikelyvariable = true) \
|
||||
fair::Logger(severity, MSG_ORIGIN) << fmt::format(__VA_ARGS__)
|
||||
|
||||
#define FAIR_LOGFD(severity, ...) \
|
||||
for (bool fairLOggerunLikelyvariable3 = false; !fair::Logger::SuppressSeverity(severity) && !fairLOggerunLikelyvariable3; fairLOggerunLikelyvariable3 = true) \
|
||||
for (bool fairLOggerunLikelyvariable = false; fair::Logger::Logging(severity) && !fairLOggerunLikelyvariable; fairLOggerunLikelyvariable = true) \
|
||||
fair::Logger(severity, MSG_ORIGIN) << fmt::sprintf(__VA_ARGS__)
|
||||
|
||||
// Log an empty line
|
||||
#define FAIR_LOGN(severity) \
|
||||
if (fair::Logger::SuppressSeverity(fair::Severity::severity)) ; else \
|
||||
for (bool fairLOggerunLikelyvariable3 = false; !fair::Logger::SuppressSeverity(fair::Severity::severity) && !fairLOggerunLikelyvariable3; fairLOggerunLikelyvariable3 = true) \
|
||||
for (bool fairLOggerunLikelyvariable = false; fair::Logger::Logging(fair::Severity::severity) && !fairLOggerunLikelyvariable; fairLOggerunLikelyvariable = true) \
|
||||
fair::Logger(fair::Severity::severity, fair::Verbosity::verylow, MSG_ORIGIN).LogEmptyLine()
|
||||
|
||||
// Log with custom file, line, function
|
||||
#define FAIR_LOGD(severity, file, line, f) \
|
||||
if (fair::Logger::SuppressSeverity(severity)) ; else \
|
||||
for (bool fairLOggerunLikelyvariable3 = false; !fair::Logger::SuppressSeverity(severity) && !fairLOggerunLikelyvariable3; fairLOggerunLikelyvariable3 = true) \
|
||||
for (bool fairLOggerunLikelyvariable = false; fair::Logger::Logging(severity) && !fairLOggerunLikelyvariable; fairLOggerunLikelyvariable = true) \
|
||||
fair::Logger(severity, file, line, f)
|
||||
|
||||
#define FAIR_LOG_IF(severity, condition) \
|
||||
if (fair::Logger::SuppressSeverity(fair::Severity::severity)) ; else \
|
||||
for (bool fairLOggerunLikelyvariable4 = false; !fair::Logger::SuppressSeverity(fair::Severity::severity) && !fairLOggerunLikelyvariable4; fairLOggerunLikelyvariable4 = true) \
|
||||
for (bool fairLOggerunLikelyvariable2 = false; condition && !fairLOggerunLikelyvariable2; fairLOggerunLikelyvariable2 = true) \
|
||||
LOG(severity)
|
||||
FAIR_LOG(severity)
|
||||
|
||||
#endif // FAIR_LOGGER_H
|
||||
|
|
100
test/Common.h
Normal file
100
test/Common.h
Normal file
|
@ -0,0 +1,100 @@
|
|||
/********************************************************************************
|
||||
* Copyright (C) 2014-2020 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef FAIR_LOGGER_TEST_COMMON_H
|
||||
#define FAIR_LOGGER_TEST_COMMON_H
|
||||
|
||||
#include <fstream>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <regex>
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include <stdio.h> // fflush
|
||||
#include <unistd.h> // dup, dup2, close
|
||||
|
||||
namespace fair
|
||||
{
|
||||
namespace logger
|
||||
{
|
||||
namespace test
|
||||
{
|
||||
|
||||
template<typename ... T>
|
||||
auto ToStr(T&&... t) -> std::string
|
||||
{
|
||||
std::stringstream ss;
|
||||
(void)std::initializer_list<int>{(ss << t, 0)...};
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
template<int S>
|
||||
class StreamCapturer
|
||||
{
|
||||
public:
|
||||
explicit StreamCapturer()
|
||||
: mFd(S)
|
||||
, mOriginalFd(dup(S)) // create a copy of the given file descriptor
|
||||
{
|
||||
char name[] = "/tmp/fairlogger_test_capture.XXXXXX";
|
||||
|
||||
const int capturedFd = mkstemp(name); // create a unique temporary file
|
||||
if (capturedFd == -1) {
|
||||
std::cout << "Could not create tmp file " << name << " for test; does the test have access to the /tmp directory?" << std::endl;
|
||||
throw std::runtime_error("Could not create tmp file for test; does the test have access to the /tmp directory?");
|
||||
}
|
||||
mTmpFile = name;
|
||||
|
||||
fflush(nullptr); // flushes all open output streams
|
||||
dup2(capturedFd, mFd);
|
||||
close(capturedFd);
|
||||
}
|
||||
|
||||
std::string GetCapture()
|
||||
{
|
||||
fflush(nullptr); // flushes all open output streams
|
||||
std::ifstream t(mTmpFile);
|
||||
std::stringstream buffer;
|
||||
buffer << t.rdbuf();
|
||||
return buffer.str();
|
||||
}
|
||||
|
||||
~StreamCapturer()
|
||||
{
|
||||
dup2(mOriginalFd, mFd);
|
||||
close(mOriginalFd);
|
||||
remove(mTmpFile.c_str());
|
||||
}
|
||||
|
||||
private:
|
||||
const int mFd;
|
||||
int mOriginalFd;
|
||||
std::string mTmpFile;
|
||||
};
|
||||
|
||||
void CheckOutput(std::string const& expected, std::function<void()> f)
|
||||
{
|
||||
std::string output;
|
||||
{
|
||||
StreamCapturer<1> c;
|
||||
f();
|
||||
output = c.GetCapture();
|
||||
}
|
||||
const std::regex e(expected);
|
||||
if (!std::regex_match(output, e)) {
|
||||
throw std::runtime_error(std::string("MISMATCH:\n##### expected (regex):\n" + expected + "\n##### found:\n" + output));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace logger
|
||||
} // namespace fair
|
||||
|
||||
#endif // FAIR_LOGGER_TEST_COMMON_H
|
41
test/ci/CMakeLists.txt
Normal file
41
test/ci/CMakeLists.txt
Normal file
|
@ -0,0 +1,41 @@
|
|||
################################################################################
|
||||
# Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
|
||||
# #
|
||||
# This software is distributed under the terms of the #
|
||||
# GNU Lesser General Public Licence (LGPL) version 3, #
|
||||
# copied verbatim in the file "LICENSE" #
|
||||
################################################################################
|
||||
|
||||
function(container)
|
||||
cmake_parse_arguments(ARGS "" "OS;VERSION" "" ${ARGN})
|
||||
|
||||
set(container "${ARGS_OS}.${ARGS_VERSION}")
|
||||
set(def "${container}.def")
|
||||
set(log "${container}.log")
|
||||
set(target "${container}.sif")
|
||||
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/linux.def.in" ${def} @ONLY)
|
||||
|
||||
add_custom_command(OUTPUT ${target}
|
||||
COMMAND ${CMAKE_COMMAND} -E env ${BASH} -c
|
||||
"${SINGULARITY} build -f -F ${target} ${def} > ${log} 2>&1"
|
||||
VERBATIM
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMENT "Building fairlogger test container ${target}, logging to ${CMAKE_CURRENT_BINARY_DIR}/${log}"
|
||||
DEPENDS ${PACKAGE_SETUP_SCRIPT} ${bootstrap_cmake_script}
|
||||
)
|
||||
|
||||
list(APPEND containers ${target})
|
||||
set(containers ${containers} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
container(OS fedora VERSION 32)
|
||||
container(OS fedora VERSION 33)
|
||||
container(OS fedora VERSION 34)
|
||||
container(OS fedora VERSION 35)
|
||||
container(OS fedora VERSION 36)
|
||||
container(OS fedora VERSION 37)
|
||||
container(OS fedora VERSION 38)
|
||||
container(OS fedora VERSION 39)
|
||||
|
||||
add_custom_target(all-containers DEPENDS ${containers})
|
8
test/ci/linux.def.in
Normal file
8
test/ci/linux.def.in
Normal file
|
@ -0,0 +1,8 @@
|
|||
Bootstrap: docker
|
||||
From: @ARGS_OS@:@ARGS_VERSION@
|
||||
|
||||
%files
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/setup-@ARGS_OS@.sh /setup.sh
|
||||
|
||||
%post
|
||||
bash /setup.sh @ARGS_VERSION@
|
7
test/ci/setup-fedora.sh
Executable file
7
test/ci/setup-fedora.sh
Executable file
|
@ -0,0 +1,7 @@
|
|||
#! /bin/bash
|
||||
|
||||
dnf -y update
|
||||
dnf -y install https://alfa-ci.gsi.de/packages/rpm/fedora-$1-x86_64/fairsoft-release-dev.rpm
|
||||
dnf -y install boost-devel ninja-build 'dnf-command(builddep)' libasan liblsan libtsan libubsan clang-tools-extra
|
||||
dnf -y builddep fairlogger
|
||||
dnf -y clean all
|
35
test/ci/slurm-submit.sh
Executable file
35
test/ci/slurm-submit.sh
Executable file
|
@ -0,0 +1,35 @@
|
|||
#! /bin/bash
|
||||
|
||||
label="$1"
|
||||
jobsh="$2"
|
||||
|
||||
ALFACI_SLURM_CPUS=4
|
||||
if [ -z "$ALFACI_SLURM_EXTRA_OPTS" ]
|
||||
then
|
||||
ALFACI_SLURM_EXTRA_OPTS="--hint=compute_bound"
|
||||
fi
|
||||
ALFACI_SLURM_TIMEOUT=10
|
||||
if [ -z "$ALFACI_SLURM_QUEUE" ]
|
||||
then
|
||||
ALFACI_SLURM_QUEUE=main
|
||||
fi
|
||||
|
||||
echo "*** Slurm request options :"
|
||||
echo "*** Working directory ..: $PWD"
|
||||
echo "*** Queue ..............: $ALFACI_SLURM_QUEUE"
|
||||
echo "*** CPUs ...............: $ALFACI_SLURM_CPUS"
|
||||
echo "*** Wall Time ..........: $ALFACI_SLURM_TIMEOUT min"
|
||||
echo "*** Job Name ...........: ${label}"
|
||||
echo "*** Extra Options ......: ${ALFACI_SLURM_EXTRA_OPTS}"
|
||||
echo "*** Submitting job at ....: $(date -R)"
|
||||
(
|
||||
set -x
|
||||
srun -p $ALFACI_SLURM_QUEUE -c $ALFACI_SLURM_CPUS -n 1 \
|
||||
-t $ALFACI_SLURM_TIMEOUT \
|
||||
--job-name="${label}" \
|
||||
${ALFACI_SLURM_EXTRA_OPTS} \
|
||||
bash "${jobsh}"
|
||||
)
|
||||
retval=$?
|
||||
echo "*** Exit Code ............: $retval"
|
||||
exit "$retval"
|
81
test/cycle.cxx
Normal file
81
test/cycle.cxx
Normal file
|
@ -0,0 +1,81 @@
|
|||
/********************************************************************************
|
||||
* Copyright (C) 2015-2025 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file LICENSE" *
|
||||
********************************************************************************/
|
||||
|
||||
#include "Common.h"
|
||||
#include <Logger.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace fair;
|
||||
using namespace fair::logger::test;
|
||||
|
||||
int main()
|
||||
{
|
||||
try {
|
||||
Logger::SetConsoleColor(false);
|
||||
Logger::SetVerbosity(Verbosity::user4);
|
||||
|
||||
cout << "initial verbosity >" << Logger::GetVerbosity() << "<" << endl << endl;
|
||||
|
||||
array<Verbosity, 10> verbositiesUp{{ Verbosity::verylow, Verbosity::low, Verbosity::medium, Verbosity::high, Verbosity::veryhigh, Verbosity::user1, Verbosity::user2, Verbosity::user3, Verbosity::user4, Verbosity::verylow }};
|
||||
for (unsigned int i = 0; i < verbositiesUp.size(); ++i) {
|
||||
Logger::CycleVerbosityUp();
|
||||
if (Logger::GetVerbosity() != verbositiesUp.at(i)) { throw runtime_error(ToStr("Expected verbosity to be ", verbositiesUp.at(i), ", but it is ", Logger::GetVerbosity())); }
|
||||
}
|
||||
|
||||
array<Verbosity, 10> verbositiesDown{{ Verbosity::user4, Verbosity::user3, Verbosity::user2, Verbosity::user1, Verbosity::veryhigh, Verbosity::high, Verbosity::medium, Verbosity::low, Verbosity::verylow, Verbosity::user4 }};
|
||||
for (unsigned int i = 0; i < verbositiesDown.size(); ++i) {
|
||||
Logger::CycleVerbosityDown();
|
||||
if (Logger::GetVerbosity() != verbositiesDown.at(i)) { throw runtime_error(ToStr("Expected verbosity to be ", verbositiesDown.at(i), ", but it is ", Logger::GetVerbosity())); }
|
||||
}
|
||||
|
||||
Logger::SetConsoleSeverity(Severity::fatal);
|
||||
cout << "initial severity >" << Logger::GetConsoleSeverity() << "<" << endl << endl;
|
||||
|
||||
array<Severity, 16> severitiesUp{{ Severity::nolog, Severity::trace, Severity::debug4, Severity::debug3, Severity::debug2, Severity::debug1, Severity::debug, Severity::detail, Severity::info, Severity::state, Severity::warn, Severity::important, Severity::alarm, Severity::error, Severity::critical, Severity::fatal }};
|
||||
#ifdef FAIR_MIN_SEVERITY
|
||||
for (unsigned int i = static_cast<int>(Severity::FAIR_MIN_SEVERITY); i < severitiesUp.size(); ++i) {
|
||||
#else
|
||||
for (unsigned int i = 0; i < severitiesUp.size(); ++i) {
|
||||
#endif
|
||||
Logger::CycleConsoleSeverityUp();
|
||||
if (Logger::GetConsoleSeverity() != severitiesUp.at(i)) { throw runtime_error(ToStr("Expected severity to be ", severitiesUp.at(i), ", but it is ", Logger::GetConsoleSeverity())); }
|
||||
}
|
||||
Logger::CycleConsoleSeverityUp();
|
||||
#ifdef FAIR_MIN_SEVERITY
|
||||
if (Logger::GetConsoleSeverity() != Severity::FAIR_MIN_SEVERITY) { throw runtime_error(ToStr("Expected severity to be ", Severity::nolog, ", but it is ", Logger::GetConsoleSeverity())); }
|
||||
#else
|
||||
if (Logger::GetConsoleSeverity() != Severity::nolog) { throw runtime_error(ToStr("Expected severity to be ", Severity::nolog, ", but it is ", Logger::GetConsoleSeverity())); }
|
||||
#endif
|
||||
|
||||
Logger::SetConsoleSeverity(Severity::fatal);
|
||||
cout << "initial severity >" << Logger::GetConsoleSeverity() << "<" << endl << endl;
|
||||
|
||||
array<Severity, 16> severitiesDown{{ Severity::critical, Severity::error, Severity::alarm, Severity::important, Severity::warn, Severity::state, Severity::info, Severity::detail, Severity::debug, Severity::debug1, Severity::debug2, Severity::debug3, Severity::debug4, Severity::trace, Severity::nolog, Severity::fatal }};
|
||||
#ifdef FAIR_MIN_SEVERITY
|
||||
for (unsigned int i = 0; i < severitiesDown.size() - static_cast<int>(Severity::FAIR_MIN_SEVERITY) - 1; ++i) {
|
||||
#else
|
||||
for (unsigned int i = 0; i < severitiesDown.size(); ++i) {
|
||||
#endif
|
||||
Logger::CycleConsoleSeverityDown();
|
||||
if (Logger::GetConsoleSeverity() != severitiesDown.at(i)) { throw runtime_error(ToStr("Expected severity to be ", severitiesDown.at(i), ", but it is ", Logger::GetConsoleSeverity())); }
|
||||
}
|
||||
Logger::CycleConsoleSeverityDown();
|
||||
#ifdef FAIR_MIN_SEVERITY
|
||||
if (Logger::GetConsoleSeverity() != Severity::fatal) { throw runtime_error(ToStr("Expected severity to be ", Severity::fatal, ", but it is ", Logger::GetConsoleSeverity())); }
|
||||
#else
|
||||
if (Logger::GetConsoleSeverity() != Severity::error) { throw runtime_error(ToStr("Expected severity to be ", Severity::error, ", but it is ", Logger::GetConsoleSeverity())); }
|
||||
#endif
|
||||
} catch (runtime_error& rte) {
|
||||
cout << rte.what() << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
62
test/logger.cxx
Normal file
62
test/logger.cxx
Normal file
|
@ -0,0 +1,62 @@
|
|||
/********************************************************************************
|
||||
* Copyright (C) 2014-2020 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
|
||||
#include <Logger.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace fair;
|
||||
|
||||
void printEverySeverity()
|
||||
{
|
||||
static int i = 1;
|
||||
|
||||
LOG(nolog) << "nolog message, counter: " << i++;
|
||||
LOG(trace) << "trace message, counter: " << i++;
|
||||
LOG(debug4) << "debug4 message, counter: " << i++;
|
||||
LOG(debug3) << "debug3 message, counter: " << i++;
|
||||
LOG(debug2) << "debug2 message, counter: " << i++;
|
||||
LOG(debug1) << "debug1 message, counter: " << i++;
|
||||
LOG(debug) << "debug message, counter: " << i++;
|
||||
LOG(detail) << "detail message, counter: " << i++;
|
||||
LOG(info) << "info message, counter: " << i++;
|
||||
LOG(state) << "state message, counter: " << i++;
|
||||
LOG(warn) << "warning message, counter: " << i++;
|
||||
LOG(important) << "important message, counter: " << i++;
|
||||
LOG(alarm) << "alarm message, counter: " << i++;
|
||||
LOG(error) << "error message, counter: " << i++;
|
||||
LOG(critical) << "critical message, counter: " << i++;
|
||||
LOG(fatal) << "fatal message, counter: " << i++;
|
||||
}
|
||||
|
||||
void printAllVerbositiesWithSeverity(Severity sev)
|
||||
{
|
||||
Logger::SetConsoleSeverity(sev);
|
||||
|
||||
for (uint32_t i = 0; i < Logger::fVerbosityNames.size(); ++i) {
|
||||
cout << "##### testing severity '" << sev << "' with verbosity '" << Logger::fVerbosityNames.at(i) << "'" << endl;
|
||||
Logger::SetVerbosity(static_cast<Verbosity>(i));
|
||||
printEverySeverity();
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
Logger::SetConsoleColor(true);
|
||||
Logger::SetVerbosity(Verbosity::veryhigh);
|
||||
cout << "##### GetConsoleSeverity = " << Logger::SeverityName(Logger::GetConsoleSeverity()) << endl;
|
||||
|
||||
cout << "##### testing severities..." << endl;
|
||||
|
||||
for (uint32_t i = 0; i < Logger::fSeverityNames.size(); ++i) {
|
||||
printAllVerbositiesWithSeverity(static_cast<Severity>(i));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,208 +0,0 @@
|
|||
/********************************************************************************
|
||||
* Copyright (C) 2014-2019 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
#include <Logger.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
|
||||
using namespace std;
|
||||
using namespace fair;
|
||||
|
||||
void printEverySeverity()
|
||||
{
|
||||
static int i = 1;
|
||||
|
||||
LOG(nolog) << "nolog message " << i++;
|
||||
LOG(error) << "error message " << i++;
|
||||
LOG(warn) << "warning message " << i++;
|
||||
LOG(state) << "state message " << i++;
|
||||
LOG(info) << "info message " << i++;
|
||||
LOG(debug) << "debug message " << i++;
|
||||
LOG(debug1) << "debug1 message " << i++;
|
||||
LOG(debug2) << "debug2 message " << i++;
|
||||
LOG(debug3) << "debug3 message " << i++;
|
||||
LOG(debug4) << "debug4 message " << i++;
|
||||
LOG(trace) << "trace message " << i++;
|
||||
}
|
||||
|
||||
void printAllVerbositiesWithSeverity(Severity sev)
|
||||
{
|
||||
Logger::SetConsoleSeverity(sev);
|
||||
|
||||
cout << endl << "cout: >>> testing severity '" << Logger::SeverityName(sev) << "' with 'verylow' verbosity..." << endl;
|
||||
Logger::SetVerbosity(Verbosity::verylow);
|
||||
printEverySeverity();
|
||||
cout << endl << "cout: >>> testing severity '" << Logger::SeverityName(sev) << "' with 'low' verbosity..." << endl;
|
||||
Logger::SetVerbosity(Verbosity::low);
|
||||
printEverySeverity();
|
||||
cout << endl << "cout: >>> testing severity '" << Logger::SeverityName(sev) << "' with 'medium' verbosity..." << endl;
|
||||
Logger::SetVerbosity(Verbosity::medium);
|
||||
printEverySeverity();
|
||||
cout << endl << "cout: >>> testing severity '" << Logger::SeverityName(sev) << "' with 'high' verbosity..." << endl;
|
||||
Logger::SetVerbosity(Verbosity::high);
|
||||
printEverySeverity();
|
||||
cout << endl << "cout: >>> testing severity '" << Logger::SeverityName(sev) << "' with 'veryhigh' verbosity..." << endl;
|
||||
Logger::SetVerbosity(Verbosity::veryhigh);
|
||||
printEverySeverity();
|
||||
cout << endl << "cout: >>> testing severity '" << Logger::SeverityName(sev) << "' with 'user1' verbosity..." << endl;
|
||||
Logger::SetVerbosity(Verbosity::user1);
|
||||
printEverySeverity();
|
||||
cout << endl << "cout: >>> testing severity '" << Logger::SeverityName(sev) << "' with 'user2' verbosity..." << endl;
|
||||
Logger::SetVerbosity(Verbosity::user2);
|
||||
printEverySeverity();
|
||||
cout << endl << "cout: >>> testing severity '" << Logger::SeverityName(sev) << "' with 'user3' verbosity..." << endl;
|
||||
Logger::SetVerbosity(Verbosity::user3);
|
||||
printEverySeverity();
|
||||
cout << endl << "cout: >>> testing severity '" << Logger::SeverityName(sev) << "' with 'user4' verbosity..." << endl;
|
||||
Logger::SetVerbosity(Verbosity::user4);
|
||||
printEverySeverity();
|
||||
}
|
||||
|
||||
void silentlyPrintAllVerbositiesWithSeverity(Severity sev)
|
||||
{
|
||||
Logger::SetConsoleSeverity(sev);
|
||||
|
||||
Logger::SetVerbosity(Verbosity::verylow);
|
||||
printEverySeverity();
|
||||
Logger::SetVerbosity(Verbosity::low);
|
||||
printEverySeverity();
|
||||
Logger::SetVerbosity(Verbosity::medium);
|
||||
printEverySeverity();
|
||||
Logger::SetVerbosity(Verbosity::high);
|
||||
printEverySeverity();
|
||||
Logger::SetVerbosity(Verbosity::veryhigh);
|
||||
printEverySeverity();
|
||||
Logger::SetVerbosity(Verbosity::user1);
|
||||
printEverySeverity();
|
||||
Logger::SetVerbosity(Verbosity::user2);
|
||||
printEverySeverity();
|
||||
Logger::SetVerbosity(Verbosity::user3);
|
||||
printEverySeverity();
|
||||
Logger::SetVerbosity(Verbosity::user4);
|
||||
printEverySeverity();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
Logger::SetConsoleColor(true);
|
||||
|
||||
auto spec = VerbositySpec::Make(VerbositySpec::Info::file_line_function,
|
||||
VerbositySpec::Info::process_name,
|
||||
VerbositySpec::Info::process_name);
|
||||
cout << "Defining custom verbosity \"user2\"" << endl;
|
||||
Logger::DefineVerbosity(Verbosity::user2, spec);
|
||||
|
||||
cout << "cout: testing severities..." << endl;
|
||||
|
||||
printAllVerbositiesWithSeverity(Severity::trace);
|
||||
printAllVerbositiesWithSeverity(Severity::debug4);
|
||||
printAllVerbositiesWithSeverity(Severity::debug3);
|
||||
printAllVerbositiesWithSeverity(Severity::debug2);
|
||||
printAllVerbositiesWithSeverity(Severity::debug1);
|
||||
printAllVerbositiesWithSeverity(Severity::debug);
|
||||
printAllVerbositiesWithSeverity(Severity::info);
|
||||
printAllVerbositiesWithSeverity(Severity::state);
|
||||
printAllVerbositiesWithSeverity(Severity::warn);
|
||||
printAllVerbositiesWithSeverity(Severity::error);
|
||||
printAllVerbositiesWithSeverity(Severity::nolog);
|
||||
|
||||
cout << endl;
|
||||
cout << "cout: setting severity to 'info' and verbosity to 'medium'" << endl;
|
||||
Logger::SetConsoleSeverity(Severity::info);
|
||||
Logger::SetVerbosity(Verbosity::medium);
|
||||
|
||||
cout << "cout: is logging trace: " << fair::Logger::Logging(Severity::trace) << endl;
|
||||
cout << "cout: is logging debug4: " << fair::Logger::Logging(Severity::debug) << endl;
|
||||
cout << "cout: is logging debug3: " << fair::Logger::Logging(Severity::debug) << endl;
|
||||
cout << "cout: is logging debug2: " << fair::Logger::Logging(Severity::debug) << endl;
|
||||
cout << "cout: is logging debug1: " << fair::Logger::Logging(Severity::debug) << endl;
|
||||
cout << "cout: is logging debug: " << fair::Logger::Logging(Severity::debug) << endl;
|
||||
cout << "cout: is logging info: " << fair::Logger::Logging(Severity::info) << endl;
|
||||
cout << "cout: is logging state: " << fair::Logger::Logging(Severity::state) << endl;
|
||||
cout << "cout: is logging warn: " << fair::Logger::Logging(Severity::warn) << endl;
|
||||
cout << "cout: is logging error: " << fair::Logger::Logging(Severity::error) << endl;
|
||||
cout << "cout: is logging fatal: " << fair::Logger::Logging(Severity::fatal) << endl;
|
||||
cout << "cout: is logging nolog: " << fair::Logger::Logging(Severity::nolog) << endl;
|
||||
|
||||
for (int i = 0; i < 1000000; ++i) {
|
||||
silentlyPrintAllVerbositiesWithSeverity(Severity::nolog);
|
||||
}
|
||||
cout << endl;
|
||||
cout << "cout: setting severity to 'trace' and verbosity to 'veryhigh'" << endl;
|
||||
Logger::SetConsoleSeverity(Severity::trace);
|
||||
Logger::SetVerbosity(Verbosity::veryhigh);
|
||||
|
||||
cout << endl;
|
||||
cout << "cout: testing conditional logging..." << endl;
|
||||
int x = 0;
|
||||
LOG(info) << "x = " << x << " (initial)";
|
||||
LOG_IF(info, (x == 0)) << "incrementing x to " << ++x;
|
||||
LOG(info) << "x = " << x << " (after increment)";
|
||||
LOG_IF(info, (x == 0)) << "this should not be printed and x not incremented: " << ++x;
|
||||
LOG(info) << "x = " << x << " (after conditional increment)";
|
||||
|
||||
cout << endl;
|
||||
cout << "cout: setting severity to 'nolog'" << endl;
|
||||
Logger::SetConsoleSeverity(Severity::nolog);
|
||||
|
||||
cout << "cout: ----------------------------" << endl;
|
||||
cout << "cout: open log file with severity 'error'" << endl;
|
||||
Logger::InitFileSink(Severity::error, "test_log", true);
|
||||
printEverySeverity();
|
||||
cout << "cout: closing log file" << endl;
|
||||
Logger::RemoveFileSink();
|
||||
|
||||
|
||||
cout << "cout: setting severity to 'nolog'" << endl;
|
||||
Logger::SetConsoleSeverity(Severity::nolog);
|
||||
cout << "cout: ----------------------------" << endl;
|
||||
cout << "cout: adding custom sink with error severity" << endl << endl;
|
||||
|
||||
Logger::AddCustomSink("CustomSink", "error", [](const string& content, const LogMetaData& metadata)
|
||||
{
|
||||
cout << "CustomSink: content: " << content << endl;
|
||||
|
||||
cout << "CustomSink: available metadata: " << endl;
|
||||
cout << "CustomSink: \tstd::time_t timestamp: " << metadata.timestamp << endl;
|
||||
cout << "CustomSink: \tstd::chrono::microseconds us: " << metadata.us.count() << endl;
|
||||
cout << "CustomSink: \tstd::string process_name: " << metadata.process_name << endl;
|
||||
cout << "CustomSink: \tstd::string file: " << metadata.file << endl;
|
||||
cout << "CustomSink: \tstd::string line: " << metadata.line << endl;
|
||||
cout << "CustomSink: \tstd::string func: " << metadata.func << endl;
|
||||
cout << "CustomSink: \tstd::string severity_name: " << metadata.severity_name << endl;
|
||||
cout << "CustomSink: \tfair::Severity severity: " << static_cast<int>(metadata.severity) << endl;
|
||||
});
|
||||
|
||||
printEverySeverity();
|
||||
|
||||
cout << endl << "cout: removing custom sink with info severity" << endl;
|
||||
|
||||
Logger::AddCustomSink("CustomSink", Severity::error, [](const string& /*content*/, const LogMetaData& /*metadata*/){});
|
||||
Logger::RemoveCustomSink("CustomSink");
|
||||
Logger::RemoveCustomSink("bla");
|
||||
|
||||
cout << "cout: setting severity to 'trace'" << endl;
|
||||
Logger::SetConsoleSeverity(Severity::trace);
|
||||
|
||||
LOGF(info, "Hello {} {}!", "world", ":-)");
|
||||
LOGP(info, "Hello %s %s!", "world", ":-)");
|
||||
|
||||
cout << "cout: setting verbosity to 'high'" << endl;
|
||||
Logger::SetVerbosity(Verbosity::high);
|
||||
|
||||
LOGV(info, verylow) << "I should be printed with very low verbosity";
|
||||
|
||||
cout << "cout: pushing 4 new lines with LOGN() in info verbosity" << endl;
|
||||
LOGN(info);
|
||||
LOGN(info);
|
||||
LOGN(info);
|
||||
LOGN(info);
|
||||
|
||||
return 0;
|
||||
}
|
67
test/macros.cxx
Normal file
67
test/macros.cxx
Normal file
|
@ -0,0 +1,67 @@
|
|||
/********************************************************************************
|
||||
* Copyright (C) 2014-2020 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
|
||||
#include "Common.h"
|
||||
#include <Logger.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace fair;
|
||||
using namespace fair::logger::test;
|
||||
|
||||
int main()
|
||||
{
|
||||
try {
|
||||
Logger::SetConsoleColor(false);
|
||||
Logger::SetConsoleSeverity(Severity::fatal);
|
||||
Logger::SetVerbosity(Verbosity::verylow);
|
||||
|
||||
int x = 0;
|
||||
|
||||
CheckOutput("^incrementing x to 1\n$", [&]() { LOG_IF(fatal, true) << "incrementing x to " << ++x; });
|
||||
if (x != 1) {
|
||||
throw runtime_error(ToStr("expected x to be 1, but it is: ", x));
|
||||
}
|
||||
|
||||
CheckOutput("^$", [&]() { LOG_IF(fatal, false) << "incrementing x to " << ++x; });
|
||||
if (x != 1) {
|
||||
throw runtime_error(ToStr("expected x to be 1, but it is: ", x));
|
||||
}
|
||||
|
||||
CheckOutput("^Hello world :-\\)!\n$", []() { LOGP(fatal, "Hello {} {}!", "world", ":-)"); });
|
||||
CheckOutput("^Hello world :-\\)!\n$", []() { LOGF(fatal, "Hello %s %s!", "world", ":-)"); });
|
||||
|
||||
CheckOutput(ToStr(R"(^\[FATAL\])", " content\n$"), []() { LOGV(fatal, low) << "content"; });
|
||||
|
||||
CheckOutput("^\n\n\n\n$", []() {
|
||||
LOGN(fatal);
|
||||
LOGN(fatal);
|
||||
LOGN(fatal);
|
||||
LOGN(fatal);
|
||||
});
|
||||
|
||||
Logger::SetVerbosity(Verbosity::veryhigh);
|
||||
|
||||
CheckOutput(ToStr(R"(^\[.*\]\[\d{2}:\d{2}:\d{2}\.\d{6}\]\[FATAL\]\[a:4:b\])", " c\n$"), []() {
|
||||
LOGD(Severity::fatal, "a", "4", "b") << "c";
|
||||
});
|
||||
|
||||
// Test dynamic severity macros
|
||||
Logger::SetVerbosity(Verbosity::verylow);
|
||||
Severity dynamicSeverity = Severity::fatal;
|
||||
|
||||
CheckOutput("^Hello dynamic world :-\\)!\n$", [&]() { LOGPD(dynamicSeverity, "Hello {} {}!", "dynamic world", ":-)"); });
|
||||
CheckOutput("^Hello dynamic world :-\\)!\n$", [&]() { LOGFD(dynamicSeverity, "Hello %s %s!", "dynamic world", ":-)"); });
|
||||
} catch (runtime_error& rte) {
|
||||
cout << rte.what() << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
64
test/nolog.cxx
Normal file
64
test/nolog.cxx
Normal file
|
@ -0,0 +1,64 @@
|
|||
/********************************************************************************
|
||||
* Copyright (C) 2014-2020 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
|
||||
#include <Logger.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace fair;
|
||||
|
||||
void printEverySeverity()
|
||||
{
|
||||
LOG(nolog) << "nolog message ";
|
||||
LOG(trace) << "trace message ";
|
||||
LOG(debug4) << "debug4 message ";
|
||||
LOG(debug3) << "debug3 message ";
|
||||
LOG(debug2) << "debug2 message ";
|
||||
LOG(debug1) << "debug1 message ";
|
||||
LOG(debug) << "debug message ";
|
||||
LOG(detail) << "detail message ";
|
||||
LOG(info) << "info message ";
|
||||
LOG(state) << "state message ";
|
||||
LOG(warn) << "warning message ";
|
||||
LOG(important) << "important message ";
|
||||
LOG(alarm) << "alarm message ";
|
||||
LOG(error) << "error message ";
|
||||
LOG(critical) << "critical message ";
|
||||
}
|
||||
|
||||
void silentlyPrintAllVerbositiesWithSeverity(Severity sev)
|
||||
{
|
||||
Logger::SetConsoleSeverity(sev);
|
||||
|
||||
Logger::SetVerbosity(Verbosity::verylow);
|
||||
printEverySeverity();
|
||||
Logger::SetVerbosity(Verbosity::low);
|
||||
printEverySeverity();
|
||||
Logger::SetVerbosity(Verbosity::medium);
|
||||
printEverySeverity();
|
||||
Logger::SetVerbosity(Verbosity::high);
|
||||
printEverySeverity();
|
||||
Logger::SetVerbosity(Verbosity::veryhigh);
|
||||
printEverySeverity();
|
||||
Logger::SetVerbosity(Verbosity::user1);
|
||||
printEverySeverity();
|
||||
Logger::SetVerbosity(Verbosity::user2);
|
||||
printEverySeverity();
|
||||
Logger::SetVerbosity(Verbosity::user3);
|
||||
printEverySeverity();
|
||||
Logger::SetVerbosity(Verbosity::user4);
|
||||
printEverySeverity();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
for (int i = 0; i < 1000000; ++i) {
|
||||
silentlyPrintAllVerbositiesWithSeverity(Severity::nolog);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
102
test/severity.cxx
Normal file
102
test/severity.cxx
Normal file
|
@ -0,0 +1,102 @@
|
|||
/********************************************************************************
|
||||
* Copyright (C) 2014-2020 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
|
||||
#include "Common.h"
|
||||
#include <Logger.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
using namespace fair;
|
||||
using namespace fair::logger::test;
|
||||
|
||||
uint32_t printEverySeverity(uint32_t i)
|
||||
{
|
||||
LOG(nolog) << "nolog message, counter: " << i++;
|
||||
LOG(trace) << "trace message, counter: " << i++;
|
||||
LOG(debug4) << "debug4 message, counter: " << i++;
|
||||
LOG(debug3) << "debug3 message, counter: " << i++;
|
||||
LOG(debug2) << "debug2 message, counter: " << i++;
|
||||
LOG(debug1) << "debug1 message, counter: " << i++;
|
||||
LOG(debug) << "debug message, counter: " << i++;
|
||||
LOG(detail) << "detail message, counter: " << i++;
|
||||
LOG(info) << "info message, counter: " << i++;
|
||||
LOG(state) << "state message, counter: " << i++;
|
||||
LOG(warn) << "warning message, counter: " << i++;
|
||||
LOG(important) << "important message, counter: " << i++;
|
||||
LOG(alarm) << "alarm message, counter: " << i++;
|
||||
LOG(error) << "error message, counter: " << i++;
|
||||
LOG(critical) << "critical message, counter: " << i++;
|
||||
LOG(fatal) << "fatal message, counter: " << i++;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
void CheckSeverity(Severity severity)
|
||||
{
|
||||
Logger::SetConsoleSeverity(severity);
|
||||
auto sev = Logger::GetConsoleSeverity();
|
||||
|
||||
cout << "##### testing severity '" << Logger::SeverityName(sev) << "' (" << static_cast<int>(sev) << "), Logging(): " << std::boolalpha << Logger::Logging(sev) << endl;
|
||||
|
||||
for (uint32_t i = 0; i < Logger::fSeverityNames.size(); ++i) {
|
||||
if (sev == Severity::nolog) {
|
||||
if (i == static_cast<int>(fair::Severity::fatal)) {
|
||||
if (!Logger::Logging(static_cast<Severity>(i))) {
|
||||
throw runtime_error(ToStr("expecting to be logging ", Logger::fSeverityNames.at(i), " during ", sev, ", but it is not."));
|
||||
}
|
||||
} else {
|
||||
if (Logger::Logging(static_cast<Severity>(i))) {
|
||||
throw runtime_error(ToStr("expecting to NOT be logging ", Logger::fSeverityNames.at(i), " during ", sev, ", but it is."));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (i >= static_cast<unsigned int>(sev)) {
|
||||
if (!Logger::Logging(static_cast<Severity>(i))) {
|
||||
throw runtime_error(ToStr("expecting to be logging ", Logger::fSeverityNames.at(i), " during ", sev, ", but it is not."));
|
||||
}
|
||||
} else {
|
||||
if (Logger::Logging(static_cast<Severity>(i))) {
|
||||
throw runtime_error(ToStr("expecting to NOT be logging ", Logger::fSeverityNames.at(i), " during ", sev, ", but it is."));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t i = 0;
|
||||
i = printEverySeverity(i);
|
||||
if (sev == Severity::nolog) {
|
||||
if (i != 1) {
|
||||
throw runtime_error(ToStr("expected: i==1, found: i==", i));
|
||||
}
|
||||
} else {
|
||||
if (i != Logger::fSeverityNames.size() - static_cast<int>(sev)) {
|
||||
throw runtime_error(ToStr("expected: i==", Logger::fSeverityNames.size() - static_cast<int>(sev) - 1, ", found: i==", i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
try {
|
||||
Logger::SetConsoleColor(true);
|
||||
|
||||
cout << "##### testing " << Logger::fSeverityNames.size() << " severities..." << endl;
|
||||
for (uint32_t i = 0; i < Logger::fSeverityNames.size(); ++i) {
|
||||
CheckSeverity(static_cast<Severity>(i));
|
||||
}
|
||||
} catch (runtime_error& rte) {
|
||||
cout << rte.what() << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
151
test/sinks.cxx
Normal file
151
test/sinks.cxx
Normal file
|
@ -0,0 +1,151 @@
|
|||
/********************************************************************************
|
||||
* Copyright (C) 2014-2020 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
|
||||
#include "Common.h"
|
||||
#include <Logger.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
using namespace fair;
|
||||
using namespace fair::logger::test;
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef FAIR_MIN_SEVERITY
|
||||
if (static_cast<int>(Severity::FAIR_MIN_SEVERITY) > static_cast<int>(Severity::warn)) {
|
||||
cout << "test requires at least FAIR_MIN_SEVERITY == warn to run, skipping" << endl;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
try {
|
||||
Logger::SetConsoleColor(false);
|
||||
Logger::SetConsoleSeverity(Severity::nolog);
|
||||
Logger::SetVerbosity(Verbosity::low);
|
||||
|
||||
if (Logger::Logging(Severity::warn)) { cout << "Logger expected to NOT log warn, but it reports to do so" << endl; return 1; }
|
||||
if (Logger::Logging(Severity::error)) { cout << "Logger expected to NOT log error, but it reports to do so" << endl; return 1; }
|
||||
if (!Logger::Logging(Severity::fatal)) { cout << "Logger expected to log fatal, but it reports not to" << endl; return 1; }
|
||||
|
||||
cout << "##### adding file sink with warn severity" << endl;
|
||||
random_device rd;
|
||||
mt19937 gen(rd());
|
||||
uniform_int_distribution<> distrib(1, 65536);
|
||||
string name = Logger::InitFileSink(Severity::warn, string("test_log_" + to_string(distrib(gen))), true);
|
||||
|
||||
if (Logger::GetFileSeverity() != Severity::warn) {
|
||||
throw runtime_error(ToStr("File sink severity (", Logger::GetFileSeverity(), ") does not match the expected one (", Severity::warn, ")"));
|
||||
}
|
||||
|
||||
CheckOutput("^\\[FATAL\\] fatal\n$", [](){
|
||||
LOG(state) << "state";
|
||||
LOG(warn) << "warning";
|
||||
LOG(error) << "error";
|
||||
LOG(fatal) << "fatal";
|
||||
});
|
||||
|
||||
if (Logger::Logging(Severity::state)) { cout << "Logger expected to NOT log warn, but it reports to do so" << endl; return 1; }
|
||||
if (!Logger::Logging(Severity::warn)) { cout << "Logger expected to log warn, but it reports not to" << endl; return 1; }
|
||||
if (!Logger::Logging(Severity::error)) { cout << "Logger expected to log error, but it reports not to" << endl; return 1; }
|
||||
if (!Logger::Logging(Severity::fatal)) { cout << "Logger expected to log fatal, but it reports not to" << endl; return 1; }
|
||||
|
||||
ifstream t(name);
|
||||
stringstream buffer;
|
||||
buffer << t.rdbuf();
|
||||
string fileContent = buffer.str();
|
||||
|
||||
if (fileContent != "[WARN] warning\n[ERROR] error\n[FATAL] fatal\n") {
|
||||
throw runtime_error(ToStr("unexpected file sink output. expected:\n[WARN] warning\n[ERROR] error\n[FATAL] fatal\nfound:\n", fileContent));
|
||||
}
|
||||
|
||||
cout << "##### removing file sink with warn severity" << endl;
|
||||
Logger::RemoveFileSink();
|
||||
|
||||
if (Logger::Logging(Severity::warn)) { cout << "Logger expected to NOT log warn, but it reports to do so" << endl; return 1; }
|
||||
if (Logger::Logging(Severity::error)) { cout << "Logger expected to NOT log error, but it reports to do so" << endl; return 1; }
|
||||
if (!Logger::Logging(Severity::fatal)) { cout << "Logger expected to log fatal, but it reports not to" << endl; return 1; }
|
||||
|
||||
cout << "##### adding custom sink with warn severity" << endl;
|
||||
|
||||
Logger::AddCustomSink("CustomSink", "warn", [](const string& content, const LogMetaData& metadata)
|
||||
{
|
||||
cout << "CustomSink " << content << endl;
|
||||
|
||||
if (metadata.severity != Severity::warn && metadata.severity != Severity::error && metadata.severity != Severity::fatal) {
|
||||
throw runtime_error(ToStr("unexpected severity message arrived at custom sink that accepts only warn,error,fatal: ", metadata.severity));
|
||||
}
|
||||
|
||||
if (metadata.severity_name != "WARN" && metadata.severity_name != "ERROR" && metadata.severity_name != "FATAL") {
|
||||
throw runtime_error(ToStr("unexpected severity name arrived at custom sink that accepts only warn,error,fatal: ", metadata.severity_name));
|
||||
}
|
||||
});
|
||||
|
||||
if (Logger::GetCustomSeverity("CustomSink") != Severity::warn) {
|
||||
throw runtime_error(ToStr("File sink severity (", Logger::GetCustomSeverity("CustomSink"), ") does not match the expected one (", Severity::warn, ")"));
|
||||
}
|
||||
|
||||
bool oorThrown = false;
|
||||
try {
|
||||
Logger::GetCustomSeverity("NonExistentSink");
|
||||
} catch (const out_of_range& oor) {
|
||||
oorThrown = true;
|
||||
}
|
||||
if (!oorThrown) {
|
||||
throw runtime_error("Did not detect a severity request from a non-existent sink");
|
||||
}
|
||||
|
||||
CheckOutput("^CustomSink warning\nCustomSink error\nCustomSink fatal\n\\[FATAL\\] fatal\n$", [](){
|
||||
LOG(state) << "state";
|
||||
LOG(warn) << "warning";
|
||||
LOG(error) << "error";
|
||||
LOG(fatal) << "fatal";
|
||||
});
|
||||
|
||||
if (Logger::Logging(Severity::state)) { cout << "Logger expected to NOT log warn, but it reports to do so" << endl; return 1; }
|
||||
if (!Logger::Logging(Severity::warn)) { cout << "Logger expected to log warn, but it reports not to" << endl; return 1; }
|
||||
if (!Logger::Logging(Severity::error)) { cout << "Logger expected to log error, but it reports not to" << endl; return 1; }
|
||||
if (!Logger::Logging(Severity::fatal)) { cout << "Logger expected to log fatal, but it reports not to" << endl; return 1; }
|
||||
|
||||
cout << "##### removing custom sink with error severity" << endl;
|
||||
|
||||
bool caught = false;
|
||||
try {
|
||||
Logger::AddCustomSink("CustomSink", Severity::error, [](const string& /*content*/, const LogMetaData& /*metadata*/){});
|
||||
} catch (runtime_error& rte) {
|
||||
caught = true;
|
||||
}
|
||||
if (!caught) {
|
||||
throw runtime_error("expected to throw a runtime_error upon adding sink with same key, but none was thrown");
|
||||
}
|
||||
|
||||
Logger::RemoveCustomSink("CustomSink");
|
||||
|
||||
if (Logger::Logging(Severity::warn)) { cout << "Logger expected to NOT log warn, but it reports to do so" << endl; return 1; }
|
||||
if (Logger::Logging(Severity::error)) { cout << "Logger expected to NOT log error, but it reports to do so" << endl; return 1; }
|
||||
if (!Logger::Logging(Severity::fatal)) { cout << "Logger expected to log fatal, but it reports not to" << endl; return 1; }
|
||||
|
||||
caught = false;
|
||||
try {
|
||||
Logger::RemoveCustomSink("bla");
|
||||
} catch (runtime_error& rte) {
|
||||
caught = true;
|
||||
}
|
||||
if (!caught) {
|
||||
throw runtime_error("expected to throw a runtime_error upon removing non-existent sink, but none was thrown");
|
||||
}
|
||||
} catch (runtime_error& rte) {
|
||||
cout << rte.what() << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
67
test/threads.cxx
Normal file
67
test/threads.cxx
Normal file
|
@ -0,0 +1,67 @@
|
|||
/********************************************************************************
|
||||
* Copyright (C) 2014-2020 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
|
||||
#include "Common.h"
|
||||
#include <Logger.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
using namespace fair;
|
||||
using namespace fair::logger::test;
|
||||
|
||||
void f()
|
||||
{
|
||||
LOG(fatal) << "a" << "b" << "c" << "d" << "e" << "f" << "g" << "h" << "i" << "j" << "k" << "l" << "m" << "n" << "o" << "p" << "q" << "r" << "s" << "t" << "u" << "v" << "w" << "x" << "y" << "z";
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
try {
|
||||
Logger::SetConsoleColor(false);
|
||||
Logger::SetConsoleSeverity(Severity::fatal);
|
||||
Logger::SetVerbosity(Verbosity::veryhigh);
|
||||
|
||||
CheckOutput(
|
||||
R"(^\[.*\]\[\d{2}:\d{2}:\d{2}\.\d{6}\]\[FATAL\]\[.*:\d+:.*\] abcdefghijklmnopqrstuvwxyz
|
||||
\[.*\]\[\d{2}:\d{2}:\d{2}\.\d{6}\]\[FATAL\]\[.*:\d+:.*\] abcdefghijklmnopqrstuvwxyz
|
||||
\[.*\]\[\d{2}:\d{2}:\d{2}\.\d{6}\]\[FATAL\]\[.*:\d+:.*\] abcdefghijklmnopqrstuvwxyz
|
||||
\[.*\]\[\d{2}:\d{2}:\d{2}\.\d{6}\]\[FATAL\]\[.*:\d+:.*\] abcdefghijklmnopqrstuvwxyz
|
||||
\[.*\]\[\d{2}:\d{2}:\d{2}\.\d{6}\]\[FATAL\]\[.*:\d+:.*\] abcdefghijklmnopqrstuvwxyz
|
||||
$)", []() {
|
||||
thread t1(f);
|
||||
thread t2(f);
|
||||
thread t3(f);
|
||||
thread t4(f);
|
||||
thread t5(f);
|
||||
t1.join();
|
||||
t2.join();
|
||||
t3.join();
|
||||
t4.join();
|
||||
t5.join();
|
||||
});
|
||||
|
||||
thread t1(f);
|
||||
thread t2(f);
|
||||
thread t3(f);
|
||||
thread t4(f);
|
||||
thread t5(f);
|
||||
t1.join();
|
||||
t2.join();
|
||||
t3.join();
|
||||
t4.join();
|
||||
t5.join();
|
||||
} catch (runtime_error& rte) {
|
||||
cout << rte.what() << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
102
test/verbosity.cxx
Normal file
102
test/verbosity.cxx
Normal file
|
@ -0,0 +1,102 @@
|
|||
/********************************************************************************
|
||||
* Copyright (C) 2014-2020 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
|
||||
* *
|
||||
* This software is distributed under the terms of the *
|
||||
* GNU Lesser General Public Licence (LGPL) version 3, *
|
||||
* copied verbatim in the file "LICENSE" *
|
||||
********************************************************************************/
|
||||
|
||||
#include "Common.h"
|
||||
#include <Logger.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
using namespace fair;
|
||||
using namespace fair::logger::test;
|
||||
|
||||
int main()
|
||||
{
|
||||
try {
|
||||
Logger::SetConsoleColor(false);
|
||||
Logger::SetConsoleSeverity(Severity::fatal);
|
||||
|
||||
auto spec1 = VerbositySpec::Make(VerbositySpec::Info::file_line_function, VerbositySpec::Info::process_name);
|
||||
auto spec2 = VerbositySpec::Make(VerbositySpec::Info::process_name, VerbositySpec::Info::file_line_function);
|
||||
|
||||
Logger::DefineVerbosity(Verbosity::user1, spec1);
|
||||
Logger::SetVerbosity(Verbosity::user1); // spec1 on user1
|
||||
CheckOutput(ToStr(R"(^\[.*:\d{2}:.*\]\[.*\])", " content\n$"), []() { LOG(fatal) << "content"; });
|
||||
|
||||
Logger::DefineVerbosity(Verbosity::user1, spec2);
|
||||
Logger::SetVerbosity(Verbosity::user1); // spec2 on user1
|
||||
CheckOutput(ToStr(R"(^\[.*\]\[.*:\d{2}:.*\])", " content\n$"), []() { LOG(fatal) << "content"; });
|
||||
|
||||
Logger::DefineVerbosity(Verbosity::user2, spec1);
|
||||
Logger::SetVerbosity(Verbosity::user2); // spec1 on user2
|
||||
CheckOutput(ToStr(R"(^\[.*:\d{2}:.*\]\[.*\])", " content\n$"), []() { LOG(fatal) << "content"; });
|
||||
|
||||
Logger::SetVerbosity(Verbosity::verylow); // content
|
||||
CheckOutput("^content\n$", []() { LOG(fatal) << "content"; });
|
||||
|
||||
Logger::SetVerbosity(Verbosity::low); // [severity] content
|
||||
CheckOutput(ToStr(R"(^\[FATAL\])", " content\n$"), []() { LOG(fatal) << "content"; });
|
||||
|
||||
Logger::SetVerbosity(Verbosity::medium); // [HH:MM:SS][severity] content
|
||||
CheckOutput(ToStr(R"(^\[\d{2}:\d{2}:\d{2}\]\[FATAL\])", " content\n$"), []() { LOG(fatal) << "content"; });
|
||||
|
||||
Logger::SetVerbosity(Verbosity::high); // [process_name][HH:MM:SS][severity] content
|
||||
CheckOutput(ToStr(R"(^\[.*\]\[\d{2}:\d{2}:\d{2}\]\[FATAL\])", " content\n$"), []() { LOG(fatal) << "content"; });
|
||||
|
||||
Logger::SetVerbosity(Verbosity::veryhigh); // [process_name][HH:MM:SS:µS][severity][file:line:function] content
|
||||
CheckOutput(ToStr(R"(^\[.*\]\[\d{2}:\d{2}:\d{2}\.\d{6}\]\[FATAL\]\[.*:\d+:.*\])", " content\n$"), []() { LOG(fatal) << "content"; });
|
||||
|
||||
Logger::SetConsoleColor(true);
|
||||
|
||||
Logger::SetVerbosity(Verbosity::verylow); // content
|
||||
CheckOutput(
|
||||
"^"
|
||||
"content\n"
|
||||
"$", []() { LOG(fatal) << "content"; });
|
||||
|
||||
Logger::SetVerbosity(Verbosity::low); // [severity] content
|
||||
CheckOutput(
|
||||
"^"
|
||||
"\\[\033\\[01;31mFATAL\033\\[0m\\]"
|
||||
" content\n"
|
||||
"$", []() { LOG(fatal) << "content"; });
|
||||
|
||||
Logger::SetVerbosity(Verbosity::medium); // [HH:MM:SS][severity] content
|
||||
CheckOutput(
|
||||
"^"
|
||||
"\\[\033\\[01;36m\\d{2}:\\d{2}:\\d{2}\033\\[0m\\]"
|
||||
"\\[\033\\[01;31mFATAL\033\\[0m\\]"
|
||||
" content\n"
|
||||
"$", []() { LOG(fatal) << "content"; });
|
||||
|
||||
Logger::SetVerbosity(Verbosity::high); // [process_name][HH:MM:SS][severity] content
|
||||
CheckOutput(
|
||||
"^"
|
||||
"\\[\033\\[01;34m.*\033\\[0m\\]"
|
||||
"\\[\033\\[01;36m\\d{2}:\\d{2}:\\d{2}\033\\[0m\\]"
|
||||
"\\[\033\\[01;31mFATAL\033\\[0m\\]"
|
||||
" content\n"
|
||||
"$", []() { LOG(fatal) << "content"; });
|
||||
|
||||
Logger::SetVerbosity(Verbosity::veryhigh); // [process_name][HH:MM:SS:µS][severity][file:line:function] content
|
||||
CheckOutput(
|
||||
"^"
|
||||
"\\[\033\\[01;34m.*\033\\[0m\\]"
|
||||
"\\[\033\\[01;36m\\d{2}:\\d{2}:\\d{2}\\.\\d{6}\033\\[0m\\]"
|
||||
"\\[\033\\[01;31mFATAL\033\\[0m\\]"
|
||||
"\\[\033\\[01;34m.*\033\\[0m:\033\\[01;33m\\d+\033\\[0m:\033\\[01;34m.*\033\\[0m\\]"
|
||||
" content\n"
|
||||
"$", []() { LOG(fatal) << "content"; });
|
||||
} catch (runtime_error& rte) {
|
||||
cout << rte.what() << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user