Commit dd1432d7 authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[master] Merge branch 'trac3804'

parents 6d7f37c4 805401e5
...@@ -174,8 +174,14 @@ ...@@ -174,8 +174,14 @@
</listitem> </listitem>
<listitem> <listitem>
<simpara><command>kea-dhcp4.hooks</command> - this logger is used <simpara><command>kea-dhcp4.hooks</command> - this logger is used
during DHCPv4 hooks operation, i.e. anything related to user to log messages related to management of hooks libraries, e.g.
libraries will be logged using this logger.</simpara> registration and deregistration of the libraries.</simpara>
</listitem>
<listitem>
<simpara><command>kea-dhcp4.callouts</command> - this logger is used
to log messages pertaining to the callouts registration and execution
for the particular hook point.
</simpara>
</listitem> </listitem>
<listitem> <listitem>
<simpara><command>kea-dhcp4.hosts</command> - this logger is used <simpara><command>kea-dhcp4.hosts</command> - this logger is used
...@@ -202,8 +208,14 @@ ...@@ -202,8 +208,14 @@
</listitem> </listitem>
<listitem> <listitem>
<simpara><command>kea-dhcp6.hooks</command> - this logger is used <simpara><command>kea-dhcp6.hooks</command> - this logger is used
during DHCPv6 hooks operation, i.e. anything related to user to log messages related to management of hooks libraries, e.g.
libraries will be logged using this logger.</simpara> registration and deregistration of the libraries.</simpara>
</listitem>
<listitem>
<simpara><command>kea-dhcp6.callouts</command> - this logger is used
to log messages pertaining to the callouts registration and execution
for the particular hook point.
</simpara>
</listitem> </listitem>
<listitem> <listitem>
<simpara><command>kea-dhcp6.hosts</command> - this logger is used <simpara><command>kea-dhcp6.hosts</command> - this logger is used
......
// Copyright (C) 2013, 2015 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2013,2015 Internet Systems Consortium, Inc. ("ISC")
// //
// Permission to use, copy, modify, and/or distribute this software for any // Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above // purpose with or without fee is hereby granted, provided that the above
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <hooks/callout_manager.h> #include <hooks/callout_manager.h>
#include <hooks/hooks_log.h> #include <hooks/hooks_log.h>
#include <hooks/pointer_converter.h> #include <hooks/pointer_converter.h>
#include <util/stopwatch.h>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
...@@ -67,7 +68,7 @@ CalloutManager::checkLibraryIndex(int library_index) const { ...@@ -67,7 +68,7 @@ CalloutManager::checkLibraryIndex(int library_index) const {
void void
CalloutManager::registerCallout(const std::string& name, CalloutPtr callout) { CalloutManager::registerCallout(const std::string& name, CalloutPtr callout) {
// Note the registration. // Note the registration.
LOG_DEBUG(hooks_logger, HOOKS_DBG_CALLS, HOOKS_CALLOUT_REGISTRATION) LOG_DEBUG(callouts_logger, HOOKS_DBG_CALLS, HOOKS_CALLOUT_REGISTRATION)
.arg(current_library_).arg(name); .arg(current_library_).arg(name);
// Sanity check that the current library index is set to a valid value. // Sanity check that the current library index is set to a valid value.
...@@ -136,6 +137,14 @@ CalloutManager::callCallouts(int hook_index, CalloutHandle& callout_handle) { ...@@ -136,6 +137,14 @@ CalloutManager::callCallouts(int hook_index, CalloutHandle& callout_handle) {
// change and potentially affect the iteration through that vector. // change and potentially affect the iteration through that vector.
CalloutVector callouts(hook_vector_[hook_index]); CalloutVector callouts(hook_vector_[hook_index]);
// This object will be used to measure execution time of each callout
// and the total time spent in callouts for this hook point.
util::Stopwatch stopwatch;
// Mark that the callouts begin for the hook.
LOG_DEBUG(callouts_logger, HOOKS_DBG_CALLS, HOOKS_CALLOUTS_BEGIN)
.arg(server_hooks_.getName(current_hook_));
// Call all the callouts. // Call all the callouts.
for (CalloutVector::const_iterator i = callouts.begin(); for (CalloutVector::const_iterator i = callouts.begin();
i != callouts.end(); ++i) { i != callouts.end(); ++i) {
...@@ -146,29 +155,43 @@ CalloutManager::callCallouts(int hook_index, CalloutHandle& callout_handle) { ...@@ -146,29 +155,43 @@ CalloutManager::callCallouts(int hook_index, CalloutHandle& callout_handle) {
// Call the callout // Call the callout
try { try {
stopwatch.start();
int status = (*i->second)(callout_handle); int status = (*i->second)(callout_handle);
stopwatch.stop();
if (status == 0) { if (status == 0) {
LOG_DEBUG(hooks_logger, HOOKS_DBG_EXTENDED_CALLS, LOG_DEBUG(callouts_logger, HOOKS_DBG_EXTENDED_CALLS,
HOOKS_CALLOUT_CALLED).arg(current_library_) HOOKS_CALLOUT_CALLED).arg(current_library_)
.arg(server_hooks_.getName(current_hook_)) .arg(server_hooks_.getName(current_hook_))
.arg(PointerConverter(i->second).dlsymPtr()); .arg(PointerConverter(i->second).dlsymPtr())
.arg(stopwatch.logFormatLastDuration());
} else { } else {
LOG_ERROR(hooks_logger, HOOKS_CALLOUT_ERROR) LOG_ERROR(callouts_logger, HOOKS_CALLOUT_ERROR)
.arg(current_library_) .arg(current_library_)
.arg(server_hooks_.getName(current_hook_)) .arg(server_hooks_.getName(current_hook_))
.arg(PointerConverter(i->second).dlsymPtr()); .arg(PointerConverter(i->second).dlsymPtr())
.arg(stopwatch.logFormatLastDuration());
} }
} catch (const std::exception& e) { } catch (const std::exception& e) {
// If an exception occurred, the stopwatch.stop() hasn't been
// called, so we have to call it here.
stopwatch.stop();
// Any exception, not just ones based on isc::Exception // Any exception, not just ones based on isc::Exception
LOG_ERROR(hooks_logger, HOOKS_CALLOUT_EXCEPTION) LOG_ERROR(callouts_logger, HOOKS_CALLOUT_EXCEPTION)
.arg(current_library_) .arg(current_library_)
.arg(server_hooks_.getName(current_hook_)) .arg(server_hooks_.getName(current_hook_))
.arg(PointerConverter(i->second).dlsymPtr()) .arg(PointerConverter(i->second).dlsymPtr())
.arg(e.what()); .arg(e.what())
.arg(stopwatch.logFormatLastDuration());
} }
} }
// Mark end of callout execution. Include the total execution
// time for callouts.
LOG_DEBUG(callouts_logger, HOOKS_DBG_CALLS, HOOKS_CALLOUTS_COMPLETE)
.arg(server_hooks_.getName(current_hook_))
.arg(stopwatch.logFormatTotalDuration());
// Reset the current hook and library indexs to an invalid value to // Reset the current hook and library indexs to an invalid value to
// catch any programming errors. // catch any programming errors.
current_hook_ = -1; current_hook_ = -1;
...@@ -214,7 +237,7 @@ CalloutManager::deregisterCallout(const std::string& name, CalloutPtr callout) { ...@@ -214,7 +237,7 @@ CalloutManager::deregisterCallout(const std::string& name, CalloutPtr callout) {
// Return an indication of whether anything was removed. // Return an indication of whether anything was removed.
bool removed = initial_size != hook_vector_[hook_index].size(); bool removed = initial_size != hook_vector_[hook_index].size();
if (removed) { if (removed) {
LOG_DEBUG(hooks_logger, HOOKS_DBG_EXTENDED_CALLS, LOG_DEBUG(callouts_logger, HOOKS_DBG_EXTENDED_CALLS,
HOOKS_CALLOUT_DEREGISTERED).arg(current_library_).arg(name); HOOKS_CALLOUT_DEREGISTERED).arg(current_library_).arg(name);
} }
...@@ -249,7 +272,7 @@ CalloutManager::deregisterAllCallouts(const std::string& name) { ...@@ -249,7 +272,7 @@ CalloutManager::deregisterAllCallouts(const std::string& name) {
// Return an indication of whether anything was removed. // Return an indication of whether anything was removed.
bool removed = initial_size != hook_vector_[hook_index].size(); bool removed = initial_size != hook_vector_[hook_index].size();
if (removed) { if (removed) {
LOG_DEBUG(hooks_logger, HOOKS_DBG_EXTENDED_CALLS, LOG_DEBUG(callouts_logger, HOOKS_DBG_EXTENDED_CALLS,
HOOKS_ALL_CALLOUTS_DEREGISTERED).arg(current_library_) HOOKS_ALL_CALLOUTS_DEREGISTERED).arg(current_library_)
.arg(name); .arg(name);
} }
......
// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2011,2015 Internet Systems Consortium, Inc. ("ISC")
// //
// Permission to use, copy, modify, and/or distribute this software for any // Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above // purpose with or without fee is hereby granted, provided that the above
...@@ -12,15 +12,17 @@ ...@@ -12,15 +12,17 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE. // PERFORMANCE OF THIS SOFTWARE.
/// Defines the logger used by the NSAS /// Defines the logger used by the Hooks
#include "hooks/hooks_log.h" #include <hooks/hooks_log.h>
namespace isc { namespace isc {
namespace hooks { namespace hooks {
isc::log::Logger hooks_logger("hooks"); isc::log::Logger hooks_logger("hooks");
isc::log::Logger callouts_logger("callouts");
} // namespace hooks } // namespace hooks
} // namespace isc } // namespace isc
// Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2013,2015 Internet Systems Consortium, Inc. ("ISC")
// //
// Permission to use, copy, modify, and/or distribute this software for any // Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above // purpose with or without fee is hereby granted, provided that the above
...@@ -44,6 +44,13 @@ const int HOOKS_DBG_EXTENDED_CALLS = DBGLVL_TRACE_DETAIL_DATA; ...@@ -44,6 +44,13 @@ const int HOOKS_DBG_EXTENDED_CALLS = DBGLVL_TRACE_DETAIL_DATA;
/// space. /// space.
extern isc::log::Logger hooks_logger; extern isc::log::Logger hooks_logger;
/// @brief Callouts logger
///
/// This is the specialized logger used to log messages pertaining to the
/// callouts execution. In particular, it logs when the callout is invoked
/// and when it ends. It also logs the callout execution times.
extern isc::log::Logger callouts_logger;
} // namespace hooks } // namespace hooks
} // namespace isc } // namespace isc
......
...@@ -20,6 +20,15 @@ by the library with the given index were removed. This is similar to ...@@ -20,6 +20,15 @@ by the library with the given index were removed. This is similar to
the HOOKS_CALLOUTS_REMOVED message (and the two are likely to be seen the HOOKS_CALLOUTS_REMOVED message (and the two are likely to be seen
together), but is issued at a lower-level in the hook framework. together), but is issued at a lower-level in the hook framework.
% HOOKS_CALLOUTS_BEGIN begin all callouts for hook %1
This debug message is issued when callout manager begins to invoke callouts
for the hook. The argument specifies the hook name.
% HOOKS_CALLOUTS_COMPLETE completed callouts for hook %1 (total callouts duration: %2)
This debug message is issued when callout manager has completed execution
of all callouts for the particular hook. The arguments specify the hook
name and total execution time for all callouts in milliseconds.
% HOOKS_CALLOUTS_REMOVED callouts removed from hook %1 for library %2 % HOOKS_CALLOUTS_REMOVED callouts removed from hook %1 for library %2
This is a debug message issued during library unloading. It notes that This is a debug message issued during library unloading. It notes that
one of more callouts registered by that library have been removed from one of more callouts registered by that library have been removed from
...@@ -27,28 +36,31 @@ the specified hook. This is similar to the HOOKS_DEREGISTER_ALL_CALLOUTS ...@@ -27,28 +36,31 @@ the specified hook. This is similar to the HOOKS_DEREGISTER_ALL_CALLOUTS
message (and the two are likely to be seen together), but is issued at a message (and the two are likely to be seen together), but is issued at a
higher-level in the hook framework. higher-level in the hook framework.
% HOOKS_CALLOUT_CALLED hooks library with index %1 has called a callout on hook %2 that has address %3 % HOOKS_CALLOUT_CALLED hooks library with index %1 has called a callout on hook %2 that has address %3 (callout duration: %4)
Only output at a high debugging level, this message indicates that Only output at a high debugging level, this message indicates that
a callout on the named hook registered by the library with the given a callout on the named hook registered by the library with the given
index (in the list of loaded libraries) has been called and returned a index (in the list of loaded libraries) has been called and returned a
success state. The address of the callout is given in the message success state. The address of the callout is given in the message.
The message includes the callout execution time in milliseconds.
% HOOKS_CALLOUT_DEREGISTERED hook library at index %1 deregistered a callout on hook %2 % HOOKS_CALLOUT_DEREGISTERED hook library at index %1 deregistered a callout on hook %2
A debug message issued when all instances of a particular callouts on A debug message issued when all instances of a particular callouts on
the hook identified in the message that were registered by the library the hook identified in the message that were registered by the library
with the given index have been removed. with the given index have been removed.
% HOOKS_CALLOUT_ERROR error returned by callout on hook %1 registered by library with index %2 (callout address %3) % HOOKS_CALLOUT_ERROR error returned by callout on hook %1 registered by library with index %2 (callout address %3) (callout duration %4)
If a callout returns an error status when called, this error message If a callout returns an error status when called, this error message
is issued. It identifies the hook to which the callout is attached, the is issued. It identifies the hook to which the callout is attached, the
index of the library (in the list of loaded libraries) that registered index of the library (in the list of loaded libraries) that registered
it and the address of the callout. The error is otherwise ignored. it and the address of the callout. The error is otherwise ignored.
The error message includes the callout execution time in milliseconds.
% HOOKS_CALLOUT_EXCEPTION exception thrown by callout on hook %1 registered by library with index %2 (callout address %3): %4 % HOOKS_CALLOUT_EXCEPTION exception thrown by callout on hook %1 registered by library with index %2 (callout address %3): %4 (callout duration: $5)
If a callout throws an exception when called, this error message is If a callout throws an exception when called, this error message is
issued. It identifies the hook to which the callout is attached, the issued. It identifies the hook to which the callout is attached, the
index of the library (in the list of loaded libraries) that registered index of the library (in the list of loaded libraries) that registered
it and the address of the callout. The error is otherwise ignored. it and the address of the callout. The error is otherwise ignored.
The error message includes the callout execution time in milliseconds.
% HOOKS_CALLOUT_REGISTRATION hooks library with index %1 registering callout for hook '%2' % HOOKS_CALLOUT_REGISTRATION hooks library with index %1 registering callout for hook '%2'
This is a debug message, output when a library (whose index in the list This is a debug message, output when a library (whose index in the list
......
...@@ -22,6 +22,8 @@ libkea_util_la_SOURCES += pid_file.h pid_file.cc ...@@ -22,6 +22,8 @@ libkea_util_la_SOURCES += pid_file.h pid_file.cc
libkea_util_la_SOURCES += process_spawn.h process_spawn.cc libkea_util_la_SOURCES += process_spawn.h process_spawn.cc
libkea_util_la_SOURCES += range_utilities.h libkea_util_la_SOURCES += range_utilities.h
libkea_util_la_SOURCES += signal_set.cc signal_set.h libkea_util_la_SOURCES += signal_set.cc signal_set.h
libkea_util_la_SOURCES += stopwatch.cc stopwatch.h
libkea_util_la_SOURCES += stopwatch_impl.cc stopwatch_impl.h
libkea_util_la_SOURCES += encode/base16_from_binary.h libkea_util_la_SOURCES += encode/base16_from_binary.h
libkea_util_la_SOURCES += encode/base32hex.h encode/base64.h libkea_util_la_SOURCES += encode/base32hex.h encode/base64.h
libkea_util_la_SOURCES += encode/base32hex_from_binary.h libkea_util_la_SOURCES += encode/base32hex_from_binary.h
......
// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <util/stopwatch.h>
#include <util/stopwatch_impl.h>
namespace isc {
namespace util {
using namespace boost::posix_time;
Stopwatch::Stopwatch(const bool autostart)
: impl_(new StopwatchImpl()) {
// If the autostart has been specified, invoke start.
if (autostart) {
start();
}
}
Stopwatch::~Stopwatch() {
delete impl_;
}
void
Stopwatch::start() {
impl_->start();
}
void
Stopwatch::stop() {
impl_->stop();
}
void
Stopwatch::reset() {
impl_->reset();
}
boost::posix_time::time_duration
Stopwatch::getLastDuration() const {
return (impl_->getLastDuration());
}
boost::posix_time::time_duration
Stopwatch::getTotalDuration() const {
return (impl_->getTotalDuration());
}
long
Stopwatch::getLastMilliseconds() const {
return (getLastDuration().total_milliseconds());
}
long
Stopwatch::getTotalMilliseconds() const {
return (getTotalDuration().total_milliseconds());
}
long
Stopwatch::getLastMicroseconds() const {
return (getLastDuration().total_microseconds());
}
long
Stopwatch::getTotalMicroseconds() const {
return (getTotalDuration().total_microseconds());
}
std::string
Stopwatch::logFormatLastDuration() const {
return (StopwatchImpl::logFormat(getLastDuration()));
}
std::string
Stopwatch::logFormatTotalDuration() const {
return (StopwatchImpl::logFormat(getTotalDuration()));
}
} // end of isc::util
} // end of isc
// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef STOPWATCH_H
#define STOPWATCH_H
#include <boost/date_time/posix_time/posix_time.hpp>
namespace isc {
namespace util {
/// @brief Forward declaration to the @c Stopwatch implementation.
class StopwatchImpl;
/// @brief Utility class to measure code execution times.
///
/// The API of this class is based on the use cases of a stopwatch. It is
/// used to measure time spent executing portions of the code. The typical
/// use case for the @c Stopwatch is to measure the time spent invoking
/// callouts in hooks library. This provides means for diagnosing the
/// server's performance degradations when hooks libraries are in use.
///
/// This class exposes functions like @c start, @c stop and @c reset which
/// behave in the same way as a stopwatch used to measure time for sport
/// activities.
///
/// It is possible to measure the cumulative execution time by invoking
/// @c start and @c stop consecutively. The total measured time will be
/// a sum of durations between the invocations of respective starts and
/// stops.
class Stopwatch {
public:
/// @brief Constructor.
///
/// @param autostart Indicates if the stopwatch should be initialized to
/// the "started" state. In this state the stopwatch is measuring the time
/// since it has been started (object has been constructed in this case.
/// If the parameter is set to false (default value), the
/// @c Stopwatch::start must be called to start time measurement.
Stopwatch(const bool autostart = true);
/// @brief Destructor.
///
/// Destroys the implementation instance.
~Stopwatch();
/// @brief Starts the stopwatch.
///
/// Sets the stopwatch to the "started" state. In this state the stopwatch
/// is measuring the duration since @c Stopwatch::start has been invoked.
///
//// This method is no-op if the stopwatch is already in the "started"
/// state.
void start();
/// @brief Stops the stopwatch.
///
/// Sets the stopwatch to the "stopped" state. The stopwatch stops the time
/// measurement and records the duration between the last stopwatch start
/// and the stop invocation. It also updates the total measured duration,
/// i.e. the sum of durations between all start/stop invocations. Both
/// values can be retrieved using @c Stopwatch::getLastDuration and
/// @c Stopwatch::getTotalDuration respectively, or their variants.
///
/// This method is no-op if the stopwatch is already in the "stopped" state.
void stop();
/// @brief Resets the stopwatch.
///
/// It resets the stopwatch to the initial state. In this state, the last
/// measured duration and the total duration is set to 0. The stopwatch
/// is set to the "stopped" state.
void reset();
/// @brief Retrieves last measured duration.
///
/// If the stopwatch is in the "stopped" state this method retrieves the
/// duration between the last start and stop. If the stopwatch is in the
/// "started" state, the retrieved duration is the duration between the
/// last start of the stopwatch and the current time.
boost::posix_time::time_duration getLastDuration() const;
/// @brief Retrieves total measured duration.
///
/// If the stopwatch is in the "stopped" state this method retrieves the
/// total duration between all starts and stops invoked during the
/// lifetime of the object or since the last reset. If the stopwatch is
/// in the "started" state, the returned is the sum of all durations
/// between respective starts and stops, and the duration since the
/// stopwatch has been last started and the current time.
boost::posix_time::time_duration getTotalDuration() const;
/// @brief Retrieves the last measured duration in milliseconds.
long getLastMilliseconds() const;
/// @brief Retrieves the total measured duration in milliseconds.
long getTotalMilliseconds() const;
/// @brief Retrieves the last measured duration in microseconds.
long getLastMicroseconds() const;
/// @brief Retrieves the total measured duration in microseconds.
long getTotalMicroseconds() const;
/// @brief Returns the last measured duration in the format directly
/// usable in log messages.
std::string logFormatLastDuration() const;
/// @brief Returns the total measured duration in the format directly
/// usable in the log messages.
std::string logFormatTotalDuration() const;
private:
/// @brief Pointer to the @c StopwatchImpl.
StopwatchImpl* impl_;
};
}
}
#endif // STOPWATCH_H
// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <util/stopwatch_impl.h>
#include <iomanip>
#include <sstream>
namespace isc {
namespace util {
using namespace boost::posix_time;
StopwatchImpl::StopwatchImpl()
: started_(false),
last_start_(getCurrentTime()),
last_stop_(last_start_),
cumulative_time_(microseconds(0)) {
}
StopwatchImpl::~StopwatchImpl() {
}
void
StopwatchImpl::start() {
// If stopwatch is "stopped", start it.
if (!started_) {
last_start_ = getCurrentTime();
started_ = true;
}
}
void
StopwatchImpl::stop() {
// Is stopwatch is "started", stop it.
if (started_) {
last_stop_ = getCurrentTime();
// Update the total time with the last measured duration.
cumulative_time_ += last_stop_ - last_start_;
started_ = false;
}
}
void
StopwatchImpl::reset() {
// Set last start and stop values to the current time. This is the
// same as in the constructor. As a result the last duration will