ballerina/observe module

Module Overview

This module provides apis for observing Ballerina services. Ballerina supports Observability out of the box. This module provides user api's to make Ballerina Observability more flexible for the user.

To observe ballerina code, the --observe flag should be given when starting the service. i.e. ballerina run --observe hello_world.bal. For more information on Ballerina Observability visit How to Observe Ballerina Services

Tracing

Samples

Start a root span & attach a child span

The following code snippet show an example of how start a root span with no parent and start another span as a child of the first span. Note: Make sure that all started spans are closed properly to ensure that all spans are reported properly.

int spanId = observe:startRootSpan("Parent Span");

// Do Something.

int spanId2 = checkpanic observe:startSpan("Child Span", parentSpanId = spanId);

// Do Something.

var ret1 = observe:finishSpan(spanId2);

// Do Something.

var ret2 = observe:finishSpan(spanId);

Start a span attached to a system trace

When no parentSpanId is given or a parentSpanId of -1 is given, a span is started as a child span to the current active span in the ootb system trace.

int spanId = checkpanic observe:startSpan("Child Span");

// Do Something.

var ret = observe:finishSpan(spanId);

Attach a tag to a span

It is possible to add tags to span by using the observe:addTagToSpan() api by providing the span id and relevant tag key and tag value.

_ = observe:addTagToSpan(spanId = spanId, "Tag Key", "Tag Value");

Attach a tag to a span in the system trace

When no spanId is provided or -1 is given, the defined tags are added to the current active span in the ootb system trace.

var ret = observe:addTagToSpan("Tag Key", "Tag Value");

Metrics

There are mainly two kind of metrics instances supported; Counter and Gauge. 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. The Gauge metric instance represents a single numerical value that can arbitrarily go up and down, and also based on the statistics configurations provided to the Gauge, it can also report the statistics such as max, min, mean, percentiles, etc.

Counter Samples

Create

The following code snippets provides the information on how Counter instances can be created. Instantiating the counter will simply create an instance based on the params passed.

// Create counter with simply by name.
observe:Counter simpleCounter = new("SimpleCounter"); 

// Create counter with description.
observe:Counter counterWithDesc = new("CounterWithDesc", desc = "This is a sample counter description");

// Create counter with tags.
map<string> counterTags = { "method": "GET" };
observe:Counter counterWithTags = new("CounterWithTags", desc = "Some description", tags = counterTags);

Register

The counter can registered with the global metrics registry, therefore it can be looked up later without having the reference of the counter that was created. Also, only the registered counters will be reported to the Metrics reporter such as Prometheus. In case, if there is already another non counter metric registered, then there will be an error returned. But if it's another counter instance, then the registered counter instance will be returned.

map<string> counterTags = { "method": "GET" };
observe:Counter counterWithTags = new("CounterWithTags", desc = "Some description", tags = counterTags);
var anyError = counterWithTags.register();
if anyError is error {
    log:printError("Cannot register the counter", err = anyError);
}

Unregister

The counter can unregistered with the global metrics registry if it is already registered. If a metrics is unregistered, then further it'll not be included in metrics reporting.

map<string> counterTags = { "method": "GET" };
observe:Counter counterWithTags = new("CounterWithTags", desc = "Some description", tags = counterTags);
var anyError = counterWithTags.register();
if anyError is error {
    log:printError("Cannot register the counter", err = anyError);
}
counterWithTags.unregister();
    

Increment

The counter can be incremented without passing any params (defaulted to 1), or by a specific amount.

map<string> counterTags = { "method": "GET" };
observe:Counter counterWithTags = new("CounterWithTags", desc = "Some description", tags = counterTags);
// Increment by 1.
counterWithTags.increment(); 
// Increment by amount 10.
counterWithTags.increment(amount = 10);

Reset

The counter can be resetted to default amount = 0.

map<string> counterTags = { "method": "GET" };
observe:Counter counterWithTags = new("CounterWithTags", desc = "Some description", tags = counterTags);
counterWithTags.reset();

Get Value

The current value can be retrieved by this operation.

map<string> counterTags = { "method": "GET" };
observe:Counter counterWithTags = new("CounterWithTags", desc = "Some description", tags = counterTags);
int currentValue = counterWithTags.getValue();

Gauge Samples

Create

The following code snippets provides the information on how Gauge instances can be created. Instantiating the gauge will simply create an instance based on the params passed.

