Add basic_seconds_clock, insight::Groups

This commit is contained in:
Vinnie Falco
2014-02-01 20:14:38 -08:00
parent af77ff3eed
commit aaced060bf
31 changed files with 809 additions and 106 deletions

View File

@@ -97,6 +97,7 @@
<ClInclude Include="..\..\beast\chrono\ratio_io.h" />
<ClInclude Include="..\..\beast\chrono\RelativeTime.h" />
<ClInclude Include="..\..\beast\chrono\ScopedTimeInterval.h" />
<ClInclude Include="..\..\beast\chrono\basic_seconds_clock.h" />
<ClInclude Include="..\..\beast\Config.h" />
<ClInclude Include="..\..\beast\config\CompilerConfig.h" />
<ClInclude Include="..\..\beast\config\compiler\Clang.h" />
@@ -131,6 +132,8 @@
<ClInclude Include="..\..\beast\http\ParsedURL.h" />
<ClInclude Include="..\..\beast\http\URL.h" />
<ClInclude Include="..\..\beast\Insight.h" />
<ClInclude Include="..\..\beast\insight\Base.h" />
<ClInclude Include="..\..\beast\insight\BaseImpl.h" />
<ClInclude Include="..\..\beast\insight\Collector.h" />
<ClInclude Include="..\..\beast\insight\Counter.h" />
<ClInclude Include="..\..\beast\insight\CounterImpl.h" />
@@ -138,6 +141,8 @@
<ClInclude Include="..\..\beast\insight\EventImpl.h" />
<ClInclude Include="..\..\beast\insight\Gauge.h" />
<ClInclude Include="..\..\beast\insight\GaugeImpl.h" />
<ClInclude Include="..\..\beast\insight\Group.h" />
<ClInclude Include="..\..\beast\insight\Groups.h" />
<ClInclude Include="..\..\beast\insight\Hook.h" />
<ClInclude Include="..\..\beast\insight\HookImpl.h" />
<ClInclude Include="..\..\beast\insight\Meter.h" />
@@ -408,6 +413,12 @@
</ClCompile>
<ClCompile Include="..\..\beast\boost\Boost.cpp" />
<ClCompile Include="..\..\beast\chrono\Chrono.cpp" />
<ClCompile Include="..\..\beast\chrono\impl\basic_seconds_clock.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\chrono\impl\chrono_io.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@@ -524,6 +535,18 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\insight\impl\Group.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\insight\impl\Groups.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\beast\insight\impl\Hook.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>

View File

@@ -1242,6 +1242,21 @@
<ClInclude Include="..\..\beast\chrono\chrono_util.h">
<Filter>beast\chrono</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\chrono\basic_seconds_clock.h">
<Filter>beast\chrono</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\insight\Group.h">
<Filter>beast\insight</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\insight\Groups.h">
<Filter>beast\insight</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\insight\Base.h">
<Filter>beast\insight</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\insight\BaseImpl.h">
<Filter>beast\insight</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\modules\beast_core\containers\DynamicObject.cpp">
@@ -1802,6 +1817,15 @@
<ClCompile Include="..\..\beast\crypto\impl\UnsignedInteger.cpp">
<Filter>beast\crypto\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\chrono\impl\basic_seconds_clock.cpp">
<Filter>beast\chrono\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\insight\impl\Group.cpp">
<Filter>beast\insight\impl</Filter>
</ClCompile>
<ClCompile Include="..\..\beast\insight\impl\Groups.cpp">
<Filter>beast\insight\impl</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Text Include="..\..\TODO.txt">

View File

@@ -131,6 +131,8 @@
<ClInclude Include="..\..\beast\http\ParsedURL.h" />
<ClInclude Include="..\..\beast\http\URL.h" />
<ClInclude Include="..\..\beast\Insight.h" />
<ClInclude Include="..\..\beast\insight\Base.h" />
<ClInclude Include="..\..\beast\insight\BaseImpl.h" />
<ClInclude Include="..\..\beast\insight\Collector.h" />
<ClInclude Include="..\..\beast\insight\Counter.h" />
<ClInclude Include="..\..\beast\insight\CounterImpl.h" />
@@ -138,6 +140,8 @@
<ClInclude Include="..\..\beast\insight\EventImpl.h" />
<ClInclude Include="..\..\beast\insight\Gauge.h" />
<ClInclude Include="..\..\beast\insight\GaugeImpl.h" />
<ClInclude Include="..\..\beast\insight\Group.h" />
<ClInclude Include="..\..\beast\insight\Groups.h" />
<ClInclude Include="..\..\beast\insight\Hook.h" />
<ClInclude Include="..\..\beast\insight\HookImpl.h" />
<ClInclude Include="..\..\beast\insight\Meter.h" />

