bes  Updated for version 3.19.1
BESLog.cc
1 // BESLog.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 <time.h>
37 #include <string>
38 
39 #include "BESLog.h"
40 #include "TheBESKeys.h"
41 #include "BESInternalFatalError.h"
42 
43 #if HAVE_UNISTD_H
44 #include <unistd.h>
45 #endif
46 
47 #define ISO8601_TIME_IN_LOGS
48 
49 using namespace std;
50 
51 BESLog *BESLog::d_instance = 0;
52 const string BESLog::mark = string("|&|");
53 
73  d_flushed(1), d_file_buffer(0), d_suspended(0), d_verbose(false), d_use_local_time(false)
74 {
75  d_suspended = 0;
76  bool found = false;
77  try {
78  TheBESKeys::TheKeys()->get_value("BES.LogName", d_file_name, found);
79  }
80  catch (...) {
81  string err ="BES Fatal: unable to determine log file name. The key BES.LogName has multiple values";
82  cerr << err << endl;
83  throw BESInternalFatalError(err, __FILE__, __LINE__);
84  }
85 
86  // By default, use UTC in the logs.
87  found = false;
88  string local_time = "no";
89  try {
90  TheBESKeys::TheKeys()->get_value("BES.LogTimeLocal", local_time, found);
91  if (local_time == "YES" || local_time == "Yes" || local_time == "yes") {
92  d_use_local_time = true;
93  }
94 
95  }
96  catch (...) {
97  string err ="BES Fatal: Unable to read the value of BES.LogTimeUTC";
98  cerr << err << endl;
99  throw BESInternalFatalError(err, __FILE__, __LINE__);
100  }
101 
102  if (d_file_name == "") {
103  string err = "BES Fatal: unable to determine log file name. Please set BES.LogName in your initialization file";
104  cerr << err << endl;
105  throw BESInternalFatalError(err, __FILE__, __LINE__);
106  }
107 
108  d_file_buffer = new ofstream(d_file_name.c_str(), ios::out | ios::app);
109  if (!(*d_file_buffer)) {
110  string err = "BES Fatal; cannot open log file " + d_file_name + ".";
111  cerr << err << endl;
112  throw BESInternalFatalError(err, __FILE__, __LINE__);
113  }
114 
115  found = false;
116  string verbose;
117  TheBESKeys::TheKeys()->get_value("BES.LogVerbose", verbose, found);
118  if (verbose == "YES" || verbose == "Yes" || verbose == "yes") {
119  d_verbose = true;
120  }
121 }
122 
128 {
129  d_file_buffer->close();
130  delete d_file_buffer;
131  d_file_buffer = 0;
132 }
133 
142 {
143 #ifdef ISO8601_TIME_IN_LOGS
144  time_t now;
145  time(&now);
146  char buf[sizeof "YYYY-MM-DDTHH:MM:SSzone"];
147  int status = 0;
148 
149  // From StackOverflow:
150  // This will work too, if your compiler doesn't support %F or %T:
151  // strftime(buf, sizeof buf, "%Y-%m-%dT%H:%M:%S%Z", gmtime(&now));
152  //
153  // Apologies for the twisted logic - UTC is the default. Override to
154  // local time using BES.LogTimeLocal=yes in bes.conf. jhrg 11/15/17
155  if (!d_use_local_time)
156  status = strftime(buf, sizeof buf, "%FT%T%Z", gmtime(&now));
157  else
158  status = strftime(buf, sizeof buf, "%FT%T%Z", localtime(&now));
159 
160  (*d_file_buffer) << buf;
161 
162 #else
163  const time_t sctime = time(NULL);
164  const struct tm *sttime = localtime(&sctime);
165  char zone_name[10];
166  strftime(zone_name, sizeof(zone_name), "%Z", sttime);
167  char *b = asctime(sttime);
168 
169  (*d_file_buffer) << zone_name << " ";
170  for (register int j = 0; b[j] != '\n'; j++)
171  (*d_file_buffer) << b[j];
172 #endif
173 
174  (*d_file_buffer) << mark << getpid() << mark;
175 
176  d_flushed = 0;
177 }
178 
186 {
187  if (!d_suspended) {
188  if (d_flushed) dump_time();
189  (*d_file_buffer) << s;
190  }
191  return *this;
192 }
193 
198 BESLog& BESLog::operator<<(const string &s)
199 {
200  if (!d_suspended) {
201  if (d_flushed) dump_time();
202  (*d_file_buffer) << s;
203  }
204  return *this;
205 }
206 
212 {
213  if (!d_suspended) {
214  if (d_flushed) dump_time();
215  if (val)
216  (*d_file_buffer) << val;
217  else
218  (*d_file_buffer) << "NULL";
219  }
220  return *this;
221 }
222 
227 BESLog& BESLog::operator<<(const char *val)
228 {
229  if (!d_suspended) {
230  if (d_flushed) {
231  dump_time();
232  }
233  if (val)
234  (*d_file_buffer) << val;
235  else
236  (*d_file_buffer) << "NULL";
237  }
238  return *this;
239 }
240 
246 {
247  if (!d_suspended) {
248  if (d_flushed) dump_time();
249  (*d_file_buffer) << val;
250  }
251  return *this;
252 }
253 
259 {
260  if (!d_suspended) {
261  if (d_flushed) dump_time();
262  (*d_file_buffer) << val;
263  }
264  return *this;
265 }
266 
272 {
273  if (!d_suspended) {
274  if (d_flushed) dump_time();
275  (*d_file_buffer) << val;
276  }
277  return *this;
278 }
279 
284 BESLog& BESLog::operator<<(unsigned long val)
285 {
286  if (!d_suspended) {
287  if (d_flushed) dump_time();
288  (*d_file_buffer) << val;
289  }
290  return *this;
291 }
292 
298 {
299  if (!d_suspended) {
300  if (d_flushed) dump_time();
301  (*d_file_buffer) << val;
302  }
303  return *this;
304 }
305 
313 BESLog& BESLog::operator<<(p_ostream_manipulator val)
314 {
315  if (!d_suspended) {
316  (*d_file_buffer) << val;
317  if ((val == (p_ostream_manipulator) endl) || (val == (p_ostream_manipulator) flush)) d_flushed = 1;
318  }
319  return *this;
320 }
321 
322 void BESLog::flush_me(){
323  (*d_file_buffer) << flush;
324  d_flushed = 1;
325 }
326 
333 BESLog& BESLog::operator<<(p_ios_manipulator val)
334 {
335  if (!d_suspended) (*d_file_buffer) << val;
336  return *this;
337 }
338 
346 void BESLog::dump(ostream &strm) const
347 {
348  strm << BESIndent::LMarg << "BESLog::dump - (" << (void *) this << ")" << endl;
349  BESIndent::Indent();
350  strm << BESIndent::LMarg << "log file: " << d_file_name << endl;
351  if (d_file_buffer && *d_file_buffer) {
352  strm << BESIndent::LMarg << "log is valid" << endl;
353  }
354  else {
355  strm << BESIndent::LMarg << "log is NOT valid" << endl;
356  }
357  strm << BESIndent::LMarg << "is verbose: " << d_verbose << endl;
358  strm << BESIndent::LMarg << "is flushed: " << d_flushed << endl;
359  strm << BESIndent::LMarg << "is suspended: " << d_suspended << endl;
360  BESIndent::UnIndent();
361 }
362 
363 BESLog *
364 BESLog::TheLog()
365 {
366  if (d_instance == 0) {
367  d_instance = new BESLog;
368  }
369  return d_instance;
370 }
371 
virtual void dump(std::ostream &strm) const
dumps information about this object
Definition: BESLog.cc:346
exception thrown if an internal error is found and is fatal to the BES
~BESLog()
Cleans up the logging mechanism.
Definition: BESLog.cc:127
BESLog & operator<<(std::string &)
Overloaded inserter that writes the specified string.
Definition: BESLog.cc:185
STL namespace.
void get_value(const string &s, string &val, bool &found)
Retrieve the value of a given key, if set.
Definition: TheBESKeys.cc:422
static TheBESKeys * TheKeys()
Definition: TheBESKeys.cc:62
std::ostream &(* p_ostream_manipulator)(std::ostream &)
Defines a data type p_std::ostream_manipulator "pointer to function that takes std::ostream& and retu...
Definition: BESLog.h:193
void dump_time()
Protected method that dumps the date/time to the log file.
Definition: BESLog.cc:141
BESLog()
constructor that sets up logging for the application.
Definition: BESLog.cc:72
Provides a mechanism for applications to log information to an external file.
Definition: BESLog.h:103