Code Monkey home page Code Monkey logo

prometheus-client-delphi's Introduction

Prometheus Client for Delphi

Prometheus Client for Delphi


This is a Delphi client library for Prometheus, similar to libraries created for other languages.

Overview

The Prometheus Delphi Client library is a set of classes that allow you to instrument your Delphi applications with Prometheus metrics.

It allows you to instrument your Delphi code with custom metrics and provides some built-in and ready to use metrics.

The library also supports Prometheus' text based exposition format, that can be configured and made available via an HTTP endpoint on your Web application's instance using specific middlewares or directly calling the text exporter.

What is Prometheus

Prometheus is a popular open-source monitoring tool that is widely used in modern software environments. It provides a powerful system for collecting and analyzing metrics from various sources, including applications, servers, and other systems.

To use Prometheus effectively, you need a client library implemented in your favorite programming language that can be integrated into your applications to expose the relevant metrics to the Prometheus server.

Here we will discuss the client library for Prometheus written for Embarcadero Delphi.

Main Features

The Prometheus Delphi Client library offers a range of features that make it a powerful and flexible tool for monitoring Delphi applications using Prometheus.

By using the library, you can gain valuable insights into the performance and behavior of your Delphi applications and make data-driven decisions to improve them.

Here are some of supported features:

  • Basic metrics: the library allows you to define some basic metrics supported by Prometheus to track some relevant values in your application, like the number of times an event has occured or the current amount of allocated memory and so on.
  • Labels: these are key-value pairs that allow you to add additional context to your metrics.
  • Custom Collectors: the library allows you to define custom collectors that can be used to collect metrics from any source.

Getting Started

To get started with the Prometheus Delphi Client library, you need to follow these steps.

โš™ Install the library

Installation is done using the boss install command:

boss install marcobreveglieri/prometheus-client-delphi

If you choose to install it manually, download the source code from GitHub simply add the following folders to your project, in Project > Options > Resource Compiler > Directories and Conditionals > Include file search path

prometheus-client-delphi/Source

๐Ÿ“ Define your metrics

Define the metrics you want to track using the appropriate classes (see below).

๐Ÿ“’ Register your metrics

Register your metrics inside the default collector registry or in a registry of your own for subsequent handling and exportation.

โœ” Update your metrics

Update your metrics as needed calling the appropriate methods you can find on collector instance depending on the classes they are based to.

๐Ÿ’พ Export all your metric samples

You can export your metrics calling the text based exporter or making use of a ready to use middleware that targets your favourite Delphi Web framework (see Middlewares section below for details).

Metrics

Prometheus Delphi Client supports the following metric types.

Counter

A counter is a cumulative metric that represents a single monotonically increasing counter whose value can only increase or be reset to zero on restart. For example, you can use a counter to represent the number of requests served, tasks completed, or errors.

Do not use a counter to expose a value that can decrease. For example, do not use a counter for the number of currently running processes; instead use a gauge.

uses
  Prometheus.Collectors.Counter;

begin
  var LCounter := TCounter.Create('sample', 'Description of this counter');
  LCounter.Inc(); // increment by 1
  LCounter.Inc(123); // increment by 123
end.

Gauge

A gauge is a metric that represents a single numerical value that can arbitrarily go up and down.

Gauges are typically used for measured values like temperatures or current memory usage, but also "counts" that can go up and down, like the number of concurrent requests.

uses
  Prometheus.Collectors.Gauge;

begin
  var LGauge := TGauge.Create('sample', 'Description of this gauge');
  LGauge.Inc(); // increment by 1
  LGauge.Inc(123); // increment by 123
  LGauge.Dec(10); // decrement by 10
  LGauge.SetTo(123); // set value directly to 123
  LGauge.SetDuration( // set value to duration of method execution
    procedure
    begin
      // User code
    end);
end.

Summary

