bes  Updated for version 3.20.10
BESDebug.cc
1 // BESDebug.cc
2 
3 // This file is part of bes, A C++ back-end server implementation framework
4 // for the OPeNDAP Data Access Protocol.
5 
6 // Copyright (c) 2004-2009 University Corporation for Atmospheric Research
7 // Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 //
23 // You can contact University Corporation for Atmospheric Research at
24 // 3080 Center Green Drive, Boulder, CO 80301
25 
26 // (c) COPYRIGHT University Corporation for Atmospheric Research 2004-2005
27 // Please read the full copyright statement in the file COPYRIGHT_UCAR.
28 //
29 // Authors:
30 // pwest Patrick West <pwest@ucar.edu>
31 // jgarcia Jose Garcia <jgarcia@ucar.edu>
32 
33 #include "config.h"
34 
35 #include <time.h>
36 #include <unistd.h>
37 
38 #include <fstream>
39 #include <iostream>
40 #include <sstream>
41 
42 #include <pthread.h>
43 
44 #include "BESDebug.h"
45 #include "BESInternalError.h"
46 #include "BESLog.h"
47 
48 using namespace std;
49 
50 ostream *BESDebug::_debug_strm = NULL;
51 bool BESDebug::_debug_strm_created = false;
52 map<string, bool> BESDebug::_debug_map;
53 
54 
59 string get_debug_log_line_prefix()
60 {
61  ostringstream strm;
62  // Time Field
63  const time_t sctime = time(NULL);
64  struct tm sttime;
65  localtime_r(&sctime, &sttime);
66  char zone_name[10];
67  strftime(zone_name, sizeof(zone_name), "%Z", &sttime);
68 
69  char b[32]; // The linux man-page for asctime_r() says "at least 26 bytes".
70  asctime_r(&sttime,b);
71  strm << "[" << zone_name << " ";
72  for (size_t j = 0; b[j] != '\n' && j<32; j++)
73  strm << b[j];
74  strm << "]";
75 
76  // PID field
77  pid_t thepid = getpid();
78  strm << "[pid:" << thepid <<"]";
79 
80  // Thread field
81  strm << "[thread:" << pthread_self() <<"]";
82  return strm.str();
83 }
84 
85 
98 void BESDebug::SetUp(const string &values)
99 {
100  if (values.empty()) {
101  string err = "Empty debug options";
102  throw BESInternalError(err, __FILE__, __LINE__);
103  }
104  string::size_type comma = 0;
105  comma = values.find(',');
106  if (comma == string::npos) {
107  string err = "Missing comma in debug options: " + values;
108  throw BESInternalError(err, __FILE__, __LINE__);
109  }
110  ostream *strm = 0;
111  bool created = false;
112  string s_strm = values.substr(0, comma);
113  if (s_strm == "cerr") {
114  strm = &cerr;
115  }
116  else if (s_strm == "LOG") {
117  strm = BESLog::TheLog()->get_log_ostream();
118  }
119  else {
120  strm = new ofstream(s_strm.c_str(), ios::out);
121  if (strm && strm->fail()) {
122  delete strm;
123  strm = 0;
124  string err = "Unable to open the debug file: " + s_strm;
125  throw BESInternalError(err, __FILE__, __LINE__);
126  }
127  created = true;
128  }
129 
130  BESDebug::SetStrm(strm, created);
131 
132  string::size_type new_comma = 0;
133  while ((new_comma = values.find(',', comma + 1)) != string::npos) {
134  string flagName = values.substr(comma + 1, new_comma - comma - 1);
135  if (flagName[0] == '-') {
136  string newflag = flagName.substr(1, flagName.length() - 1);
137  BESDebug::Set(newflag, false);
138  }
139  else {
140  BESDebug::Set(flagName, true);
141  }
142  comma = new_comma;
143  }
144  string flagName = values.substr(comma + 1, values.length() - comma - 1);
145  if (flagName[0] == '-') {
146  string newflag = flagName.substr(1, flagName.length() - 1);
147  BESDebug::Set(newflag, false);
148  }
149  else {
150  BESDebug::Set(flagName, true);
151  }
152 }
153 
162 void BESDebug::Help(ostream &strm)
163 {
164  strm << "Debug help:" << endl << " Set on the command line with " << "-d \"file_name|cerr,[-]context1,...,[-]context\"" << endl
165  << " context with dash (-) in front will be turned off" << endl << " context of all will turn on debugging for all contexts" << endl << endl
166  << "Possible context(s):" << endl;
167 
168  if (_debug_map.size()) {
169  BESDebug::debug_citer i = _debug_map.begin();
170  BESDebug::debug_citer e = _debug_map.end();
171  for (; i != e; i++) {
172  strm << " " << (*i).first << ": ";
173  if ((*i).second)
174  strm << "on" << endl;
175  else
176  strm << "off" << endl;
177  }
178  }
179  else {
180  strm << " none specified" << endl;
181  }
182 }
183 
184 bool BESDebug::IsContextName(const string &name)
185 {
186  return _debug_map.count(name) > 0;
187 }
188 
197 {
198  ostringstream oss;
199 
200  if (_debug_map.size()) {
201  BESDebug::debug_citer i = _debug_map.begin();
202  BESDebug::debug_citer e = _debug_map.end();
203  for (; i != e; i++) {
204  if (!(*i).second) oss << "-";
205  oss << (*i).first << ",";
206  }
207  string retval = oss.str();
208  return retval.erase(retval.length() - 1);
209  }
210  else {
211  return "";
212  }
213 }
214 
static void SetStrm(std::ostream *strm, bool created)
set the debug output stream to the specified stream
Definition: BESDebug.h:209
static void SetUp(const std::string &values)
Sets up debugging for the bes.
Definition: BESDebug.cc:98
static void Help(std::ostream &strm)
Writes help information for so that developers know what can be set for debugging.
Definition: BESDebug.cc:162
static std::string GetOptionsString()
Definition: BESDebug.cc:196
static void Set(const std::string &flagName, bool value)
set the debug context to the specified value
Definition: BESDebug.h:127
exception thrown if internal error encountered