diff --git a/Framework/CMakeLists.txt b/Framework/CMakeLists.txt index 40a33ea80fdfe..ae70c0ab62cee 100644 --- a/Framework/CMakeLists.txt +++ b/Framework/CMakeLists.txt @@ -19,6 +19,7 @@ add_subdirectory(Utils) add_subdirectory(AnalysisSupport) add_subdirectory(PhysicsSupport) +add_subdirectory(DataTakingSupport) add_subdirectory(RootAnalysisHelpers) diff --git a/Framework/Core/CMakeLists.txt b/Framework/Core/CMakeLists.txt index f87c531d0687a..9dd322fb7ae5d 100644 --- a/Framework/Core/CMakeLists.txt +++ b/Framework/Core/CMakeLists.txt @@ -140,7 +140,6 @@ o2_add_library(Framework test/TestClasses.cxx PRIVATE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/src PUBLIC_LINK_LIBRARIES AliceO2::Configuration - AliceO2::InfoLogger AliceO2::Monitoring CURL::libcurl FairMQ::FairMQ @@ -205,7 +204,6 @@ foreach(t HistogramRegistry HTTPParser IndexBuilder - InfoLogger InputRecord InputRecordWalker InputSpan @@ -248,6 +246,12 @@ o2_add_test(Root2ArrowTable NAME test_Framework_test_Root2ArrowTable LABELS framework PUBLIC_LINK_LIBRARIES O2::Framework ROOT::ROOTDataFrame) +o2_add_test(InfoLogger NAME test_Framework_test_InfoLogger + SOURCES test/test_InfoLogger.cxx + COMPONENT_NAME Framework + LABELS framework + PUBLIC_LINK_LIBRARIES O2::Framework AliceO2::InfoLogger) + o2_add_executable(dpl-null-sink SOURCES src/o2NullSink.cxx PUBLIC_LINK_LIBRARIES O2::Framework diff --git a/Framework/Core/include/Framework/CommonServices.h b/Framework/Core/include/Framework/CommonServices.h index 361a4518a6195..598b62cb055c2 100644 --- a/Framework/Core/include/Framework/CommonServices.h +++ b/Framework/Core/include/Framework/CommonServices.h @@ -53,8 +53,6 @@ struct CommonServices { static ServiceSpec driverClientSpec(); static ServiceSpec monitoringSpec(); static ServiceSpec datatakingContextSpec(); - static ServiceSpec infologgerContextSpec(); - static ServiceSpec infologgerSpec(); static ServiceSpec configurationSpec(); static ServiceSpec controlSpec(); static ServiceSpec rootFileSpec(); diff --git a/Framework/Core/src/CommonServices.cxx b/Framework/Core/src/CommonServices.cxx index dee37c6f03853..0bce8acb7a752 100644 --- a/Framework/Core/src/CommonServices.cxx +++ b/Framework/Core/src/CommonServices.cxx @@ -48,7 +48,6 @@ #include #include #include -#include #include #include @@ -59,8 +58,6 @@ #include #include -using AliceO2::InfoLogger::InfoLogger; -using AliceO2::InfoLogger::InfoLoggerContext; using o2::configuration::ConfigurationFactory; using o2::configuration::ConfigurationInterface; using o2::monitoring::Monitoring; @@ -76,12 +73,6 @@ using Value = o2::monitoring::tags::Value; namespace o2::framework { -/// This is a global service because read only -template <> -struct ServiceKindExtractor { - constexpr static ServiceKind kind = ServiceKind::Global; -}; - #define MONITORING_QUEUE_SIZE 100 o2::framework::ServiceSpec CommonServices::monitoringSpec() { @@ -200,154 +191,9 @@ o2::framework::ServiceSpec CommonServices::datatakingContextSpec() .kind = ServiceKind::Serial}; } -o2::framework::ServiceSpec CommonServices::infologgerContextSpec() -{ - return ServiceSpec{ - .name = "infologger-contex", - .init = simpleServiceInit(), - .configure = noConfiguration(), - .start = [](ServiceRegistry& services, void* service) { - auto& infoLoggerContext = services.get(); - auto run = services.get().device()->fConfig->GetProperty("runNumber", "unspecified"); - infoLoggerContext.setField(InfoLoggerContext::FieldName::Run, run); - auto partition = services.get().device()->fConfig->GetProperty("environment_id", "unspecified"); - infoLoggerContext.setField(InfoLoggerContext::FieldName::Partition, partition); - }, - .kind = ServiceKind::Serial}; -} - -// Creates the sink for FairLogger / InfoLogger integration -auto createInfoLoggerSinkHelper(InfoLogger* logger, InfoLoggerContext* ctx) -{ - return [logger, - ctx](const std::string& content, const fair::LogMetaData& metadata) { - // translate FMQ metadata - InfoLogger::InfoLogger::Severity severity = InfoLogger::Severity::Undefined; - int level = InfoLogger::undefinedMessageOption.level; - - if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::nolog)) { - // discard - return; - } else if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::fatal)) { - severity = InfoLogger::Severity::Fatal; - level = 1; - } else if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::error)) { - severity = InfoLogger::Severity::Error; - level = 3; - } else if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::alarm)) { - severity = InfoLogger::Severity::Warning; - level = 4; - } else if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::important)) { - severity = InfoLogger::Severity::Info; - level = 5; - } else if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::warn)) { - severity = InfoLogger::Severity::Warning; - level = 6; - } else if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::state)) { - severity = InfoLogger::Severity::Info; - level = 8; - } else if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::info)) { - severity = InfoLogger::Severity::Info; - level = 10; - } else if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::debug)) { - severity = InfoLogger::Severity::Debug; - level = 11; - } else if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::debug1)) { - severity = InfoLogger::Severity::Debug; - level = 12; - } else if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::debug2)) { - severity = InfoLogger::Severity::Debug; - level = 13; - } else if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::debug3)) { - severity = InfoLogger::Severity::Debug; - level = 14; - } else if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::debug4)) { - severity = InfoLogger::Severity::Debug; - level = 15; - } else if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::trace)) { - severity = InfoLogger::Severity::Debug; - level = 50; - } - - InfoLogger::InfoLoggerMessageOption opt = { - severity, - level, - InfoLogger::undefinedMessageOption.errorCode, - metadata.file.c_str(), - atoi(metadata.line.c_str())}; - - if (logger) { - logger->log(opt, *ctx, "%s", content.c_str()); - } - }; -}; - struct MissingService { }; -o2::framework::ServiceSpec CommonServices::infologgerSpec() -{ - return ServiceSpec{ - .name = "infologger", - .init = [](ServiceRegistry& services, DeviceState&, fair::mq::ProgOptions& options) -> ServiceHandle { - auto infoLoggerMode = options.GetPropertyAsString("infologger-mode"); - auto infoLoggerSeverity = options.GetPropertyAsString("infologger-severity"); - if (infoLoggerSeverity.empty() == false && options.GetPropertyAsString("infologger-mode") == "") { - LOGP(info, "Using O2_INFOLOGGER_MODE=infoLoggerD since infologger-severity is set"); - infoLoggerMode = "infoLoggerD"; - } - if (infoLoggerMode != "") { - setenv("O2_INFOLOGGER_MODE", infoLoggerMode.c_str(), 1); - } - char const* infoLoggerEnv = getenv("O2_INFOLOGGER_MODE"); - if (infoLoggerEnv == nullptr || strcmp(infoLoggerEnv, "none") == 0) { - return ServiceHandle{.hash = TypeIdHelpers::uniqueId(), - .instance = nullptr, - .kind = ServiceKind::Serial, - .name = "infologger"}; - } - InfoLogger* infoLoggerService = nullptr; - try { - infoLoggerService = new InfoLogger; - } catch (...) { - LOGP(error, "Unable to initialise InfoLogger with O2_INFOLOGGER_MODE={}.", infoLoggerMode); - return ServiceHandle{.hash = TypeIdHelpers::uniqueId(), - .instance = nullptr, - .kind = ServiceKind::Serial, - .name = "infologger"}; - } - auto infoLoggerContext = &services.get(); - // Only print the first 10 characters and the last 18 if the - // string length is greater than 32 bytes. - auto truncate = [](std::string in) -> std::string { - if (in.size() < 32) { - return in; - } - char name[32]; - memcpy(name, in.data(), 10); - name[10] = '.'; - name[11] = '.'; - name[12] = '.'; - memcpy(name + 13, in.data() + in.size() - 18, 18); - name[31] = 0; - return name; - }; - infoLoggerContext->setField(InfoLoggerContext::FieldName::Facility, truncate(services.get().name)); - infoLoggerContext->setField(InfoLoggerContext::FieldName::System, std::string("DPL")); - infoLoggerService->setContext(*infoLoggerContext); - - if (infoLoggerSeverity != "") { - fair::Logger::AddCustomSink("infologger", infoLoggerSeverity, createInfoLoggerSinkHelper(infoLoggerService, infoLoggerContext)); - } - return ServiceHandle{.hash = TypeIdHelpers::uniqueId(), - .instance = infoLoggerService, - .kind = ServiceKind::Serial, - .name = "infologger"}; - }, - .configure = noConfiguration(), - .kind = ServiceKind::Serial}; -} - o2::framework::ServiceSpec CommonServices::configurationSpec() { return ServiceSpec{ @@ -917,8 +763,6 @@ std::vector CommonServices::defaultServices(int numThreads) driverClientSpec(), datatakingContextSpec(), monitoringSpec(), - infologgerContextSpec(), - infologgerSpec(), configurationSpec(), controlSpec(), rootFileSpec(), @@ -936,6 +780,7 @@ std::vector CommonServices::defaultServices(int numThreads) decongestionSpec(), CommonMessageBackends::rawBufferBackendSpec()}; + std::string loadableServicesStr = "O2FrameworkDataTakingSupport:InfoLoggerContext,O2FrameworkDataTakingSupport:InfoLogger"; // Load plugins depending on the environment std::vector loadableServices = {}; char* loadableServicesEnv = getenv("DPL_LOAD_SERVICES"); @@ -943,9 +788,11 @@ std::vector CommonServices::defaultServices(int numThreads) // // library1:name1,library2:name2,... if (loadableServicesEnv) { - loadableServices = ServiceHelpers::parseServiceSpecString(loadableServicesEnv); - ServiceHelpers::loadFromPlugin(loadableServices, specs); + loadableServicesStr += ","; + loadableServicesStr += loadableServicesEnv; } + loadableServices = ServiceHelpers::parseServiceSpecString(loadableServicesStr.c_str()); + ServiceHelpers::loadFromPlugin(loadableServices, specs); // I should make it optional depending wether the GUI is there or not... specs.push_back(CommonServices::guiMetricsSpec()); if (numThreads) { diff --git a/Framework/Core/src/runDataProcessing.cxx b/Framework/Core/src/runDataProcessing.cxx index 52af861926b14..f0047cba69929 100644 --- a/Framework/Core/src/runDataProcessing.cxx +++ b/Framework/Core/src/runDataProcessing.cxx @@ -73,7 +73,6 @@ #include #include #include -#include #include "ResourcesMonitoringHelper.h" #include @@ -146,7 +145,6 @@ using namespace o2::monitoring; using namespace o2::configuration; -using namespace AliceO2::InfoLogger; using namespace o2::framework; namespace bpo = boost::program_options; diff --git a/Framework/Core/test/test_SlowConsumer.cxx b/Framework/Core/test/test_SlowConsumer.cxx index e210909e8e154..b2335b1a314a9 100644 --- a/Framework/Core/test/test_SlowConsumer.cxx +++ b/Framework/Core/test/test_SlowConsumer.cxx @@ -14,7 +14,6 @@ #include "Framework/RawDeviceService.h" #include "Framework/ControlService.h" #include -#include #include #include diff --git a/Framework/DataTakingSupport/CMakeLists.txt b/Framework/DataTakingSupport/CMakeLists.txt new file mode 100644 index 0000000000000..ea5d75a42d5c2 --- /dev/null +++ b/Framework/DataTakingSupport/CMakeLists.txt @@ -0,0 +1,14 @@ +# Copyright 2019-2020 CERN and copyright holders of ALICE O2. +# See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +# All rights not expressly granted are reserved. +# +# This software is distributed under the terms of the GNU General Public +# License v3 (GPL Version 3), copied verbatim in the file "COPYING". +# +# In applying this license CERN does not waive the privileges and immunities +# granted to it by virtue of its status as an Intergovernmental Organization +# or submit itself to any jurisdiction. +o2_add_library(FrameworkDataTakingSupport + SOURCES src/Plugin.cxx + PRIVATE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR}/src + PUBLIC_LINK_LIBRARIES O2::Framework AliceO2::InfoLogger) diff --git a/Framework/DataTakingSupport/src/Plugin.cxx b/Framework/DataTakingSupport/src/Plugin.cxx new file mode 100644 index 0000000000000..a9fd6e06ebce8 --- /dev/null +++ b/Framework/DataTakingSupport/src/Plugin.cxx @@ -0,0 +1,194 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +#include "Framework/Plugins.h" +#include "Framework/ServiceHandle.h" +#include "Framework/ServiceSpec.h" +#include "Framework/CommonServices.h" +#include "Framework/RawDeviceService.h" +#include "Framework/DeviceSpec.h" +#include +#include +#include +#include +#include + +using AliceO2::InfoLogger::InfoLogger; +using AliceO2::InfoLogger::InfoLoggerContext; + +using namespace o2::framework; + +namespace o2::framework +{ +/// This is a global service because read only +template <> +struct ServiceKindExtractor { + constexpr static ServiceKind kind = ServiceKind::Global; +}; + +} // namespace o2::framework + +struct MissingService { +}; + +struct InfoLoggerContextPlugin : o2::framework::ServicePlugin { + o2::framework::ServiceSpec* create() final + { + return new ServiceSpec{ + .name = "infologger-contex", + .init = CommonServices::simpleServiceInit(), + .configure = CommonServices::noConfiguration(), + .start = [](ServiceRegistry& services, void* service) { + auto& infoLoggerContext = services.get(); + auto run = services.get().device()->fConfig->GetProperty("runNumber", "unspecified"); + infoLoggerContext.setField(InfoLoggerContext::FieldName::Run, run); + auto partition = services.get().device()->fConfig->GetProperty("environment_id", "unspecified"); + infoLoggerContext.setField(InfoLoggerContext::FieldName::Partition, partition); + }, + .kind = ServiceKind::Serial}; + } +}; + +// Creates the sink for FairLogger / InfoLogger integration +auto createInfoLoggerSinkHelper(InfoLogger* logger, InfoLoggerContext* ctx) +{ + return [logger, + ctx](const std::string& content, const fair::LogMetaData& metadata) { + // translate FMQ metadata + InfoLogger::InfoLogger::Severity severity = InfoLogger::Severity::Undefined; + int level = InfoLogger::undefinedMessageOption.level; + + if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::nolog)) { + // discard + return; + } else if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::fatal)) { + severity = InfoLogger::Severity::Fatal; + level = 1; + } else if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::error)) { + severity = InfoLogger::Severity::Error; + level = 3; + } else if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::alarm)) { + severity = InfoLogger::Severity::Warning; + level = 4; + } else if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::important)) { + severity = InfoLogger::Severity::Info; + level = 5; + } else if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::warn)) { + severity = InfoLogger::Severity::Warning; + level = 6; + } else if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::state)) { + severity = InfoLogger::Severity::Info; + level = 8; + } else if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::info)) { + severity = InfoLogger::Severity::Info; + level = 10; + } else if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::debug)) { + severity = InfoLogger::Severity::Debug; + level = 11; + } else if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::debug1)) { + severity = InfoLogger::Severity::Debug; + level = 12; + } else if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::debug2)) { + severity = InfoLogger::Severity::Debug; + level = 13; + } else if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::debug3)) { + severity = InfoLogger::Severity::Debug; + level = 14; + } else if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::debug4)) { + severity = InfoLogger::Severity::Debug; + level = 15; + } else if (metadata.severity_name == fair::Logger::SeverityName(fair::Severity::trace)) { + severity = InfoLogger::Severity::Debug; + level = 50; + } + + InfoLogger::InfoLoggerMessageOption opt = { + severity, + level, + InfoLogger::undefinedMessageOption.errorCode, + metadata.file.c_str(), + atoi(metadata.line.c_str())}; + + if (logger) { + logger->log(opt, *ctx, "%s", content.c_str()); + } + }; +}; + +struct InfoLoggerPlugin : o2::framework::ServicePlugin { + o2::framework::ServiceSpec* create() final + { + return new ServiceSpec{ + .name = "infologger", + .init = [](ServiceRegistry& services, DeviceState&, fair::mq::ProgOptions& options) -> ServiceHandle { + auto infoLoggerMode = options.GetPropertyAsString("infologger-mode"); + auto infoLoggerSeverity = options.GetPropertyAsString("infologger-severity"); + if (infoLoggerSeverity.empty() == false && options.GetPropertyAsString("infologger-mode") == "") { + LOGP(info, "Using O2_INFOLOGGER_MODE=infoLoggerD since infologger-severity is set"); + infoLoggerMode = "infoLoggerD"; + } + if (infoLoggerMode != "") { + setenv("O2_INFOLOGGER_MODE", infoLoggerMode.c_str(), 1); + } + char const* infoLoggerEnv = getenv("O2_INFOLOGGER_MODE"); + if (infoLoggerEnv == nullptr || strcmp(infoLoggerEnv, "none") == 0) { + return ServiceHandle{.hash = TypeIdHelpers::uniqueId(), + .instance = nullptr, + .kind = ServiceKind::Serial, + .name = "infologger"}; + } + InfoLogger* infoLoggerService = nullptr; + try { + infoLoggerService = new InfoLogger; + } catch (...) { + LOGP(error, "Unable to initialise InfoLogger with O2_INFOLOGGER_MODE={}.", infoLoggerMode); + return ServiceHandle{.hash = TypeIdHelpers::uniqueId(), + .instance = nullptr, + .kind = ServiceKind::Serial, + .name = "infologger"}; + } + auto infoLoggerContext = &services.get(); + // Only print the first 10 characters and the last 18 if the + // string length is greater than 32 bytes. + auto truncate = [](std::string in) -> std::string { + if (in.size() < 32) { + return in; + } + char name[32]; + memcpy(name, in.data(), 10); + name[10] = '.'; + name[11] = '.'; + name[12] = '.'; + memcpy(name + 13, in.data() + in.size() - 18, 18); + name[31] = 0; + return name; + }; + infoLoggerContext->setField(InfoLoggerContext::FieldName::Facility, truncate(services.get().name)); + infoLoggerContext->setField(InfoLoggerContext::FieldName::System, std::string("DPL")); + infoLoggerService->setContext(*infoLoggerContext); + + if (infoLoggerSeverity != "") { + fair::Logger::AddCustomSink("infologger", infoLoggerSeverity, createInfoLoggerSinkHelper(infoLoggerService, infoLoggerContext)); + } + return ServiceHandle{.hash = TypeIdHelpers::uniqueId(), + .instance = infoLoggerService, + .kind = ServiceKind::Serial, + .name = "infologger"}; + }, + .configure = CommonServices::noConfiguration(), + .kind = ServiceKind::Serial}; + } +}; + +DEFINE_DPL_PLUGINS_BEGIN +DEFINE_DPL_PLUGIN_INSTANCE(InfoLoggerContextPlugin, CustomService); +DEFINE_DPL_PLUGIN_INSTANCE(InfoLoggerPlugin, CustomService); +DEFINE_DPL_PLUGINS_END diff --git a/Utilities/Mergers/CMakeLists.txt b/Utilities/Mergers/CMakeLists.txt index ccd0a506f0182..aee20bd2d0b2f 100644 --- a/Utilities/Mergers/CMakeLists.txt +++ b/Utilities/Mergers/CMakeLists.txt @@ -14,7 +14,7 @@ o2_add_library(Mergers SOURCES src/MergerAlgorithm.cxx src/IntegratingMerger.cxx src/MergerInfrastructureBuilder.cxx src/MergerBuilder.cxx src/FullHistoryMerger.cxx src/ObjectStore.cxx - PUBLIC_LINK_LIBRARIES O2::Framework) + PUBLIC_LINK_LIBRARIES O2::Framework AliceO2::InfoLogger) o2_target_root_dictionary( Mergers