Skip to content
14 changes: 7 additions & 7 deletions docs/configuration/cluster_manager/cluster_stats.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ Every cluster has a statistics tree rooted at *cluster.<name>.* with the followi
upstream_cx_connect_fail, Counter, Total connection failures
upstream_cx_connect_timeout, Counter, Total connection timeouts
upstream_cx_overflow, Counter, Total times that the cluster's connection circuit breaker overflowed
upstream_cx_connect_ms, Timer, Connection establishment milliseconds
upstream_cx_length_ms, Timer, Connection length milliseconds
upstream_cx_connect_ms, Histogram, Connection establishment milliseconds
upstream_cx_length_ms, Histogram, Connection length milliseconds
upstream_cx_destroy, Counter, Total destroyed connections
upstream_cx_destroy_local, Counter, Total connections destroyed locally
upstream_cx_destroy_remote, Counter, Total connections destroyed remotely
Expand Down Expand Up @@ -120,16 +120,16 @@ are rooted at *cluster.<name>.* and contain the following statistics:

upstream_rq_<\*xx>, Counter, "Aggregate HTTP response codes (e.g., 2xx, 3xx, etc.)"
upstream_rq_<\*>, Counter, "Specific HTTP response codes (e.g., 201, 302, etc.)"
upstream_rq_time, Timer, Request time milliseconds
upstream_rq_time, Histogram, Request time milliseconds
canary.upstream_rq_<\*xx>, Counter, Upstream canary aggregate HTTP response codes
canary.upstream_rq_<\*>, Counter, Upstream canary specific HTTP response codes
canary.upstream_rq_time, Timer, Upstream canary request time milliseconds
canary.upstream_rq_time, Histogram, Upstream canary request time milliseconds
internal.upstream_rq_<\*xx>, Counter, Internal origin aggregate HTTP response codes
internal.upstream_rq_<\*>, Counter, Internal origin specific HTTP response codes
internal.upstream_rq_time, Timer, Internal origin request time milliseconds
internal.upstream_rq_time, Histogram, Internal origin request time milliseconds
external.upstream_rq_<\*xx>, Counter, External origin aggregate HTTP response codes
external.upstream_rq_<\*>, Counter, External origin specific HTTP response codes
external.upstream_rq_time, Timer, External origin request time milliseconds
external.upstream_rq_time, Histogram, External origin request time milliseconds

.. _config_cluster_manager_cluster_stats_alt_tree:

Expand All @@ -156,7 +156,7 @@ Envoy will track the following statistics in *cluster.<name>.zone.<from_zone>.<t

upstream_rq_<\*xx>, Counter, "Aggregate HTTP response codes (e.g., 2xx, 3xx, etc.)"
upstream_rq_<\*>, Counter, "Specific HTTP response codes (e.g., 201, 302, etc.)"
upstream_rq_time, Timer, Request time milliseconds
upstream_rq_time, Histogram, Request time milliseconds

Load balancer statistics
------------------------
Expand Down
4 changes: 2 additions & 2 deletions docs/configuration/http_conn_man/stats.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ statistics:
downstream_cx_websocket_active, Gauge, Total active WebSocket connections
downstream_cx_http2_active, Gauge, Total active HTTP/2 connections
downstream_cx_protocol_error, Counter, Total protocol errors
downstream_cx_length_ms, Timer, Connection length milliseconds
downstream_cx_length_ms, Histogram, Connection length milliseconds
downstream_cx_rx_bytes_total, Counter, Total bytes received
downstream_cx_rx_bytes_buffered, Gauge, Total received bytes currently buffered
downstream_cx_tx_bytes_total, Counter, Total bytes sent
Expand All @@ -50,7 +50,7 @@ statistics:
downstream_rq_4xx, Counter, Total 4xx responses
downstream_rq_5xx, Counter, Total 5xx responses
downstream_rq_ws_on_non_ws_route, Counter, Total WebSocket upgrade requests rejected by non WebSocket routes
downstream_rq_time, Timer, Request time milliseconds
downstream_rq_time, Histogram, Request time milliseconds
rs_too_large, Counter, Total response errors due to buffering an overly large body.

Per user agent statistics
Expand Down
8 changes: 4 additions & 4 deletions docs/configuration/http_filters/dynamodb_filter.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ namespace.
:widths: 1, 1, 2

