JustEat.StatsD 5.0.0

The ID prefix of this package has been reserved for one of the owners of this package by NuGet.org. Prefix Reserved
.NET 6.0 .NET Standard 2.0 .NET Framework 4.6.2
dotnet add package JustEat.StatsD --version 5.0.0
NuGet\Install-Package JustEat.StatsD -Version 5.0.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="JustEat.StatsD" Version="5.0.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add JustEat.StatsD --version 5.0.0
#r "nuget: JustEat.StatsD, 5.0.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install JustEat.StatsD as a Cake Addin
#addin nuget:?package=JustEat.StatsD&version=5.0.0

// Install JustEat.StatsD as a Cake Tool
#tool nuget:?package=JustEat.StatsD&version=5.0.0


NuGet version Build status

codecov OpenSSF Scorecard


We use this library within our components to publish StatsD metrics from .NET code to a server. We've been using this in most of our things, since around 2013.

Supported platforms

JustEat.StatsD version 5.0.0 is built for these target frameworks:

  • net462
  • netstandard2.0
  • net6.0


  • Easy to use.
  • Robust and proven.
  • Tuned for high performance and low resource usage using BenchmarkDotNet. Typically zero allocation on sending a metric on target frameworks where Span<T> is available.
  • Works well with modern .NET apps - async ... await, .NET Core, .NET Standard 2.0.
  • Supports standard StatsD primitives: Increment, Decrement, Timing and Gauge.
  • Supports tagging on Increment, Decrement, Timing and Gauge.
  • Supports sample rate for cutting down of sends of high-volume metrics.
  • Helpers to make it easy to time a delegate such as a Func<T> or Action<T>, or a code block inside a using statement.
  • Send stats over UDP or IP.
  • Send stats to a server by name or IP address.
Publishing statistics

IStatsDPublisher is the interface that you will use to send stats. The concrete class that implements IStatsDPublisher is StatsDPublisher. The StatsDPublisher constructor takes an instance of StatsDConfiguration.

For the configuration's values, you will always need the StatsD server host name or IP address. Optionally, you can also change the port from the default (8125). You can also prepend a prefix to all stats. These values often come from configuration as the host name and/or prefix may vary between test and production environments.

It is best practice to create a StatsDPublisher at application start and use it for the lifetime of the application, instead of creating a new one for each usage.

Setting up StatsD

Simple example of setting up a StatsDPublisher

An example of a very simple StatsD publisher configuration, using the default values for most things.

.NET Core

Using IServiceCollection and the built-in DI container:

// Registration

// Consumption
public class MyService
    public MyService(IStatsDPublisher statsPublisher)
        // Use the publisher

Simplest example

No service registration or IoC. Works for both .NET Framework and .NET Core.

var statsDConfig = new StatsDConfiguration { Host = "metrics_server.mycompany.com" };
IStatsDPublisher statsDPublisher = new StatsDPublisher(statsDConfig);

IoC Examples

.NET (Core)

An example of registering StatsD dependencies using IServiceCollection:

    (provider) =>
        var options = provider.GetRequiredService<MyOptions>().StatsD;

        return new StatsDConfiguration()
            Host = options.HostName,
            Port = options.Port,
            Prefix = options.Prefix,
            OnError = ex => LogError(ex)
.NET Core (AWS Lambda functions)

An example of registering StatsD dependencies using IServiceCollection when using the IP transport, e.g. for an AWS Lambda function:

    (provider) =>
        var options = provider.GetRequiredService<MyOptions>().StatsD;

        return new StatsDConfiguration
            Prefix = options.Prefix,
            Host = options.HostName,
            SocketProtocol = SocketProtocol.IP
.NET Framework

An example of IoC in Ninject for StatsD publisher with values for all options, read from configuration:

// read config values from app settings
string statsdHostName =  ConfigurationManager.AppSettings["statsd.hostname"];
int statsdPort = int.Parse(ConfigurationManager.AppSettings["statsd.port"]);
string statsdPrefix =  ConfigurationManager.AppSettings["statsd.prefix"];

// assemble a StatsDConfiguration object
// since the configuration doesn't change for the lifetime of the app,
// it can be a preconfigured singleton instance
var statsDConfig = new StatsDConfiguration
  Host = statsdHostName,
  Port = statsdPort,
  Prefix = statsdPrefix,
  OnError = ex => LogError(ex)

// register with NInject

StatsDConfiguration fields

Name Type Default Comments
Host string The host name or IP address of the StatsD server. There is no default, this must be set.
Port int 8125 The StatsD port.
DnsLookupInterval TimeSpan? 5 minutes Length of time to cache the host name to IP address lookup. Only used when "Host" contains a host name.
Prefix string string.Empty Prepend a prefix to all stats.
SocketProtocol SocketProtocol, one of Udp, IP Udp Type of socket to use when sending stats to the server.
TagsFormatter IStatsDTagsFormatter NoOpTagsFormatter Format used for tags for the different providers. Out-of-the-box formatters can be accessed using the TagsFormatter class.
OnError Func<Exception, bool> null Function to receive notification of any exceptions.

