Compare commits

...

15 Commits

Author SHA1 Message Date
Alexey Rybalchenko
71aac1199a Add GitHub CI workflow 2025-07-02 13:28:30 +02:00
Alexey Rybalchenko
2a4be75246 Add LOGFD and LOGPD macros 2025-07-02 13:28:30 +02:00
Alexey Rybalchenko
290070cbcf Use prefixed macros in case non-prefixed ones are undefined 2025-07-02 13:28:30 +02:00
Alexey Rybalchenko
832376101d add install/ to git ignore 2025-07-02 13:28:30 +02:00
Alexey Rybalchenko
cd9e392ce0 CMake: remove C from project versions 2025-05-19 12:40:32 +02:00
Alexey Rybalchenko
27527ad87b Add critical severity level between fatal and error 2025-02-06 15:20:41 +01:00
Dennis Klein
f3d68fb4ba build: Adopt all CMake policies up to 3.30 2024-08-20 15:56:57 +02:00
Giulio Eulisse
0ae9a697b4 Avoid extra allocation when creating the LogMetaData
By using a std::string_view for LogMetaData strings we avoid an implicit
memory allocation when passing __file__, etc. which are char const*
(notice this is also the case for the standardized
std::source_location::file_name etc).
2024-05-23 19:47:55 +02:00
Giulio Eulisse
fdbc047591 Bump minimum required C++ standard to C++17 2024-05-23 19:47:55 +02:00
Alexey Rybalchenko
ea4067c474 Update CI nodes 2024-02-22 10:31:38 +01:00
Alexey Rybalchenko
067dcc0e26 Update CI nodes 2024-02-21 13:54:16 +01:00
Alexey Rybalchenko
0ab390c465 Avoid semicolon insertion when modifying linker flags 2024-02-19 11:36:33 +01:00
Alexey Rybalchenko
56b90a7445 Avoid "Unknown severity" message also for uppercase fatal 2022-06-28 11:23:57 +02:00
Giulio Eulisse
7fc05f3808 Avoid "Unknown severity" message for fatal 2022-06-28 11:23:57 +02:00
Dennis Klein
d93fb0870b ci: Update macOS builds 2022-04-17 06:10:15 +02:00
15 changed files with 222 additions and 168 deletions

85
.github/workflows/ci.yml vendored Normal file
View 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
View File

@ -1,2 +1,3 @@
build/
.vscode
install/

View File

@ -1,5 +1,5 @@
################################################################################
# Copyright (C) 2018-2021 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,7 +7,7 @@
################################################################################
cmake_minimum_required(VERSION 3.9.4 FATAL_ERROR)
cmake_policy(VERSION 3.9...3.19)
cmake_policy(VERSION 3.9...3.30)
# Project ######################################################################
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
@ -16,7 +16,7 @@ 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()
@ -54,7 +54,7 @@ add_library(FairLogger
logger/Logger.cxx
logger/Logger.h
)
target_compile_features(FairLogger PUBLIC cxx_std_14)
target_compile_features(FairLogger PUBLIC cxx_std_17)
if(USE_BOOST_PRETTY_FUNCTION)
target_link_libraries(FairLogger PUBLIC Boost::boost)

View File

@ -15,14 +15,10 @@ set(CTEST_USE_LAUNCHERS ON)
set(CTEST_CONFIGURATION_TYPE "RelWithDebInfo")
if(NOT NCPUS)
if(ENV{SLURM_CPUS_PER_TASK})
set(NCPUS $ENV{SLURM_CPUS_PER_TASK})
else()
include(ProcessorCount)
ProcessorCount(NCPUS)
if(NCPUS EQUAL 0)
set(NCPUS 1)
endif()
include(ProcessorCount)
ProcessorCount(NCPUS)
if(NCPUS EQUAL 0)
set(NCPUS 1)
endif()
endif()
@ -32,10 +28,10 @@ else()
set(CTEST_SITE $ENV{CTEST_SITE})
endif()
if ("$ENV{LABEL}" STREQUAL "")
if ("$ENV{CTEST_BUILD_NAME}" STREQUAL "")
set(CTEST_BUILD_NAME "build")
else()
set(CTEST_BUILD_NAME $ENV{LABEL})
set(CTEST_BUILD_NAME $ENV{CTEST_BUILD_NAME})
endif()
ctest_start(Continuous)

74
Jenkinsfile vendored
View File