upstream_rq_total, Counter, Total number of requests with <operation_name>
upstream_rq_time, Timer, Time spent on <operation_name>
upstream_rq_time, Histogram, Time spent on <operation_name>
upstream_rq_total_xxx, Counter, Total number of requests with <operation_name> per response code (503/2xx/etc)
upstream_rq_time_xxx, Timer, Time spent on <operation_name> per response code (400/3xx/etc)
upstream_rq_time_xxx, Histogram, Time spent on <operation_name> per response code (400/3xx/etc)

Per table stats can be found in the *http.<stat_prefix>.dynamodb.table.<table_name>.* namespace.
Most of the operations to DynamoDB involve a single table, but BatchGetItem and BatchWriteItem can
Expand All @@ -46,9 +46,9 @@ in all operations from the batch.
:widths: 1, 1, 2

upstream_rq_total, Counter, Total number of requests on <table_name> table
upstream_rq_time, Timer, Time spent on <table_name> table
upstream_rq_time, Histogram, Time spent on <table_name> table
upstream_rq_total_xxx, Counter, Total number of requests on <table_name> table per response code (503/2xx/etc)
upstream_rq_time_xxx, Timer, Time spent on <table_name> table per response code (400/3xx/etc)
upstream_rq_time_xxx, Histogram, Time spent on <table_name> table per response code (400/3xx/etc)

*Disclaimer: Please note that this is a pre-release Amazon DynamoDB feature that is not yet widely available.*
Per partition and operation stats can be found in the *http.<stat_prefix>.dynamodb.table.<table_name>.*
Expand Down
2 changes: 1 addition & 1 deletion docs/configuration/http_filters/router_filter.rst
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ statistics:

upstream_rq_<\*xx>, Counter, "Aggregate HTTP response codes (e.g., 2xx, 3xx, etc.)"
upstream_rq_<\*>, Counter, "Specific HTTP response codes (e.g., 201, 302, etc.)"
upstream_rq_time, Timer, Request time milliseconds
upstream_rq_time, Histogram, Request time milliseconds

Runtime
-------
Expand Down
2 changes: 1 addition & 1 deletion docs/configuration/listeners/stats.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Every listener has a statistics tree rooted at *listener.<port>.* with the follo
downstream_cx_total, Counter, Total connections
downstream_cx_destroy, Counter, Total destroyed connections
downstream_cx_active, Gauge, Total active connections
downstream_cx_length_ms, Timer, Connection length milliseconds
downstream_cx_length_ms, Histogram, Connection length milliseconds
ssl.connection_error, Counter, Total TLS connection errors not including failed certificate verifications
ssl.handshake, Counter, Total successful TLS connection handshakes
ssl.no_certificate, Counter, Total successul TLS connections with no client certificate
Expand Down
4 changes: 2 additions & 2 deletions docs/configuration/network_filters/mongo_proxy_filter.rst
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ namespace.
total, Counter, Number of commands
reply_num_docs, Histogram, Number of documents in reply
reply_size, Histogram, Size of the reply in bytes
reply_time_ms, Timer, Command time in milliseconds
reply_time_ms, Histogram, Command time in milliseconds

.. _config_network_filters_mongo_proxy_collection_stats:

Expand All @@ -147,7 +147,7 @@ The MongoDB filter will gather statistics for queries in the
multi_get, Counter, Number of multi gets
reply_num_docs, Histogram, Number of documents in reply
reply_size, Histogram, Size of the reply in bytes
reply_time_ms, Timer, Query time in milliseconds
reply_time_ms, Histogram, Query time in milliseconds

.. _config_network_filters_mongo_proxy_callsite_stats:

Expand Down
4 changes: 3 additions & 1 deletion docs/intro/arch_overview/statistics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ documented in detail in the operations guide.

Envoy uses statsd as the statistics output format, though plugging in a different statistics sink
would not be difficult. Both TCP and UDP statsd is supported. Internally, counters and gauges are
batched and periodically flushed to improve performance. Timers are written as they are received.
batched and periodically flushed to improve performance. Histograms are written as they are
received. Note: what were previously referred to as timers have become histograms as the only
difference between the two representations was the units.

Statistics :ref:`configuration <config_overview>`.
8 changes: 4 additions & 4 deletions docs/operations/admin.rst
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ The fields are:

.. http:get:: /stats

