artdaq_core  v3_00_03
configureMessageFacility.cc
1 #include "artdaq-core/Utilities/configureMessageFacility.hh"
2 #include "messagefacility/MessageLogger/MessageLogger.h"
3 #if CANVAS_HEX_VERSION >= 0x20002 // art v2_07_03 means a new versions of fhicl, boost, etc
4 # include "fhiclcpp/ParameterSet.h"
5 # include <boost/lexical_cast.hpp>
6 #endif
7 #include "fhiclcpp/make_ParameterSet.h"
8 #include "cetlib_except/exception.h"
9 #include <boost/filesystem.hpp>
10 #include <unistd.h>
11 #include <fstream>
12 #include <sstream>
13 #include "trace.h" // TRACE_CNTL, TRACE
14 
15 namespace BFS = boost::filesystem;
16 
17 std::string artdaq::generateMessageFacilityConfiguration(char const* progname, bool useConsole, bool printDebug)
18 {
19  std::string logPathProblem = "";
20  std::string logfileName = "";
21  char* logRootString = getenv("ARTDAQ_LOG_ROOT");
22  char* logFhiclCode = getenv("ARTDAQ_LOG_FHICL");
23  char* artdaqMfextensionsDir = getenv("ARTDAQ_MFEXTENSIONS_DIR");
24 
25 #if 0
26  setenv("TRACE_LVLS", "0xf", 0/*0 = no overwrite*/);
27  unsigned long long lvls = strtoull(getenv("TRACE_LVLS"), NULL, 0);
28  // NOTE: If TRACEs occur before this, they would be done with a different lvl S mask.
29  // To check this, one could: treset;tonMg 0-63; tcntl trig -nTRACE 4 50; <app>
30  // checking for TRACEs before the TRACE below.
31  // If an existing trace file is used, the value of modeS is unchanged.
32  TRACE_CNTL("lvlmskSg", lvls);
33  TRACE(4, "configureMessageFacility lvlmskSg set to 0x%llx", lvls);
34 #endif
35 
36  std::string logfileDir = "";
37  if (logRootString != nullptr)
38  {
39  if (!BFS::exists(logRootString))
40  {
41  logPathProblem = "Log file root directory ";
42  logPathProblem.append(logRootString);
43  logPathProblem.append(" does not exist!");
44  throw cet::exception("ConfigureMessageFacility") << logPathProblem;
45  }
46  else
47  {
48  logfileDir = logRootString;
49  logfileDir.append("/");
50  logfileDir.append(progname);
51 
52  // As long as the top-level directory exists, I don't think we really care if we have to create application directories...
53  if (!BFS::exists(logfileDir))
54  {
55  BFS::create_directory(logfileDir);
56  /*logPathProblem = "Log file directory ";
57  logPathProblem.append(logfileDir);
58  logPathProblem.append(" does not exist!");
59  throw cet::exception("ConfigureMessageFacility") << logPathProblem;*/
60  }
61  else
62  {
63  time_t rawtime;
64  struct tm* timeinfo;
65  char timeBuff[256];
66  time(&rawtime);
67  timeinfo = localtime(&rawtime);
68  strftime(timeBuff, 256, "%Y%m%d%H%M%S", timeinfo);
69 
70  char hostname[256];
71  std::string hostString = "";
72  if (gethostname(&hostname[0], 256) == 0)
73  {
74  std::string tmpString(hostname);
75  hostString = tmpString;
76  size_t pos = hostString.find(".");
77  if (pos != std::string::npos && pos > 2)
78  {
79  hostString = hostString.substr(0, pos);
80  }
81  }
82 
83  logfileName.append(logfileDir);
84  logfileName.append("/");
85  logfileName.append(progname);
86  logfileName.append("-");
87  logfileName.append(timeBuff);
88  logfileName.append("-");
89  if (hostString.size() > 0)
90  {
91  logfileName.append(hostString);
92  logfileName.append("-");
93  }
94  logfileName.append(boost::lexical_cast<std::string>(getpid()));
95  logfileName.append(".log");
96  }
97  }
98  }
99 
100  std::ostringstream ss;
101  ss << "debugModules:[\"*\"] "
102 #if MESSAGEFACILITY_HEX_VERSION < 0x20103
103  << " statistics:[\"stats\"] "
104 #endif
105  << " destinations : { ";
106 
107  if (useConsole)
108  {
109  std::string outputLevel = "\"INFO\" ";
110  if (printDebug) outputLevel = "\"DEBUG\" ";
111  if (artdaqMfextensionsDir != nullptr)
112  {
113  ss << " console : { "
114  << " type : \"ANSI\" threshold : " << outputLevel
115 #if MESSAGEFACILITY_HEX_VERSION < 0x20103
116  << " noTimeStamps : true "
117 #else
118  << " format: { timestamp: none } "
119 #endif
120  << " bell_on_error: true "
121  << " } ";
122  }
123  else
124  {
125  ss << " console : { "
126  << " type : \"cout\" threshold :" << outputLevel
127 #if MESSAGEFACILITY_HEX_VERSION < 0x20103
128  << " noTimeStamps : true "
129 #else
130  << " format: { timestamp: none } "
131 #endif
132  << " } ";
133  }
134  }
135 
136  if (artdaqMfextensionsDir != nullptr)
137  {
138  ss << " file: { "
139  << " type: \"GenFile\" threshold: \"DEBUG\" sep: \"-\" "
140  << " file_name_prefix: \"" << progname << "\" ";
141  if (logfileDir.size())
142  {
143  ss << " base_directory: \"" << logfileDir << "\"";
144  }
145  ss << " append : false "
146  << " } ";
147  }
148  else if (logfileName.length() > 0)
149  {
150  ss << " file : { "
151  << " type : \"file\" threshold : \"DEBUG\" "
152  << " filename : \"" << logfileName << "\" "
153  << " append : false "
154  << " } ";
155  }
156 
157  if (artdaqMfextensionsDir != nullptr)
158  {
159  ss << " trace : { "
160  << " type : \"TRACE\" threshold : \"DEBUG\" format:{noLineBreaks: true} lvls: 0x7 lvlm: 0xF"
161  << " } ";
162  }
163 
164  if (logFhiclCode != nullptr)
165  {
166  std::ifstream logfhicl(logFhiclCode);
167 
168  if (logfhicl.is_open())
169  {
170  std::stringstream fhiclstream;
171  fhiclstream << logfhicl.rdbuf();
172  ss << fhiclstream.str();
173  }
174  else
175  {
176  throw cet::exception("configureMessageFacility") << "Unable to open requested fhicl file \"" << logFhiclCode << "\".";
177  }
178  }
179 
180  ss << " } ";
181 
182  std::string pstr(ss.str());
183  std::cout << "Message Facility Config is: " << pstr << std::endl;
184  return pstr;
185 }
186 
187 void artdaq::configureMessageFacility(char const* progname, bool useConsole, bool printDebug)
188 {
189  auto pstr = generateMessageFacilityConfiguration(progname, useConsole, printDebug);
190  fhicl::ParameterSet pset;
191  fhicl::make_ParameterSet(pstr, pset);
192 
193 #if CANVAS_HEX_VERSION >= 0x20002 // art v2_07_03 means a new versions of fhicl, boost, etc
194  mf::StartMessageFacility(pset);
195 
196  mf::SetApplicationName(progname);
197 
198  mf::setEnabledState("");
199 # else
200  mf::StartMessageFacility(mf::MessageFacilityService::MultiThread, pset);
201 
202  mf::SetModuleName(progname);
203  mf::SetContext(progname);
204 # endif
205 }
206 
207 void artdaq::setMsgFacAppName(const std::string& appType, unsigned short port)
208 {
209  std::string appName(appType);
210 
211  char hostname[256];
212  if (gethostname(&hostname[0], 256) == 0)
213  {
214  std::string hostString(hostname);
215  size_t pos = hostString.find(".");
216  if (pos != std::string::npos && pos > 2)
217  {
218  hostString = hostString.substr(0, pos);
219  }
220  appName.append("-");
221  appName.append(hostString);
222  }
223 
224  appName.append("-");
225  appName.append(boost::lexical_cast<std::string>(port));
226 
227  mf::SetApplicationName(appName);
228 }
void 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)
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...