@ -1,74 +0,0 @@
#!groovy
def jobMatrix(String prefix, String type, List specs) {
def nodes = [:]
for (spec in specs) {
job = "${spec.os}-${spec.ver}-${spec.arch}-${spec.compiler}"
def label = "${type}/${job}"
def selector = "${spec.os}-${spec.ver}-${spec.arch}"
def os = spec.os
def ver = spec.ver
def check = spec.check
nodes[label] = {
node(selector) {
githubNotify(context: "${prefix}/${label}", description: 'Building ...', status: 'PENDING')
try {
deleteDir()
checkout scm
def jobscript = 'job.sh'
def ctestcmd = "ctest -S FairLoggerTest.cmake -V --output-on-failure"
sh "echo \"set -e\" >> ${jobscript}"
sh "echo \"export LABEL=\\\"\${JOB_BASE_NAME} ${label}\\\"\" >> ${jobscript}"
if (selector =~ /^macos/) {
sh "echo \"${ctestcmd}\" >> ${jobscript}"
sh "cat ${jobscript}"
sh "bash ${jobscript}"
} else {
def containercmd = "singularity exec -B/shared ${env.SINGULARITY_CONTAINER_ROOT}/fairlogger/${os}.${ver}.sif bash -l -c \\\"${ctestcmd}\\\""
sh """\
echo \"echo \\\"*** Job started at .......: \\\$(date -R)\\\"\" >> ${jobscript}
echo \"echo \\\"*** Job ID ...............: \\\${SLURM_JOB_ID}\\\"\" >> ${jobscript}
echo \"echo \\\"*** Compute node .........: \\\$(hostname -f)\\\"\" >> ${jobscript}
echo \"unset http_proxy\" >> ${jobscript}
echo \"unset HTTP_PROXY\" >> ${jobscript}
echo \"${containercmd}\" >> ${jobscript}
"""
sh "cat ${jobscript}"
sh "test/ci/slurm-submit.sh \"FairLogger \${JOB_BASE_NAME} ${label}\" ${jobscript}"
}
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 {
def builds = jobMatrix('alfa-ci', 'build', [
[os: 'fedora', ver: '32', arch: 'x86_64', compiler: 'gcc-10'],
[os: 'fedora', ver: '33', arch: 'x86_64', compiler: 'gcc-10'],
[os: 'fedora', ver: '34', arch: 'x86_64', compiler: 'gcc-11'],
[os: 'macos', ver: '11', arch: 'x86_64', compiler: 'apple-clang-12'],
[os: 'macos', ver: '11', arch: 'arm64', compiler: 'apple-clang-13'],
])
parallel(builds)
}
}
}
}
}

View File

@ -68,9 +68,11 @@ 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::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
@ -100,6 +102,7 @@ where severity level is one of the following:
"important",
"alarm",
"error",
"critical",
"fatal",
```
@ -223,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.

View File

@ -94,7 +94,7 @@ macro(set_fairlogger_defaults)
endif()
# Handle C++ standard level
set(PROJECT_MIN_CXX_STANDARD 14)
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()
@ -128,8 +128,8 @@ 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")
list(APPEND CMAKE_EXE_LINKER_FLAGS "-Wl,--enable-new-dtags")
list(APPEND CMAKE_SHARED_LINKER_FLAGS "-Wl,--enable-new-dtags")
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")
list(APPEND CMAKE_INSTALL_RPATH "@loader_path/../${PROJECT_INSTALL_LIBDIR}")

View File

@ -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>
@ -44,56 +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 },
{ "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 }
{ {"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, 15> Logger::fSeverityNames =
const array<string_view, 16> Logger::fSeverityNames =
{
{
"NOLOG",
@ -110,11 +114,12 @@ const array<string, 15> Logger::fSeverityNames =
"IMPORTANT",
"ALARM",
"ERROR",
"CRITICAL",
"FATAL"
}
};
const array<string, 9> Logger::fVerbosityNames =
const array<string_view, 9> Logger::fVerbosityNames =
{
{
"verylow",
@ -142,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;
@ -287,6 +291,7 @@ 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;

View File

@ -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, *
@ -45,6 +45,7 @@
#include <time.h> // time_t
#include <type_traits> // is_same
#include <unordered_map>
#include <string_view>
#include <utility> // pair
namespace fair
@ -66,7 +67,8 @@ enum class Severity : int
important = 11,
alarm = 12,
error = 13,
fatal = 14,
critical = 14,
fatal = 15,
// aliases
warning = warn,
// backwards-compatibility
@ -175,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);
@ -244,7 +246,7 @@ 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);
@ -285,8 +287,8 @@ class Logger
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);
@ -322,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, 15> 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;
@ -392,16 +394,16 @@ inline std::ostream& operator<<(std::ostream& os, const Verbosity& v) { return o
#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
@ -417,6 +419,16 @@ inline std::ostream& operator<<(std::ostream& os, const Verbosity& v) { return o
#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) \
@ -431,8 +443,19 @@ inline std::ostream& operator<<(std::ostream& os, const Verbosity& v) { return o
fair::Logger(fair::Severity::severity, fair::Verbosity::verbosity, MSG_ORIGIN)
// Log with fmt- or printf-like formatting
#define FAIR_LOGP(severity, ...) LOG(severity) << fmt::format(__VA_ARGS__)
#define FAIR_LOGF(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) \
@ -449,6 +472,6 @@ inline std::ostream& operator<<(std::ostream& os, const Verbosity& v) { return o
#define FAIR_LOG_IF(severity, condition) \
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

View File

@ -32,5 +32,10 @@ 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})

View File

@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (C) 2015-2020 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* 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, *
@ -38,7 +38,7 @@ int main()
Logger::SetConsoleSeverity(Severity::fatal);
cout << "initial severity >" << Logger::GetConsoleSeverity() << "<" << endl << endl;
array<Severity, 15> 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::fatal }};
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
@ -57,7 +57,7 @@ int main()
Logger::SetConsoleSeverity(Severity::fatal);
cout << "initial severity >" << Logger::GetConsoleSeverity() << "<" << endl << endl;
array<Severity, 15> severitiesDown{{ 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 }};
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

View File

@ -31,6 +31,7 @@ void printEverySeverity()
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++;
}

View File

@ -51,6 +51,13 @@ int main()
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;

View File

@ -27,6 +27,7 @@ void printEverySeverity()
LOG(important) << "important message ";
LOG(alarm) << "alarm message ";
LOG(error) << "error message ";
LOG(critical) << "critical message ";
}
void silentlyPrintAllVerbositiesWithSeverity(Severity sev)

View File

@ -34,6 +34,7 @@ uint32_t printEverySeverity(uint32_t 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;