diff --git a/src/beast/Builds/VisualStudio2012/beast.vcxproj b/src/beast/Builds/VisualStudio2012/beast.vcxproj
index 6a3412a1e4..707588afea 100644
--- a/src/beast/Builds/VisualStudio2012/beast.vcxproj
+++ b/src/beast/Builds/VisualStudio2012/beast.vcxproj
@@ -120,6 +120,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -504,6 +518,37 @@
true
true
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
+
+ true
+ true
+ true
+ true
+
+
true
true
diff --git a/src/beast/Builds/VisualStudio2012/beast.vcxproj.filters b/src/beast/Builds/VisualStudio2012/beast.vcxproj.filters
index 765753011f..cc49cebe69 100644
--- a/src/beast/Builds/VisualStudio2012/beast.vcxproj.filters
+++ b/src/beast/Builds/VisualStudio2012/beast.vcxproj.filters
@@ -318,6 +318,12 @@
{793e2d61-14f6-4fa1-a17f-af6bbec13ba1}
+
+ {174b9125-76a7-4796-be97-79c2dcc751f1}
+
+
+ {04f27818-7843-4ef3-967c-1761dc892342}
+
@@ -1296,6 +1302,48 @@
beast
+
+ beast
+
+
+ beast\insight
+
+
+ beast\insight
+
+
+ beast\insight
+
+
+ beast\insight
+
+
+ beast\insight
+
+
+ beast\insight
+
+
+ beast\insight
+
+
+ beast\insight
+
+
+ beast\insight
+
+
+ beast\insight
+
+
+ beast\insight
+
+
+ beast\insight
+
+
+ beast\insight
+
@@ -1856,6 +1904,24 @@
beast\stl
+
+ beast\insight
+
+
+ beast\insight\impl
+
+
+ beast\insight\impl
+
+
+ beast\insight\impl
+
+
+ beast\insight\impl
+
+
+ beast\insight\impl
+
diff --git a/src/beast/beast/Insight.h b/src/beast/beast/Insight.h
new file mode 100644
index 0000000000..20efda393b
--- /dev/null
+++ b/src/beast/beast/Insight.h
@@ -0,0 +1,35 @@
+//------------------------------------------------------------------------------
+/*
+ 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_H_INCLUDED
+#define BEAST_INSIGHT_H_INCLUDED
+
+#include "insight/Counter.h"
+#include "insight/CounterImpl.h"
+#include "insight/Event.h"
+#include "insight/EventImpl.h"
+#include "insight/Gauge.h"
+#include "insight/GaugeImpl.h"
+#include "insight/Hook.h"
+#include "insight/HookImpl.h"
+#include "insight/Collector.h"
+#include "insight/NullCollector.h"
+#include "insight/StatsDCollector.h"
+
+#endif
diff --git a/src/beast/beast/insight/Collector.h b/src/beast/beast/insight/Collector.h
new file mode 100644
index 0000000000..da923d5fe5
--- /dev/null
+++ b/src/beast/beast/insight/Collector.h
@@ -0,0 +1,96 @@
+//------------------------------------------------------------------------------
+/*
+ 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_COLLECTOR_H_INCLUDED
+#define BEAST_INSIGHT_COLLECTOR_H_INCLUDED
+
+#include "../stl/function.h"
+#include "../stl/shared_ptr.h"
+
+#include "Counter.h"
+#include "Event.h"
+#include "Gauge.h"
+#include "Hook.h"
+#include "Meter.h"
+
+namespace beast {
+namespace insight {
+
+/** Interface for a manager that allows collection of metrics.
+
+ To export metrics from a class, pass and save a shared_ptr to this
+ interface in the class constructor. Create the metric objects
+ as desired (counters, events, gauges, meters, and an optional hook)
+ using the interface.
+
+ @see Counter, Event, Gauge, Hook, Meter
+ @see NullCollector, StatsDCollector
+*/
+class Collector
+{
+public:
+ virtual ~Collector() = 0;
+
+ /** Create a hook.
+
+ A hook is called at each collection interval, on an implementation
+ defined thread. This is a convenience facility for gathering metrics
+ in the polling style. The typical usage is to update all the metrics
+ of interest in the handler.
+
+ Handler will be called with this signature:
+ void handler (void)
+
+ @see Hook
+ */
+ /** @{ */
+ template
+ Hook make_hook (Handler handler)
+ {
+ return make_hook (HookImpl::HandlerType (handler));
+ }
+
+ virtual Hook make_hook (HookImpl::HandlerType const& handler) = 0;
+ /** @} */
+
+ /** Create a counter with the specified name.
+ @see Counter
+ */
+ virtual Counter make_counter (std::string const& name) = 0;
+
+ /** Create an event with the specified name.
+ @see Event
+ */
+ virtual Event make_event (std::string const& name) = 0;
+
+ /** Create a gauge with the specified name.
+ @see Gauge
+ */
+ virtual Gauge make_gauge (std::string const& name) = 0;
+
+ /** Create a meter with the specified name.
+ @see Meter
+ */
+ virtual Meter make_meter (std::string const& name) = 0;
+};
+
+}
+}
+
+#endif
diff --git a/src/beast/beast/insight/Counter.h b/src/beast/beast/insight/Counter.h
new file mode 100644
index 0000000000..ecffa911e9
--- /dev/null
+++ b/src/beast/beast/insight/Counter.h
@@ -0,0 +1,109 @@
+//------------------------------------------------------------------------------
+/*
+ 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_COUNTER_H_INCLUDED
+#define BEAST_INSIGHT_COUNTER_H_INCLUDED
+
+#include "CounterImpl.h"
+
+#include "../stl/shared_ptr.h"
+
+namespace beast {
+namespace insight {
+
+/** A metric for measuring an integral value.
+
+ A counter is a gauge calculated at the server. The owner of the counter
+ may increment and decrement the value by an amount.
+
+ 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
+{
+public:
+ typedef CounterImpl::value_type value_type;
+
+ /** Create a null metric.
+ A null metric reports no information.
+ */
+ Counter ()
+ {
+ }
+
+ /** Create the metric reference the specified implementation.
+ Normally this won't be called directly. Instead, call the appropriate
+ factory function in the Collector interface.
+ @see Collector.
+ */
+ explicit Counter (shared_ptr const& impl)
+ : 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 (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
+ {
+ if (m_impl)
+ m_impl->increment (amount);
+ }
+
+ Counter const& operator+= (value_type amount) const
+ { increment (amount); return *this; }
+
+ Counter const& operator-= (value_type amount) const
+ { increment (-amount); return *this; }
+
+ Counter const& operator++ () const
+ { increment (1); return *this; }
+
+ Counter const& operator++ (int) const
+ { increment (1); return *this; }
+
+ Counter const& operator-- () const
+ { increment (-1); return *this; }
+
+ Counter const& operator-- (int) const
+ { increment (-1); return *this; }
+ /** @} */
+
+private:
+ shared_ptr m_impl;
+};
+
+}
+}
+
+#endif
diff --git a/src/beast/beast/insight/CounterImpl.h b/src/beast/beast/insight/CounterImpl.h
new file mode 100644
index 0000000000..047a988198
--- /dev/null
+++ b/src/beast/beast/insight/CounterImpl.h
@@ -0,0 +1,42 @@
+//------------------------------------------------------------------------------
+/*
+ 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_COUNTERIMPL_H_INCLUDED
+#define BEAST_INSIGHT_COUNTERIMPL_H_INCLUDED
+
+namespace beast {
+namespace insight {
+
+class Counter;
+
+class CounterImpl : public enable_shared_from_this
+{
+public:
+ typedef int64 value_type;
+ typedef beast::function HandlerType;
+
+ virtual ~CounterImpl () = 0;
+ virtual void increment (value_type amount) = 0;
+ virtual void set_handler (HandlerType const& handler) = 0;
+};
+
+}
+}
+
+#endif
diff --git a/src/beast/beast/insight/Event.h b/src/beast/beast/insight/Event.h
new file mode 100644
index 0000000000..a892c780b6
--- /dev/null
+++ b/src/beast/beast/insight/Event.h
@@ -0,0 +1,78 @@
+//------------------------------------------------------------------------------
+/*
+ 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_EVENT_H_INCLUDED
+#define BEAST_INSIGHT_EVENT_H_INCLUDED
+
+#include "EventImpl.h"
+
+#include "../stl/shared_ptr.h"
+
+namespace beast {
+namespace insight {
+
+/** A metric for reporting event timing.
+
+ An event is an operation that has an associated millisecond time, or
+ other integral value. Because events happen at a specific moment, the
+ metric only supports a push-style interface.
+
+ 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
+{
+public:
+ typedef EventImpl::value_type value_type;
+
+ /** Create a null metric.
+ A null metric reports no information.
+ */
+ Event ()
+ {
+ }
+
+ /** Create the metric reference the specified implementation.
+ Normally this won't be called directly. Instead, call the appropriate
+ factory function in the Collector interface.
+ @see Collector.
+ */
+ explicit Event (shared_ptr const& impl)
+ : m_impl (impl)
+ {
+ }
+
+ /** Push an event notification.
+ The value specifies the elapsed time in milliseconds, or any other
+ domain specific value.
+ */
+ void notify (value_type value) const
+ {
+ if (m_impl)
+ m_impl->notify (value);
+ }
+
+private:
+ shared_ptr m_impl;
+};
+
+}
+}
+
+#endif
diff --git a/src/beast/beast/insight/EventImpl.h b/src/beast/beast/insight/EventImpl.h
new file mode 100644
index 0000000000..ef93a2334c
--- /dev/null
+++ b/src/beast/beast/insight/EventImpl.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_EVENTIMPL_H_INCLUDED
+#define BEAST_INSIGHT_EVENTIMPL_H_INCLUDED
+
+namespace beast {
+namespace insight {
+
+class Event;
+
+class EventImpl : public enable_shared_from_this
+{
+public:
+ typedef uint64 value_type;
+
+ virtual ~EventImpl () = 0;
+ virtual void notify (value_type value) = 0;
+};
+
+}
+}
+
+#endif
diff --git a/src/beast/beast/insight/Gauge.h b/src/beast/beast/insight/Gauge.h
new file mode 100644
index 0000000000..16fc484fd1
--- /dev/null
+++ b/src/beast/beast/insight/Gauge.h
@@ -0,0 +1,127 @@
+//------------------------------------------------------------------------------
+/*
+ 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_GAUGE_H_INCLUDED
+#define BEAST_INSIGHT_GAUGE_H_INCLUDED
+
+#include "GaugeImpl.h"
+
+#include "../stl/shared_ptr.h"
+
+namespace beast {
+namespace insight {
+
+/** A metric for measuring an integral value.
+
+ A gauge is an instantaneous measurement of a value, like the gas gauge
+ in a car. The caller directly sets the value, or adjusts it by a
+ specified amount. The value is kept in the client rather than the collector.
+
+ 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
+{
+public:
+ typedef GaugeImpl::value_type value_type;
+ typedef GaugeImpl::difference_type difference_type;
+
+ /** Create a null metric.
+ A null metric reports no information.
+ */
+ Gauge ()
+ {
+ }
+
+ /** Create the metric reference the specified implementation.
+ Normally this won't be called directly. Instead, call the appropriate
+ factory function in the Collector interface.
+ @see Collector.
+ */
+ explicit Gauge (shared_ptr const& impl)
+ : 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 (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
+ collection interval.
+ */
+ /** @{ */
+ void set (value_type value) const
+ {
+ if (m_impl)
+ m_impl->set (value);
+ }
+
+ Gauge const& operator= (value_type value) const
+ { set (value); return *this; }
+ /** @} */
+
+ /** Adjust the value of the gauge. */
+ /** @{ */
+ void increment (difference_type amount) const
+ {
+ if (m_impl)
+ m_impl->increment (amount);
+ }
+
+ Gauge const& operator+= (difference_type amount) const
+ { increment (amount); return *this; }
+
+ Gauge const& operator-= (difference_type amount) const
+ { increment (-amount); return *this; }
+
+ Gauge const& operator++ () const
+ { increment (1); return *this; }
+
+ Gauge const& operator++ (int) const
+ { increment (1); return *this; }
+
+ Gauge const& operator-- () const
+ { increment (-1); return *this; }
+
+ Gauge const& operator-- (int) const
+ { increment (-1); return *this; }
+ /** @} */
+
+private:
+ shared_ptr m_impl;
+};
+
+}
+}
+
+#endif
diff --git a/src/beast/beast/insight/GaugeImpl.h b/src/beast/beast/insight/GaugeImpl.h
new file mode 100644
index 0000000000..0e26cb47e5
--- /dev/null
+++ b/src/beast/beast/insight/GaugeImpl.h
@@ -0,0 +1,44 @@
+//------------------------------------------------------------------------------
+/*
+ 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_GAUGEIMPL_H_INCLUDED
+#define BEAST_INSIGHT_GAUGEIMPL_H_INCLUDED
+
+namespace beast {
+namespace insight {
+
+class Gauge;
+
+class GaugeImpl : public enable_shared_from_this
+{
+public:
+ typedef uint64 value_type;
+ typedef int64 difference_type;
+ typedef beast::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;
+};
+
+}
+}
+
+#endif
diff --git a/src/beast/beast/insight/Hook.h b/src/beast/beast/insight/Hook.h
new file mode 100644
index 0000000000..06ef844907
--- /dev/null
+++ b/src/beast/beast/insight/Hook.h
@@ -0,0 +1,57 @@
+//------------------------------------------------------------------------------
+/*
+ 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_HOOK_H_INCLUDED
+#define BEAST_INSIGHT_HOOK_H_INCLUDED
+
+#include "HookImpl.h"
+
+#include "../stl/shared_ptr.h"
+
+namespace beast {
+namespace insight {
+
+/** A reference to a handler for performing polled collection. */
+class Hook
+{
+public:
+ /** Create a null hook.
+ A null hook has no associated handler.
+ */
+ Hook ()
+ { }
+
+ /** Create a hook referencing the specified implementation.
+ Normally this won't be called directly. Instead, call the appropriate
+ factory function in the Collector interface.
+ @see Collector.
+ */
+ explicit Hook (shared_ptr const& impl)
+ : m_impl (impl)
+ {
+ }
+
+private:
+ shared_ptr m_impl;
+};
+
+}
+}
+
+#endif
diff --git a/src/beast/beast/insight/HookImpl.h b/src/beast/beast/insight/HookImpl.h
new file mode 100644
index 0000000000..cbbf371849
--- /dev/null
+++ b/src/beast/beast/insight/HookImpl.h
@@ -0,0 +1,39 @@
+//------------------------------------------------------------------------------
+/*
+ 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_HOOKIMPL_H_INCLUDED
+#define BEAST_INSIGHT_HOOKIMPL_H_INCLUDED
+
+#include "../stl/shared_ptr.h"
+
+namespace beast {
+namespace insight {
+
+class HookImpl : public enable_shared_from_this
+{
+public:
+ typedef beast::function HandlerType;
+
+ virtual ~HookImpl () = 0;
+};
+
+}
+}
+
+#endif
diff --git a/src/beast/beast/insight/Insight.cpp b/src/beast/beast/insight/Insight.cpp
new file mode 100644
index 0000000000..1426d5073d
--- /dev/null
+++ b/src/beast/beast/insight/Insight.cpp
@@ -0,0 +1,32 @@
+//------------------------------------------------------------------------------
+/*
+ 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 "BeastConfig.h"
+
+#include "../Config.h"
+
+#include "../../modules/beast_core/beast_core.h" // for UnitTest
+
+#include "../Insight.h"
+
+#include "impl/Collector.cpp"
+#include "impl/Hook.cpp"
+#include "impl/Metric.cpp"
+#include "impl/NullCollector.cpp"
+#include "impl/StatsDCollector.cpp"
diff --git a/src/beast/beast/insight/Meter.h b/src/beast/beast/insight/Meter.h
new file mode 100644
index 0000000000..bf2090c1d9
--- /dev/null
+++ b/src/beast/beast/insight/Meter.h
@@ -0,0 +1,98 @@
+//------------------------------------------------------------------------------
+/*
+ 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_METER_H_INCLUDED
+#define BEAST_INSIGHT_METER_H_INCLUDED
+
+#include "MeterImpl.h"
+
+#include "../stl/shared_ptr.h"
+
+namespace beast {
+namespace insight {
+
+/** A metric for measuring an integral value.
+
+ A meter may be thought of as an increment-only counter.
+
+ 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
+{
+public:
+ typedef MeterImpl::value_type value_type;
+
+ /** Create a null metric.
+ A null metric reports no information.
+ */
+ Meter ()
+ {
+ }
+
+ /** Create the metric reference the specified implementation.
+ Normally this won't be called directly. Instead, call the appropriate
+ factory function in the Collector interface.
+ @see Collector.
+ */
+ explicit Meter (shared_ptr const& impl)
+ : 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
+ {
+ if (m_impl)
+ m_impl->increment (amount);
+ }
+
+ Meter const& operator+= (value_type amount) const
+ { increment (amount); return *this; }
+
+ Meter const& operator++ () const
+ { increment (1); return *this; }
+
+ Meter const& operator++ (int) const
+ { increment (1); return *this; }
+ /** @} */
+
+private:
+ shared_ptr m_impl;
+};
+
+}
+}
+
+#endif
diff --git a/src/beast/beast/insight/MeterImpl.h b/src/beast/beast/insight/MeterImpl.h
new file mode 100644
index 0000000000..057bd155dd
--- /dev/null
+++ b/src/beast/beast/insight/MeterImpl.h
@@ -0,0 +1,42 @@
+//------------------------------------------------------------------------------
+/*
+ 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_METERIMPL_H_INCLUDED
+#define BEAST_INSIGHT_METERIMPL_H_INCLUDED
+
+namespace beast {
+namespace insight {
+
+class Meter;
+
+class MeterImpl : public enable_shared_from_this
+{
+public:
+ typedef uint64 value_type;
+ typedef beast::function HandlerType;
+
+ virtual ~MeterImpl () = 0;
+ virtual void increment (value_type amount) = 0;
+ virtual void set_handler (HandlerType const& handler) = 0;
+};
+
+}
+}
+
+#endif
diff --git a/src/beast/beast/insight/NullCollector.h b/src/beast/beast/insight/NullCollector.h
new file mode 100644
index 0000000000..af1f22d6be
--- /dev/null
+++ b/src/beast/beast/insight/NullCollector.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_NULLCOLLECTOR_H_INCLUDED
+#define BEAST_INSIGHT_NULLCOLLECTOR_H_INCLUDED
+
+#include "Collector.h"
+
+namespace beast {
+namespace insight {
+
+/** A Collector which does not collect metrics. */
+class NullCollector : public Collector
+{
+public:
+ static shared_ptr New ();
+};
+
+}
+}
+
+#endif
diff --git a/src/beast/beast/insight/StatsDCollector.h b/src/beast/beast/insight/StatsDCollector.h
new file mode 100644
index 0000000000..931c478f93
--- /dev/null
+++ b/src/beast/beast/insight/StatsDCollector.h
@@ -0,0 +1,49 @@
+//------------------------------------------------------------------------------
+/*
+ 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_STATSDCOLLECTOR_H_INCLUDED
+#define BEAST_INSIGHT_STATSDCOLLECTOR_H_INCLUDED
+
+#include "Collector.h"
+
+#include "../net/IPAddress.h"
+
+namespace beast {
+namespace insight {
+
+/** A Collector that reports metrics to a StatsD server.
+ Reference:
+ https://github.com/b/statsd_spec
+*/
+class StatsDCollector : public Collector
+{
+public:
+ /** Create a StatsD collector.
+ @param address The IP address and port of the StatsD server.
+ @param prefix A string pre-pended before each metric name.
+ @param journal Destination for logging output.
+ */
+ static shared_ptr New (IPAddress const& address,
+ std::string const& prefix, Journal journal);
+};
+
+}
+}
+
+#endif
diff --git a/src/beast/beast/insight/impl/Collector.cpp b/src/beast/beast/insight/impl/Collector.cpp
new file mode 100644
index 0000000000..2ab1d2fc57
--- /dev/null
+++ b/src/beast/beast/insight/impl/Collector.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 {
+
+Collector::~Collector ()
+{
+}
+
+}
+}
diff --git a/src/beast/beast/insight/impl/Hook.cpp b/src/beast/beast/insight/impl/Hook.cpp
new file mode 100644
index 0000000000..e9392a59f6
--- /dev/null
+++ b/src/beast/beast/insight/impl/Hook.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 {
+
+HookImpl::~HookImpl ()
+{
+}
+
+}
+}
diff --git a/src/beast/beast/insight/impl/Metric.cpp b/src/beast/beast/insight/impl/Metric.cpp
new file mode 100644
index 0000000000..f40cd493bb
--- /dev/null
+++ b/src/beast/beast/insight/impl/Metric.cpp
@@ -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.
+*/
+//==============================================================================
+
+namespace beast {
+namespace insight {
+
+CounterImpl::~CounterImpl ()
+{
+}
+
+EventImpl::~EventImpl ()
+{
+}
+
+GaugeImpl::~GaugeImpl ()
+{
+}
+
+MeterImpl::~MeterImpl ()
+{
+}
+
+}
+}
diff --git a/src/beast/beast/insight/impl/NullCollector.cpp b/src/beast/beast/insight/impl/NullCollector.cpp
new file mode 100644
index 0000000000..f1ab857f65
--- /dev/null
+++ b/src/beast/beast/insight/impl/NullCollector.cpp
@@ -0,0 +1,149 @@
+//------------------------------------------------------------------------------
+/*
+ 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 {
+
+class NullHookImpl : public HookImpl
+{
+private:
+ NullHookImpl& operator= (NullHookImpl const&);
+};
+
+//------------------------------------------------------------------------------
+
+class NullCounterImpl : public CounterImpl
+{
+public:
+ void increment (value_type)
+ {
+ }
+
+ void set_handler (HandlerType const&)
+ {
+ }
+
+private:
+ NullCounterImpl& operator= (NullCounterImpl const&);
+};
+
+//------------------------------------------------------------------------------
+
+class NullEventImpl : public EventImpl
+{
+public:
+ void notify (value_type)
+ {
+ }
+
+private:
+ NullEventImpl& operator= (NullEventImpl const&);
+};
+
+//------------------------------------------------------------------------------
+
+class NullGaugeImpl : public GaugeImpl
+{
+public:
+ void set (value_type)
+ {
+ }
+
+ void increment (difference_type)
+ {
+ }
+
+ void set_handler (HandlerType const&)
+ {
+ }
+
+private:
+ NullGaugeImpl& operator= (NullGaugeImpl const&);
+};
+
+//------------------------------------------------------------------------------
+
+class NullMeterImpl : public MeterImpl
+{
+public:
+ void increment (value_type)
+ {
+ }
+
+ void set_handler (HandlerType const&)
+ {
+ }
+
+private:
+ NullMeterImpl& operator= (NullMeterImpl const&);
+};
+
+//------------------------------------------------------------------------------
+
+class NullCollectorImp : public NullCollector
+{
+private:
+public:
+ NullCollectorImp ()
+ {
+ }
+
+ ~NullCollectorImp ()
+ {
+ }
+
+ Hook make_hook (HookImpl::HandlerType const&)
+ {
+ return Hook (make_shared ());
+ }
+
+ Counter make_counter (std::string const&)
+ {
+ return Counter (make_shared ());
+ }
+
+ Event make_event (std::string const&)
+ {
+ return Event (make_shared ());
+ }
+
+ Gauge make_gauge (std::string const&)
+ {
+ return Gauge (make_shared ());
+ }
+
+ Meter make_meter (std::string const&)
+ {
+ return Meter (make_shared ());
+ }
+};
+
+}
+
+//------------------------------------------------------------------------------
+
+shared_ptr NullCollector::New ()
+{
+ return beast::make_shared ();
+}
+
+}
+}
diff --git a/src/beast/beast/insight/impl/StatsDCollector.cpp b/src/beast/beast/insight/impl/StatsDCollector.cpp
new file mode 100644
index 0000000000..86d540d3cb
--- /dev/null
+++ b/src/beast/beast/insight/impl/StatsDCollector.cpp
@@ -0,0 +1,712 @@
+//------------------------------------------------------------------------------
+/*
+ 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 "../../asio/IPAddressConversion.h"
+#include "../../threads/SharedData.h"
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+namespace beast {
+namespace insight {
+
+namespace detail {
+
+class StatsDCollectorImp;
+
+//------------------------------------------------------------------------------
+
+class StatsDMetricBase : public List ::Node
+{
+public:
+ virtual void do_process () = 0;
+};
+
+//------------------------------------------------------------------------------
+
+class StatsDHookImpl
+ : public HookImpl
+ , public StatsDMetricBase
+{
+public:
+ StatsDHookImpl (
+ HandlerType const& handler,
+ beast::shared_ptr const& impl);
+
+ ~StatsDHookImpl ();
+
+ void do_process ();
+
+private:
+ StatsDHookImpl& operator= (StatsDHookImpl const&);
+
+ beast::shared_ptr m_impl;
+ HandlerType m_handler;
+};
+
+//------------------------------------------------------------------------------
+
+class StatsDCounterImpl
+ : public CounterImpl
+ , public StatsDMetricBase
+{
+public:
+ StatsDCounterImpl (std::string const& name,
+ beast::shared_ptr const& impl);
+
+ ~StatsDCounterImpl ();
+
+ void increment (CounterImpl::value_type amount);
+ void set_handler (HandlerType const& handler);
+
+ void flush ();
+ void do_increment (CounterImpl::value_type amount,
+ shared_ptr const& ptr);
+ void do_process ();
+
+private:
+ StatsDCounterImpl& operator= (StatsDCounterImpl const&);
+
+ beast::shared_ptr m_impl;
+ std::string m_name;
+ CounterImpl::value_type m_value;
+ bool m_dirty;
+ HandlerType m_handler;
+};
+
+//------------------------------------------------------------------------------
+
+class StatsDEventImpl
+ : public EventImpl
+{
+public:
+ StatsDEventImpl (std::string const& name,
+ beast::shared_ptr const& impl);
+
+ ~StatsDEventImpl ();
+
+ void notify (EventImpl::value_type value);
+
+ void do_notify (EventImpl::value_type value,
+ shared_ptr const& ptr);
+ void do_process ();
+
+private:
+ StatsDEventImpl& operator= (StatsDEventImpl const&);
+
+ beast::shared_ptr m_impl;
+ std::string m_name;
+};
+
+//------------------------------------------------------------------------------
+
+class StatsDGaugeImpl
+ : public GaugeImpl
+ , public StatsDMetricBase
+{
+public:
+ StatsDGaugeImpl (std::string const& name,
+ beast::shared_ptr const& impl);
+
+ ~StatsDGaugeImpl ();
+
+ 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,
+ shared_ptr const& ptr);
+ void do_increment (GaugeImpl::difference_type amount,
+ shared_ptr const& ptr);
+ void do_process ();
+
+private:
+ StatsDGaugeImpl& operator= (StatsDGaugeImpl const&);
+
+ beast::shared_ptr m_impl;
+ std::string m_name;
+ GaugeImpl::value_type m_last_value;
+ GaugeImpl::value_type m_value;
+ bool m_dirty;
+ HandlerType m_handler;
+};
+
+//------------------------------------------------------------------------------
+
+class StatsDMeterImpl
+ : public MeterImpl
+ , public StatsDMetricBase
+{
+public:
+ explicit StatsDMeterImpl (std::string const& name,
+ beast::shared_ptr const& impl);
+
+ ~StatsDMeterImpl ();
+
+ void increment (MeterImpl::value_type amount);
+ void set_handler (HandlerType const& handler);
+
+ void flush ();
+ void do_increment (MeterImpl::value_type amount,
+ shared_ptr const& ptr);
+ void do_process ();
+
+private:
+ StatsDMeterImpl& operator= (StatsDMeterImpl const&);
+
+ beast::shared_ptr m_impl;
+ std::string m_name;
+ MeterImpl::value_type m_value;
+ bool m_dirty;
+ HandlerType m_handler;
+};
+
+//------------------------------------------------------------------------------
+
+class StatsDCollectorImp
+ : public StatsDCollector
+ , public beast::enable_shared_from_this
+{
+private:
+ enum
+ {
+ //max_packet_size = 484
+ max_packet_size = 1472
+ };
+
+ struct StateType
+ {
+ List metrics;
+ };
+
+ typedef SharedData State;
+
+ Journal m_journal;
+ IPAddress m_address;
+ std::string m_prefix;
+ boost::asio::io_service m_io_service;
+ boost::optional m_work;
+ boost::asio::deadline_timer m_timer;
+ boost::asio::ip::udp::socket m_socket;
+ std::deque m_data;
+ State m_state;
+
+ // Must come last for order of init
+ beast::thread m_thread;
+
+ static boost::asio::ip::udp::endpoint to_endpoint (
+ IPAddress const &address)
+ {
+ if (address.isV4 ())
+ {
+ return boost::asio::ip::udp::endpoint (
+ boost::asio::ip::address_v4 (
+ address.v4().value), address.port ());
+ }
+
+ // VFALCO TODO IPv6 support
+ bassertfalse;
+ return boost::asio::ip::udp::endpoint (
+ boost::asio::ip::address_v6 (), 0);
+ }
+
+public:
+ StatsDCollectorImp (
+ IPAddress const& address,
+ std::string const& prefix,
+ Journal journal)
+ : m_journal (journal)
+ , m_address (address)
+ , m_prefix (prefix)
+ , m_work (boost::ref (m_io_service))
+ , m_timer (m_io_service)
+ , m_socket (m_io_service)
+ , m_thread (&StatsDCollectorImp::run, this)
+ {
+ }
+
+ ~StatsDCollectorImp ()
+ {
+ boost::system::error_code ec;
+ m_timer.cancel (ec);
+
+ m_work = boost::none;
+ m_thread.join ();
+ }
+
+ Hook make_hook (HookImpl::HandlerType const& handler)
+ {
+ return Hook (beast::make_shared (
+ handler, shared_from_this ()));
+ }
+
+ Counter make_counter (std::string const& name)
+ {
+ return Counter (beast::make_shared (
+ name, shared_from_this ()));
+ }
+
+ Event make_event (std::string const& name)
+ {
+ return Event (beast::make_shared (
+ name, shared_from_this ()));
+ }
+
+ Gauge make_gauge (std::string const& name)
+ {
+ return Gauge (beast::make_shared (
+ name, shared_from_this ()));
+ }
+
+ Meter make_meter (std::string const& name)
+ {
+ return Meter (beast::make_shared (
+ name, shared_from_this ()));
+ }
+
+ //--------------------------------------------------------------------------
+
+ void add (StatsDMetricBase& metric)
+ {
+ State::Access state (m_state);
+ state->metrics.push_back (metric);
+ }
+
+ void remove (StatsDMetricBase& metric)
+ {
+ State::Access state (m_state);
+ state->metrics.erase (state->metrics.iterator_to (metric));
+ }
+
+ //--------------------------------------------------------------------------
+
+ boost::asio::io_service& get_io_service ()
+ {
+ return m_io_service;
+ }
+
+ std::string const& prefix () const
+ {
+ return m_prefix;
+ }
+
+ void do_post_buffer (std::string const& buffer)
+ {
+ m_journal.info <<
+ buffer;
+ m_data.emplace_back (buffer);
+ }
+
+ void post_buffer (std::string&& buffer)
+ {
+ m_io_service.dispatch (boost::bind (
+ &StatsDCollectorImp::do_post_buffer, this,
+ boost::move (buffer)));
+ }
+
+ void on_send (boost::system::error_code ec, std::size_t)
+ {
+ if (ec == boost::asio::error::operation_aborted)
+ return;
+
+ if (ec)
+ {
+ m_journal.error <<
+ "async_send failed: " << ec.message();
+ return;
+ }
+ }
+
+ // Send what we have
+ void send_buffers ()
+ {
+ // Break up the array of strings into blocks
+ // that each fit into one UDP packet.
+ //
+ boost::system::error_code ec;
+ std::vector buffers;
+ buffers.reserve (m_data.size ());
+ std::size_t size (0);
+ for (std::deque ::const_iterator iter (m_data.begin());
+ iter != m_data.end(); ++iter)
+ {
+ std::string const& buffer (*iter);
+ std::size_t const length (buffer.size ());
+ check_precondition (! buffer.empty ());
+ if (! buffers.empty () && (size + length) > max_packet_size)
+ {
+ m_socket.async_send (buffers, boost::bind (
+ &StatsDCollectorImp::on_send, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred));
+ buffers.clear ();
+ size = 0;
+ }
+ buffers.emplace_back (&buffer[0], length);
+ size += length;
+ }
+ if (! buffers.empty ())
+ {
+ m_socket.async_send (buffers, boost::bind (
+ &StatsDCollectorImp::on_send, this,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred));
+ }
+ m_data.clear ();
+ }
+
+ void set_timer ()
+ {
+ m_timer.expires_from_now (boost::posix_time::seconds (1));
+ m_timer.async_wait (boost::bind (
+ &StatsDCollectorImp::on_timer, this,
+ boost::asio::placeholders::error));
+ }
+
+ void on_timer (boost::system::error_code ec)
+ {
+ if (ec == boost::asio::error::operation_aborted)
+ return;
+
+ if (ec)
+ {
+ m_journal.error <<
+ "on_timer failed: " << ec.message();
+ return;
+ }
+
+ State::Access state (m_state);
+
+ for (List ::iterator iter (state->metrics.begin());
+ iter != state->metrics.end(); ++iter)
+ iter->do_process();
+
+ send_buffers ();
+
+ m_journal.info <<
+ "on_timer";
+
+ set_timer ();
+ }
+
+ void run ()
+ {
+ m_journal.sink().console (true);
+
+ boost::system::error_code ec;
+
+ if (m_socket.connect (to_endpoint (m_address), ec))
+ {
+ m_journal.error <<
+ "Connect failed: " << ec.message();
+ return;
+ }
+
+ set_timer ();
+
+ m_io_service.run ();
+
+ m_socket.shutdown (
+ boost::asio::ip::udp::socket::shutdown_send, ec);
+
+ m_socket.close ();
+
+ m_io_service.poll ();
+ }
+};
+
+//------------------------------------------------------------------------------
+
+StatsDHookImpl::StatsDHookImpl (HandlerType const& handler,
+ beast::shared_ptr const& impl)
+ : m_impl (impl)
+ , m_handler (handler)
+{
+ m_impl->add (*this);
+}
+
+StatsDHookImpl::~StatsDHookImpl ()
+{
+ m_impl->remove (*this);
+}
+
+void StatsDHookImpl::do_process ()
+{
+ m_handler ();
+}
+
+//------------------------------------------------------------------------------
+
+StatsDCounterImpl::StatsDCounterImpl (std::string const& name,
+ beast::shared_ptr const& impl)
+ : m_impl (impl)
+ , m_name (name)
+ , m_value (0)
+ , m_dirty (false)
+{
+ m_impl->add (*this);
+}
+
+StatsDCounterImpl::~StatsDCounterImpl ()
+{
+ m_impl->remove (*this);
+}
+
+void StatsDCounterImpl::increment (CounterImpl::value_type amount)
+{
+ m_impl->get_io_service().dispatch (boost::bind (
+ &StatsDCounterImpl::do_increment, this, amount, shared_from_this()));
+}
+
+void StatsDCounterImpl::set_handler (HandlerType const& handler)
+{
+ m_handler = handler;
+}
+
+void StatsDCounterImpl::flush ()
+{
+ if (m_dirty)
+ {
+ m_dirty = false;
+ std::stringstream ss;
+ ss <<
+ m_impl->prefix() << "." <<
+ m_name << ":" <<
+ m_value << "|c" <<
+ "\n";
+ m_value = 0;
+ m_impl->post_buffer (ss.str ());
+ }
+}
+
+void StatsDCounterImpl::do_increment (CounterImpl::value_type amount,
+ shared_ptr const&)
+{
+ m_value += amount;
+ m_dirty = true;
+}
+
+void StatsDCounterImpl::do_process ()
+{
+ if (m_handler)
+ m_handler (Counter (shared_from_this ()));
+ flush ();
+}
+
+//------------------------------------------------------------------------------
+
+StatsDEventImpl::StatsDEventImpl (std::string const& name,
+ beast::shared_ptr const& impl)
+ : m_impl (impl)
+ , m_name (name)
+{
+}
+
+StatsDEventImpl::~StatsDEventImpl ()
+{
+}
+
+void StatsDEventImpl::notify (EventImpl::value_type value)
+{
+ m_impl->get_io_service().dispatch (boost::bind (
+ &StatsDEventImpl::do_notify, this, value, shared_from_this()));
+}
+
+void StatsDEventImpl::do_notify (EventImpl::value_type value,
+ shared_ptr const&)
+{
+ std::stringstream ss;
+ ss <<
+ m_impl->prefix() << "." <<
+ m_name << ":" <<
+ value << "|ms" <<
+ "\n";
+ m_impl->post_buffer (ss.str ());
+}
+
+//------------------------------------------------------------------------------
+
+StatsDGaugeImpl::StatsDGaugeImpl (std::string const& name,
+ beast::shared_ptr const& impl)
+ : m_impl (impl)
+ , m_name (name)
+ , m_last_value (0)
+ , m_value (0)
+ , m_dirty (false)
+{
+ m_impl->add (*this);
+}
+
+StatsDGaugeImpl::~StatsDGaugeImpl ()
+{
+ m_impl->remove (*this);
+}
+
+void StatsDGaugeImpl::set (GaugeImpl::value_type value)
+{
+ m_impl->get_io_service().dispatch (boost::bind (
+ &StatsDGaugeImpl::do_set, this, value, shared_from_this ()));
+}
+
+void StatsDGaugeImpl::increment (GaugeImpl::difference_type amount)
+{
+ m_impl->get_io_service().dispatch (boost::bind (
+ &StatsDGaugeImpl::do_increment, this, amount, shared_from_this()));
+}
+
+void StatsDGaugeImpl::set_handler (HandlerType const& handler)
+{
+ m_handler = handler;
+}
+
+void StatsDGaugeImpl::flush ()
+{
+ if (m_dirty)
+ {
+ m_dirty = false;
+ std::stringstream ss;
+ ss <<
+ m_impl->prefix() << "." <<
+ m_name << ":" <<
+ m_value << "|c" <<
+ "\n";
+ m_impl->post_buffer (ss.str ());
+ }
+}
+
+void StatsDGaugeImpl::do_set (GaugeImpl::value_type value,
+ shared_ptr const&)
+{
+ m_value = value;
+
+ if (m_value != m_last_value)
+ {
+ m_last_value = m_value;
+ m_dirty = true;
+ }
+}
+
+void StatsDGaugeImpl::do_increment (GaugeImpl::difference_type amount,
+ shared_ptr const& ptr)
+{
+ GaugeImpl::value_type value (m_value);
+
+ if (amount > 0)
+ {
+ value +=
+ (amount >= std::numeric_limits ::max() - m_value)
+ ? std::numeric_limits ::max() - m_value
+ : GaugeImpl::value_type (amount);
+ }
+ else if (amount < 0)
+ {
+ value -=
+ (std::abs (amount) >= m_value)
+ ? m_value
+ : std::abs (amount);
+ }
+
+ do_set (value, ptr);
+}
+
+void StatsDGaugeImpl::do_process ()
+{
+ if (m_handler)
+ m_handler (Gauge (shared_from_this ()));
+ flush ();
+}
+
+//------------------------------------------------------------------------------
+
+StatsDMeterImpl::StatsDMeterImpl (std::string const& name,
+ beast::shared_ptr const& impl)
+ : m_impl (impl)
+ , m_name (name)
+ , m_value (0)
+ , m_dirty (false)
+{
+ m_impl->add (*this);
+}
+
+StatsDMeterImpl::~StatsDMeterImpl ()
+{
+ m_impl->remove (*this);
+}
+
+void StatsDMeterImpl::increment (MeterImpl::value_type amount)
+{
+ m_impl->get_io_service().dispatch (boost::bind (
+ &StatsDMeterImpl::do_increment, this, amount, shared_from_this()));
+}
+
+void StatsDMeterImpl::set_handler (HandlerType const& handler)
+{
+ m_handler = handler;
+}
+
+void StatsDMeterImpl::flush ()
+{
+ if (m_dirty)
+ {
+ m_dirty = false;
+ std::stringstream ss;
+ ss <<
+ m_impl->prefix() << "." <<
+ m_name << ":" <<
+ m_value << "|m" <<
+ "\n";
+ m_value = 0;
+ m_impl->post_buffer (ss.str ());
+ }
+}
+
+void StatsDMeterImpl::do_increment (MeterImpl::value_type amount,
+ shared_ptr const&)
+{
+ m_value += amount;
+ m_dirty = true;
+}
+
+void StatsDMeterImpl::do_process ()
+{
+ if (m_handler)
+ m_handler (Meter (shared_from_this ()));
+ flush ();
+}
+
+}
+
+//------------------------------------------------------------------------------
+
+shared_ptr StatsDCollector::New (
+ IPAddress const& address, std::string const& prefix, Journal journal)
+{
+ return beast::make_shared (
+ address, prefix, journal);
+}
+
+}
+}