OnError is a function to receive notification of any errors that occur when trying to publish a metric. This function should return:

  • true if the exception was handled and no further action is needed
  • false if the exception should be thrown

The default behaviour is to ignore the error.

Tagging support

Tags or dimensions are not covered by the StatsD specification. Providers supporting tags have implemented their own flavours. Some of the major providers are supported out-of-the-box from 5.0.0+ are:

var config = new StatsDConfiguration
    Prefix = "prefix",
    Host = "",
    TagsFormatter = TagsFormatter.CloudWatch,
Extending tags formatter

As tags are not part of the StatsD specification, the IStatsDTagsFormatter used can be extended and specified by the StatsDConfiguration.

The template class StatsDTagsFormatter can be inherited from providing the StatsDTagsFormatterConfiguration:

  • Prefix: the string that will appear before the tag(s).
  • Suffix: the string that will appear after the tag(s).
  • AreTrailing: a boolean indicating if the tag(s) are placed at the end of the StatsD message (like it is supported by AWS CloudWatch, DataDog and Splunk) or otherwise they are right after the bucket name (like it is supported by InfluxDB, Librato and SignalFX).
  • TagsSeparator: the string that will be placed between tags.
  • KeyValueSeparator: the string that will be placed between the tag key and its value.

Example of using the interface

Given an existing instance of IStatsDPublisher called stats you can do for e.g.:

var stopWatch = Stopwatch.StartNew();
var success = DoSomething();


var statName = "DoSomething." + success ? "Success" : "Failure";
stats.Timing(statName, stopWatch.Elapsed);

Simple timers

This syntax for timers less typing in simple cases, where you always want to time the operation, and always with the same stat name. Given an existing instance of IStatsDPublisher you can do:

//  timing a block of code in a using statement:
using (stats.StartTimer("someStat"))

// also works with async
using (stats.StartTimer("someStat"))
    await DoSomethingAsync();

The StartTimer returns an IDisposableTimer that wraps a stopwatch and implements IDisposable. The stopwatch is automatically stopped and the metric sent when it falls out of scope and is disposed on the closing } of the using statement.

Changing the name of simple timers

Sometimes the decision of which stat to send should not be taken before the operation completes. e.g. When you are timing http operations and want different status codes to be logged under different stats.

The IDisposableTimer has a Bucket property to set or change the stat bucket - i.e. the name of the stat. To use this you need a reference to the timer, e.g. using (var timer = stats.StartTimer("statName")) instead of using (stats.StartTimer("statName"))

The stat name must be set to a non-empty string at the end of the using block.

using (var timer = stats.StartTimer("SomeHttpOperation."))
    var response = DoSomeHttpOperation();
    timer.Bucket = timer.Bucket + (int)response.StatusCode;
    return response;
Functional style
//  timing an action without a return value:
stats.Time("someStat", t => DoSomething());

//  timing a function with a return value:
var result = stats.Time("someStat", t => GetSomething());

// and it correctly times async code using the usual syntax:
await stats.Time("someStat", async t => await DoSomethingAsync());
var result = await stats.Time("someStat", async t => await GetSomethingAsync());

In all these cases the function or delegate is supplied with an IDisposableTimer t so that the stat name can be changed if need be.


The idea of "disposable timers" for using statements is an old one, see for example this StatsD client and MiniProfiler.

How to contribute


How to release


Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 is compatible.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Additional computed target framework(s)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (6)

Showing the top 5 NuGet packages that depend on JustEat.StatsD:

Package Downloads

Purplebricks message subscriber infrastructure: StatsD Monitoring Behaviour

Akka.Monitoring.StatsD The ID prefix of this package has been reserved for one of the owners of this package by NuGet.org.

StatsD monitoring support for Akka.NET actors.


Package Description


Drop in exception stats and logging for webapi


Embedding tests into applications to execute at run-time.

GitHub repositories (2)

Showing the top 2 popular GitHub repositories that depend on JustEat.StatsD:

Repository Stars
Bringing Azure Monitor metrics where you need them.
Monitoring system instrumentation for Akka.NET actor systems
Version Downloads Last updated
5.0.0 98 12/5/2023
4.2.0 1,553,914 11/10/2020
4.1.0 586,402 10/11/2019
4.0.1 348,398 4/8/2019
4.0.0 201,136 1/21/2019
4.0.0-beta01 1,008 12/18/2018
3.2.2 127,751 10/8/2018
3.2.1 2,313 10/3/2018
3.2.0 1,001 10/2/2018
3.1.1 17,683 8/6/2018
3.1.0-beta01 868 8/1/2018
3.0.0 34,417 6/20/2018
2.1.0 22,690 3/6/2018
2.0.0 12,406 2/22/2018
1.1.0 69,399 3/8/2017 157,992 2/26/2016 5,189 10/28/2015 1,639 10/28/2015 39,886 7/24/2015 2,821 7/24/2015 1,856 7/22/2015