• Stars
    star
    136
  • Rank 267,670 (Top 6 %)
  • Language
    C#
  • License
    MIT License
  • Created almost 10 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A .NET client to send metrics to a variety of metrics backends

StackExchange.Metrics

Build status

A thread-safe C# .NET client for reporting metrics to various providers, including Bosun (Time Series Alerting Framework) and SignalFx. This library is more than a simple wrapper around relevant APIs. It is designed to encourage best-practices while making it easy to create counters and gauges, including multi-aggregate gauges. It automatically reports metrics on an interval and handles temporary API or network outages using a re-try queue.

VIEW CHANGES IN StackExchange.Metrics 2.0

Package Status

MyGet Pre-release feed: https://www.myget.org/gallery/stackoverflow

Package NuGet Stable NuGet Pre-release Downloads MyGet
StackExchange.Metrics StackExchange.Metrics StackExchange.Metrics StackExchange.Metrics StackExchange.Metrics MyGet

Basic Usage

.NET Full Framework

First, create a MetricsCollector object. This is the top-level container which will hold all of your metrics and handle sending them to various metric endpoints. Therefore, you should only instantiate one, and make it a global singleton.

public class AppMetricSource : MetricSource
{
    public static readonly MetricSourceOptions Options = new MetricSourceOptions
    {
        DefaultTags = 
        {
            ["host"]  = Environment.MachineName
        }
    };

    public AppMetricSource() : base(Options)
    {
    }
}

var collector = new MetricsCollector(
    new MetricsCollectorOptions
    {
        ExceptionHandler = ex => HandleException(ex),
	    Endpoints = new[] {
		    new MetricEndpoint("Bosun", new BosunMetricHandler(new Uri("http://bosun.mydomain.com:8070"))),
		    new MetricEndpoint("SignalFx", new SignalFxMetricHandler(new Uri("https://mydomain.signalfx.com/api", "API_KEY"))),
	    },
        Sources =  new[] {
            new GarbageCollectorMetricSource(AppMetricSource.DefaultOptions), 
            new ProcessMetricSource(AppMetricSource.DefaultOptions), 
            new AppMetricSource() 
        }
    }
);

// start the collector; it'll start sending metrics
collector.Start();

// ...

// and then, during application shutdown, stop the collector
collector.Stop();

.NET Core

For .NET Core, you can configure a MetricsCollector in your Startup.cs.

Using the snippet below will register an IHostedService in the service collection that manages the lifetime of the MetricsCollector and configures it with the specified endpoints and metric sources.

public class AppMetricSource : MetricSource
{
    public AppMetricSource(MetricSourceOptions options) : base(options)
    {
    }
}

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMetricsCollector()
            // configure things like default tags
            .ConfigureSources(
                o =>
                {
                    // NOTE: default tags include the host name by default
                    p.DefaultTags.Add("tier", "dev");
                }
            )
            // add common metric sources
            // that includes ProcessMetricSource, AspNetMetricSource & RuntimeMetricSource
            .AddDefaultSources()
            // and then add our application-specific metric source
            .AddSource<AppMetricSource>()
            // add endpoints we care about. By default we add a `LocalMetricHandler` that 
            // just maintains the latest metrics in memory (useful for debugging)
            .AddBosunEndpoint(new Uri("http://bosun.mydomain.com:8070"))
            .AddSignalFxEndpoint(new Uri("https://mydomain.signalfx.com/api", "API_KEY"))
            .UseExceptionHandler(ex => HandleException(ex))
            // tweak other options in of `MetricsCollectionOptions`
            .Configure(
                o => {
                    o.SnapshotInterval = TimeSpan.FromSeconds(5);
                }
            )
    }
}

All of the available options are documented in the MetricCollectorOptions class or the individual metric handlers:

Metrics are configured in a MetricSource. Using our AppMetricSource above:

Create a counter with only the default tags:

public class AppMetricSource : MetricSource
{
    public Counter MyCounter { get; }
    
    public AppMetricSource(MetricSourceOptions options) : base(options)
    {
        MyCounter = AddCounter("my_counter", "units", "description");
    }
}

Increment the counter by 1:

appSource.MyCounter.Increment();

Using Tags

Tags are used to subdivide data in various metric platforms. In StackExchange.Metrics, tags are by specifying additional arguments when creating a metric. For example:

public class AppMetricSource : MetricSource
{
    public Counter<string> MyCounterWithTag { get; }
    
    public AppMetricSource(MetricSourceOptions options) : base(options)
    {
        MyCounterWithTag = AddCounter("my_counter", "units", "description", new MetricTag<string>("some_tag"));
    }
}

Incrementing that counter works exactly the same as incrementing a counter without tags, but we need to specify the values:

appSource.MyCounter.Increment("tag_value");

For more details, see the Tags Documentation.

Metric Types

There are two high-level metric types: counters and gauges.

Counters are for counting things. The most common use case is to increment a counter each time an event occurs. Many metric platforms normalize this data and is able to show you a rate (events per second) in the graphing interface. StackExchange.Metrics has two built-in counter types.