// Create gauge with simply by name. 
// Uses the default statistics configuration. 
observe:Gauge simpleGauge = new("SimpleGauge"); 

// Create gauge with description.
// Uses the default statistics configuration. 
observe:Gauge gaugeWithDesc = new("GaugeWithDesc", desc = "This is a sample gauge description");

// Create gauge with tags.
// Uses the default statistics configuration. 
map<string> gaugeTags = { "method": "GET" };
observe:Counter gaugeWithTags = new("GaugeWithTags", desc = "Some description", tags = gaugeTags);

// Create gauge with disabled statistics. 
observe:StatisticConfig[] statsConfigs = [];
observe:Gauge gaugeWithNoStats = new("GaugeWithTags", desc = "Some description", 
                                    tags = gaugeTags, statisticConfig = statsConfigs);

// Create gauge with statistics config. 
observe:StatisticConfig config = { timeWindow: 30000, percentiles: [0.33, 0.5, 0.9, 0.99], buckets: 3 };
statsConfigs[0]=config; 

observe:Gauge gaugeWithStats = new("GaugeWithTags", desc = "Some description", 
                                   tags = gaugeTags, statisticConfig = statsConfigs);

Register

The gauge can registered with the global metrics registry, therefore it can be looked up later without having the reference of the gauge that was created. Also, only the registered counters will be reported to the Metrics reporter such as Prometheus. In case, if there is already another non gauge metric registered, then there will be an error returned. But if it's another gauge instance, then the registered gauge instance will be returned.

map<string> gaugeTags = { "method": "GET" };
observe:Gauge gaugeWithTags = new("GaugeWithTags", desc = "Some description", tags = gaugeTags);
var anyError = gaugeWithTags.register();
if anyError is error {
    log:printError("Cannot register the gauge", err = anyError);
}

Unregister

The gauge can unregistered with the global metrics registry if it is already registered. If a metrics is unregistered, then further it'll not be included in metrics reporting.

map<string> gaugeTags = { "method": "GET" };
observe:Gauge gaugeWithTags = new("GaugeWithTags", desc = "Some description", tags = gaugeTags);
var anyError = gaugeWithTags.register();
if anyError is error {
    log:printError("Cannot register the gauge", err = anyError);
}
gaugeWithTags.unregister();

Increment

The gauge can be incremented without passing any params (defaulted to 1.0), or by a specific amount.

map<string> gaugeTags = { "method": "GET" };
observe:Gauge gaugeWithTags = new("GaugeWithTags", desc = "Some description", tags = gaugeTags);
// Increment by 1.
gaugeWithTags.increment(); 
// Increment by amount 10.
gaugeWithTags.increment(amount = 10.0);  

Decrement

The gauge can be decremented without passing any params (defaulted to 1.0), or by a specific amount.

map<string> gaugeTags = { "method": "GET" };
observe:Gauge gaugeWithTags = new("GaugeWithTags", desc = "Some description", tags = gaugeTags);
// Increment by 1.
gaugeWithTags.decrement(); 
// Increment by amount 10.
gaugeWithTags.decrement(amount = 10.0);

Set Value

This method sets the gauge's value with specific amount.

map<string> gaugeTags = { "method": "GET" };
observe:Gauge gaugeWithTags = new("GaugeWithTags", desc = "Some description", tags = gaugeTags);
gaugeWithTags.setValue(100.0);

Get Value.

The current value can be retrieved by this operation.

map<string> gaugeTags = { "method": "GET" };
observe:Gauge gaugeWithTags = new("GaugeWithTags", desc = "Some description", tags = gaugeTags);
float currentValue = gaugeWithTags.getValue(); 

Get Snapshot.

This method retrieves current snapshot of the statistics calculation based on the configurations passed to the gauge. If the statistics are disabled, then it'll be returning nil ().

map<string> gaugeTags = { "method": "GET" };
observe:Gauge gaugeWithTags = new("GaugeWithTags", desc = "Some description", tags = gaugeTags);
gaugeWithTags.setValue(1.0);
gaugeWithTags.setValue(2.0);
gaugeWithTags.setValue(3.0);

observe:Snapshot[]? summarySnapshot = gaugeWithTags.getSnapshot();
if summarySnapshot is observe:Snapshot[] {
    io:println(summarySnapshot);
} else {
    io:println("No statistics available!");
}

Global Metrics Samples

