Code Monkey home page Code Monkey logo

pulse-prometheus's Introduction

pulse-prometheus

Build Status codecov Nuget MIT License

pulse-prometheus is a .NET library that implements the pulse interface and abstracts the C# prometheus-net library.

Abstracted metrics libraries are helpful in the event the underlying monitoring system changes. Whether the underlying monitoring library experiences breaking changes or you decide to do a complete swap of the underlying monitoring library, rest assured that you will only have to update the abstracted library and not your service code.

Table of Contents

Requirements

Download

pulse-prometheus is distributed via the NuGet gallery.

Best Practices and Usage

This library allows you to instrument your code with custom metrics. You are expected to be familiar with:

Quick Start

  1. Configure the endpoint. See Middleware Extensions.
  2. Register the IMetricFactory. See Dependency Injection. Optionally, create an IMetricFactory instead of injecting it.
  3. Use your IMetricFactory to create counters, gauges, histograms, and summaries.
  4. Use your metrics to do other cool things like track operation duration, count in-progress operations, and count exceptions. Also check out how to use mutable labels and immutable labels

Middleware Extensions

Use metric middleware extensions to output metrics to an endpoint.

The default is /metrics.

public class Startup
{
    ...

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseEndpoints(endpoints =>
        {
            ...
            endpoints.MapMetrics();
        });
    }
    
    ...
}

Dependency Injection

Use IServiceCollection extensions to make it easy for consumers to register implementations for the included IMetricFactory.

public class Startup
{
    ...
    
    public void ConfigureServices(IServiceCollection services)
    {
        ...
        services.AddMetricFactory();
    }
    
    ...
}

In subsequent code, request an implementation for the IMetricFactory by including it in the constructor of the classes which require it.

public class Example
{
    private readonly pulseMetricFactory;

    public Example(IMetricFactory metricFactory)
    {
        pulseMetricFactory = metricFactory;
    }

    public void TrackSomething()
    {
        var counter = pulseMetricFactory.CreateCounter("counter", "this is a counter metric");
        using (counter.NewTimer())
        {
            Thread.Sleep(1000);
        }
    }
}

Metric Factory

Create a metric factory as an entry point into the library, or use dependency injection.

private static readonly IMetricFactory MyAppMetricFactory = new PulseMetricFactory(new PrometheusMetricFactory());

Counter

Counters only increase in value and reset to zero when the process restarts.

private static readonly ICounter LogCounter = 
    MyAppMetricFactory.CreateCounter("myapp_number_of_logs_emitted", "Number of logs emitted.");

...

Log();
LogCounter.Increment();

Gauge

Gauges can have any numeric value and change arbitrarily.

private static readonly IGauge JobQueueGauge = 
    MyAppMetricFactory.CreateGauge("myapp_jobs_queued", "Number of jobs queued.");

...

jobs.Enqueue(job);
JobQueueGauge.Increment();

...

jobs.Dequeue(job);
JobQueueGauge.Decrement();

Histogram

Histograms track the size and number of events in buckets. This allows for aggregatable calculation over a set of buckets.

double[] buckets = new double[] { 100.0, 200.0, 300.0, 400.0, 500.0 } 

private static readonly IHistogram OrderValueHistogram = 
    MyAppMetricFactory.CreateHistogram(
        "myapp_order_value_usd", 
        "Histogram of received order values (in USD).", 
        new HistogramConfiguration()
        {
            Buckets = buckets
        });

...

OrderValueHistogram.Observe(order.TotalValueUsd);

Summary

Summaries track events over time, with a default of 10 minutes.

private static readonly ISummary UploadSizeSummary = 
    MyAppMetricFactory.CreateSummary(
        "myapp_upload_size_bytes", 
        "Summary of upload sizes (in bytes) over last 10 minutes.");

...

UploadSizeSummary.Observe(file.Length);

Tracking Operation Duration

Timers can be used to report the duration of an operation (in seconds) to a Summary, Histogram, Gauge or Counter. Wrap the operation you want to measure in a using block.

double[] buckets = new double[] { 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0 };

private static readonly IHistogram UploadDuration = 
    MyAppMetricFactory.CreateHistogram(
        "myapp_upload_duration_seconds", 
        "Histogram of file upload durations.", 
        new HistogramConfiguration()
        {
            Buckets = buckets
        });

...

using (UploadDuration.NewTimer())
{
    Scheduler.Upload(file);
}

Counting In-Progress Operations

You can use Gauge.TrackInProgress() to track how many concurrent operations are taking place. Wrap the operation you want to track in a using block.

private static readonly IGauge UploadsInProgress = 
    MyAppMetricFactory.CreateGauge(
        "myapp_uploads_in_progress", 
        "Number of upload operations occuring.");

...

using (UploadsInProgress.TrackInProgress())
{
    Scheduler.Upload(file);
}

Counting Exceptions

You can use Counter.CountExceptions() to count the number of exceptions that occur while executing some code.

private static readonly ICounter FailedExtractions =
    MyAppMetricFactory.CreateCounter(
        "myapp_extractions_failed_total", 
        "Number of extraction operations that failed.");

...

FailedExtractions.CountExceptions(() => Extractor.Extract(file));

You can also filter the exception types to observe:

FailedExtractions.CountExceptions(() => Extractor.Extract(file), IsExtractionRelatedException);

bool IsExtractionRelatedException(Exception ex)
{
    return ex is ExtractionException; // Only count ExtractionExceptions.
}

Mutable Labels

All metrics can have mutable labels, allowing grouping of related time series.

See the best practices on naming and labels.

  • Labels should contain a limited set of label values.
    • URLs would be a bad choice. There are infinite options.
    • HTTP response codes would be a good choice. There is a finite set of options.

Taking a counter as an example:

private static readonly ICounter HttpResponseCounter = 
    MyAppMetricFactory.CreateCounter(
        "myapp_http_responses_total", 
        "Number of responses received by http method and response code.", 
        new CounterConfiguration()
        {
            MutableLabelNames = new string[] { "http_method", "http_response_code" }
        });

...

// Specify the value(s) for the label(s) when you want to call a metric operation.
HttpResponseCounter.WithLabels("GET", "200").Inc();

Immutable Labels

You can add immutable labels that always have fixed values.

Taking a counter as an example with immutable labels and mutable labels:

Dictionary<string, string> immutableLabels = new Dictionary<string, string>() { { "service_name", "scheduler" } };
...
private static readonly ICounter HttpResponseCounter = 
    MyAppMetricFactory.CreateCounterWithStaticLabels(
        "myapp_http_responses_received", 
        "Count of responses received, labelled by response code.", 
        new CounterConfiguration()
        {
            ImmutableLabels = immutableLabels
            MutableLabelNames = new string[] { "http_response_code" }
        });

...

// Labels applied to individual instances of the metric.
HttpResponseCounter.WithLabels("404").Inc();
HttpResponseCounter.WithLabels("200").Inc();

Switching to a Different Metrics Library?

  • All pulse-projects implement the pulse interface, meaning all pulse-projects are interchangable.
  • If you need to change monitoring systems in the future, you can do so without having to change your projects code!
  • If a pulse-project does not exist for the metric monitoring system you need to use, you can easily create one by implementing the pulse common interface.

Trademarks

This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines.

Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies.

pulse-prometheus's People

Contributors

microsoft-github-operations[bot] avatar microsoftopensource avatar shinypancake avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.