View File

@@ -1242,6 +1242,18 @@
<ClInclude Include="..\..\beast\chrono\chrono_util.h">
<Filter>beast\chrono</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\insight\Base.h">
<Filter>beast\insight</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\insight\BaseImpl.h">
<Filter>beast\insight</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\insight\Group.h">
<Filter>beast\insight</Filter>
</ClInclude>
<ClInclude Include="..\..\beast\insight\Groups.h">
<Filter>beast\insight</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\modules\beast_core\containers\DynamicObject.cpp">

View File

@@ -21,6 +21,7 @@
#define BEAST_CHRONO_H_INCLUDED
#include "chrono/abstract_clock.h"
#include "chrono/basic_seconds_clock.h"
#include "chrono/chrono_io.h"
#include "chrono/chrono_util.h"
#include "chrono/manual_clock.h"

View File

@@ -26,6 +26,8 @@
#include "insight/EventImpl.h"
#include "insight/Gauge.h"
#include "insight/GaugeImpl.h"
#include "insight/Group.h"
#include "insight/Groups.h"
#include "insight/Hook.h"
#include "insight/HookImpl.h"
#include "insight/Collector.h"

View File

@@ -24,6 +24,7 @@
#include "impl/abstract_clock.cpp"
#include "impl/chrono_io.cpp"
#include "impl/basic_seconds_clock.cpp"
#include "impl/CPUMeter.cpp"
#include "impl/RelativeTime.cpp"

View File