Outputs all statistics on demand. This includes only counters and gauges. Timers are not output as
Envoy currently has no built in histogram support and relies on statsd for timer aggregation. This
command is very useful for local debugging. See :ref:`here <operations_stats>` for more
information.
Outputs all statistics on demand. This includes only counters and gauges. Histograms are not
output as Envoy currently has no built in histogram support and relies on statsd for
aggregation. This command is very useful for local debugging. See :ref:`here <operations_stats>`
for more information.
9 changes: 9 additions & 0 deletions include/envoy/stats/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ envoy_cc_library(
hdrs = ["stats.h"],
)

envoy_cc_library(
name = "timespan",
hdrs = ["timespan.h"],
deps = [
":stats_interface",
"//include/envoy/common:time_interface",
],
)

envoy_cc_library(
name = "stats_macros",
hdrs = ["stats_macros.h"],
Expand Down
85 changes: 34 additions & 51 deletions include/envoy/stats/stats.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,79 +19,72 @@ class Instance;

namespace Stats {

/**
* General interface for all stats objects.
*/
class Metric {
public:
virtual ~Metric() {}
/**
* Returns the full name of the Metric.
*/
virtual const std::string& name() const PURE;
};

/**
* An always incrementing counter with latching capability. Each increment is added both to a
* global counter as well as periodic counter. Calling latch() returns the periodic counter and
* clears it.
*/
class Counter {
class Counter : public virtual Metric {
public:
virtual ~Counter() {}
virtual void add(uint64_t amount) PURE;
virtual void inc() PURE;
virtual uint64_t latch() PURE;
virtual std::string name() PURE;
virtual void reset() PURE;
virtual bool used() PURE;
virtual uint64_t value() PURE;
virtual bool used() const PURE;
virtual uint64_t value() const PURE;
};

typedef std::shared_ptr<Counter> CounterSharedPtr;

/**
* A gauge that can both increment and decrement.
*/
class Gauge {
class Gauge : public virtual Metric {
public:
virtual ~Gauge() {}

virtual void add(uint64_t amount) PURE;
virtual void dec() PURE;
virtual void inc() PURE;
virtual std::string name() PURE;
virtual void set(uint64_t value) PURE;
virtual void sub(uint64_t amount) PURE;
virtual bool used() PURE;
virtual uint64_t value() PURE;
virtual bool used() const PURE;
virtual uint64_t value() const PURE;
};

typedef std::shared_ptr<Gauge> GaugeSharedPtr;

/**
* An individual timespan that is owned by a timer. The initial time is captured on construction.
* A timespan must be completed via complete() for it to be stored. If the timespan is deleted
* this will be treated as a cancellation.
* A histogram that records values one at a time.
* Note: Histograms now incorporate what used to be timers because the only difference between the
* two stat types was the units being represented. It is assumed that no downstream user of this
* class (Sinks, in particular) will need to explicitly differentiate between histograms
* representing durations and histograms representing other types of data.
*/
class Timespan {
class Histogram : public virtual Metric {
public:
virtual ~Timespan() {}

/**
* Complete the span using the default name of the timer that the span was allocated from.
*/
virtual void complete() PURE;
virtual ~Histogram() {}

/**
* Complete the span using a dynamic name. This is useful if a span needs to get counted
* against a timer with a dynamic name.
* Records an unsigned value. If a timer, values are in units of milliseconds.
*/
virtual void complete(const std::string& dynamic_name) PURE;
virtual void recordValue(uint64_t value) PURE;
};

typedef std::unique_ptr<Timespan> TimespanPtr;

/**
* A timer that can capture timespans.
*/
class Timer {
public:
virtual ~Timer() {}

virtual TimespanPtr allocateSpan() PURE;
virtual std::string name() PURE;
};

typedef std::shared_ptr<Timer> TimerSharedPtr;
typedef std::shared_ptr<Histogram> HistogramSharedPtr;

/**
* A sink for stats. Each sink is responsible for writing stats to a backing store.
Expand All @@ -109,12 +102,12 @@ class Sink {
/**
* Flush a counter delta.
*/
virtual void flushCounter(const std::string& name, uint64_t delta) PURE;
virtual void flushCounter(const Counter& counter, uint64_t delta) PURE;

/**
* Flush a gauge value.
*/
virtual void flushGauge(const std::string& name, uint64_t value) PURE;
virtual void flushGauge(const Gauge& gauge, uint64_t value) PURE;

/**
* This will be called after beginFlush(), some number of flushCounter(), and some number of
Expand All @@ -125,12 +118,7 @@ class Sink {
/**
* Flush a histogram value.
*/
virtual void onHistogramComplete(const std::string& name, uint64_t value) PURE;

/**
* Flush a timespan value.
*/
virtual void onTimespanComplete(const std::string& name, std::chrono::milliseconds ms) PURE;
virtual void onHistogramComplete(const Histogram& histogram, uint64_t value) PURE;
};

typedef std::unique_ptr<Sink> SinkPtr;
Expand All @@ -157,12 +145,7 @@ class Scope {
/**
* Deliver an individual histogram value to all registered sinks.
*/
virtual void deliverHistogramToSinks(const std::string& name, uint64_t value) PURE;

/**
* Deliver an individual timespan completion to all registered sinks.
*/
virtual void deliverTimingToSinks(const std::string& name, std::chrono::milliseconds ms) PURE;
virtual void deliverHistogramToSinks(const Histogram& histogram, uint64_t value) PURE;

/**
* @return a counter within the scope's namespace.
Expand All @@ -175,9 +158,9 @@ class Scope {
virtual Gauge& gauge(const std::string& name) PURE;

/**
* @return a timer within the scope's namespace.
* @return a histogram within the scope's namespace with a particular value type.
*/
virtual Timer& timer(const std::string& name) PURE;
virtual Histogram& histogram(const std::string& name) PURE;
};

/**
Expand Down
14 changes: 7 additions & 7 deletions include/envoy/stats/stats_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,33 @@ namespace Envoy {
* is also easy to mock and test. The general flow looks like this:
*
* Define a block of stats like this:
* #define MY_COOL_STATS(COUNTER, GAUGE, TIMER) \
* #define MY_COOL_STATS(COUNTER, GAUGE, HISTOGRAM) \
* COUNTER(counter1)
* GAUGE(gauge1)
* TIMER(timer1)
* HISTOGRAM(histogram1)
* ...
*
* Now actually put these stats somewhere, usually as a member of a struct:
* struct MyCoolStats {
* MY_COOL_STATS(GENERATE_COUNTER_STRUCT, GENERATE_GAUGE_STRUCT, GENERATE_TIMER_STRUCT)
* MY_COOL_STATS(GENERATE_COUNTER_STRUCT, GENERATE_GAUGE_STRUCT, GENERATE_HISTOGRAM_STRUCT)
* };
*
* Finally, when you want to actually instantiate the above struct using a Stats::Pool, you do:
* MyCoolStats stats{
* MY_COOL_STATS(POOL_COUNTER(...), POOL_GAUGE(...), POOL_TIMER(...))};
* MY_COOL_STATS(POOL_COUNTER(...), POOL_GAUGE(...), POOL_HISTOGRAM(...))};
*/

#define GENERATE_COUNTER_STRUCT(NAME) Stats::Counter& NAME##_;
#define GENERATE_GAUGE_STRUCT(NAME) Stats::Gauge& NAME##_;
#define GENERATE_TIMER_STRUCT(NAME) Stats::Timer& NAME##_;
#define GENERATE_HISTOGRAM_STRUCT(NAME) Stats::Histogram& NAME##_;

#define FINISH_STAT_DECL_(X) + std::string(#X)),

#define POOL_COUNTER_PREFIX(POOL, PREFIX) (POOL).counter(PREFIX FINISH_STAT_DECL_
#define POOL_GAUGE_PREFIX(POOL, PREFIX) (POOL).gauge(PREFIX FINISH_STAT_DECL_
#define POOL_TIMER_PREFIX(POOL, PREFIX) (POOL).timer(PREFIX FINISH_STAT_DECL_
#define POOL_HISTOGRAM_PREFIX(POOL, PREFIX) (POOL).histogram(PREFIX FINISH_STAT_DECL_

#define POOL_COUNTER(POOL) POOL_COUNTER_PREFIX(POOL, "")
#define POOL_GAUGE(POOL) POOL_GAUGE_PREFIX(POOL, "")
#define POOL_TIMER(POOL) POOL_TIMER_PREFIX(POOL, "")
#define POOL_HISTOGRAM(POOL) POOL_HISTOGRAM_PREFIX(POOL, "")
} // Envoy
Loading