Project
Loading...
Searching...
No Matches
Plugin.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11//
12#include "Framework/Plugins.h"
18#include <InfoLogger/InfoLogger.hxx>
19#include <fairlogger/Logger.h>
20#include <fairmq/Device.h>
21#include <fairmq/shmem/Monitor.h>
22#include <fairmq/shmem/Common.h>
23#include <fairmq/ProgOptions.h>
24
25using AliceO2::InfoLogger::InfoLogger;
26using AliceO2::InfoLogger::InfoLoggerContext;
27
28using namespace o2::framework;
29
30namespace o2::framework
31{
33template <>
34struct ServiceKindExtractor<InfoLoggerContext> {
36};
37
38} // namespace o2::framework
39
41};
42
45 {
46 return new ServiceSpec{
47 .name = "infologger-contex",
48 .init = CommonServices::simpleServiceInit<InfoLoggerContext, InfoLoggerContext>(),
50 .start = [](ServiceRegistryRef services, void* service) {
51 auto& infoLoggerContext = services.get<InfoLoggerContext>();
52 auto run = services.get<RawDeviceService>().device()->fConfig->GetProperty<std::string>("runNumber", "unspecified");
53 infoLoggerContext.setField(InfoLoggerContext::FieldName::Run, run);
54 auto partition = services.get<RawDeviceService>().device()->fConfig->GetProperty<std::string>("environment_id", "unspecified");
55 infoLoggerContext.setField(InfoLoggerContext::FieldName::Partition, partition);
56 },
57 .kind = ServiceKind::Serial};
58 }
59};
60
61// Creates the sink for FairLogger / InfoLogger integration
62auto createInfoLoggerSinkHelper(InfoLogger* logger, InfoLoggerContext* ctx)
63{
64 return [logger,
65 ctx](const std::string& content, const fair::LogMetaData& metadata) {
66 // translate FMQ metadata
67 InfoLogger::InfoLogger::Severity severity = InfoLogger::Severity::Undefined;
68 int level = InfoLogger::undefinedMessageOption.level;
69
70 switch (metadata.severity) {
71 case fair::Severity::fatal:
72 severity = InfoLogger::Severity::Fatal;
73 level = 1;
74 break;
75 case fair::Severity::critical:
76 severity = InfoLogger::Severity::Error;
77 level = 1;
78 break;
79 case fair::Severity::error:
80 severity = InfoLogger::Severity::Error;
81 level = 2;
82 break;
83 case fair::Severity::alarm:
84 severity = InfoLogger::Severity::Warning;
85 level = 6;
86 break;
87 case fair::Severity::important:
88 severity = InfoLogger::Severity::Info;
89 level = 7;
90 break;
91 case fair::Severity::warn:
92 severity = InfoLogger::Severity::Warning;
93 level = 11;
94 break;
95 case fair::Severity::state:
96 severity = InfoLogger::Severity::Info;
97 level = 12;
98 break;
99 case fair::Severity::info:
100 severity = InfoLogger::Severity::Info;
101 level = 13;
102 break;
103 case fair::Severity::debug:
104 severity = InfoLogger::Severity::Debug;
105 level = 14;
106 break;
107 case fair::Severity::detail:
108 severity = InfoLogger::Severity::Debug;
109 level = 15;
110 break;
111 case fair::Severity::debug1:
112 severity = InfoLogger::Severity::Debug;
113 level = 16;
114 break;
115 case fair::Severity::debug2:
116 severity = InfoLogger::Severity::Debug;
117 level = 17;
118 break;
119 case fair::Severity::debug3:
120 severity = InfoLogger::Severity::Debug;
121 level = 18;
122 break;
123 case fair::Severity::debug4:
124 severity = InfoLogger::Severity::Debug;
125 level = 19;
126 break;
127 case fair::Severity::trace:
128 severity = InfoLogger::Severity::Debug;
129 level = 21;
130 break;
131 case fair::Severity::nolog: // discard
132 return;
133 }
134
135 if (logger) {
136 logger->log({severity,
137 level,
138 InfoLogger::undefinedMessageOption.errorCode,
139 std::string(metadata.file).c_str(),
140 atoi(std::string(metadata.line).c_str())},
141 *ctx, "%s", content.c_str());
142 }
143 };
144};
145
148 {
149 return new ServiceSpec{
150 .name = "infologger",
151 .init = [](ServiceRegistryRef services, DeviceState&, fair::mq::ProgOptions& options) -> ServiceHandle {
152 auto infoLoggerMode = options.GetPropertyAsString("infologger-mode");
153 auto infoLoggerSeverity = options.GetPropertyAsString("infologger-severity");
154 if (infoLoggerSeverity.empty() == false && options.GetPropertyAsString("infologger-mode") == "") {
155 LOGP(info, "Using O2_INFOLOGGER_MODE=infoLoggerD since infologger-severity is set");
156 infoLoggerMode = "infoLoggerD";
157 }
158 if (infoLoggerMode != "") {
159 setenv("O2_INFOLOGGER_MODE", infoLoggerMode.c_str(), 1);
160 }
161 char const* infoLoggerEnv = getenv("O2_INFOLOGGER_MODE");
162 if (infoLoggerEnv == nullptr || strcmp(infoLoggerEnv, "none") == 0) {
163 return ServiceHandle{.hash = TypeIdHelpers::uniqueId<MissingService>(),
164 .instance = nullptr,
165 .kind = ServiceKind::Serial,
166 .name = "infologger"};
167 }
168 InfoLogger* infoLoggerService = nullptr;
169 try {
170 infoLoggerService = new InfoLogger;
171 } catch (...) {
172 LOGP(error, "Unable to initialise InfoLogger with O2_INFOLOGGER_MODE={}.", infoLoggerMode);
173 return ServiceHandle{.hash = TypeIdHelpers::uniqueId<MissingService>(),
174 .instance = nullptr,
175 .kind = ServiceKind::Serial,
176 .name = "infologger"};
177 }
178 auto infoLoggerContext = &services.get<InfoLoggerContext>();
179 // Only print the first 10 characters and the last 18 if the
180 // string length is greater than 32 bytes.
181 auto truncate = [](std::string in) -> std::string {
182 if (in.size() < 32) {
183 return in;
184 }
185 char name[32];
186 memcpy(name, in.data(), 10);
187 name[10] = '.';
188 name[11] = '.';
189 name[12] = '.';
190 memcpy(name + 13, in.data() + in.size() - 18, 18);
191 name[31] = 0;
192 return name;
193 };
194 infoLoggerContext->setField(InfoLoggerContext::FieldName::Facility, truncate(services.get<DeviceSpec const>().name));
195 infoLoggerContext->setField(InfoLoggerContext::FieldName::System, std::string("DPL"));
196 infoLoggerService->setContext(*infoLoggerContext);
197
198 if (infoLoggerSeverity != "") {
199 fair::Logger::AddCustomSink("infologger", infoLoggerSeverity, createInfoLoggerSinkHelper(infoLoggerService, infoLoggerContext));
200 }
201 return ServiceHandle{.hash = TypeIdHelpers::uniqueId<InfoLogger>(),
202 .instance = infoLoggerService,
203 .kind = ServiceKind::Serial,
204 .name = "infologger"};
205 },
206 .configure = CommonServices::noConfiguration(),
207 .kind = ServiceKind::Serial};
208 }
209};
210
auto createInfoLoggerSinkHelper(InfoLogger *logger, InfoLoggerContext *ctx)
Definition Plugin.cxx:62
#define DEFINE_DPL_PLUGIN_INSTANCE(NAME, KIND)
Definition Plugins.h:112
#define DEFINE_DPL_PLUGINS_END
Definition Plugins.h:115
#define DEFINE_DPL_PLUGINS_BEGIN
Definition Plugins.h:107
GLuint const GLchar * name
Definition glcorearb.h:781
GLint level
Definition glcorearb.h:275
GLenum GLenum severity
Definition glcorearb.h:2513
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
ServiceKind
The kind of service we are asking for.
uint32_t truncate(int32_t j, uint32_t val)
o2::framework::ServiceSpec * create() final
Definition Plugin.cxx:44
o2::framework::ServiceSpec * create() final
Definition Plugin.cxx:147
static ServiceConfigureCallback noConfiguration()
std::string name
The name of the associated DataProcessorSpec.
Definition DeviceSpec.h:50
Running state information of a given device.
Definition DeviceState.h:34
unsigned int hash
Unique hash associated to the type of service.
static constexpr ServiceKind kind
std::string name
Name of the service.