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::error:
76 severity = InfoLogger::Severity::Error;
77 level = 2;
78 break;
79 case fair::Severity::alarm:
80 severity = InfoLogger::Severity::Warning;
81 level = 6;
82 break;
83 case fair::Severity::important:
84 severity = InfoLogger::Severity::Info;
85 level = 7;
86 break;
87 case fair::Severity::warn:
88 severity = InfoLogger::Severity::Warning;
89 level = 11;
90 break;
91 case fair::Severity::state:
92 severity = InfoLogger::Severity::Info;
93 level = 12;
94 break;
95 case fair::Severity::info:
96 severity = InfoLogger::Severity::Info;
97 level = 13;
98 break;
99 case fair::Severity::debug:
100 severity = InfoLogger::Severity::Debug;
101 level = 14;
102 break;
103 case fair::Severity::detail:
104 severity = InfoLogger::Severity::Debug;
105 level = 15;
106 break;
107 case fair::Severity::debug1:
108 severity = InfoLogger::Severity::Debug;
109 level = 16;
110 break;
111 case fair::Severity::debug2:
112 severity = InfoLogger::Severity::Debug;
113 level = 17;
114 break;
115 case fair::Severity::debug3:
116 severity = InfoLogger::Severity::Debug;
117 level = 18;
118 break;
119 case fair::Severity::debug4:
120 severity = InfoLogger::Severity::Debug;
121 level = 19;
122 break;
123 case fair::Severity::trace:
124 severity = InfoLogger::Severity::Debug;
125 level = 21;
126 break;
127 case fair::Severity::nolog: // discard
128 return;
129 }
130
131 InfoLogger::InfoLoggerMessageOption opt = {
132 severity,
133 level,
134 InfoLogger::undefinedMessageOption.errorCode,
135 metadata.file.data(),
136 atoi(metadata.line.data())};
137
138 if (logger) {
139 logger->log(opt, *ctx, "%s", content.c_str());
140 }
141 };
142};
143
146 {
147 return new ServiceSpec{
148 .name = "infologger",
149 .init = [](ServiceRegistryRef services, DeviceState&, fair::mq::ProgOptions& options) -> ServiceHandle {
150 auto infoLoggerMode = options.GetPropertyAsString("infologger-mode");
151 auto infoLoggerSeverity = options.GetPropertyAsString("infologger-severity");
152 if (infoLoggerSeverity.empty() == false && options.GetPropertyAsString("infologger-mode") == "") {
153 LOGP(info, "Using O2_INFOLOGGER_MODE=infoLoggerD since infologger-severity is set");
154 infoLoggerMode = "infoLoggerD";
155 }
156 if (infoLoggerMode != "") {
157 setenv("O2_INFOLOGGER_MODE", infoLoggerMode.c_str(), 1);
158 }
159 char const* infoLoggerEnv = getenv("O2_INFOLOGGER_MODE");
160 if (infoLoggerEnv == nullptr || strcmp(infoLoggerEnv, "none") == 0) {
161 return ServiceHandle{.hash = TypeIdHelpers::uniqueId<MissingService>(),
162 .instance = nullptr,
163 .kind = ServiceKind::Serial,
164 .name = "infologger"};
165 }
166 InfoLogger* infoLoggerService = nullptr;
167 try {
168 infoLoggerService = new InfoLogger;
169 } catch (...) {
170 LOGP(error, "Unable to initialise InfoLogger with O2_INFOLOGGER_MODE={}.", infoLoggerMode);
171 return ServiceHandle{.hash = TypeIdHelpers::uniqueId<MissingService>(),
172 .instance = nullptr,
173 .kind = ServiceKind::Serial,
174 .name = "infologger"};
175 }
176 auto infoLoggerContext = &services.get<InfoLoggerContext>();
177 // Only print the first 10 characters and the last 18 if the
178 // string length is greater than 32 bytes.
179 auto truncate = [](std::string in) -> std::string {
180 if (in.size() < 32) {
181 return in;
182 }
183 char name[32];
184 memcpy(name, in.data(), 10);
185 name[10] = '.';
186 name[11] = '.';
187 name[12] = '.';
188 memcpy(name + 13, in.data() + in.size() - 18, 18);
189 name[31] = 0;
190 return name;
191 };
192 infoLoggerContext->setField(InfoLoggerContext::FieldName::Facility, truncate(services.get<DeviceSpec const>().name));
193 infoLoggerContext->setField(InfoLoggerContext::FieldName::System, std::string("DPL"));
194 infoLoggerService->setContext(*infoLoggerContext);
195
196 if (infoLoggerSeverity != "") {
197 fair::Logger::AddCustomSink("infologger", infoLoggerSeverity, createInfoLoggerSinkHelper(infoLoggerService, infoLoggerContext));
198 }
199 return ServiceHandle{.hash = TypeIdHelpers::uniqueId<InfoLogger>(),
200 .instance = infoLoggerService,
201 .kind = ServiceKind::Serial,
202 .name = "infologger"};
203 },
204 .configure = CommonServices::noConfiguration(),
205 .kind = ServiceKind::Serial};
206 }
207};
208
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:145
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.