Get All Metrics

This method returns all the metrics that are registered in the global metrics registry. This method is mainly useful for metric reporters, where they can fetch all metrics, format those, and report.

observe:Metric[] metrics = observe:getAllMetrics();
foreach var metric in metrics {
    // Do something.
}

Lookup Metric

This method will lookup for the metric from the global metric registry and return it.

map<string> tags = { "method": "GET" };
observe:Counter|observe:Gauge|() metric = observe:lookupMetric("MetricName", tags = tags);
if metric is observe:Counter {
    metric.increment(amount = 10);
} else if metric is observe:Gauge {
    metric.increment(amount = 10.0);
} else {
    io:println("No Metric Found!");
}

Module Detail

Records

Record Description
Metric This represents the generic metric record that can represent both counter and gauge.
PercentileValue This represents the percentile value record.
Snapshot This represents the snapshot of the statistics calculation of the gauge.
StatisticConfig This represents the statistic configuration that can be used to instatiate gauge metric.

Objects

Object Description
Counter

This represents the metric type - counter, that can be only increased by an integer number.

Gauge

This represents the metric type - gauge, that can hold instantaneous, increased or decreased value during the usage.

Functions

Function Description
addTagToSpan

Add a key value pair as a tag to the span.

finishSpan

Finish the current span.

getAllMetrics

Retrieve all registered metrics including default metrics from the ballerina runtime, and user defined metrics.

lookupMetric

Retrieves the specific metric that is described by the given name and tags.

startRootSpan

Start a span with no parent span.

startSpan

Start a span and create child relationship to current active span or user specified span.

public type Metric

This represents the generic metric record that can represent both counter and gauge.

Field Name Data Type Default Value Description
name string

Name of the metric.

desc string

Description of the metric.

tags map<string>

Tags associated with the metric.

metricType string

Type of the metric.

value int|float

Current value the metric.

summary observe:Snapshot[]?

If the metric is configured with statistics config, then the calculated statistics of the metric.

public type PercentileValue

This represents the percentile value record.

Field Name Data Type Default Value Description
percentile float

The percentile of the reported value.

value float

The value of the percentile.

public type Snapshot

This represents the snapshot of the statistics calculation of the gauge.

Field Name Data Type Default Value Description
timeWindow int

The time window in which variation of the values are considered.

mean float

The average value within the time window.

max float

The max value within the time window.

min float

The min value within the time window.

stdDev float

The standard deviation value within the time window.

percentileValues observe:PercentileValue[]

The percentiles values calculated wihtin the time window.

public type StatisticConfig

This represents the statistic configuration that can be used to instatiate gauge metric.

Field Name Data Type Default Value Description
percentiles float[]

The percentiles that needs to be calculated.

timeWindow int

The time window (in milli seconds) in which variation of the values are considered.

buckets int

The number of buckets used in the sliding time window.

public function addTagToSpan(string tagKey, string tagValue, int spanId) returns (error?<>)

Add a key value pair as a tag to the span.

Parameter Name Data Type Default Value Description
tagKey string

Key of the tag

tagValue string

Value of the tag

spanId int -1

Id of span to which the tags should be added or -1 to add tags to the current active span

Return Type Description
error?<>

An error if an error occured while attaching tag to the span

public function finishSpan(int spanId) returns (error?<>)

Finish the current span.

Parameter Name Data Type Default Value Description
spanId int

Id of span to finish

Return Type Description
error?<>

An error if an error occured while finishing the span

public function getAllMetrics() returns (Metric[])

Retrieve all registered metrics including default metrics from the ballerina runtime, and user defined metrics.

Return Type Description
Metric[]

Array of all registered metrics.

public function lookupMetric(string name, map<string>? tags) returns (Counter|Gauge)

Retrieves the specific metric that is described by the given name and tags.

Parameter Name Data Type Default Value Description
name string

Name of the metric to lookup.

tags map? ()

The key/value pair tags that associated with the metric that should be looked up.

Return Type Description
Counter|Gauge

The metric instance.

public function startRootSpan(string spanName, map<string>? tags) returns (int)

Start a span with no parent span.

Parameter Name Data Type Default Value Description
spanName string

Name of the span

tags map? ()

Tags to be associated to the span

Return Type Description
int

SpanId of the started span

public function startSpan(string spanName, map<string>? tags, int parentSpanId) returns (int|error<>)