Similar to a histogram, a summary samples observations (usually things like request durations and response sizes). While it also provides a total count of observations and a sum of all observed values, it calculates configurable quantiles over a sliding time window.

*** !!! Under Development !!! ***

Histogram

A histogram samples observations (usually things like request durations or response sizes) and counts them in configurable buckets. It also provides a sum of all observed values.

*** !!! Under Development !!! ***

Custom metrics

You can also implement your own custom metrics by inheriting the appropriate classes (TCollector or TSimpleCollector).

Labels

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

Taking a counter as an example:

uses
  Prometheus.Collectors.Counter;

begin
  var LCounter := TCounter
    .Create('http_requests_handled', 'HTTP handled requests total', ['path', 'status'])
    .Register();
end.

Metrics with labels are not initialized when declared, because the client can't know what values the label can have. It is recommended to initialize the label values by calling the appropriate method and then eventually call another method to alter the value of the metric associated to label values:

uses
  Prometheus.Collectors.Counter;

begin
  TCollectorRegistry.DefaultRegistry
    .GetCollector<TCounter>('http_requests_handled')
    .Labels(['/api', 200]) // ['path', 'status']
    .Inc(); // increment child counter attached to these label values
end.

Exporting metrics

There are several options for exporting metrics. For example, you can export metrics from a Windows Service Application using a TIdHttp server component from Indy Components and exposing a "/metrics" endpoint where you export text based metrics data to Prometheus server.

You can also download a middleware for your favourite Web framework or take a look at the sample projects.

Middlewares

To ease the use of Prometheus Client inside Web applications created with Delphi, you will find here middlewares to download and install.

Each middleware integrates support for exposing metrics to Prometheus server using the appropriate format and without having to code each endpoint manually.

You can find official Prometheus Client middlewares into these separate repositories:

Middleware
Delphi MVC Framework
Horse

Delphi compatibility

Prometheus Client works with Delphi 11 Alexandria as it makes use of advanced features of Delphi language, but with some slight changes it maybe could work in previous versions.

Additional links

prometheus-client-delphi's People

Contributors

marcobreveglieri avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

prometheus-client-delphi's Issues

Use of TMonitor prone to deadlocks

The library makes extensive use of TMonitor to provide threadsafe access to global collections.
However I am concerned that the pattern used makes the library subject to thread deadlocks.

I refer you to a question I asked on Stack Overflow related to the same code pattern, but in my own code base. Allana Bauer was kind enough to answer.
https://stackoverflow.com/questions/77490742/using-tmonitor-in-delphi-to-block-access-to-global-object

I would recommend using a private instance field for the lock rather than Self. This would stay away from the "locking this (Self) is bad" issue. Otherwise some external "bad actor" could take the same lock you're using internally.

So for example in the Prometheus.Collectors.Counter.pas unit I would change

procedure TCounterChild.Inc(const AAmount: Double);
begin
  TMonitor.Enter(Self);
  try
    if AAmount <= 0 then
      raise EArgumentOutOfRangeException.Create(StrErrAmountLessThanZero);
    FValue := FValue + AAmount;
  finally
    TMonitor.Exit(Self);
  end;
end;

to

procedure TCounterChild.Inc(const AAmount: Double);
begin
  TMonitor.Enter(FLock);  // a private lock field
  try
    if AAmount <= 0 then
      raise EArgumentOutOfRangeException.Create(StrErrAmountLessThanZero);
    FValue := FValue + AAmount;
  finally
    TMonitor.Exit(FLock);
  end;
end;

Histogram Metric

Hello Marco Breveglieri,
I trust this message finds you well.

I am writing to inform you that I have completed the implementation of the histogram metric for prometheus-client-delphi. I am eager to contribute and believe that my work can add value to the project.

May I kindly request access to the repository to open a pull request? This will allow you to review the code and provide any necessary feedback or suggestions for improvement.

I appreciate your time and consideration.

Best regards,
Rennan Augusto

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.