artdaq_core  v3_00_00
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Pages
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:[\"*\"] statistics:[\"stats\"] "
102  << " destinations : { ";
103 
104  if (useConsole)
105  {
106  std::string outputLevel = "\"INFO\" ";
107  if (printDebug) outputLevel = "\"DEBUG\" ";
108  if (artdaqMfextensionsDir != nullptr)
109  {
110  ss << " console : { "
111  << " type : \"ANSI\" threshold : " << outputLevel
112  << " noTimeStamps : true "
113  << " bell_on_error: true "
114  << " } ";
115  }
116  else
117  {
118  ss << " console : { "
119  << " type : \"cout\" threshold :" << outputLevel
120  << " noTimeStamps : true "
121  << " } ";
122  }
123  }
124 
125  if (artdaqMfextensionsDir != nullptr)
126  {
127  ss << " file: { "
128  << " type: \"GenFile\" threshold: \"DEBUG\" sep: \"-\" "
129  << " file_name_prefix: \"" << progname << "\" ";
130  if (logfileDir.size())
131  {
132  ss << " base_directory: \"" << logfileDir << "\"";
133  }
134  ss << " append : false "
135  << " } ";
136  }
137  else if (logfileName.length() > 0)
138  {
139  ss << " file : { "
140  << " type : \"file\" threshold : \"DEBUG\" "
141  << " filename : \"" << logfileName << "\" "
142  << " append : false "
143  << " } ";
144  }
145 
146  if (artdaqMfextensionsDir != nullptr)
147  {
148  ss << " trace : { "
149  << " type : \"TRACE\" threshold : \"DEBUG\" format:{noLineBreaks: true} lvls: 0x7 lvlm: 0xF"
150  << " } ";
151  }
152 
153  if (logFhiclCode != nullptr)
154  {
155  std::ifstream logfhicl(logFhiclCode);
156 
157  if (logfhicl.is_open())
158  {
159  std::stringstream fhiclstream;
160  fhiclstream << logfhicl.rdbuf();
161  ss << fhiclstream.str();
162  }
163  else
164  {
165  throw cet::exception("configureMessageFacility") << "Unable to open requested fhicl file \"" << logFhiclCode << "\".";
166  }
167  }
168 
169  ss << " } ";
170 
171  std::string pstr(ss.str());
172  //std::cout << "Message Facility Config is: " << pstr << std::endl;
173  return pstr;
174 }
175 
176 void artdaq::configureMessageFacility(char const* progname, bool useConsole, bool printDebug)
177 {
178  auto pstr = generateMessageFacilityConfiguration(progname, useConsole, printDebug);
179  fhicl::ParameterSet pset;
180  fhicl::make_ParameterSet(pstr, pset);
181 
182 #if CANVAS_HEX_VERSION >= 0x20002 // art v2_07_03 means a new versions of fhicl, boost, etc
183  mf::StartMessageFacility(pset);
184 
185  mf::SetApplicationName(progname);
186 # else
187  mf::StartMessageFacility(mf::MessageFacilityService::MultiThread, pset);
188 
189  mf::SetModuleName(progname);
190  mf::SetContext(progname);
191 # endif
192 }
193 
194 void artdaq::setMsgFacAppName(const std::string& appType, unsigned short port)
195 {
196  std::string appName(appType);
197 
198  char hostname[256];
199  if (gethostname(&hostname[0], 256) == 0)
200  {
201  std::string hostString(hostname);
202  size_t pos = hostString.find(".");
203  if (pos != std::string::npos && pos > 2)
204  {
205  hostString = hostString.substr(0, pos);
206  }
207  appName.append("-");
208  appName.append(hostString);
209  }
210 
211  appName.append("-");
212  appName.append(boost::lexical_cast<std::string>(port));
213 
214  mf::SetApplicationName(appName);
215 }
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...