Messenger.cxx
Go to the documentation of this file.
1 //____________________________________________________________________________
2 /*
3  Copyright (c) 2003-2019, The GENIE Collaboration
4  For the full text of the license visit http://copyright.genie-mc.org
5  or see $GENIE/LICENSE
6 
7  Author: Costas Andreopoulos <costas.andreopoulos \at stfc.ac.uk>
8  University of Liverpool & STFC Rutherford Appleton Lab - June 16, 2004
9 
10  For the class documentation see the corresponding header file.
11 
12  Important revisions after version 2.0.0 :
13  @ Jun 01, 2008 - CA
14  At Configure(), if the GPRODMODE environmental variable is set then use
15  mesg thresholds from Messenger_production.xml rather than Messenger.xml.
16  That minimizes verbosity during production jobs.
17  @ Dec 06, 2008 - CA
18  Adding gAbortingInErr to be set if GENE is exiting in err so as to prevent
19  output clutter (caused by reporting singletons) and help spotting the fatal
20  mesg more easily. In PriorityFromString() re-ordered the if-statements,
21  putting the most commonly used priorities on top, so to improve performance.
22  @ Aug 25, 2009 - RH
23  Use the GetXMLFilePath() to search the potential XML config file locations
24  and return the first actual file that can be found. Adapt code to use the
25  utils::xml namespace.
26  @ Jan 31, 2013 - CA
27  The $GMSGCONF var is no longer used. Instead, call
28  Messenger::SetPrioritiesFromXmlFile(string filename) explicitly.
29 
30 */
31 //____________________________________________________________________________
32 
33 #include <iostream>
34 #include <vector>
35 #include <iomanip>
36 
37 #include "libxml/parser.h"
38 #include "libxml/xmlmemory.h"
39 #include "log4cpp/SimpleLayout.hh"
40 
41 #include <TSystem.h>
42 
47 
48 using std::setw;
49 using std::setfill;
50 using std::cout;
51 using std::endl;
52 using std::vector;
53 
54 using namespace genie;
55 
56 bool genie::gAbortingInErr = false;
57 
58 //____________________________________________________________________________
60 //____________________________________________________________________________
62 {
63  fInstance = 0;
64 }
65 //____________________________________________________________________________
67 {
68  fInstance = 0;
69 }
70 //____________________________________________________________________________
72 {
73  if(fInstance == 0) {
74 
75  // the first thing that get's printed in a GENIE session is the banner
77 
78  static Messenger::Cleaner cleaner;
80 
81  fInstance = new Messenger;
82 
83  log4cpp::Appender * appender;
84  appender = new log4cpp::OstreamAppender("default", &cout);
85  const char* layoutenv = gSystem->Getenv("GMSGLAYOUT");
86  std::string layoutstr = (layoutenv) ? string(layoutenv) : "BASIC";
87  if ( layoutstr == "SIMPLE" )
88  appender->setLayout(new log4cpp::SimpleLayout());
89  else
90  appender->setLayout(new log4cpp::BasicLayout());
91 
92 
93  log4cpp::Category & MSG = log4cpp::Category::getRoot();
94 
95  MSG.setAdditivity(false);
96  MSG.addAppender(appender);
97 
98  fInstance->Configure(); // set user-defined priority levels
99  }
100  return fInstance;
101 }
102 //____________________________________________________________________________
103 log4cpp::Category & Messenger::operator () (const char * stream)
104 {
105  log4cpp::Category & MSG = log4cpp::Category::getInstance(stream);
106 
107  return MSG;
108 }
109 //____________________________________________________________________________
111  const char * stream, log4cpp::Priority::Value priority)
112 {
113  log4cpp::Category & MSG = log4cpp::Category::getInstance(stream);
114 
115  MSG.setPriority(priority);
116 }
117 //____________________________________________________________________________
119 {
120 // The Configure() method will look for priority level xml config files, read
121 // the priority levels and set them.
122 // By default, first it will look for the $GENIE/config/Messenger.xml file.
123 // Look at this file for the XML schema.
124 
125  string msg_config_file = utils::xml::GetXMLFilePath("Messenger.xml");
126 
127  // parse & set the default priority levels
128  bool ok = this->SetPrioritiesFromXmlFile(msg_config_file);
129  if(!ok) {
130  SLOG("Messenger", pERROR)
131  << "Priority levels from: " << msg_config_file << " were not set!";
132  }
133 
134 }
135 //____________________________________________________________________________
137 {
138 // Reads input XML config file and sets the priority levels.
139 // The input can be a colection of XML files, delimited with a ":".
140 // The full path for each file should be given.
141 // In case of multiple files, all files are read.
142 // The later each file is, the higher priority it has (if the same mesg
143 // stream is listed twice with conflicting priority, the last one is used.).
144 //
145 
146  if(filenames.size()==0) return false;
147 
148  vector<string> filename_vec = utils::str::Split(filenames, ":");
149  if(filename_vec.size() == 0) return false;
150 
151  vector<string>::const_iterator filename_iter;
152  for(filename_iter = filename_vec.begin();
153  filename_iter != filename_vec.end(); ++filename_iter)
154  {
155  // look in all known XML locations, just like primary file
156  string filename = utils::xml::GetXMLFilePath(*filename_iter);
157 
158  SLOG("Messenger", pNOTICE)
159  << "Reading msg stream priorities from XML file: " << filename;
160 
161  xmlDocPtr xml_doc = xmlParseFile(filename.c_str());
162  if(xml_doc==NULL) {
163  SLOG("Messenger", pERROR)
164  << "XML file could not be parsed! [file: " << filename << "]";
165  return false;
166  }
167 
168  xmlNodePtr xml_root = xmlDocGetRootElement(xml_doc);
169  if(xml_root==NULL) {
170  SLOG("Messenger", pERROR)
171  << "XML doc. has null root element! [file: " << filename << "]";
172  xmlFreeDoc(xml_doc);
173  return false;
174  }
175 
176  if( xmlStrcmp(xml_root->name, (const xmlChar *) "messenger_config") ) {
177  SLOG("Messenger", pERROR)
178  << "XML doc. has invalid root element! [file: " << filename << "]";
179  xmlFreeNode(xml_root);
180  xmlFreeDoc(xml_doc);
181  return false;
182  }
183 
184  xmlNodePtr xml_msgp = xml_root->xmlChildrenNode; // <priority>'s
185 
186  // loop over all xml tree nodes that are children of the <spline> node
187  while (xml_msgp != NULL) {
188 
189  // enter everytime you find a <priority> tag
190  if( (!xmlStrcmp(xml_msgp->name, (const xmlChar *) "priority")) ) {
191 
192  string msgstream = utils::str::TrimSpaces(
193  utils::xml::GetAttribute(xml_msgp, "msgstream"));
194  string priority =
195  utils::xml::TrimSpaces( xmlNodeListGetString(
196  xml_doc, xml_msgp->xmlChildrenNode, 1));
197  log4cpp::Priority::Value pv = this->PriorityFromString(priority);
198  this->SetPriorityLevel(msgstream.c_str(), pv);
199  SLOG("Messenger", pINFO)
200  << "Set priority level: " << setfill('.')
201  << setw(24) << msgstream << " --> " << priority;
202  }
203  xml_msgp = xml_msgp->next;
204  }//xml_msgp != NULL
205 
206  //xmlFree(xml_msgp);
207  xmlFreeNode(xml_msgp);
208  xmlFreeDoc(xml_doc);
209  }//filename_iter
210 
211  return true;
212 }
213 //____________________________________________________________________________
214 log4cpp::Priority::Value Messenger::PriorityFromString(string p)
215 {
216  if ( p.find("DEBUG") != string::npos ) return log4cpp::Priority::DEBUG;
217  if ( p.find("INFO") != string::npos ) return log4cpp::Priority::INFO;
218  if ( p.find("NOTICE") != string::npos ) return log4cpp::Priority::NOTICE;
219  if ( p.find("WARN") != string::npos ) return log4cpp::Priority::WARN;
220  if ( p.find("ERROR") != string::npos ) return log4cpp::Priority::ERROR;
221  if ( p.find("CRIT") != string::npos ) return log4cpp::Priority::CRIT;
222  if ( p.find("ALERT") != string::npos ) return log4cpp::Priority::ALERT;
223  if ( p.find("FATAL") != string::npos ) return log4cpp::Priority::FATAL;
224 
225  SLOG("Messenger", pWARN)
226  << "Unknown priority = " << p << " - Setting to INFO";
228 }
229 //____________________________________________________________________________
THE MAIN GENIE PROJECT NAMESPACE
Definition: GeneratorBase.h:8
#define pERROR
Definition: Messenger.h:60
void DummyMethodAndSilentCompiler()
Definition: Messenger.h:283
string TrimSpaces(xmlChar *xmls)
const char * p
Definition: xmltok.h:285
virtual ~Messenger()
Definition: Messenger.cxx:66
log4cpp::Priority::Value PriorityFromString(string priority)
Definition: Messenger.cxx:214
string filename
Definition: shutoffs.py:106
log4cpp::Category & operator()(const char *stream)
Definition: Messenger.cxx:103
void Configure(void)
Definition: Messenger.cxx:118
bool SetPrioritiesFromXmlFile(string filename)
Definition: Messenger.cxx:136
static Messenger * Instance(void)
Definition: Messenger.cxx:71
#define ERROR
string GetXMLFilePath(string basename)
#define pINFO
Definition: Messenger.h:63
#define pWARN
Definition: Messenger.h:61
OStream cout
Definition: OStream.cxx:6
string TrimSpaces(string input)
Definition: StringUtils.cxx:24
A more convenient interface to the log4cpp Message Service.
Definition: Messenger.h:261
::xsd::cxx::tree::string< char, simple_type > string
Definition: Database.h:154
void PrintBanner(void)
Definition: PrintUtils.cxx:121
vector< string > Split(string input, string delim)
Definition: StringUtils.cxx:42
void SetPriorityLevel(const char *stream, log4cpp::Priority::Value p)
Definition: Messenger.cxx:110
#define pNOTICE
Definition: Messenger.h:62
#define SLOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a short string (using the FUNCTION and...
Definition: Messenger.h:85
string GetAttribute(xmlNodePtr xml_cur, string attr_name)
bool gAbortingInErr
Definition: Messenger.cxx:56
static Messenger * fInstance
Definition: Messenger.h:276