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 #include "fhiclcpp/make_ParameterSet.h"
13 #define TRACE_NAME "configureMessageFacility"
16 namespace BFS = boost::filesystem;
20 std::string logPathProblem;
21 std::string logfileName;
22 char* logRootString = getenv(
"ARTDAQ_LOG_ROOT");
23 char* logFhiclCode = getenv(
"ARTDAQ_LOG_FHICL");
24 char* artdaqMfextensionsDir = getenv(
"ARTDAQ_MFEXTENSIONS_DIR");
25 char* useMFExtensionsS = getenv(
"ARTDAQ_MFEXTENSIONS_ENABLED");
26 bool useMFExtensions =
false;
27 if (useMFExtensionsS !=
nullptr && !(strncmp(useMFExtensionsS,
"0", 1) == 0))
29 useMFExtensions =
true;
32 char* printTimestampsToConsoleS = getenv(
"ARTDAQ_LOG_TIMESTAMPS_TO_CONSOLE");
33 bool printTimestampsToConsole =
true;
34 if (printTimestampsToConsoleS !=
nullptr && strncmp(printTimestampsToConsoleS,
"0", 1) == 0)
36 printTimestampsToConsole =
false;
39 std::string logfileDir;
40 if (logRootString !=
nullptr)
42 if (!BFS::exists(logRootString))
44 logPathProblem =
"Log file root directory ";
45 logPathProblem.append(logRootString);
46 logPathProblem.append(
" does not exist!");
47 throw cet::exception(
"ConfigureMessageFacility") << logPathProblem;
50 logfileDir = logRootString;
51 logfileDir.append(
"/");
52 logfileDir.append(progname);
56 if (!BFS::exists(logfileDir))
58 BFS::create_directory(logfileDir);
59 BFS::permissions(logfileDir, BFS::add_perms | BFS::owner_all | BFS::group_all | BFS::others_read);
66 timeinfo = localtime(&rawtime);
67 strftime(timeBuff, 256,
"%Y%m%d%H%M%S", timeinfo);
70 std::string hostString;
71 if (gethostname(&hostname[0], 256) == 0)
73 std::string tmpString(hostname);
74 hostString = tmpString;
75 size_t pos = hostString.find(
'.');
76 if (pos != std::string::npos && pos > 2)
78 hostString = hostString.substr(0, pos);
82 logfileName.append(logfileDir);
83 logfileName.append(
"/");
84 logfileName.append(progname);
85 logfileName.append(
"-");
86 if (!hostString.empty() && logfileName.find(hostString) == std::string::npos)
88 logfileName.append(hostString);
89 logfileName.append(
"-");
91 logfileName.append(timeBuff);
92 logfileName.append(
"-");
93 logfileName.append(boost::lexical_cast<std::string>(getpid()));
94 logfileName.append(
".log");
97 std::ostringstream ss;
99 ss <<
" destinations : { ";
103 std::string outputLevel =
"\"INFO\" ";
106 outputLevel =
"\"DEBUG\" ";
108 if (artdaqMfextensionsDir !=
nullptr && useMFExtensions)
110 ss <<
" console : { "
111 <<
" type : \"ANSI\" threshold : " << outputLevel;
112 if (!printTimestampsToConsole)
114 ss <<
" format: { timestamp: none } ";
116 ss <<
" bell_on_error: true ";
121 ss <<
" console : { "
122 <<
" type : \"cout\" threshold :" << outputLevel;
123 if (!printTimestampsToConsole)
125 ss <<
" format: { timestamp: none } ";
131 if (!logfileDir.empty())
134 ss << R
"( type: "GenFile" threshold: "DEBUG" seperator: "-")";
135 ss << " pattern: \"" << progname <<
"-%?H%t-%p.log"
137 ss <<
" timestamp_pattern: \"%Y%m%d%H%M%S\"";
138 ss <<
" directory: \"" << logfileDir <<
"\"";
139 ss <<
" append : false";
142 #if 0 // ELF 01/17/2018 Removed because it violates the "every EVB art process must have identical configuration" rule
143 else if (logfileName.length() > 0)
146 <<
" type : \"file\" threshold : \"DEBUG\" "
147 <<
" filename : \"" << logfileName <<
"\" "
148 <<
" append : false "
153 if (artdaqMfextensionsDir !=
nullptr && useMFExtensions)
156 << R
"( type : "TRACE" threshold : "DEBUG" format:{noLineBreaks: true} lvls: 0x7 lvlm: 0xF)"
160 if (logFhiclCode !=
nullptr)
162 std::ifstream logfhicl(logFhiclCode);
164 if (logfhicl.is_open())
166 std::stringstream fhiclstream;
167 fhiclstream << logfhicl.rdbuf();
168 ss << fhiclstream.str();
172 throw cet::exception(
"configureMessageFacility") <<
"Unable to open requested fhicl file \"" << logFhiclCode <<
"\".";
178 std::string pstr(ss.str());
181 fhicl::ParameterSet tmp_pset;
184 fhicl::make_ParameterSet(pstr, tmp_pset);
186 catch (cet::exception
const& ex)
188 ExceptionHandler(ExceptionHandlerRethrow::yes, std::string(
"Exception occurred while processing fhicl ParameterSet string ") + pstr +
":");
190 return tmp_pset.to_string();
212 std::vector<std::string> names = trace_pset.get_names();
213 std::vector<std::string> trace_envs = {
214 "TRACE_LIMIT_MS",
"TRACE_MODE",
"TRACE_NAMLVLSET"};
215 std::unordered_map<std::string, bool> envs_set_to_unset;
216 for (
const auto& env : trace_envs)
218 envs_set_to_unset[env] =
false;
221 for (
const auto& name : names)
223 if (name ==
"TRACE_NUMENTS" || name ==
"TRACE_ARGSMAX" || name ==
"TRACE_MSGMAX" || name ==
"TRACE_FILE")
226 setenv(name.c_str(), trace_pset.get<std::string>(name).c_str(), 0);
229 else if (name ==
"TRACE_LIMIT_MS")
231 if (getenv(name.c_str()) ==
nullptr)
233 envs_set_to_unset[name] =
true;
234 auto limit = trace_pset.get<std::vector<uint32_t>>(name);
236 std::string limits = std::to_string(limit[0]) +
"," + std::to_string(limit[1]) +
"," + std::to_string(limit[2]);
237 setenv(name.c_str(), limits.c_str(), 0);
240 else if (name ==
"TRACE_MODE")
242 if (getenv(name.c_str()) ==
nullptr)
244 envs_set_to_unset[name] =
true;
245 setenv(name.c_str(), trace_pset.get<std::string>(name).c_str(), 0);
248 else if (name ==
"TRACE_NAMLVLSET")
250 if (getenv(name.c_str()) ==
nullptr)
252 envs_set_to_unset[name] =
true;
253 std::stringstream lvlsbldr;
254 auto lvls_pset = trace_pset.get<fhicl::ParameterSet>(name);
255 std::vector<std::string> tnames = lvls_pset.get_names();
256 for (
const auto& tname : tnames)
259 auto msks = lvls_pset.get<std::vector<uint64_t>>(tname);
260 for (
auto msk : msks)
262 lvlsbldr <<
" 0x" << std::hex << static_cast<unsigned long long>(msk);
266 setenv(name.c_str(), lvlsbldr.str().c_str(), 0);
270 TRACE_CNTL(
"namlvlset");
271 for (
const auto& env : trace_envs)
273 if (envs_set_to_unset[env])
275 unsetenv(env.c_str());
283 fhicl::ParameterSet pset;
286 fhicl::make_ParameterSet(pstr, pset);
288 catch (cet::exception
const&)
290 ExceptionHandler(ExceptionHandlerRethrow::yes, std::string(
"Exception occurred while processing fhicl ParameterSet string ") + pstr +
":");
293 fhicl::ParameterSet trace_pset;
294 if (!pset.get_if_present<fhicl::ParameterSet>(
"TRACE", trace_pset))
296 fhicl::ParameterSet trace_dflt_pset;
297 fhicl::make_ParameterSet(
"TRACE:{TRACE_MSGMAX:0 TRACE_LIMIT_MS:[10,500,1500]}", trace_dflt_pset);
298 pset.put<fhicl::ParameterSet>(
"TRACE", trace_dflt_pset.get<fhicl::ParameterSet>(
"TRACE"));
299 trace_pset = pset.get<fhicl::ParameterSet>(
"TRACE");
302 pstr = pset.to_string();
305 #if CANVAS_HEX_VERSION >= 0x30300 // art v2_11_00
306 mf::StartMessageFacility(pset, progname);
309 mf::StartMessageFacility(pset);
311 mf::SetApplicationName(progname);
313 mf::setEnabledState(
"");
315 TLOG(TLVL_TRACE) <<
"Message Facility Config input is: " << pstr;
316 TLOG(TLVL_INFO) <<
"Message Facility Application " << progname <<
" configured with: " << pset.to_string();
321 std::string appName(appType);
324 if (gethostname(&hostname[0], 256) == 0)
326 std::string hostString(hostname);
327 size_t pos = hostString.find(
'.');
328 if (pos != std::string::npos && pos > 2)
330 hostString = hostString.substr(0, pos);
333 appName.append(hostString);
337 appName.append(boost::lexical_cast<std::string>(port));
339 mf::SetApplicationName(appName);
void configureTRACE(fhicl::ParameterSet &trace_pset)
Configure TRACE.
std::string generateMessageFacilityConfiguration(char const *progname, bool useConsole=true, bool printDebug=false)
Create the MessageFacility configuration Fhicl string.
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...
void ExceptionHandler(ExceptionHandlerRethrow decision, const std::string &optional_message)
The ExceptionHandler class prints out all available information about an excection, then optionally re-throws.