@@ -121,7 +121,7 @@ template <class TrivialClock, class Duration>
struct abstract_clock_wrapper
: public basic_abstract_clock_wrapper <TrivialClock, Duration>
{
// generic conversion displays the duration
// generic conversion displays the duration
std::string to_string (typename basic_abstract_clock_wrapper <
TrivialClock, Duration>::time_point const& tp)
{

View File

@@ -0,0 +1,237 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
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 THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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 BEAST_CHRONO_BASIC_SECONDS_CLOCK_H_INCLUDED
#define BEAST_CHRONO_BASIC_SECONDS_CLOCK_H_INCLUDED
#include <algorithm>
#include <chrono>
#ifndef BEAST_BASIC_SECONDS_CLOCK_BOOST_WORKAROUND
# ifdef _MSC_VER
// Visual Studio 2012, 2013 have a bug in std::thread that
// causes a hang on exit, in the library function atexit()
# if BEAST_USE_BOOST_FEATURES
# define BEAST_BASIC_SECONDS_CLOCK_BOOST_WORKAROUND 1
# else
# define BEAST_BASIC_SECONDS_CLOCK_BOOST_WORKAROUND 0
# endif
# else
# define BEAST_BASIC_SECONDS_CLOCK_BOOST_WORKAROUND 0
# endif
#endif
#if BEAST_BASIC_SECONDS_CLOCK_BOOST_WORKAROUND
# include <boost/version.hpp>
# if BOOST_VERSION >= 105500
# include <boost/thread/thread.hpp>
# include <boost/thread/mutex.hpp>
# include <boost/thread/condition_variable.hpp>
# include <boost/chrono.hpp>
# else
# error "Boost version 1.55.0 or later is required"
# endif
#else
# include <condition_variable>
# include <mutex>
# include <thread>
#endif
#include "../chrono/chrono_util.h"
namespace beast {
namespace detail {
class seconds_clock_worker
{
public:
virtual void sample () = 0;
};
//------------------------------------------------------------------------------
// Updates the clocks
class seconds_clock_thread
{
public:
#if BEAST_BASIC_SECONDS_CLOCK_BOOST_WORKAROUND
typedef boost::mutex mutex;
typedef boost::condition_variable cond_var;
typedef boost::lock_guard <mutex> lock_guard;
typedef boost::unique_lock <mutex> unique_lock;
typedef boost::chrono::steady_clock clock_type;
typedef boost::chrono::seconds seconds;
typedef boost::thread thread;
#else
typedef std::mutex mutex;
typedef std::condition_variable cond_var;
typedef std::lock_guard <mutex> lock_guard;
typedef std::unique_lock <mutex> unique_lock;
typedef std::chrono::steady_clock clock_type;
typedef std::chrono::seconds seconds;
typedef std::thread thread;
#endif
typedef std::vector <seconds_clock_worker*> workers;
bool m_stop;
mutex m_mutex;
cond_var m_cond;
workers m_workers;
thread m_thread;
seconds_clock_thread ()
: m_stop (false)
{
m_thread = thread (std::bind(
&seconds_clock_thread::run, this));
}
~seconds_clock_thread ()
{
{
lock_guard lock (m_mutex);
m_stop = true;
}
m_cond.notify_all();
m_thread.join ();
}
void add (seconds_clock_worker& w)
{
lock_guard lock (m_mutex);
m_workers.push_back (&w);
}
void remove (seconds_clock_worker& w)
{
lock_guard lock (m_mutex);
m_workers.erase (std::find (
m_workers.begin (), m_workers.end(), &w));
}
void run ()
{
unique_lock lock (m_mutex);;
for (;;)
{
for (auto iter : m_workers)
iter->sample();
clock_type::time_point const when (
floor <seconds> (
clock_type::now().time_since_epoch()) +
seconds (1));
if (m_cond.wait_until (lock, when, [this]{ return m_stop; }))
return;
}
}
static seconds_clock_thread& instance ()
{
static seconds_clock_thread singleton;
return singleton;
}
};
}
//------------------------------------------------------------------------------
/** A clock whose minimum resolution is one second.
The purpose of this class is to optimize the performance of the now()
member function call. It uses a dedicated thread that wakes up at least
once per second to sample the requested trivial clock.
@tparam TrivialClock The clock to sample.
*/
template <class TrivialClock>
class basic_seconds_clock
{
public:
typedef std::chrono::seconds resolution;
typedef typename resolution::rep rep;
typedef typename resolution::period period;
typedef std::chrono::duration <rep, period> duration;
typedef std::chrono::time_point <basic_seconds_clock> time_point;
static bool const is_steady = TrivialClock::is_steady;
static time_point now ()
{
// Make sure the thread is constructed before the
// worker otherwise we will crash during destruction
// of objects with static storage duration.
struct initializer
{
initializer ()
{
detail::seconds_clock_thread::instance();
}
};
static initializer init;
struct worker : detail::seconds_clock_worker
{
typedef std::mutex mutex;
typedef std::lock_guard <mutex> lock_guard;
time_point m_now;
mutex m_mutex;
static time_point get_now ()
{
return time_point (floor <resolution> (
TrivialClock::now().time_since_epoch()));
}
worker ()
: m_now (get_now ())
{
detail::seconds_clock_thread::instance().add (*this);
}
~worker ()
{
detail::seconds_clock_thread::instance().remove (*this);
}
time_point now()
{
lock_guard lock (m_mutex);
return m_now;
}
void sample ()
{
lock_guard lock (m_mutex);
m_now = get_now ();
}
};
static worker w;
return w.now ();
}
};
}
#endif

View File

@@ -0,0 +1,47 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
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 THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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 "../basic_seconds_clock.h"
#include "../../Config.h"
#include "../../../modules/beast_core/beast_core.h" // for UnitTest
namespace beast {
class basic_seconds_clock_Tests : public UnitTest
{
public:
void runTest ()
{
beginTestCase ("now");
auto const now (basic_seconds_clock <
std::chrono::steady_clock>::now ());
pass ();
}
basic_seconds_clock_Tests() : UnitTest("basic_seconds_clock", "beast")
{
}
};
static basic_seconds_clock_Tests basic_seconds_clock_tests;
}

38
beast/insight/Base.h Normal file
View File

@@ -0,0 +1,38 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
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 THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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 BEAST_INSIGHT_BASE_H_INCLUDED
#define BEAST_INSIGHT_BASE_H_INCLUDED
#include <memory>
namespace beast {
namespace insight {
/** Base for all metrics and hooks. */
class Base
{
public:
virtual ~Base () = 0;
};
}
}
#endif

40
beast/insight/BaseImpl.h Normal file
View File

@@ -0,0 +1,40 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
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 THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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 BEAST_INSIGHT_BASEIMPL_H_INCLUDED
#define BEAST_INSIGHT_BASEIMPL_H_INCLUDED
#include <memory>
namespace beast {
namespace insight {
/** Base for all metrics and hook implementations. */
class BaseImpl
{
public:
typedef std::shared_ptr <BaseImpl> ptr;
virtual ~BaseImpl () = 0;
};
}
}
#endif

View File

@@ -73,22 +73,58 @@ public:
/** Create a counter with the specified name.
@see Counter
*/
/** @{ */
virtual Counter make_counter (std::string const& name) = 0;
Counter make_counter (std::string const& prefix, std::string const& name)
{
if (prefix.empty ())
return make_counter (name);
return make_counter (prefix + "." + name);
}
/** @} */
/** Create an event with the specified name.
@see Event
*/
/** @{ */
virtual Event make_event (std::string const& name) = 0;
Event make_event (std::string const& prefix, std::string const& name)
{
if (prefix.empty ())
return make_event (name);
return make_event (prefix + "." + name);
}
/** @} */
/** Create a gauge with the specified name.
@see Gauge
*/
/** @{ */
virtual Gauge make_gauge (std::string const& name) = 0;
Gauge make_gauge (std::string const& prefix, std::string const& name)
{
if (prefix.empty ())
return make_gauge (name);
return make_gauge (prefix + "." + name);
}
/** @} */
/** Create a meter with the specified name.
@see Meter
*/
/** @{ */
virtual Meter make_meter (std::string const& name) = 0;
Meter make_meter (std::string const& prefix, std::string const& name)
{
if (prefix.empty ())
return make_meter (name);
return make_meter (prefix + "." + name);
}
/** @} */
};
}

