Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ISC Open Source Projects
Kea
Commits
dd1432d7
Commit
dd1432d7
authored
Apr 22, 2015
by
Marcin Siodelski
Browse files
[master] Merge branch 'trac3804'
parents
6d7f37c4
805401e5
Changes
12
Hide whitespace changes
Inline
Side-by-side
doc/guide/logging.xml
View file @
dd1432d7
...
...
@@ -174,8 +174,14 @@
</listitem>
<listitem>
<simpara><command>
kea-dhcp4.hooks
</command>
- this logger is used
during DHCPv4 hooks operation, i.e. anything related to user
libraries will be logged using this logger.
</simpara>
to log messages related to management of hooks libraries, e.g.
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>
<simpara><command>
kea-dhcp4.hosts
</command>
- this logger is used
...
...
@@ -202,8 +208,14 @@
</listitem>
<listitem>
<simpara><command>
kea-dhcp6.hooks
</command>
- this logger is used
during DHCPv6 hooks operation, i.e. anything related to user
libraries will be logged using this logger.
</simpara>
to log messages related to management of hooks libraries, e.g.
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>
<simpara><command>
kea-dhcp6.hosts
</command>
- this logger is used
...
...
src/lib/hooks/callout_manager.cc
View file @
dd1432d7
// 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
// purpose with or without fee is hereby granted, provided that the above
...
...
@@ -18,6 +18,7 @@
#include <hooks/callout_manager.h>
#include <hooks/hooks_log.h>
#include <hooks/pointer_converter.h>
#include <util/stopwatch.h>
#include <boost/static_assert.hpp>
...
...
@@ -67,7 +68,7 @@ CalloutManager::checkLibraryIndex(int library_index) const {
void
CalloutManager
::
registerCallout
(
const
std
::
string
&
name
,
CalloutPtr
callout
)
{
// Note the registration.
LOG_DEBUG
(
hook
s_logger
,
HOOKS_DBG_CALLS
,
HOOKS_CALLOUT_REGISTRATION
)
LOG_DEBUG
(
callout
s_logger
,
HOOKS_DBG_CALLS
,
HOOKS_CALLOUT_REGISTRATION
)
.
arg
(
current_library_
).
arg
(
name
);
// 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) {
// change and potentially affect the iteration through that vector.
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.
for
(
CalloutVector
::
const_iterator
i
=
callouts
.
begin
();
i
!=
callouts
.
end
();
++
i
)
{
...
...
@@ -146,29 +155,43 @@ CalloutManager::callCallouts(int hook_index, CalloutHandle& callout_handle) {
// Call the callout
try
{
stopwatch
.
start
();
int
status
=
(
*
i
->
second
)(
callout_handle
);
stopwatch
.
stop
();
if
(
status
==
0
)
{
LOG_DEBUG
(
hook
s_logger
,
HOOKS_DBG_EXTENDED_CALLS
,
LOG_DEBUG
(
callout
s_logger
,
HOOKS_DBG_EXTENDED_CALLS
,
HOOKS_CALLOUT_CALLED
).
arg
(
current_library_
)
.
arg
(
server_hooks_
.
getName
(
current_hook_
))
.
arg
(
PointerConverter
(
i
->
second
).
dlsymPtr
());
.
arg
(
PointerConverter
(
i
->
second
).
dlsymPtr
())
.
arg
(
stopwatch
.
logFormatLastDuration
());
}
else
{
LOG_ERROR
(
hook
s_logger
,
HOOKS_CALLOUT_ERROR
)
LOG_ERROR
(
callout
s_logger
,
HOOKS_CALLOUT_ERROR
)
.
arg
(
current_library_
)
.
arg
(
server_hooks_
.
getName
(
current_hook_
))
.
arg
(
PointerConverter
(
i
->
second
).
dlsymPtr
());
.
arg
(
PointerConverter
(
i
->
second
).
dlsymPtr
())
.
arg
(
stopwatch
.
logFormatLastDuration
());
}
}
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
LOG_ERROR
(
hook
s_logger
,
HOOKS_CALLOUT_EXCEPTION
)
LOG_ERROR
(
callout
s_logger
,
HOOKS_CALLOUT_EXCEPTION
)
.
arg
(
current_library_
)
.
arg
(
server_hooks_
.
getName
(
current_hook_
))
.
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
// catch any programming errors.
current_hook_
=
-
1
;
...
...
@@ -214,7 +237,7 @@ CalloutManager::deregisterCallout(const std::string& name, CalloutPtr callout) {
// Return an indication of whether anything was removed.
bool
removed
=
initial_size
!=
hook_vector_
[
hook_index
].
size
();
if
(
removed
)
{
LOG_DEBUG
(
hook
s_logger
,
HOOKS_DBG_EXTENDED_CALLS
,
LOG_DEBUG
(
callout
s_logger
,
HOOKS_DBG_EXTENDED_CALLS
,
HOOKS_CALLOUT_DEREGISTERED
).
arg
(
current_library_
).
arg
(
name
);
}
...
...
@@ -249,7 +272,7 @@ CalloutManager::deregisterAllCallouts(const std::string& name) {
// Return an indication of whether anything was removed.
bool
removed
=
initial_size
!=
hook_vector_
[
hook_index
].
size
();
if
(
removed
)
{
LOG_DEBUG
(
hook
s_logger
,
HOOKS_DBG_EXTENDED_CALLS
,
LOG_DEBUG
(
callout
s_logger
,
HOOKS_DBG_EXTENDED_CALLS
,
HOOKS_ALL_CALLOUTS_DEREGISTERED
).
arg
(
current_library_
)
.
arg
(
name
);
}
...
...
src/lib/hooks/hooks_log.cc
View file @
dd1432d7
// 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
// purpose with or without fee is hereby granted, provided that the above
...
...
@@ -12,15 +12,17 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// 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
hooks
{
isc
::
log
::
Logger
hooks_logger
(
"hooks"
);
isc
::
log
::
Logger
callouts_logger
(
"callouts"
);
}
// namespace hooks
}
// namespace isc
src/lib/hooks/hooks_log.h
View file @
dd1432d7
// 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
// 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;
/// space.
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 isc
...
...
src/lib/hooks/hooks_messages.mes
View file @
dd1432d7
...
...
@@ -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
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
This is a debug message issued during library unloading. It notes that
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
message (and the two are likely to be seen together), but is issued at a
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
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
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
A debug message issued when all instances of a particular callouts on
the hook identified in the message that were registered by the library
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
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
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
issued. It identifies the hook to which the callout is attached, the
index of the library (in the list of loaded libraries) that registered
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'
This is a debug message, output when a library (whose index in the list
...
...
src/lib/util/Makefile.am
View file @
dd1432d7
...
...
@@ -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
+=
range_utilities.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/base32hex.h encode/base64.h
libkea_util_la_SOURCES
+=
encode/base32hex_from_binary.h
...
...
src/lib/util/stopwatch.cc
0 → 100644
View file @
dd1432d7
// 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
src/lib/util/stopwatch.h
0 → 100644
View file @
dd1432d7
// 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
src/lib/util/stopwatch_impl.cc
0 → 100644
View file @
dd1432d7
// 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
// be 0.
last_start_
=
getCurrentTime
();
last_stop_
=
last_start_
;
// Set the total duration to 0.
cumulative_time_
=
microseconds
(
0
);
started_
=
false
;
}
time_duration
StopwatchImpl
::
getLastDuration
()
const
{
// If the stopwatch is started, the time measured is between the
// start time and the current time. Otherwise, it is between the
// start time and last stop.
ptime
end_time
=
started_
?
getCurrentTime
()
:
last_stop_
;
return
(
end_time
-
last_start_
);
}
time_duration
StopwatchImpl
::
getTotalDuration
()
const
{
// Get the total time recorded so far.
time_duration
total_duration
=
cumulative_time_
;
if
(
started_
)
{
// If the stopwatch is started, add the duration between the
// start time and current time.
total_duration
+=
(
getCurrentTime
()
-
last_start_
);
}
return
(
total_duration
);
}
std
::
string
StopwatchImpl
::
logFormat
(
const
boost
::
posix_time
::
time_duration
&
duration
)
{
std
::
ostringstream
s
;
s
<<
duration
.
total_milliseconds
()
<<
"."
;
s
<<
std
::
setfill
(
'0'
)
<<
std
::
setw
(
3
)
<<
(
duration
.
total_microseconds
()
%
1000
)
<<
" ms"
;
return
(
s
.
str
());
}
ptime
StopwatchImpl
::
getCurrentTime
()
const
{
return
(
microsec_clock
::
universal_time
());
}
}
// end of isc::util
}
// end of isc
src/lib/util/stopwatch_impl.h
0 → 100644
View file @
dd1432d7
// 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_IMPL_H
#define STOPWATCH_IMPL_H
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/scoped_ptr.hpp>
namespace
isc
{
namespace
util
{
/// @brief @c Stopwatch class implementation.
///
/// The @c Stopwatch class uses the plimpl idiom to make it easier to unit
/// test behavior of the @c Stopwatch class without a need to rely on the system
/// clock. The @c StopwatchImpl API allows for overriding the @c getCurrentTime
/// method to return the arbitrary time value as current time to various
/// methods. By setting the current time to arbitrary values the test can expect
/// arbitrary values being returned by the class methods.
///
/// Also, by using the pimpl idiom the @c Stopwatch class hides its implementation
/// details and leaves the header with only the pointer to the @c StopwatchImpl
/// class.
class
StopwatchImpl
{
public:
/// @brief Constructor.
///
/// Initializes the internally used timestamps. It also sets the state of
/// the stopwatch to "stopped".
StopwatchImpl
();
/// @brief Virtual destructor.
///
/// This destructor is virtual because the @c StopwatchImpl::getCurrentTime
/// is virtual.
virtual
~
StopwatchImpl
();
/// @brief Starts the stopwatch.
///
/// Sets the stopwatch to the "started" state. It also records the time when