bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
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 <iostream>
36#include <sstream>
37#include <algorithm>
38#include <iomanip>
39
40#include <ctime>
41#include <unistd.h>
42
43#include "BESDebug.h"
44#include "BESInternalError.h"
45#include "BESLog.h"
46
47using namespace std;
48
49ostream *BESDebug::_debug_strm = nullptr;
50bool BESDebug::_debug_strm_created = false;
51BESDebug::DebugMap BESDebug::_debug_map;
52
57string get_debug_log_line_prefix()
58{
59 // Given C++11, this could be done with std::put_time() and std::localtime().
60 std::ostringstream oss;
61
62 // Time Field
63 auto t = time(nullptr);
64 struct tm stm{};
65 localtime_r(&t, &stm);
66 // Mimic zone + asctime: GMT Thu Nov 24 18:22:48 1986
67 oss << std::put_time(&stm, "[%Z %c]");
68
69 // PID field
70 oss << "[pid:" << getpid() <<"]";
71
72 // Thread field
73 oss << "[thread:" << pthread_self() <<"]";
74
75 return oss.str();
76}
77
78
91void BESDebug::SetUp(const string &values)
92{
93 if (values.empty()) {
94 string err = "Empty debug options";
95 throw BESInternalError(err, __FILE__, __LINE__);
96 }
97 string::size_type comma = 0;
98 comma = values.find(',');
99 if (comma == string::npos) {
100 string err = "Missing comma in debug options: " + values;
101 throw BESInternalError(err, __FILE__, __LINE__);
102 }
103 ostream *strm = 0;
104 bool created = false;
105 string s_strm = values.substr(0, comma);
106 if (s_strm == "cerr") {
107 strm = &cerr;
108 }
109 else if (s_strm == "LOG") {
110 strm = BESLog::TheLog()->get_log_ostream();
111 }
112 else {
113 strm = new ofstream(s_strm.c_str(), ios::out);
114 if (strm && strm->fail()) {
115 delete strm;
116 strm = 0;
117 string err = "Unable to open the debug file: " + s_strm;
118 throw BESInternalError(err, __FILE__, __LINE__);
119 }
120 created = true;
121 }
122
123 BESDebug::SetStrm(strm, created);
124
125 string::size_type new_comma = 0;
126 while ((new_comma = values.find(',', comma + 1)) != string::npos) {
127 string flagName = values.substr(comma + 1, new_comma - comma - 1);
128 if (flagName[0] == '-') {
129 string newflag = flagName.substr(1, flagName.size() - 1);
130 BESDebug::Set(newflag, false);
131 }
132 else {
133 BESDebug::Set(flagName, true);
134 }
135 comma = new_comma;
136 }
137 string flagName = values.substr(comma + 1, values.size() - comma - 1);
138 if (flagName[0] == '-') {
139 string newflag = flagName.substr(1, flagName.size() - 1);
140 BESDebug::Set(newflag, false);
141 }
142 else {
143 BESDebug::Set(flagName, true);
144 }
145}
146
157void BESDebug::Set(const std::string &flagName, bool value)
158{
159 if (value && flagName == "all") {
160 std::for_each(_debug_map.begin(), _debug_map.end(), [](DebugMap::value_type &p) { p.second = true; });
161 }
162 _debug_map[flagName] = value;
163}
164
173void BESDebug::Help(ostream &strm)
174{
175 strm << "Debug help:" << endl << " Set on the command line with " << "-d \"file_name|cerr,[-]context1,...,[-]context\"" << endl
176 << " context with dash (-) in front will be turned off" << endl << " context of all will turn on debugging for all contexts" << endl << endl
177 << "Possible context(s):" << endl;
178
179 if (!_debug_map.empty()) {
180 std::for_each(_debug_map.begin(), _debug_map.end(), [&strm](const auto &pair) {
181 strm << " " << pair.first << ": ";
182 if (pair.second)
183 strm << "on" << endl;
184 else
185 strm << "off" << endl;
186 });
187 }
188 else {
189 strm << " none specified" << endl;
190 }
191}
192
193bool BESDebug::IsContextName(const string &name)
194{
195 return _debug_map.count(name) > 0;
196}
197
206{
207 ostringstream oss;
208
209 if (!_debug_map.empty()) {
210 std::for_each(_debug_map.begin(), _debug_map.end(), [&oss](const std::pair<std::string, bool> &p) {
211 if (!p.second) oss << "-";
212 oss << p.first << ",";
213 });
214
215 string retval = oss.str();
216 return retval.erase(retval.size() - 1);
217 }
218 else {
219 return {""};
220 }
221}
222
static void SetStrm(std::ostream *strm, bool created)
set the debug output stream to the specified stream
Definition BESDebug.h:185
static void SetUp(const std::string &values)
Sets up debugging for the bes.
Definition BESDebug.cc:91
static void Help(std::ostream &strm)
Writes help information for so that developers know what can be set for debugging.
Definition BESDebug.cc:173
static std::string GetOptionsString()
Definition BESDebug.cc:205
static void Set(const std::string &flagName, bool value)
set the debug context to the specified value
Definition BESDebug.cc:157
exception thrown if internal error encountered