Start a span and create child relationship to current active span or user specified span.

Parameter Name Data Type Default Value Description
spanName string

Name of the span

tags map? ()

Tags to be associated to the span

parentSpanId int -1

Id of the parent span or -1 if parent span should be taken from system trace

Return Type Description
int|error<>

SpanId of the started span

public type Counter object

This represents the metric type - counter, that can be only increased by an integer number.

Field Name Data Type Default Value Description
name string

Name of the counter metric.

description string

Description of the counter metric.

metricTags map<string>

Tags associated with the counter metric.

  • <Counter> __init(string name, string? desc, map<string>? tags)

    This instantiates the Counter object. Name field is mandatory, and description and tags fields are optional and have its own default values when no params are passed.

    Parameter Name Data Type Default Value Description
    name string

    Name of the Counter instance.

    desc string?

    Description of the Counter instance. If no description is provided, the the default empty string will be used.

    tags map? ()

    The key/value pair of Tags. If no tags are provided, the default nil value will be used.

  • <Counter> register() returns (error?<>)

    Register the counter metric instance with the Metric Registry.

    Return Type Description
    error?<>

    Returns error if there is any metric registered already with the same name but different parameters or in a different kind.

  • <Counter> unregister()

    Unregister the counter metric instance with the Metric Registry.

  • <Counter> increment(int amount)

    Increment the counter's value by an amount.

    Parameter Name Data Type Default Value Description
    amount int 1

    The amount by which the value needs to be increased. The amount is defaulted as 1 and will be used if there is no amount passed in.

  • <Counter> reset()

    Resets the counter's value to zero.

  • <Counter> getValue() returns (int)

    Retrieves the counter's current value.

    Return Type Description
    int

    The current value of the counter.

public type Gauge object

This represents the metric type - gauge, that can hold instantaneous, increased or decreased value during the usage.

Field Name Data Type Default Value Description
name string

Name of the counter metric.

description string

Description of the counter metric.

metricTags map<string>

Tags associated with the counter metric.

statisticConfigs observe:StatisticConfig[]

Array of StatisticConfig objects which defines about the statistical calculation of the gauge during its usage.

  • <Gauge> __init(string name, string? desc, map<string>? tags, observe:StatisticConfig[]? statisticConfig)

    This instantiates the Gauge object. Name field is mandatory, and description, tags, and statitics config fields are optional and have its own default values when no params are passed.

    Parameter Name Data Type Default Value Description
    name string

    Name of the Gauge instance.

    desc string?

    Description of the Gauge instance. If no description is provided, the the default empty string will be used.

    tags map? ()

    The key/value pair of Tags. If no tags are provided, the default nil value will be used.

    statisticConfig observe:StatisticConfig[]? ()

    Statistics configurations array is used for statistics calculation. In case if empty statistics configurations array is passed, then statistics calculation will be disabled. If nil () is passed, then default statistics configs will be used for the statitics calculation.

  • <Gauge> register() returns (error?<>)

    Register the gauge metric instance with the Metric Registry.

    Return Type Description
    error?<>

    Returns error if there is any metric registered already with the same name but different parameters or in a different kind.

  • <Gauge> unregister()

    Unregister the counter metric instance with the Metric Registry.

  • <Gauge> increment(float amount)

    Increment the gauge's value by an amount.

    Parameter Name Data Type Default Value Description
    amount float 1.0

    The amount by which the value of gauge needs to be increased. The amount is defaulted as 1.0 and will be used if there is no amount passed in.

  • <Gauge> decrement(float amount)

    Decrement the gauge's value by an amount.

    Parameter Name Data Type Default Value Description
    amount float 1.0

    The amount by which the value of gauge needs to be decreased. The amount is defaulted as 1.0 and will be used if there is no amount passed in.

  • <Gauge> setValue(float amount)

    Sets the instantaneous value for gauge.

    Parameter Name Data Type Default Value Description
    amount float

    The instantaneous value that needs to be set as gauge value.

  • <Gauge> getValue() returns (float)

    Retrieves the gauge's current value.

    Return Type Description
    float

    The current value of the gauge.

  • <Gauge> getSnapshot() returns (Snapshot[])

    Retrieves statistics snapshots based on the statistics configs of the gauge.

    Return Type Description
    Snapshot[]

    Array of the statistics snapshots. If there is no statisticsConfigs provided, then it will be nil.