1 #include "artdaq-core/Utilities/configureMessageFacility.hh"
2 #include "messagefacility/MessageLogger/MessageLogger.h"
5 #include <boost/filesystem.hpp>
6 #include <boost/lexical_cast.hpp>
9 #include "artdaq-core/Utilities/ExceptionHandler.hh"
10 #include "cetlib_except/exception.h"
11 #include "fhiclcpp/ParameterSet.h"
12 #define TRACE_NAME "configureMessageFacility"
13 #include "TRACE/tracemf.h"
15 namespace BFS = boost::filesystem;
23 fhicl::ParameterSet
make_pset(std::string
const& config_str)
25 return fhicl::ParameterSet::make(config_str);
31 std::string logPathProblem;
32 char* logRootString = getenv(
"ARTDAQ_LOG_ROOT");
33 char* logFhiclCode = getenv(
"ARTDAQ_LOG_FHICL");
34 char* artdaqMfextensionsDir = getenv(
"ARTDAQ_MFEXTENSIONS_DIR");
35 char* useMFExtensionsS = getenv(
"ARTDAQ_MFEXTENSIONS_ENABLED");
36 char* run_number = getenv(
"ARTDAQ_RUN_NUMBER");
37 bool useMFExtensions =
false;
38 if (useMFExtensionsS !=
nullptr && !(strncmp(useMFExtensionsS,
"0", 1) == 0))
40 useMFExtensions =
true;
43 char* printTimestampsToConsoleS = getenv(
"ARTDAQ_LOG_TIMESTAMPS_TO_CONSOLE");
44 bool printTimestampsToConsole =
true;
45 if (printTimestampsToConsoleS !=
nullptr && strncmp(printTimestampsToConsoleS,
"0", 1) == 0)
47 printTimestampsToConsole =
false;
50 std::string logfileDir;
51 if (logRootString !=
nullptr)
53 if (!BFS::exists(logRootString))
55 logPathProblem =
"Log file root directory ";
56 logPathProblem.append(logRootString);
57 logPathProblem.append(
" does not exist!");
58 throw cet::exception(
"ConfigureMessageFacility") << logPathProblem;
61 logfileDir = logRootString;
62 logfileDir.append(
"/");
63 logfileDir.append(progname);
67 if (!BFS::exists(logfileDir))
69 BFS::create_directory(logfileDir);
70 BFS::permissions(logfileDir, BFS::add_perms | BFS::owner_all | BFS::group_all | BFS::others_read);
74 std::ostringstream ss;
76 ss <<
" destinations : { ";
80 std::string outputLevel =
"\"INFO\" ";
83 outputLevel =
"\"DEBUG\" ";
85 if (artdaqMfextensionsDir !=
nullptr && useMFExtensions)
88 <<
" type : \"ANSI\" threshold : " << outputLevel;
89 if (!printTimestampsToConsole)
91 ss <<
" format: { timestamp: none } ";
93 ss <<
" bell_on_error: true ";
99 <<
" type : \"cout\" threshold :" << outputLevel;
100 if (!printTimestampsToConsole)
102 ss <<
" format: { timestamp: none } ";
108 if (!logfileDir.empty())
111 ss << R
"( type: "GenFile" threshold: "DEBUG" seperator: "-")";
114 if (run_number ==
nullptr) {
115 ss <<
" pattern: \"" << progname << fileExtraName <<
"-%?H%t-%p.log" <<
"\"";
122 sprintf(c,
"%06i",std::stoi(run_number));
123 ss <<
" pattern: \"" << progname <<
"-" << c << fileExtraName <<
"-%?H%t-%p.log" <<
"\"";
126 ss <<
" timestamp_pattern: \"%Y%m%d%H%M%S\"";
127 ss <<
" directory: \"" << logfileDir <<
"\"";
128 ss <<
" append : false";
132 if (artdaqMfextensionsDir !=
nullptr && useMFExtensions)
135 << R
"( type : "TRACE" threshold : "DEBUG" format:{noLineBreaks: true} lvls: 0x7 lvlm: 0xF)"
139 if (logFhiclCode !=
nullptr)
141 std::ifstream logfhicl(logFhiclCode);
143 if (logfhicl.is_open())
145 std::stringstream fhiclstream;
146 fhiclstream << logfhicl.rdbuf();
147 ss << fhiclstream.str();
151 TLOG(TLVL_ERROR) <<
"Unable to open requested fhicl file ARTDAQ_LOG_FHICL=\"" << logFhiclCode <<
"\".";
152 throw cet::exception(
"ConfigureMessageFacility") <<
"Unable to open requested fhicl file ARTDAQ_LOG_FHICL=\"" << logFhiclCode <<
"\".";
158 std::string pstr(ss.str());
161 fhicl::ParameterSet tmp_pset;
164 tmp_pset = make_pset(pstr);
166 catch (cet::exception
const& ex)
168 ExceptionHandler(ExceptionHandlerRethrow::yes, std::string(
"Exception occurred while processing fhicl ParameterSet string ") + pstr +
":");
170 return tmp_pset.to_string();
192 std::vector<std::string> names = trace_pset.get_names();
193 std::vector<std::string> trace_envs = {
194 "TRACE_LIMIT_MS",
"TRACE_MODE",
"TRACE_NAMLVLSET"};
195 std::unordered_map<std::string, bool> envs_set_to_unset;
196 for (
const auto& env : trace_envs)
198 envs_set_to_unset[env] =
false;
201 for (
const auto& name : names)
203 if (name ==
"TRACE_NUMENTS" || name ==
"TRACE_ARGSMAX" || name ==
"TRACE_MSGMAX" || name ==
"TRACE_FILE")
206 setenv(name.c_str(), trace_pset.get<std::string>(name).c_str(), 0);
209 else if (name ==
"TRACE_LIMIT_MS")
211 if (getenv(name.c_str()) ==
nullptr)
213 envs_set_to_unset[name] =
true;
214 auto limit = trace_pset.get<std::vector<uint32_t>>(name);
216 std::string limits = std::to_string(limit[0]) +
"," + std::to_string(limit[1]) +
"," + std::to_string(limit[2]);
217 setenv(name.c_str(), limits.c_str(), 0);
220 else if (name ==
"TRACE_MODE")
222 if (getenv(name.c_str()) ==
nullptr)
224 envs_set_to_unset[name] =
true;
225 setenv(name.c_str(), trace_pset.get<std::string>(name).c_str(), 0);
228 else if (name ==
"TRACE_NAMLVLSET")
230 if (getenv(name.c_str()) ==
nullptr)
232 envs_set_to_unset[name] =
true;
233 std::stringstream lvlsbldr;
234 auto lvls_pset = trace_pset.get<fhicl::ParameterSet>(name);
235 std::vector<std::string> tnames = lvls_pset.get_names();
236 for (
const auto& tname : tnames)
239 auto msks = lvls_pset.get<std::vector<double>>(tname);
240 for (
auto msk : msks)
242 lvlsbldr <<
" 0x" << std::hex << static_cast<unsigned long long>(msk);
246 setenv(name.c_str(), lvlsbldr.str().c_str(), 0);
250 TRACE_CNTL(
"namlvlset");
251 for (
const auto& env : trace_envs)
253 if (envs_set_to_unset[env])
255 unsetenv(env.c_str());
263 fhicl::ParameterSet pset;
266 pset = make_pset(pstr);
268 catch (cet::exception
const&)
270 ExceptionHandler(ExceptionHandlerRethrow::yes, std::string(
"Exception occurred while processing fhicl ParameterSet string ") + pstr +
":");
273 fhicl::ParameterSet trace_pset;
274 if (!pset.get_if_present<fhicl::ParameterSet>(
"TRACE", trace_pset))
276 auto trace_dflt_pset = make_pset(
"TRACE:{TRACE_MSGMAX:0 TRACE_LIMIT_MS:[10,500,1500]}");
277 pset.put<fhicl::ParameterSet>(
"TRACE", trace_dflt_pset.get<fhicl::ParameterSet>(
"TRACE"));
278 trace_pset = pset.get<fhicl::ParameterSet>(
"TRACE");
281 pstr = pset.to_string();
284 mf::StartMessageFacility(pset, progname);
286 TLOG(TLVL_DEBUG + 33) <<
"Message Facility Config input is: " << pstr;
287 TLOG(TLVL_INFO) <<
"Message Facility Application " << progname <<
" configured with: " << pset.to_string();
292 std::string appName(appType);
295 if (gethostname(&hostname[0], 256) == 0)
297 std::string hostString(hostname);
298 size_t pos = hostString.find(
'.');
299 if (pos != std::string::npos && pos > 2)
301 hostString = hostString.substr(0, pos);
304 appName.append(hostString);
308 appName.append(boost::lexical_cast<std::string>(port));
310 mf::SetApplicationName(appName);
void configureTRACE(fhicl::ParameterSet &trace_pset)
Configure TRACE.
void configureMessageFacility(char const *progname, bool useConsole=true, bool printDebug=false)
Configure and start the message facility. Provide the program name so that messages will be appropria...
std::string setMsgFacAppName(const std::string &appType, unsigned short port)
Set the message facility application name using the specified application type and port number...
std::string generateMessageFacilityConfiguration(char const *progname, bool useConsole=true, bool printDebug=false, char const *fileExtraName="")
Create the MessageFacility configuration Fhicl string.
void ExceptionHandler(ExceptionHandlerRethrow decision, const std::string &optional_message)
The ExceptionHandler class prints out all available information about an excection, then optionally re-throws.