diff --git a/Builds/VisualStudio2012/beast.vcxproj b/Builds/VisualStudio2012/beast.vcxproj
index ec1388eac9..0bb02c5cb8 100644
--- a/Builds/VisualStudio2012/beast.vcxproj
+++ b/Builds/VisualStudio2012/beast.vcxproj
@@ -97,6 +97,7 @@
+
@@ -131,6 +132,8 @@
+
+
@@ -138,6 +141,8 @@
+
+
@@ -408,6 +413,12 @@
+
+ true
+ true
+ true
+ true
+
true
true
@@ -524,6 +535,18 @@
true
true
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
true
true
diff --git a/Builds/VisualStudio2012/beast.vcxproj.filters b/Builds/VisualStudio2012/beast.vcxproj.filters
index 5bd137834e..6c9f7d5d51 100644
--- a/Builds/VisualStudio2012/beast.vcxproj.filters
+++ b/Builds/VisualStudio2012/beast.vcxproj.filters
@@ -1242,6 +1242,21 @@
beast\chrono
+
+ beast\chrono
+
+
+ beast\insight
+
+
+ beast\insight
+
+
+ beast\insight
+
+
+ beast\insight
+
@@ -1802,6 +1817,15 @@
beast\crypto\impl
+
+ beast\chrono\impl
+
+
+ beast\insight\impl
+
+
+ beast\insight\impl
+
diff --git a/Builds/VisualStudio2013/beast.vcxproj b/Builds/VisualStudio2013/beast.vcxproj
index ba9d4f9e62..f4b93cdcb6 100644
--- a/Builds/VisualStudio2013/beast.vcxproj
+++ b/Builds/VisualStudio2013/beast.vcxproj
@@ -131,6 +131,8 @@
+
+
@@ -138,6 +140,8 @@
+
+
diff --git a/Builds/VisualStudio2013/beast.vcxproj.filters b/Builds/VisualStudio2013/beast.vcxproj.filters
index 2d7cc5e900..9a1c036675 100644
--- a/Builds/VisualStudio2013/beast.vcxproj.filters
+++ b/Builds/VisualStudio2013/beast.vcxproj.filters
@@ -1242,6 +1242,18 @@
beast\chrono
+
+ beast\insight
+
+
+ beast\insight
+
+
+ beast\insight
+
+
+ beast\insight
+
diff --git a/beast/Chrono.h b/beast/Chrono.h
index 3d9c46a8f9..cc41b72f58 100644
--- a/beast/Chrono.h
+++ b/beast/Chrono.h
@@ -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"
diff --git a/beast/Insight.h b/beast/Insight.h
index 20efda393b..2ec5b42ed1 100644
--- a/beast/Insight.h
+++ b/beast/Insight.h
@@ -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"
diff --git a/beast/chrono/Chrono.cpp b/beast/chrono/Chrono.cpp
index dc50936e04..28f92f8ccd 100644
--- a/beast/chrono/Chrono.cpp
+++ b/beast/chrono/Chrono.cpp
@@ -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"
diff --git a/beast/chrono/abstract_clock.h b/beast/chrono/abstract_clock.h
index c47c1bd1fe..d150d267ce 100644
--- a/beast/chrono/abstract_clock.h
+++ b/beast/chrono/abstract_clock.h
@@ -121,7 +121,7 @@ template
struct abstract_clock_wrapper
: public basic_abstract_clock_wrapper
{
- // 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)
{
diff --git a/beast/chrono/basic_seconds_clock.h b/beast/chrono/basic_seconds_clock.h
new file mode 100644
index 0000000000..2e15fdcc42
--- /dev/null
+++ b/beast/chrono/basic_seconds_clock.h
@@ -0,0 +1,237 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ 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
+#include
+
+#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
+# if BOOST_VERSION >= 105500
+# include
+# include
+# include
+# include
+# else
+# error "Boost version 1.55.0 or later is required"
+# endif
+#else
+# include
+# include
+# include
+#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 lock_guard;
+ typedef boost::unique_lock 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 lock_guard;
+ typedef std::unique_lock unique_lock;
+ typedef std::chrono::steady_clock clock_type;
+ typedef std::chrono::seconds seconds;
+ typedef std::thread thread;
+#endif
+ typedef std::vector 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 (
+ 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 basic_seconds_clock
+{
+public:
+ typedef std::chrono::seconds resolution;
+ typedef typename resolution::rep rep;
+ typedef typename resolution::period period;
+ typedef std::chrono::duration duration;
+ typedef std::chrono::time_point 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 lock_guard;
+
+ time_point m_now;
+ mutex m_mutex;
+
+ static time_point get_now ()
+ {
+ return time_point (floor (
+ 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
diff --git a/beast/chrono/impl/basic_seconds_clock.cpp b/beast/chrono/impl/basic_seconds_clock.cpp
new file mode 100644
index 0000000000..fcbdd17ee0
--- /dev/null
+++ b/beast/chrono/impl/basic_seconds_clock.cpp
@@ -0,0 +1,47 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ 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;
+
+}
diff --git a/beast/insight/Base.h b/beast/insight/Base.h
new file mode 100644
index 0000000000..f885d5fa92
--- /dev/null
+++ b/beast/insight/Base.h
@@ -0,0 +1,38 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ 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
+
+namespace beast {
+namespace insight {
+
+/** Base for all metrics and hooks. */
+class Base
+{
+public:
+ virtual ~Base () = 0;
+};
+
+}
+}
+
+#endif
diff --git a/beast/insight/BaseImpl.h b/beast/insight/BaseImpl.h
new file mode 100644
index 0000000000..86953efe0d
--- /dev/null
+++ b/beast/insight/BaseImpl.h
@@ -0,0 +1,40 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ 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
+
+namespace beast {
+namespace insight {
+
+/** Base for all metrics and hook implementations. */
+class BaseImpl
+{
+public:
+ typedef std::shared_ptr ptr;
+
+ virtual ~BaseImpl () = 0;
+};
+
+}
+}
+
+#endif
diff --git a/beast/insight/Collector.h b/beast/insight/Collector.h
index 5595d88c05..74bb8998a9 100644
--- a/beast/insight/Collector.h
+++ b/beast/insight/Collector.h
@@ -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);
+ }
+ /** @} */
};
}
diff --git a/beast/insight/Counter.h b/beast/insight/Counter.h
index 4e78013384..9f27128b66 100644
--- a/beast/insight/Counter.h
+++ b/beast/insight/Counter.h
@@ -22,6 +22,7 @@
#include
+#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
- 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 const& impl () const
+ {
+ return m_impl;
+ }
+
private:
std::shared_ptr m_impl;
};
diff --git a/beast/insight/CounterImpl.h b/beast/insight/CounterImpl.h
index f6c0b6e0db..c1a0254be3 100644
--- a/beast/insight/CounterImpl.h
+++ b/beast/insight/CounterImpl.h
@@ -22,20 +22,22 @@
#include
+#include "BaseImpl.h"
+
namespace beast {
namespace insight {
class Counter;
-class CounterImpl : public std::enable_shared_from_this
+class CounterImpl
+ : public std::enable_shared_from_this
+ , public BaseImpl
{
public:
typedef int64 value_type;
- typedef std::function HandlerType;
virtual ~CounterImpl () = 0;
virtual void increment (value_type amount) = 0;
- virtual void set_handler (HandlerType const& handler) = 0;
};
}
diff --git a/beast/insight/Event.h b/beast/insight/Event.h
index fac4be70e6..0bcf6df590 100644
--- a/beast/insight/Event.h
+++ b/beast/insight/Event.h
@@ -23,6 +23,7 @@
#include
#include
+#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));
}
+ std::shared_ptr const& impl () const
+ {
+ return m_impl;
+ }
+
private:
std::shared_ptr m_impl;
};
diff --git a/beast/insight/EventImpl.h b/beast/insight/EventImpl.h
index 567a1def2b..d2d684e555 100644
--- a/beast/insight/EventImpl.h
+++ b/beast/insight/EventImpl.h
@@ -22,12 +22,16 @@
#include
+#include "BaseImpl.h"
+
namespace beast {
namespace insight {
class Event;
-class EventImpl : public std::enable_shared_from_this
+class EventImpl
+ : public std::enable_shared_from_this
+ , public BaseImpl
{
public:
typedef std::chrono::milliseconds value_type;
diff --git a/beast/insight/Gauge.h b/beast/insight/Gauge.h
index 70fff9b05d..22875214f9 100644
--- a/beast/insight/Gauge.h
+++ b/beast/insight/Gauge.h
@@ -22,6 +22,7 @@
#include
+#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
- 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 const& impl () const
+ {
+ return m_impl;
+ }
+
private:
std::shared_ptr m_impl;
};
diff --git a/beast/insight/GaugeImpl.h b/beast/insight/GaugeImpl.h
index e816e6ce7e..1f5794e958 100644
--- a/beast/insight/GaugeImpl.h
+++ b/beast/insight/GaugeImpl.h
@@ -20,25 +20,26 @@
#ifndef BEAST_INSIGHT_GAUGEIMPL_H_INCLUDED
#define BEAST_INSIGHT_GAUGEIMPL_H_INCLUDED
-#include
#include
+#include "BaseImpl.h"
+
namespace beast {
namespace insight {
class Gauge;
-class GaugeImpl : public std::enable_shared_from_this
+class GaugeImpl
+ : public std::enable_shared_from_this
+ , public BaseImpl
{
public:
typedef uint64 value_type;
typedef int64 difference_type;
- typedef std::function 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;
};
}
diff --git a/beast/insight/Group.h b/beast/insight/Group.h
new file mode 100644
index 0000000000..273472914e
--- /dev/null
+++ b/beast/insight/Group.h
@@ -0,0 +1,43 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ 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
+
+#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 ptr;
+
+ /** Returns the name of this group, for diagnostics. */
+ virtual std::string const& name () const = 0;
+};
+
+}
+}
+
+#endif
diff --git a/beast/insight/Groups.h b/beast/insight/Groups.h
new file mode 100644
index 0000000000..6138938205
--- /dev/null
+++ b/beast/insight/Groups.h
@@ -0,0 +1,55 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ 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
+#include
+
+#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 make_Groups (Collector::ptr const& collector);
+
+}
+}
+
+#endif
diff --git a/beast/insight/Hook.h b/beast/insight/Hook.h
index a529c0e1be..783477a4e7 100644
--- a/beast/insight/Hook.h
+++ b/beast/insight/Hook.h
@@ -20,15 +20,16 @@
#ifndef BEAST_INSIGHT_HOOK_H_INCLUDED
#define BEAST_INSIGHT_HOOK_H_INCLUDED
-#include "HookImpl.h"
-
#include
+#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 const& impl)
: m_impl (impl)
+ { }
+
+ std::shared_ptr const& impl () const
{
+ return m_impl;
}
private:
diff --git a/beast/insight/HookImpl.h b/beast/insight/HookImpl.h
index 6c8cda2a0e..84b2b3e7f2 100644
--- a/beast/insight/HookImpl.h
+++ b/beast/insight/HookImpl.h
@@ -23,10 +23,14 @@
#include
#include
+#include "BaseImpl.h"
+
namespace beast {
namespace insight {
-class HookImpl : public std::enable_shared_from_this
+class HookImpl
+ : public std::enable_shared_from_this
+ , public BaseImpl
{
public:
typedef std::function HandlerType;
diff --git a/beast/insight/Insight.cpp b/beast/insight/Insight.cpp
index 1426d5073d..eaf1faaea6 100644
--- a/beast/insight/Insight.cpp
+++ b/beast/insight/Insight.cpp
@@ -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"
diff --git a/beast/insight/Meter.h b/beast/insight/Meter.h
index 2743e9c2cd..2cf3d38efe 100644
--- a/beast/insight/Meter.h
+++ b/beast/insight/Meter.h
@@ -20,10 +20,11 @@
#ifndef BEAST_INSIGHT_METER_H_INCLUDED
#define BEAST_INSIGHT_METER_H_INCLUDED
-#include "MeterImpl.h"
-
#include
+#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
- 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 const& impl () const
+ {
+ return m_impl;
+ }
+
private:
std::shared_ptr m_impl;
};
diff --git a/beast/insight/MeterImpl.h b/beast/insight/MeterImpl.h
index ca3fffaa55..21dae58a0c 100644
--- a/beast/insight/MeterImpl.h
+++ b/beast/insight/MeterImpl.h
@@ -20,23 +20,24 @@
#ifndef BEAST_INSIGHT_METERIMPL_H_INCLUDED
#define BEAST_INSIGHT_METERIMPL_H_INCLUDED
-#include
#include
+#include "BaseImpl.h"
+
namespace beast {
namespace insight {
class Meter;
-class MeterImpl : public std::enable_shared_from_this
+class MeterImpl
+ : public std::enable_shared_from_this
+ , public BaseImpl
{
public:
typedef uint64 value_type;
- typedef std::function HandlerType;
virtual ~MeterImpl () = 0;
virtual void increment (value_type amount) = 0;
- virtual void set_handler (HandlerType const& handler) = 0;
};
}
diff --git a/beast/insight/impl/Group.cpp b/beast/insight/impl/Group.cpp
new file mode 100644
index 0000000000..a80baa47b1
--- /dev/null
+++ b/beast/insight/impl/Group.cpp
@@ -0,0 +1,28 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ 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 {
+
+}
+
+}
+}
diff --git a/beast/insight/impl/Groups.cpp b/beast/insight/impl/Groups.cpp
new file mode 100644
index 0000000000..186cb87bbd
--- /dev/null
+++ b/beast/insight/impl/Groups.cpp
@@ -0,0 +1,144 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ 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
+
+#include "../../make_unique.h"
+
+namespace beast {
+namespace insight {
+
+namespace detail {
+
+class GroupImp
+ : public std::enable_shared_from_this
+ , public Group
+{
+public:
+ typedef std::vector > 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 > 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 result (
+ m_items.emplace (name, Group::ptr ()));
+ Group::ptr& group (result.first->second);
+ if (result.second)
+ group = std::make_shared (name, m_collector);
+ return group;
+ }
+};
+
+}
+
+//------------------------------------------------------------------------------
+
+Groups::~Groups ()
+{
+}
+
+std::unique_ptr make_Groups (Collector::ptr const& collector)
+{
+ return std::make_unique (collector);
+}
+
+}
+}
diff --git a/beast/insight/impl/Metric.cpp b/beast/insight/impl/Metric.cpp
index f40cd493bb..22a7bd0496 100644
--- a/beast/insight/impl/Metric.cpp
+++ b/beast/insight/impl/Metric.cpp
@@ -20,6 +20,14 @@
namespace beast {
namespace insight {
+Base::~Base ()
+{
+}
+
+BaseImpl::~BaseImpl ()
+{
+}
+
CounterImpl::~CounterImpl ()
{
}
diff --git a/beast/insight/impl/NullCollector.cpp b/beast/insight/impl/NullCollector.cpp
index 97b242c322..cf7229de1e 100644
--- a/beast/insight/impl/NullCollector.cpp
+++ b/beast/insight/impl/NullCollector.cpp
@@ -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&);
};
diff --git a/beast/insight/impl/StatsDCollector.cpp b/beast/insight/impl/StatsDCollector.cpp
index b99f52fc5b..744b3b2704 100644
--- a/beast/insight/impl/StatsDCollector.cpp
+++ b/beast/insight/impl/StatsDCollector.cpp
@@ -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 ();
}