Name Description
Counter A general-purpose manually incremented long-integer counter.
SnapshotCounter Calls a user-provided Func<long?> to get the current counter value each time metrics are going to be posted to a metric handler.
CumulativeCounter A persistent counter (no resets) for very low-volume events.

Gauges describe a measurement at a point in time. A good example would be measuring how much RAM is being consumed by a process. StackExchange.Metrics provides several different built-in types of gauges in order to support different programmatic use cases.

Name Description
SnapshotGauge Similar to a SnapshotCounter, it calls a user provided Func<double?> to get the current gauge value each time metrics are going to be posted to the metrics handlers.
EventGauge Every data point is sent to the metrics handlers. Good for low-volume events.
AggregateGauge Aggregates data points (min, max, avg, median, etc) before sending them to the metrics handlers. Good for recording high-volume events.
SamplingGauge Record as often as you want, but only the last value recorded before the reporting interval is sent to the metrics handlers (it samples the current value).

If none of the built-in metric types meet your specific needs, it's easy to create your own.

Metric Sources

Metric sets are pre-packaged sources of metrics that are useful across different applications. See Documentation for further details.

Implementation Notes

Periodically a MetricsCollector instance serializes all the metrics from the sources attached to it. When it does so it serially calls WriteReadings on each metric. WriteValue uses an IMetricBatch to assist in writing metrics into an endpoint-defined format using an implementation of IBufferWriter<byte> for buffering purposes.

For each type of payload that can be sent to an endpoint an IBufferWriter<byte> is created that manages an underlying buffer consisting of zero or more contiguous byte arrays.

At a specific interval the MetricsCollector flushes all metrics that have been serialized into the IBufferWriter<byte> to the underlying transport implemented by an endpoint (generally an HTTP JSON API or statsd UDP endpoint). Once flushed the associated buffer is released back to be used by the next batch of metrics being serialized. This keeps memory allocations low.

More Repositories

1

blackbox

Safely store secrets in Git/Mercurial/Subversion
Go
6,670
star
2

StackExchange.Redis

General purpose redis client
C#
5,889
star
3

dnscontrol

Infrastructure as code for DNS!
Go
3,043
star
4

NetGain

A high performance websocket server library powering Stack Overflow.
C#
933
star
5

Stacks

Stack Overflow’s Design System
Less
610
star
6

wmi

WMI for Go
Go
433
star
7

pagedown

The Markdown editor and converter used on Stack Overflow and the other Stack Exchange sites
JavaScript
419
star
8

Stacks-Editor

Stack Overflow's Combination Rich Text / Markdown Editor
TypeScript
362
star
9

StackExchange.DataExplorer

Stack Exchange Data Explorer
JavaScript
353
star
10

MarkdownSharp

Open source C# implementation of Markdown processor, used by Stack Overflow.
C#
246
star
11

stack-blog

Stack Overflow Blog
HTML
238
star
12

StackExchange.Utils

Utility class packages used at Stack Exchange...but on NuGet!
C#
195
star
13

httpunit

httpUnit tests compliance of web and net servers with desired output.
Go
164
star
14

StackExchange.Precompilation

Roslyn based csc.exe and aspnet_compiler.exe replacement with metaprogramming hooks for ASP.NET MVC projects from the pre-DNX era
C#
154
star
15

Stacks-Icons

Authoring tools for Stack Overflow's shared icon set.
TypeScript
35
star
16

NRediSearch

C#
31
star
17

stackegg

The core game logic of Stack Overflow's April 1st 2015 game, StackEgg.
C#
30
star
18

mayflower

A simple MS SQL Server database migrator using Node.js and TDS.
JavaScript
26
star
19

StackID

An OpenID provider implemented for the Stack Exchange network, built on top of dotNetOpenAuth.
C#
20
star
20

stackexchange.github.com

Source for stackexchange.github.com
HTML
19
star
21

apca-check

Axe rules to check against APCA bronze and silver+ conformance levels.
TypeScript
18
star
22

unikong

Stack Overflow's April 1, 2016 game
JavaScript
16
star
23

haproxy-kubefigurator

Dynamic haproxy configuration for Kubernetes services
Go
14
star
24

RyuJIT-TailCallBug

Tail Call Parameter Corruption Repro for .Net 4.6
C#
12
star
25

signalfx-powershell

This is a PowerShell wrapper around the SignalFx API
PowerShell
10
star
26

mof

Package mof parses and marshals Managed Object Format (MOF) structures
Go
9
star
27

pat

A wrapper for "puppet agent --test"
Go
9
star
28

stackexchange-superfirewall

A facade for firewall::firewall{} that adds enhanced functionality.
Puppet
7
star
29

browserslist-viewer

Static site to parse and display a browserslist string
TypeScript
6
star
30

stacks-utils

A monorepo containing a collection of Stacks config files and other utilities
JavaScript
6
star
31

Stacks-TagHelpers

A set of .Net Core Tag Helpers for use with Stacks
C#
5
star
32

DesignSprint

This repository was used for building a Stack Overflow Talent exploratory design sprint.
HTML
2
star
33

terraform-provider-stackoverflow

Terraform Provider for Stack Overflow
Go
2
star
34

sre-log-1

1
star
35

marketing-resources

1
star