Prometheus
Key takeaways
PrometheusCounters | Component used to create different metrics or counters. |
PrometheusMetricsService | Component used to send metrics to /metrics. |
increment | Method used to create a counter that increases according to a given number. |
incrementOne | Method used to create a counter that increases by one. |
timestamp | Method used to create a counter with the timestamp format. |
timestampNow | Method used to create a counter that stores the current date and time in a timestamp format. |
beginTiming and endTiming | Method used to create a counter that measures an interval of time, such as execution time. |
dump | Method used to store obtained metrics. |
setInterval | Method used to set an interval for dumps. |
Introduction
In this tutorial, you will learn how to send different metrics to Prometheus. First, we will see how to do this via the Pushgateway. Then, we will understand how to show our metrics on a /metrics page. Finally, we will go through a set of different methods, which are useful to create different counters.
Sending metrics to Pushgateway
One of the options presented by Prometheus is to send metrics directly to its Pushgateway interface. For this, Pip.Services has the PrometheusCounters component, which allows us to define different types of counters and send their values to it. The following sections explain how to do this.
Pre-requisites
In order to send our counters to Prometheus, we need to import the PrometheusCounters component. The following command shows how to do this.
import { PrometheusCounters } from "pip-services3-prometheus-nodex";
using PipServices3.Prometheus.Count;
import (
pcount "github.com/pip-services3-gox/pip-services3-prometheus-gox/count"
)
import 'package:pip_services3_prometheus/pip_services3_prometheus.dart';
from pip_services3_prometheus.count import PrometheusCounters
Adding the counters to our component
Once we have imported our component, we can create a class containing one or more counters. In our example, we create a class named “MyComponent”, which contains a method called “mymethod”. Within this method, we include two metrics. One is a counter that measures the number of calls to this method, and the other is a variable that measures execution time.
class MyComponentA {
public consoleLog: boolean = true;
private counters: CachedCounters;
public constructor(counter: CachedCounters) {
this.counters = counter;
if (this.consoleLog)
console.log("MyComponentA has been created.");
}
public myMethod(): void {
this.counters.increment("mycomponent.mymethod.calls", 1);
var timing = this.counters.beginTiming("mycomponent.mymethod.exec_time");
try {
if (this.consoleLog) {
console.log("Hola amigo");
console.log("Bonjour mon ami");
}
} finally {
timing.endTiming();
}
this.counters.dump();
}
}
using PipServices3.Components.Count;
public class MyComponentA
{
public bool ConsoleLog = true;
private CachedCounters counters;
public MyComponentA(CachedCounters counter)
{
counters = counter;
if (ConsoleLog)
Console.WriteLine("MyComponentA has been created.");
}
public void MyMethod()
{
counters.Increment("mycomponent.mymethod.calls", 1);
var timing = counters.BeginTiming("mycomponent.mymethod.exec_time");
try
{
if (ConsoleLog)
{
Console.WriteLine("Hola amigo");
Console.WriteLine("Bonjour mon ami");
}
} finally {
timing.EndTiming();
}
counters.Dump();
}
}
import (
"context"
"fmt"
pcount "github.com/pip-services3-gox/pip-services3-prometheus-gox/count"
)
type MyComponentA struct {
counters *pcount.PrometheusCounters
ConsoleLog bool
}
func NewMyComponentA(counter *pcount.PrometheusCounters) *MyComponentA {
c := MyComponentA{
counters: counter,
ConsoleLog: true,
}
if c.ConsoleLog {
fmt.Println("MyComponentA has been created.")
}
return &c
}
func (c *MyComponentA) MyMethod(ctx context.Context) {
c.counters.Increment(ctx, "mycomponent.mymethod.calls", 1)
timing := c.counters.BeginTiming(ctx, "mycomponent.mymethod.exec_time")
defer timing.EndTiming(ctx)
if c.ConsoleLog {
fmt.Println("Hola amigo")
fmt.Println("Bonjour mon ami")
}
c.counters.Dump(ctx)
}
class MyComponentA {
bool consoleLog = true;
CachedCounters counters;
MyComponentA(this.counters) {
if (consoleLog) print('MyComponentA has been created.');
}
void myMethod() {
counters.increment('mycomponent.mymethod.calls', 1);
var timing = counters.beginTiming('mycomponent.mymethod.exec_time');
try {
if (consoleLog) {
print('Hola amigo');
print('Bonjour mon ami');
}
} finally {
timing.endTiming();
}
counters.dump();
}
}
from pip_services3_components.count import CachedCounters
class MyComponentA:
_console_log = True
def __init__(self, counters: CachedCounters):
self.counters = counters
if _console_log:
print("MyComponentA has been created.")
def mymethod(self):
self.counters.increment("mycomponent.mymethod.calls", 1)
timing = self.counters.begin_timing("mycomponent.mymethod.exec_time")
try:
if _console_log:
print("Hola amigo")
print("Bonjour mon ami")
finally:
timing.end_timing()
self.counters.dump()
Defining and connecting the counter
Once we have our component with the necessary counters, we create an instance of it and connect this object to Prometheus. To do this, we use the configure() method to provide the connection information and the open() method to connect it.
import { PrometheusCounters } from "pip-services3-prometheus-nodex";
let counters = new PrometheusCounters();
counters.configure(ConfigParams.fromTuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 8080
));
await counters.open(null);
let mycomponent = new MyComponentA(counters);
using PipServices3.Commons.Config;
var counters = new PrometheusCounters();
counters.Configure(ConfigParams.FromTuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 8080
));
await counters.OpenAsync(null);
var mycomponent = new MyComponentA(counters);
import (
"context"
"fmt"
cconf "github.com/pip-services3-gox/pip-services3-commons-gox/config"
pcount "github.com/pip-services3-gox/pip-services3-prometheus-gox/count"
)
func main() {
counters := pcount.NewPrometheusCounters()
counters.Configure(context.Background(), cconf.NewConfigParamsFromTuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 8080,
))
_ = counters.Open(context.Background(), "123")
myComponentA := NewMyComponentA(counters)
}
import 'package:pip_services3_prometheus/pip_services3_prometheus.dart';
var counters = PrometheusCounters();
counters.configure(ConfigParams.fromTuples([
'connection.protocol',
'http',
'connection.host',
'localhost',
'connection.port',
8080
]));
await counters.open(null);
var mycomponent = MyComponentA(counters);
from pip_services3_commons.config import ConfigParams
counters = PrometheusCounters()
counters.configure(ConfigParams.from_tuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 8080
))
counters.open("123")
mycomponent = MyComponentA(counters)
Calling the method
Now that we are connected, we can call “mymethod” one or more times. In the example below, we call it twice.
let execCount = 2;
for (let i = 0; i < execCount; i++)
mycomponent.myMethod();
var execCount = 2;
for (int i = 0; i < execCount; i++)
{
mycomponent.MyMethod();
}
execCount := 2
for i := 0; i < execCount; i++ {
myComponentA.MyMethod(context.Background())
}
var execCount = 2;
for (var i = 0; i < execCount; i++) {
mycomponent.myMethod();
}
count_exec = 2
for i in range(count_exec):
mycomponent.mymethod()
Results on console
And, after running our code we get the following messages on our console:
Obtaining and analyzing the results
We can get the counters with the getAll() method, which returns a list containing all the counters used.
let result = counters.getAll();
var result = counters.GetAll();
result := counters.GetAll()
var result = counters.getAll();
result = counters.get_all()
Once we have our list of counters, we can obtain some information from them via the count, min, max, average, time, name and type methods. The following example shows how to obtain these values
for (let item of result)
{
console.log(item.count);
console.log(item.min);
console.log(item.max);
console.log(item.average);
console.log(item.time);
console.log(item.name);
console.log(item.type);
console.log("-----------------");
}
foreach (var item in result)
{
Console.WriteLine(item.Count);
Console.WriteLine(item.Min);
Console.WriteLine(item.Max);
Console.WriteLine(item.Average);
Console.WriteLine(item.Time);
Console.WriteLine(item.Name);
Console.WriteLine(item.Type);
Console.WriteLine("-----------------");
}
for _, item := range result {
fmt.Println(item.Count)
fmt.Println(item.Min)
fmt.Println(item.Max)
fmt.Println(item.Average)
fmt.Println(item.Time)
fmt.Println(item.Name)
fmt.Println(item.Type)
fmt.Println("-----------------")
}
for (var item in result) {
print(item.count);
print(item.min);
print(item.max);
print(item.average);
print(item.time);
print(item.name);
print(item.type);
print('-----------------');
}
i = 0
while i < len(result):
print(result[i].count)
print(result[i].min)
print(result[i].max)
print(result[i].average)
print(result[i].time)
print(result[i].name)
print(result[i].type)
print("-----------------")
i += 1
Which after running presents the following values for the previously defined metrics:
Pushgateway results
If we are connected to the Prometheus' Pushgateway, we will find our metrics reflected in its interface. Thus, for example, in the image below, we can see the counter value of two, which indicates that the method was called twice, as we did before in our code.
Closing counters
Finally, to finish our code, we close the counters object to free resources.
await counters.close(null);
await counters.CloseAsync("123");
err := counters.Close(context.Background(), "123")
await counters.close(null);
counters.close("123")
Sending metrics to /metrics
Another option presented by Prometheus is to store the metric values on a page located at /metrics. For this purpose, Pip.Services offers the PrometheusMetricsService. Its use is explained in the following sections.
Pre-requisites
In order to use the PrometheusMetricsService component, we need to import it first. This can be done with the following command:
import { PrometheusMetricsService } from "pip-services3-prometheus-nodex";
using PipServices3.Prometheus.Services;
import (
pservice "github.com/pip-services3-gox/pip-services3-prometheus-gox/services"
)
import 'package:pip_services3_prometheus/pip_services3_prometheus.dart';
from pip_services3_prometheus.services import PrometheusMetricsService
Creating the component and the counters
As we did in the previous example, to send metrics to Prometheus, we need to create a component that generates these metrics first. We also need to create and configure a PrometheusCounters object. The following code shows how to do this:
export async function main() {
let counters = new PrometheusCounters();
counters.configure(ConfigParams.fromTuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 8080
));
await counters.open(null);
let mycomponent = new MyComponentA(counters);
}
export class MyComponentA {
public consoleLog: boolean = true;
private counters: CachedCounters;
public constructor(counter: CachedCounters) {
this.counters = counter;
if (this.consoleLog)
console.log("MyComponentA has been created.");
}
public myMethod(): void {
this.counters.increment("mycomponent.mymethod.calls", 1);
var timing = this.counters.beginTiming("mycomponent.mymethod.exec_time");
try {
if (this.consoleLog) {
console.log("Hola amigo");
console.log("Bonjour mon ami");
}
} finally {
timing.endTiming();
}
this.counters.dump();
}
}
namespace ExampleApp
{
class Program
{
static void Main(string[] args)
{
var counters = new PrometheusCounters();
counters.Configure(ConfigParams.FromTuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 8080
));
counters.OpenAsync(null).Wait();
var mycomponent = new MyComponentA(counters);
}
}
public class MyComponentA
{
public bool ConsoleLog = true;
private CachedCounters counters;
public MyComponentA(CachedCounters counter)
{
counters = counter;
if (ConsoleLog)
Console.WriteLine("MyComponentA has been created.");
}
public void MyMethod()
{
counters.Increment("mycomponent.mymethod.calls", 1);
var timing = counters.BeginTiming("mycomponent.mymethod.exec_time");
try
{
if (ConsoleLog)
{
Console.WriteLine("Hola amigo");
Console.WriteLine("Bonjour mon ami");
}
} finally {
timing.EndTiming();
}
counters.Dump();
}
}
}
package main
import (
"context"
"fmt"
cconf "github.com/pip-services3-gox/pip-services3-commons-gox/config"
pcount "github.com/pip-services3-gox/pip-services3-prometheus-gox/count"
)
func main() {
counters := pcount.NewPrometheusCounters()
counters.Configure(context.Background(), cconf.NewConfigParamsFromTuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 8080,
))
err := counters.Open(context.Background(), "123")
if err != nil {
fmt.Println(err)
}
myComponentA := NewMyComponentA(counters)
}
type MyComponentA struct {
counters *pcount.PrometheusCounters
ConsoleLog bool
}
func NewMyComponentA(counter *pcount.PrometheusCounters) *MyComponentA {
c := MyComponentA{
counters: counter,
ConsoleLog: true,
}
if c.ConsoleLog {
fmt.Println("MyComponentA has been created.")
}
return &c
}
func (c *MyComponentA) MyMethod(ctx context.Context) {
c.counters.Increment(ctx, "mycomponent.mymethod.calls", 1)
timing := c.counters.BeginTiming(ctx, "mycomponent.mymethod.exec_time")
defer timing.EndTiming(ctx)
if c.ConsoleLog {
fmt.Println("Hola amigo")
fmt.Println("Bonjour mon ami")
}
c.counters.Dump(ctx)
}
void main(List<String> argument) async {
var counters = PrometheusCounters();
counters.configure(ConfigParams.fromTuples([
'connection.protocol',
'http',
'connection.host',
'localhost',
'connection.port',
8080
]));
await counters.open(null);
var mycomponent = MyComponentA(counters);
}
class MyComponentA {
bool consoleLog = true;
CachedCounters counters;
MyComponentA(this.counters) {
if (consoleLog) print('MyComponentA has been created.');
}
void myMethod() {
counters.increment('mycomponent.mymethod.calls', 1);
var timing = counters.beginTiming('mycomponent.mymethod.exec_time');
try {
if (consoleLog) {
print('Hola amigo');
print('Bonjour mon ami');
}
} finally {
timing.endTiming();
}
counters.dump();
}
}
class MyComponentA:
_console_log = True
def __init__(self, counters: CachedCounters):
self.counters = counters
if self._console_log:
print("MyComponentA has been created.")
def mymethod(self):
self.counters.increment("mycomponent.mymethod.calls", 1)
timing = self.counters.begin_timing("mycomponent.mymethod.exec_time")
try:
if self._console_log:
print("Hola amigo")
print("Bonjour mon ami")
finally:
timing.end_timing()
self.counters.dump()
counters = PrometheusCounters()
counters.configure(ConfigParams.from_tuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 8080
))
mycomponent = MyComponentA(counters)
Creating the service
To create the /metrics page, we need to create an instance of the PrometheusMetricsService component and configure it. In the following example, we specify that our /metrics page will be located on our machine and connected via port 8080. We also say that this page will show the results obtained from the counters object. Our code is as follows:
let service = new PrometheusMetricsService();
service.configure(ConfigParams.fromTuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 8080
));
var service = new PrometheusMetricsService();
service.Configure(ConfigParams.FromTuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 8080
));
service := pservice.NewPrometheusMetricsService()
service.Configure(context.Background(), cconf.NewConfigParamsFromTuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 8080,
))
var service = PrometheusMetricsService();
service.configure(ConfigParams.fromTuples([
'connection.protocol',
'http',
'connection.host',
'localhost',
'connection.port',
8080
]));
service = PrometheusMetricsService()
service.configure(ConfigParams.from_tuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 8080
))
Setting the references
To relate the service and the counters, we need to set the references for the contextInfo, counters and service objects. This is done with the following code:
let context_info = new ContextInfo();
context_info.name = "Test";
context_info.description = "This is a test container";
let references = References.fromTuples(
new Descriptor("pip-services", "context-info", "default", "default", "1.0"), context_info,
new Descriptor("pip-services", "counters", "prometheus", "default", "1.0"), counters,
new Descriptor("pip-services", "metrics-service", "prometheus", "default", "1.0"), service
);
service.setReferences(references);
counters.setReferences(references);
var context_info = new ContextInfo();
context_info.Name = "Test";
context_info.Description = "This is a test container";
var references = References.FromTuples(
new Descriptor("pip-services", "context-info", "default", "default", "1.0"), context_info,
new Descriptor("pip-services", "counters", "prometheus", "default", "1.0"), counters,
new Descriptor("pip-services", "metrics-service", "prometheus", "default", "1.0"), service
);
service.SetReferences(references);
counters.SetReferences(references);
contextInfo := cinfo.NewContextInfo()
contextInfo.Name = "Test"
contextInfo.Description = "This is a test container"
references := refer.NewReferencesFromTuples(context.Background(),
refer.NewDescriptor("pip-services", "context-info", "default", "default", "1.0"), contextInfo,
refer.NewDescriptor("pip-services", "counters", "prometheus", "default", "1.0"), counters,
refer.NewDescriptor("pip-services", "metrics-service", "prometheus", "default", "1.0"), service,
)
service.SetReferences(context.Background(), references)
counters.SetReferences(context.Background(), references)
var context_info = ContextInfo();
context_info.name = 'Test';
context_info.description = 'This is a test container';
var references = References.fromTuples([
Descriptor('pip-services', 'context-info', 'default', 'default', '1.0'), context_info,
Descriptor('pip-services', 'counters', 'prometheus', 'default', '1.0'), counters,
Descriptor('pip-services', 'metrics-service', 'prometheus', 'default', '1.0'), service
]);
service.setReferences(references);
counters.setReferences(references);
context_info = ContextInfo()
context_info.name = 'Test'
context_info.description = 'This is a test container'
references = References.from_tuples(
Descriptor("pip-services", "context-info", "default", "default", "1.0"), context_info,
Descriptor("pip-services", "counters", "prometheus", "default", "1.0"), counters,
Descriptor("pip-services", "metrics-service", "prometheus", "default", "1.0"), service
)
service.set_references(references)
counters.set_references(references)
Connecting and calling the method
Now, as we did in the previous example, we connect to Prometheus and call the method twice. In this case, we need to connect both, the counters and service objects. Then, we call mymethod() with a loop. The code is as follows:
await service.open(null);
await counters.open(null);
var countExec = 2;
for (let i = 0; i < countExec; i++)
mycomponent.myMethod();
await service.OpenAsync(null);
await counters.OpenAsync(null);
var countExec = 2;
for (int i = 0; i < countExec; i++)
mycomponent.MyMethod();
err := service.Open(context.Background(), "123")
if err != nil {
fmt.Println(err)
}
err = counters.Open(context.Background(), "123")
if err != nil {
fmt.Println(err)
}
countExec := 2
for i := 0; i < countExec; i++ {
myComponentA.MyMethod(context.Background())
}
await service.open(null);
await counters.open(null);
var countExec = 2;
for (var i = 0; i < countExec; i++) {
mycomponent.myMethod();
}
service.open("123")
counters.open("123")
count_exec = 2
for i in range(count_exec):
mycomponent.mymethod()
Closing the resources
Finally, we can free resources by closing both, the counters and service objects.
await counters.close(null);
await service.close(null);
await counters.CloseAsync(null);
await service.CloseAsync(null);
err = service.Close(context.Background(), "123")
if err != nil {
fmt.Println(err)
}
err = counters.Close(context.Background(), "123")
if err != nil {
fmt.Println(err)
}
await counters.close(null);
await service.close(null);
counters.close()
service.close()
/metrics results
The figure below shows the /metrics page containing the example’s counters and their values.
Complete code
Below is the complete code for the example.
Code Example
import { ConfigParams, Descriptor, IReferenceable, IReferences, References } from "pip-services3-commons-nodex";
import { CachedCounters, ContextInfo } from "pip-services3-components-nodex";
import { PrometheusCounters, PrometheusMetricsService } from "pip-services3-prometheus-nodex";
export async function main() {
let mycomponent = new MyComponentA();
// Create an instance of PrometheusCounters and configure it
let counters = new PrometheusCounters();
counters.configure(ConfigParams.fromTuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 8080
));
// Create an instance of PrometheusMetricsService and configure it
let service = new PrometheusMetricsService();
service.configure(ConfigParams.fromTuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 8080
));
// Create the references
let context_info = new ContextInfo();
context_info.name = "Test";
context_info.description = "This is a test container";
let references = References.fromTuples(
new Descriptor("pip-services", "context-info", "default", "default", "1.0"), context_info,
new Descriptor("pip-services", "counters", "prometheus", "default", "1.0"), counters,
new Descriptor("pip-services", "metrics-service", "prometheus", "default", "1.0"), service
);
service.setReferences(references);
counters.setReferences(references);
mycomponent.setReferences(references);
// Connect the service and counters objects
await service.open(null);
await counters.open(null);
// Run "mymethod"
var countExec = 2;
for (let i = 0; i < countExec; i++)
mycomponent.myMethod();
// Get the counters
let result = counters.getAll();
// close counter, for closing Http client for prometheus
await counters.close("123");
// close service for closing Http server
await service.close(null);
}
class MyComponentA implements IReferenceable {
public consoleLog: boolean = true; // console log flag
private counters: CachedCounters;
public constructor() {
if (this.consoleLog)
console.log("MyComponentA has been created.");
}
public setReferences(references: IReferences): void {
this.counters = references.getOneRequired<CachedCounters>(
new Descriptor("*", "counters", "*", "*", "*")
);
}
public myMethod(): void {
// Count the number of calls to this method
this.counters.increment("mycomponent.mymethod.calls", 1);
// Measure execution time
var timing = this.counters.beginTiming("mycomponent.mymethod.exec_time");
// Task for this method: print greetings in two languages.
try {
if (this.consoleLog) {
console.log("Hola amigo");
console.log("Bonjour mon ami");
}
} finally {
timing.endTiming();
}
// Save the values of counters
this.counters.dump();
}
}
Code Example
using System;
using PipServices3.Commons.Config;
using PipServices3.Commons.Refer;
using PipServices3.Components.Count;
using PipServices3.Components.Info;
using PipServices3.Prometheus.Count;
using PipServices3.Prometheus.Services;
namespace ExampleApp
{
class Program
{
static void Main(string[] args)
{
var mycomponent = new MyComponentA();
// Create an instance of PrometheusCounters and configure it
var counters = new PrometheusCounters();
counters.Configure(ConfigParams.FromTuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 8080
));
// Create an instance of PrometheusMetricsService and configure it
var service = new PrometheusMetricsService();
service.Configure(ConfigParams.FromTuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 8080
));
// Create the references
var context_info = new ContextInfo();
context_info.Name = "Test";
context_info.Description = "This is a test container";
var references = References.FromTuples(
new Descriptor("pip-services", "context-info", "default", "default", "1.0"), context_info,
new Descriptor("pip-services", "counters", "prometheus", "default", "1.0"), counters,
new Descriptor("pip-services", "metrics-service", "prometheus", "default", "1.0"), service
);
service.SetReferences(references);
counters.SetReferences(references);
mycomponent.SetReferences(references);
// Connect the service and counters objects
service.OpenAsync(null).Wait();
counters.OpenAsync(null).Wait();
// Run "mymethod"
var countExec = 2;
for (int i = 0; i < countExec; i++)
mycomponent.MyMethod();
// Get the counters
var result = counters.GetAll();
// close counter, for closing Http client for prometheus
counters.CloseAsync("123").Wait();
// close service for closing Http server
service.CloseAsync(null).Wait();
}
}
public class MyComponentA: IReferenceable
{
public bool ConsoleLog = true; // console log flag
private CachedCounters counters;
public MyComponentA()
{
if (ConsoleLog)
Console.WriteLine("MyComponentA has been created.");
}
public void SetReferences(IReferences references)
{
counters = references.GetOneRequired<CachedCounters>(
new Descriptor("*", "counters", "*", "*", "*")
);
}
public void MyMethod()
{
// Count the number of calls to this method
counters.Increment("mycomponent.mymethod.calls", 1);
// Measure execution time
var timing = counters.BeginTiming("mycomponent.mymethod.exec_time");
// Task for this method: print greetings in two languages.
try
{
if (ConsoleLog)
{
Console.WriteLine("Hola amigo");
Console.WriteLine("Bonjour mon ami");
}
} finally {
timing.EndTiming();
}
// Save the values of counters
counters.Dump();
}
}
}
Code Example
package main
import (
"context"
"fmt"
cconf "github.com/pip-services3-gox/pip-services3-commons-gox/config"
refer "github.com/pip-services3-gox/pip-services3-commons-gox/refer"
cinfo "github.com/pip-services3-gox/pip-services3-components-gox/info"
pcount "github.com/pip-services3-gox/pip-services3-prometheus-gox/count"
pservice "github.com/pip-services3-gox/pip-services3-prometheus-gox/services"
)
func main() {
myComponentA := NewMyComponentA()
// Create an instance of PrometheusCounters and configure it
counters := pcount.NewPrometheusCounters()
counters.Configure(context.Background(), cconf.NewConfigParamsFromTuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 8080,
))
// Create an instance of PrometheusMetricsService and configure it
service := pservice.NewPrometheusMetricsService()
service.Configure(context.Background(), cconf.NewConfigParamsFromTuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 8080,
))
// Create the references
contextInfo := cinfo.NewContextInfo()
contextInfo.Name = "Test"
contextInfo.Description = "This is a test container"
references := refer.NewReferencesFromTuples(context.Background(),
refer.NewDescriptor("pip-services", "context-info", "default", "default", "1.0"), contextInfo,
refer.NewDescriptor("pip-services", "counters", "prometheus", "default", "1.0"), counters,
refer.NewDescriptor("pip-services", "metrics-service", "prometheus", "default", "1.0"), service,
)
service.SetReferences(context.Background(), references)
counters.SetReferences(context.Background(), references)
myComponentA.SetReferences(context.Background(), references)
// Connect the service and counters objects
err := service.Open(context.Background(), "123")
if err != nil {
fmt.Println(err)
}
err = counters.Open(context.Background(), "123")
if err != nil {
fmt.Println(err)
}
// Run "mymethod"
countExec := 2
for i := 0; i < countExec; i++ {
myComponentA.MyMethod(context.Background())
}
// Get the counters
result := counters.GetAll()
fmt.Println(result)
// close counter, for closing Http client for prometheus
err = counters.Close(context.Background(), "123")
if err != nil {
fmt.Println(err)
}
// close service for closing Http server
err = service.Close(context.Background(), "123")
if err != nil {
fmt.Println(err)
}
}
type MyComponentA struct {
counters *pcount.PrometheusCounters
ConsoleLog bool // console log flag
}
func NewMyComponentA() *MyComponentA {
c := MyComponentA{
ConsoleLog: true,
}
if c.ConsoleLog {
fmt.Println("MyComponentA has been created.")
}
return &c
}
func (c *MyComponentA) SetReferences(ctx context.Context, references refer.IReferences) {
p, err := references.GetOneRequired(
refer.NewDescriptor("*", "counters", "prometheus", "*", "*"),
)
if p != nil && err == nil {
c.counters = p.(*pcount.PrometheusCounters)
}
}
func (c *MyComponentA) MyMethod(ctx context.Context) {
// Count the number of calls to this method
c.counters.Increment(context.Background(), "mycomponent.mymethod.calls", 1)
// Measure execution time
timing := c.counters.BeginTiming(context.Background(), "mycomponent.mymethod.exec_time")
defer timing.EndTiming(context.Background())
// Task for this method: print greetings in two languages.
if c.ConsoleLog {
fmt.Println("Hola amigo")
fmt.Println("Bonjour mon ami")
}
// Save the values of counters
c.counters.Dump(context.Background())
}
Code Example
import 'package:pip_services3_commons/pip_services3_commons.dart';
import 'package:pip_services3_components/pip_services3_components.dart';
import 'package:pip_services3_prometheus/pip_services3_prometheus.dart';
void main(List<String> argument) async {
var mycomponent = MyComponentA();
// Create an instance of PrometheusCounters and configure it
var counters = PrometheusCounters();
counters.configure(ConfigParams.fromTuples([
'connection.protocol',
'http',
'connection.host',
'localhost',
'connection.port',
8080
]));
// Create an instance of PrometheusMetricsService and configure it
var service = PrometheusMetricsService();
service.configure(ConfigParams.fromTuples([
'connection.protocol',
'http',
'connection.host',
'localhost',
'connection.port',
8080
]));
// Create the references
var context_info = ContextInfo();
context_info.name = 'Test';
context_info.description = 'This is a test container';
var references = References.fromTuples([
Descriptor('pip-services', 'context-info', 'default', 'default', '1.0'),
context_info,
Descriptor('pip-services', 'counters', 'prometheus', 'default', '1.0'),
counters,
Descriptor(
'pip-services', 'metrics-service', 'prometheus', 'default', '1.0'),
service
]);
service.setReferences(references);
counters.setReferences(references);
mycomponent.setReferences(references);
// Connect the service and counters objects
await service.open(null);
await counters.open(null);
// Run "mymethod"
var countExec = 2;
for (var i = 0; i < countExec; i++) {
mycomponent.myMethod();
}
// Get the counters
var result = counters.getAll();
// close service for closing Http server
await service.close(null);
// close counter, for closing Http client for prometheus
await counters.close(null);
}
class MyComponentA implements IReferenceable {
bool consoleLog = true; // console log flag
CachedCounters? counters;
MyComponentA() {
if (consoleLog) print('MyComponentA has been created.');
}
@override
void setReferences(IReferences references) {
counters = references.getOneRequired<CachedCounters>(
Descriptor('*', 'counters', '*', '*', '*'));
}
void myMethod() {
// Count the number of calls to this method
counters!.increment('mycomponent.mymethod.calls', 1);
// Measure execution time
var timing = counters!.beginTiming('mycomponent.mymethod.exec_time');
// Task for this method: print greetings in two languages.
try {
if (consoleLog) {
print('Hola amigo');
print('Bonjour mon ami');
}
} finally {
timing.endTiming();
}
// Save the values of counters
counters!.dump();
}
}
Code Example
from pip_services3_commons.config import ConfigParams
from pip_services3_commons.refer import Descriptor, References, IReferences
from pip_services3_components.info import ContextInfo
from pip_services3_prometheus.count import PrometheusCounters
from pip_services3_prometheus.services import PrometheusMetricsService
from pip_services3_commons.refer import IReferenceable
class MyComponentA(IReferenceable):
console_log: bool = True # console log flag
def __init__(self):
self._counters: PrometheusCounters = None
if self.console_log:
print("MyComponentA has been created.")
# Added references for getting counters
def set_references(self, references: IReferences):
self._counters = references.get_one_required(
Descriptor("*", "counters", "*", "*", "*")
)
def mymethod(self):
# Count the number of calls to this method
self._counters.increment("mycomponent.mymethod.calls", 1)
# Measure execution time
timing = self._counters.begin_timing("mycomponent.mymethod.exec_time")
# Task for this method: print greetings in two languages.
try:
if self.console_log:
print("Hola amigo")
print("Bonjour mon ami")
finally:
timing.end_timing()
# Save the values of counters
self._counters.dump()
# Create an instance of the component
mycomponent = MyComponentA()
# Create an instance of PrometheusCounters and configure it
counters = PrometheusCounters()
counters.configure(ConfigParams.from_tuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 8080
))
# Create an instance of PrometheusMetricsService and configure it
service = PrometheusMetricsService()
service.configure(ConfigParams.from_tuples(
"connection.protocol", "http",
"connection.host", "localhost",
"connection.port", 8080
))
# Create the references
context_info = ContextInfo()
context_info.name = 'Test'
context_info.description = 'This is a test container'
references = References.from_tuples(
Descriptor("pip-services", "context-info", "default", "default", "1.0"), context_info,
Descriptor("pip-services", "counters", "prometheus", "default", "1.0"), counters,
Descriptor("pip-services", "metrics-service", "prometheus", "default", "1.0"), service
)
service.set_references(references)
counters.set_references(references)
mycomponent.set_references(references)
# Connect the service and counters objects
service.open("123")
counters.open("123")
# Run "mymethod"
count_exec = 2
for i in range(count_exec):
mycomponent.mymethod()
# Get the counters
result = counters.get_all()
# close service for closing Http server
service.close('123')
# close counter, for closing Http client for prometheus
counters.close('123')
Main counter methods
Most methods available from the PrometheusCounters component are inherited from its parent class CachedCounters. This section explains the most relevant ones.
increment
This method can be used to create a counter that increments by a specified value. Its syntax is increment(name: string, value: number) where name is the name of the counter and value is the increment number.
An example of its implementation is
counters.increment("mycomponent.mymethod.calls1", 1);
counters.Increment("mycomponent.mymethod.calls1", 1);
counters.Increment(context.Background(), "mycomponent.mymethod.calls1", 1)
counters.increment('mycomponent.mymethod.calls1', 1);
counters.increment("mycomponent.mymethod.calls1", 2)
where we create a counter named “mycomponent.mymethod.calls1” that increases by two every time it is called.
incrementOne
This method is similar to the previous one, but uses a fixed increment value of one. Its syntax is incrementOne(name: string) where name represents the name of the counter.
For example, we can create a counter called “mycomponent.mymethod.calls2” that increases by one every time it is called:
counters.incrementOne("mycomponent.mymethod.calls2");
counters.IncrementOne("mycomponent.mymethod.calls2");
counters.IncrementOne(context.Background(), "mycomponent.mymethod.calls2")
counters.incrementOne('mycomponent.mymethod.calls2');
counters.increment_one("mycomponent.mymethod.calls2")
timestamp
This method records a given timestamp. Its syntax is: timestamp(name: string, value: DateTime) where name is the name of the counter and value is the given timestamp.
In the example below, we use this command to create a metric that measures the difference between the current time and a base time.
let diff = new Date(new Date().getTime() - this.baseTime);
counters.timestamp("mycomponent.mymethod.times1", diff);
var diff = new DateTime(0) + DateTime.Now.Subtract(this.baseTime);
counters.Timestamp("mycomponent.mymethod.times1", diff);
diff := time.Unix(0, time.Now().UnixNano() - baseTime)
counters.Timestamp(context.Background(), "mycomponent.mymethod.times1", diff)
var diff = DateTime.fromMillisecondsSinceEpoch(DateTime.now().millisecondsSinceEpoch - this.baseTime);
counters.timestamp('mycomponent.mymethod.times1', diff);
counters.timestamp("mycomponent.mymethod.times1", datetime.datetime.now() - self.baseTime)
timestampNow
Similar to the previous one, this method records the current time as a timestamp. Its syntax is timestampNow(name: string) where name is the name of the counter.
Using it, the example below shows how to create a metric that measures the current time:
counters.timestampNow("mycomponent.mymethod.times2");
counters.TimestampNow("mycomponent.mymethod.times2");
counters.TimestampNow(context.Background(), "mycomponent.mymethod.times2")
counters.timestampNow('mycomponent.mymethod.times2');
counters.timestamp_now("mycomponent.mymethod.times2")
beginTiming and endTiming
The beginTiming() method starts the measurement of an execution time interval. It returns a CounterTiming object, which by calling the endTiming() method ends the measurement and updates the counter. Their syntaxes are beginTiming(name: string): CounterTiming and endTiming()
dump
This method saves the current values of counters. Its syntax is dump()
The following example shows how to create a timing for a method named mymethod. Here, we measure the execution time of a task, and then, we save the value with the dump() method.
public myMethod(): void {
let timing = this.counters.beginTiming("mycomponent.mymethod.exec_time");
try {
// our task
} finally {
timing.endTiming();
}
counters.dump();
}
public void MyMethod()
{
var timing = counters.BeginTiming("mycomponent.mymethod.exec_time");
try
{
// our task
}
finally {
timing.EndTiming();
}
counters.Dump();
}
func MyMethod() {
timing := counters.BeginTiming(context.Background(), "mycomponent.mymethod.exec_time")
defer timing.EndTiming(context.Background())
// our task
counters.Dump(context.Background())
}
void myMethod() {
var timing = counters.beginTiming('mycomponent.mymethod.exec_time');
try {
// our task
} finally {
timing.endTiming();
}
counters!.dump();
}
def mymethod(self):
timing = counters.begin_timing("mycomponent.mymethod.exec_time")
try:
# our task
finally:
timing.end_timing()
counters.dump()
setInterval
This method sets the time interval for the dump() method. Its syntax is setInterval(value: float) where value is the time interval in milliseconds.
In the example below, we use this command to set the interval to one minute.
counters.setInterval(60000);
counters.Configure(ConfigParams.FromTuples(
"interval", 60000L,
"..."
));
counters.Configure(context.Background(), cconf.NewConfigParamsFromTuples(
"interval", 60000,
"...",
))
counters.setInterval(60000);
counters.set_interval(60000)
Wrapping up
In this tutorial, we have learned how to send metric values to Prometheus. First, we saw how to send them to its Pushgateway and analyze the results. Then, we learned how to present our metrics on a page under /metrics. Finally, we explored the main methods available for counters.