View File

@@ -22,6 +22,7 @@
#include <memory>
#include "Base.h"
#include "CounterImpl.h"
namespace beast {
@@ -35,7 +36,7 @@ namespace insight {
This is a lightweight reference wrapper which is cheap to copy and assign.
When the last reference goes away, the metric is no longer collected.
*/
class Counter
class Counter : public Base
{
public:
typedef CounterImpl::value_type value_type;
@@ -57,21 +58,6 @@ public:
{
}
/** Set a handler for polling.
If a handler is set, it will be called once per collection interval.
This may be used to implement polling style collection instead of
push style.
Handler will be called with this signature:
void Handler (Counter const&);
*/
template <class Handler>
void set_handler (Handler handler) const
{
if (m_impl)
m_impl->set_handler (handler);
}
/** Increment the counter. */
/** @{ */
void increment (value_type amount) const
@@ -99,6 +85,11 @@ public:
{ increment (-1); return *this; }
/** @} */
std::shared_ptr <CounterImpl> const& impl () const
{
return m_impl;
}
private:
std::shared_ptr <CounterImpl> m_impl;
};

View File

@@ -22,20 +22,22 @@
#include <memory>
#include "BaseImpl.h"
namespace beast {
namespace insight {
class Counter;
class CounterImpl : public std::enable_shared_from_this <CounterImpl>
class CounterImpl
: public std::enable_shared_from_this <CounterImpl>
, public BaseImpl
{
public:
typedef int64 value_type;
typedef std::function <void (Counter const&)> HandlerType;
virtual ~CounterImpl () = 0;
virtual void increment (value_type amount) = 0;
virtual void set_handler (HandlerType const& handler) = 0;
};
}

View File

@@ -23,6 +23,7 @@
#include <chrono>
#include <memory>
#include "Base.h"
#include "EventImpl.h"
#include "../chrono/chrono_util.h"
@@ -39,7 +40,7 @@ namespace insight {
This is a lightweight reference wrapper which is cheap to copy and assign.
When the last reference goes away, the metric is no longer collected.
*/
class Event
class Event : public Base
{
public:
typedef EventImpl::value_type value_type;
@@ -67,6 +68,11 @@ public:
m_impl->notify (ceil <value_type> (value));
}
std::shared_ptr <EventImpl> const& impl () const
{
return m_impl;
}
private:
std::shared_ptr <EventImpl> m_impl;
};

View File

@@ -22,12 +22,16 @@
#include <memory>
#include "BaseImpl.h"
namespace beast {
namespace insight {
class Event;
class EventImpl : public std::enable_shared_from_this <EventImpl>
class EventImpl
: public std::enable_shared_from_this <EventImpl>
, public BaseImpl
{
public:
typedef std::chrono::milliseconds value_type;

View File

@@ -22,6 +22,7 @@
#include <memory>
#include "Base.h"
#include "GaugeImpl.h"
namespace beast {
@@ -36,7 +37,7 @@ namespace insight {
This is a lightweight reference wrapper which is cheap to copy and assign.
When the last reference goes away, the metric is no longer collected.
*/
class Gauge
class Gauge : public Base
{
public:
typedef GaugeImpl::value_type value_type;
@@ -59,21 +60,6 @@ public:
{
}
/** Set a handler for polling.
If a handler is set, it will be called once per collection interval.
This may be used to implement polling style collection instead of
push style.
Handler will be called with this signature:
void Handler (Gauge const&);
*/
template <class Handler>
void set_handler (Handler handler) const
{
if (m_impl)
m_impl->set_handler (handler);
}
/** Set the value on the gauge.
A Collector implementation should combine multiple calls to value
changes into a single change if the calls occur within a single
@@ -117,6 +103,11 @@ public:
{ increment (-1); return *this; }
/** @} */
std::shared_ptr <GaugeImpl> const& impl () const
{
return m_impl;
}
private:
std::shared_ptr <GaugeImpl> m_impl;
};

View File

@@ -20,25 +20,26 @@
#ifndef BEAST_INSIGHT_GAUGEIMPL_H_INCLUDED
#define BEAST_INSIGHT_GAUGEIMPL_H_INCLUDED
#include <functional>
#include <memory>
#include "BaseImpl.h"
namespace beast {
namespace insight {
class Gauge;
class GaugeImpl : public std::enable_shared_from_this <GaugeImpl>
class GaugeImpl
: public std::enable_shared_from_this <GaugeImpl>
, public BaseImpl
{
public:
typedef uint64 value_type;
typedef int64 difference_type;
typedef std::function <void (Gauge const&)> HandlerType;
virtual ~GaugeImpl () = 0;
virtual void set (value_type value) = 0;
virtual void increment (difference_type amount) = 0;
virtual void set_handler (HandlerType const& handler) = 0;
};
}

43
beast/insight/Group.h Normal file
View File

@@ -0,0 +1,43 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
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 THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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 BEAST_INSIGHT_GROUP_H_INCLUDED
#define BEAST_INSIGHT_GROUP_H_INCLUDED
#include <memory>
#include "Collector.h"
namespace beast {
namespace insight {
/** A collector front-end that manages a group of metrics. */
class Group : public Collector
{
public:
typedef std::shared_ptr <Group> ptr;
/** Returns the name of this group, for diagnostics. */
virtual std::string const& name () const = 0;
};
}
}
#endif

55
beast/insight/Groups.h Normal file
View File

@@ -0,0 +1,55 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
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 THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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 BEAST_INSIGHT_GROUPS_H_INCLUDED
#define BEAST_INSIGHT_GROUPS_H_INCLUDED
#include <memory>
#include <string>
#include "Collector.h"
#include "Group.h"
namespace beast {
namespace insight {
/** A container for managing a set of metric groups. */
class Groups
{
public:
virtual ~Groups() = 0;
/** Find or create a new collector with a given name. */
/** @{ */
virtual Group::ptr const& get (std::string const& name) = 0;
Group::ptr const& operator[] (std::string const& name)
{
return get (name);
}
/** @} */
};
/** Create a group container that uses the specified collector. */
std::unique_ptr <Groups> make_Groups (Collector::ptr const& collector);
}
}
#endif

View File

@@ -20,15 +20,16 @@
#ifndef BEAST_INSIGHT_HOOK_H_INCLUDED
#define BEAST_INSIGHT_HOOK_H_INCLUDED
#include "HookImpl.h"
#include <memory>
#include "Base.h"
#include "HookImpl.h"
namespace beast {
namespace insight {
/** A reference to a handler for performing polled collection. */
class Hook
class Hook : public Base
{
public:
/** Create a null hook.
@@ -44,7 +45,11 @@ public:
*/
explicit Hook (std::shared_ptr <HookImpl> const& impl)
: m_impl (impl)
{ }
std::shared_ptr <HookImpl> const& impl () const
{
return m_impl;
}
private:

View File

@@ -23,10 +23,14 @@
#include <functional>
#include <memory>
#include "BaseImpl.h"
namespace beast {
namespace insight {
class HookImpl : public std::enable_shared_from_this <HookImpl>
class HookImpl
: public std::enable_shared_from_this <HookImpl>
, public BaseImpl
{
public:
typedef std::function <void (void)> HandlerType;

View File

@@ -26,6 +26,8 @@
#include "../Insight.h"
#include "impl/Collector.cpp"
#include "impl/Group.cpp"
#include "impl/Groups.cpp"
#include "impl/Hook.cpp"
#include "impl/Metric.cpp"
#include "impl/NullCollector.cpp"

View File

@@ -20,10 +20,11 @@
#ifndef BEAST_INSIGHT_METER_H_INCLUDED
#define BEAST_INSIGHT_METER_H_INCLUDED
#include "MeterImpl.h"
#include <memory>
#include "Base.h"
#include "MeterImpl.h"
namespace beast {
namespace insight {
@@ -34,7 +35,7 @@ namespace insight {
This is a lightweight reference wrapper which is cheap to copy and assign.
When the last reference goes away, the metric is no longer collected.
*/
class Meter
class Meter : public Base
{
public:
typedef MeterImpl::value_type value_type;
@@ -54,20 +55,6 @@ public:
: m_impl (impl)
{ }
/** Set a handler for polling.
If a handler is set, it will be called once per collection interval.
This may be used to implement polling style collection instead of
push style.
Handler will be called with this signature:
void Handler (Meter const&);
*/
template <class Handler>
void set_handler (Handler handler) const
{
m_impl->set_handler (handler);
}
/** Increment the meter. */
/** @{ */
void increment (value_type amount) const
@@ -95,6 +82,11 @@ public:
}
/** @} */
std::shared_ptr <MeterImpl> const& impl () const
{
return m_impl;
}
private:
std::shared_ptr <MeterImpl> m_impl;
};

View File

@@ -20,23 +20,24 @@
#ifndef BEAST_INSIGHT_METERIMPL_H_INCLUDED
#define BEAST_INSIGHT_METERIMPL_H_INCLUDED
#include <functional>
#include <memory>
#include "BaseImpl.h"
namespace beast {
namespace insight {
class Meter;
class MeterImpl : public std::enable_shared_from_this <MeterImpl>
class MeterImpl
: public std::enable_shared_from_this <MeterImpl>
, public BaseImpl
{
public:
typedef uint64 value_type;
typedef std::function <void (Meter const&)> HandlerType;
virtual ~MeterImpl () = 0;
virtual void increment (value_type amount) = 0;
virtual void set_handler (HandlerType const& handler) = 0;
};
}

View File

@@ -0,0 +1,28 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
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 THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
*/
//==============================================================================
namespace beast {
namespace insight {
namespace detail {
}
}
}

View File

@@ -0,0 +1,144 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
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 THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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 <unordered_map>
#include "../../make_unique.h"
namespace beast {
namespace insight {
namespace detail {
class GroupImp
: public std::enable_shared_from_this <GroupImp>
, public Group
{
public:
typedef std::vector <std::shared_ptr <BaseImpl>> Items;
std::string const m_name;
Collector::ptr m_collector;
Items m_items;
GroupImp (std::string const& name_,
Collector::ptr const& collector)
: m_name (name_)
, m_collector (collector)
{
}
~GroupImp ()
{
}
std::string const& name () const
{
return m_name;
}
std::string make_name (std::string const& name)
{
return m_name + "." + name;
}
Hook make_hook (HookImpl::HandlerType const& handler)
{
Hook hook (m_collector->make_hook (handler));
m_items.emplace_back (hook.impl ());
return hook;
}
Counter make_counter (std::string const& name)
{
Counter counter (m_collector->make_counter (make_name (name)));
m_items.emplace_back (counter.impl ());
return counter;
}
Event make_event (std::string const& name)
{
Event event (m_collector->make_event (make_name (name)));
m_items.emplace_back (event.impl ());
return event;
}
Gauge make_gauge (std::string const& name)
{
Gauge gauge (m_collector->make_gauge (make_name (name)));
m_items.emplace_back (gauge.impl ());
return gauge;
}
Meter make_meter (std::string const& name)
{
Meter meter (m_collector->make_meter (make_name (name)));
m_items.emplace_back (meter.impl ());
return meter;
}
private:
GroupImp& operator= (GroupImp const&);
};
//------------------------------------------------------------------------------
class GroupsImp : public Groups
{
public:
typedef std::unordered_map <std::string, std::shared_ptr <Group>> Items;
Collector::ptr m_collector;
Items m_items;
GroupsImp (Collector::ptr const& collector)
: m_collector (collector)
{
}
~GroupsImp ()
{
}
Group::ptr const& get (std::string const& name)
{
std::pair <Items::iterator, bool> result (
m_items.emplace (name, Group::ptr ()));
Group::ptr& group (result.first->second);
if (result.second)
group = std::make_shared <GroupImp> (name, m_collector);
return group;
}
};
}
//------------------------------------------------------------------------------
Groups::~Groups ()
{
}
std::unique_ptr <Groups> make_Groups (Collector::ptr const& collector)
{
return std::make_unique <detail::GroupsImp> (collector);
}
}
}

View File

@@ -20,6 +20,14 @@
namespace beast {
namespace insight {
Base::~Base ()
{
}
BaseImpl::~BaseImpl ()
{
}
CounterImpl::~CounterImpl ()
{
}

View File

@@ -37,10 +37,6 @@ public:
{
}
void set_handler (HandlerType const&)
{
}
private:
NullCounterImpl& operator= (NullCounterImpl const&);
};
@@ -71,10 +67,6 @@ public:
{
}
void set_handler (HandlerType const&)
{
}
private:
NullGaugeImpl& operator= (NullGaugeImpl const&);
};
@@ -88,10 +80,6 @@ public:
{
}
void set_handler (HandlerType const&)
{
}
private:
NullMeterImpl& operator= (NullMeterImpl const&);
};

View File

@@ -85,7 +85,6 @@ public:
~StatsDCounterImpl ();
void increment (CounterImpl::value_type amount);
void set_handler (HandlerType const& handler);
void flush ();
void do_increment (CounterImpl::value_type amount);
@@ -98,7 +97,6 @@ private:
std::string m_name;
CounterImpl::value_type m_value;
bool m_dirty;
HandlerType m_handler;
};
//------------------------------------------------------------------------------
@@ -138,7 +136,6 @@ public:
void set (GaugeImpl::value_type value);
void increment (GaugeImpl::difference_type amount);
void set_handler (HandlerType const& handler);
void flush ();
void do_set (GaugeImpl::value_type value);
@@ -153,7 +150,6 @@ private:
GaugeImpl::value_type m_last_value;
GaugeImpl::value_type m_value;
bool m_dirty;
HandlerType m_handler;
};
//------------------------------------------------------------------------------
@@ -169,7 +165,6 @@ public:
~StatsDMeterImpl ();
void increment (MeterImpl::value_type amount);
void set_handler (HandlerType const& handler);
void flush ();
void do_increment (MeterImpl::value_type amount);
@@ -182,7 +177,6 @@ private:
std::string m_name;
MeterImpl::value_type m_value;
bool m_dirty;
HandlerType m_handler;
};
//------------------------------------------------------------------------------
@@ -480,11 +474,6 @@ void StatsDCounterImpl::increment (CounterImpl::value_type amount)
shared_from_this ()), amount));
}
void StatsDCounterImpl::set_handler (HandlerType const& handler)
{
m_handler = handler;
}
void StatsDCounterImpl::flush ()
{
if (m_dirty)
@@ -509,8 +498,6 @@ void StatsDCounterImpl::do_increment (CounterImpl::value_type amount)
void StatsDCounterImpl::do_process ()
{
if (m_handler)
m_handler (Counter (shared_from_this ()));
flush ();
}
@@ -580,11 +567,6 @@ void StatsDGaugeImpl::increment (GaugeImpl::difference_type amount)
shared_from_this ()), amount));
}
void StatsDGaugeImpl::set_handler (HandlerType const& handler)
{
m_handler = handler;
}
void StatsDGaugeImpl::flush ()
{
if (m_dirty)
@@ -636,8 +618,6 @@ void StatsDGaugeImpl::do_increment (GaugeImpl::difference_type amount)
void StatsDGaugeImpl::do_process ()
{
if (m_handler)
m_handler (Gauge (shared_from_this ()));
flush ();
}
@@ -666,11 +646,6 @@ void StatsDMeterImpl::increment (MeterImpl::value_type amount)
shared_from_this ()), amount));
}
void StatsDMeterImpl::set_handler (HandlerType const& handler)
{
m_handler = handler;
}
void StatsDMeterImpl::flush ()
{
if (m_dirty)
@@ -695,8 +670,6 @@ void StatsDMeterImpl::do_increment (MeterImpl::value_type amount)
void StatsDMeterImpl::do_process ()
{
if (m_handler)
m_handler (Meter (shared_from_this ()));
flush ();
}