bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
BESStopWatch.cc
1// BESStopWatch.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// ndp Nathan Potter <ndp@opendap.org>
31// pwest Patrick West <pwest@ucar.edu>
32// jgarcia Jose Garcia <jgarcia@ucar.edu>
33
34#include "config.h"
35
36#include <cerrno>
37#include <string>
38#include <iostream>
39#include <cstring>
40#include <sstream>
41
42#include "BESStopWatch.h"
43
44#include <BESUtil.h>
45
46#include "BESDebug.h"
47#include "BESLog.h"
48
49using std::string;
50using std::endl;
51using std::ostream;
52
53
54#define MODULE TIMING_LOG_KEY
55#define prolog string("BESStopWatch::").append(__func__).append("() - ")
56
57namespace bes_timing {
58BESStopWatch *elapsedTimeToReadStart = nullptr;
59BESStopWatch *elapsedTimeToTransmitStart = nullptr;
60}
61
69bool BESStopWatch::start(const std::string &name, BESDataHandlerInterface *dhi) {
70 string reqId = dhi->data[REQUEST_ID_KEY];
71 if (!reqId.empty()) {
72 string uuid = dhi->data[REQUEST_UUID_KEY];
73 if (uuid.empty()) {
74 uuid = "BESStopWatch-" + BESUtil::uuid();
75 dhi->data[REQUEST_UUID_KEY] = uuid;
76 }
77 reqId = reqId + "-" + uuid;
78 }
79 else {
80 // If we grab it from BESLog we know the uuid is already a part of the request id value.
81 reqId = BESLog::TheLog()->get_request_id();
82 }
83 if (reqId.empty()) {
84 reqId = prolog + "OUCH! The values of dhi->data[\"" REQUEST_ID_KEY "\" and BESLog::TheLog()->get_request_id() were empty.";
85 }
86 return start(name,reqId);
87}
88
89
90
91
102bool BESStopWatch::start(const string &name, const string &reqID) {
103 d_timer_name = name;
104 d_req_id = (reqID.empty()?"ReqIdEmpty":reqID);
105
106 // get timing for current usage
107 if (!get_time_of_day(d_start_usage)) {
108 d_started = false;
109 return d_started;
110 }
111 d_started = true;
112
113 std::stringstream msg;
114 if (BESLog::TheLog()->is_verbose()) {
115 msg << "start_us" << BESLog::mark << get_start_us() << BESLog::mark;
116 msg << d_req_id << BESLog::mark;
117 msg << d_timer_name << endl;
118 TIMING_LOG(msg.str());
119 }
120 // either we started the stop watch, or failed to start it. Either way,
121 // no timings are available, so set stopped to false.
122 return d_started;
123}
124
125bool BESStopWatch::get_time_of_day(struct timeval &time_val) {
126 bool retval = true;
127 if (gettimeofday(&time_val, nullptr) != 0) {
128 const char *c_err = strerror(errno);
129 string errno_msg = c_err != nullptr ? c_err : "unknown error";
130 string msg = prolog + "ERROR The gettimeofday() function failed. errno_msg: " + errno_msg + "\n";
131 BESDEBUG(TIMING_LOG_KEY, msg );
132 ERROR_LOG(msg);
133 retval = false;
134 }
135 return retval;
136}
137
146 // if we have started, then stop and update the log.
147 if (d_started) {
148 // get timing for current usage
149
150 if (!get_time_of_day(d_stop_usage)) {
151 d_started = false;
152 return;
153 }
154
155 BESDEBUG(TIMING_LOG_KEY, get_debug_log_line_prefix() + "[" << d_log_name + "]"
156 + "[ELAPSED][" + std::to_string(get_elapsed_us()) + " us]"
157 + "[STARTED][" + std::to_string(get_start_us()) + " us]"
158 + "[STOPPED][" + std::to_string(get_stop_us()) + " us]"
159 + "[" + (d_req_id.empty() ? "-" : d_req_id) + "]" + "[" << d_timer_name + "]\n");
160
161 TIMING_LOG( "elapsed-us" + BESLog::mark + std::to_string(get_elapsed_us()) + BESLog::mark
162 + "start-us" + BESLog::mark + std::to_string(get_start_us()) + BESLog::mark
163 + "stop-us" + BESLog::mark + std::to_string(get_stop_us()) + BESLog::mark
164 + (d_req_id.empty() ? "-" : d_req_id) + BESLog::mark
165 + d_timer_name + "\n");
166 }
167}
168
174unsigned long int BESStopWatch::get_elapsed_us() const {
175 return get_stop_us() - get_start_us();
176}
177
178unsigned long int BESStopWatch::get_start_us() const {
179 return d_start_usage.tv_sec * 1000 * 1000 + d_start_usage.tv_usec;
180}
181
182unsigned long int BESStopWatch::get_stop_us() const {
183 return d_stop_usage.tv_sec * 1000 * 1000 + d_stop_usage.tv_usec;
184}
185
186
193void
194BESStopWatch::dump(ostream &strm) const {
195 strm << BESIndent::LMarg << "BESStopWatch::dump - ("
196 << (void *) this << ")" << endl;
197}
198
199
200
201
202
Structure storing information used by the BES to handle the request.
std::map< std::string, std::string > data
the map of string data that will be required for the current request.
void dump(std::ostream &strm) const override
dumps information about this object
virtual bool start(const std::string &name, const std::string &reqID={BESLog::TheLog() ->get_request_id()})
~BESStopWatch() override