Metrics

The driver exposes measurements of its internal behavior through an API composed by abstractions. The client application must provide an implementation of these abstractions (IDriverMetricsProvider) in order to enable metrics.

DataStax offers an Extension package based on the App.Metrics library. Application developers can use App.Metrics to export metrics to a monitoring tool.

Structure

There are two categories of metrics:

  • session-level: the measured data is global to a Session instance. For example, connected-nodes measures the number of nodes to which we have connections.
  • node-level: the data is specific to a node (and therefore there is one metric instance per node). For example, pool.open-connections measures the number of connections open to this particular node.

Metric names are path-like, dot-separated strings. An example is errors.connection.init. Metrics are represented by the classes SessionMetric and NodeMetric. These classes have public static readonly properties with all individual metrics that can be enabled on the driver. For instance, NodeMetric.Counters.ConnectionInitErrors is a NodeMetric object with a Name property that returns errors.connection.init.

Metrics are grouped into buckets and each bucket has a name. The most common scenario is to concatenate the bucket name with the metric name which is what the App.Metrics provider does. The bucket name is the name of the session (see DseClusterBuilder.WithSessionName()) and, in the case of node-level metrics, nodes followed by a textual representation of the node’s address. If the client application specifies a bucket prefix with DriverMetricsOptions.SetBucketPrefix(), the driver will prepend that prefix to the bucket name.

Here is an example of a session metric and a node metric without a bucket prefix and how their structure looks like:

Bucket Name Metric
s0 connected-nodes SessionMetric.Gauges.ConnectedNodes
s0.nodes.127_0_0_1:9042 pool.open-connections NodeMetric.Gauges.OpenConnections

Here are the same examples but with a bucket prefix set in the Builder:

Bucket Name Metric
prefix.s0 connected-nodes SessionMetric.Gauges.ConnectedNodes
prefix.s0.nodes.127_0_0_1:9042 pool.open-connections NodeMetric.Gauges.OpenConnections

Configuration

Metrics are disabled by default. To enable them, use DseClusterBuilder.WithMetrics() method when creating the session.

When DseClusterBuilder.WithMetrics(provider) is called, the default metrics will be enabled. The default metrics are composed of every metric except those of type Timer. The reasoning behind this is the fact that enabling Timer metrics might increase CPU usage and impact throughput of the driver, so it’s recommended to benchmark the client application with Timer metrics enabled before enabling them in production.

DseClusterBuilder.WithMetrics(IDriverMetricsProvider,DriverMetricsOptions) can be used to customize options related to metrics. DriverMetricsOptions.SetEnabledNodeMetrics() and DriverMetricsOptions.SetEnabledSessionMetrics() can be used to specify which metrics should be enabled. Note that this will override the default enabled metrics, i.e., if you want to enable Timer metrics on top of the default metrics then all metrics must be specified. SessionMetric and NodeMetric have a couple of static properties to make it easier to specify which metrics to enable. Here are some examples:

// Enable all session metrics
builder.WithMetrics(provider, new DriverMetricsOptions().SetEnabledSessionMetrics(SessionMetric.AllSessionMetrics));

// Enable default session metrics (same effect as not calling the method at all)
builder.WithMetrics(provider, new DriverMetricsOptions().SetEnabledSessionMetrics(SessionMetric.DefaultSessionMetrics));

// Enable default session metrics except "bytes-sent", using LINQ
builder.WithMetrics(provider, new DriverMetricsOptions()
    .SetEnabledSessionMetrics(SessionMetric.DefaultSessionMetrics.Except(new [] { SessionMetric.Meters.BytesSent })));

// Enable default session metrics and 'cql-requests' timer metric, using LINQ
builder.WithMetrics(provider, new DriverMetricsOptions()
    .SetEnabledSessionMetrics(SessionMetric.DefaultSessionMetrics.Union(new [] { SessionMetric.Timers.CqlRequests })));

DriverMetricsOptions.SetBucketPrefix can be used to specify a custom prefix to be added to the bucket name of every metric. See the previous section for information about his.

The provider parameter must be an implementation of IDriverMetricsProvider. As was mentioned previouly, DataStax offers an App.Metrics based implementation on a separate extension nuget package.

Exporting metrics

With our App.Metrics provider, you can use the features offered by App.Metrics to export metrics. There are several reporter plugins that extend App.Metrics and these are available usually as nuget packages. For more information, see the manual section related to this provider.

Retrieving metrics

The driver exposes an API to retrieve metrics but this API consists of mostly abstractions. The available methods on each metric type will depend on the provider that is used (if the provider exposes such methods).

Note that if you are using our App.Metrics provider, you most likely don’t need this API since App.Metrics offers built in reporters that export metrics to technologies like Graphite, InfluxDB, Elasticsearch and many others.

Generic API for retrieving metrics

Here is an example of the generic API available no matter what provider is used:

// Get metrics object
IDriverMetrics metrics = session.GetMetrics();

// Get session metrics and / or node metrics
IReadOnlyDictionary<Host, IMetricsRegistry<NodeMetric>> allNodeMetrics = metrics.NodeMetrics;
IMetricsRegistry<SessionMetric> sessionMetrics = metrics.SessionMetrics;

// Get specific host's node metrics
Host host = session.Cluster.AllHosts().First();
allNodeMetrics.TryGetValue(host, out IMetricsRegistry<NodeMetric> nodeMetrics);

// Get a specific metric of a specific host
IDriverMeter counter = metrics.GetNodeMetric<IDriverCounter>(host, NodeMetric.Counters.Errors);

Note that the driver’s interface of each metric type is empty. This api exists to expose the metric implementations created by the metrics provider. You can set the generic parameter of the GetNodeMetric method to the provider’s implementation type like the next section shows (with AppMetrics).

Extension methods available in the DataStax provider based on AppMetrics

Refer to the manual section related to this provider for more information.

Here is a small example on how to use the provider extensions to retrieve metrics:

// Get a specific metric of a specific host using the generic registry and converting it to the provider's type
IAppMetricsTimer cqlMessagesMetric = nodeMetrics.Timers[NodeMetric.Counters.Errors].ToAppMetricsTimer();

// Get a specific metric of a specific host (requires AppMetrics Provider)
IAppMetricsCounter counterAppMetrics = metrics.GetNodeMetric<IAppMetricsCounter>(host, NodeMetric.Counters.Errors);

// Get a specific metric of a specific host with AppMetrics extension method
IAppMetricsCounter counterAppMetrics = metrics.GetNodeCounter(host, NodeMetric.Counters.Errors);

// Get value of that metric (IAppMetricsCounter provides a GetValue() method)
long bytesSent = counterAppMetrics.GetValue();

Providing your own implementation of IDriverMetricsProvider

There is no specific requirement for the implementation but note that the performance of the methods declared in IDriverMetricsProvider will affect the performance of the driver if metrics are enabled.

The instances returned by the IDriverMetricsProvider methods will be exposed by the generic API described in the previous section.