import ballerina/http;
import ballerina/io;
import ballerina/log;
import ballerina/observe;
import ballerinax/prometheus as _;
//Create a gauge as a global variable in the service with the optional field description,
//default statistics configurations = { timeWindow: 600000, buckets: 5,
// and percentiles: [0.33, 0.5, 0.66, 0.99] }.
observe:Gauge globalGauge = new ("global_gauge", "Global gauge defined");
service /onlineStoreService on new http:Listener(9090) {
resource function get makeOrder(http:Caller caller, http:Request req) {
io:println("------------------------------------------");
//Incrementing the global gauge defined by 15.0.
globalGauge.increment(15.0);
//Log the current state of global gauge.
printGauge(globalGauge);
//Create a gauge with simply a name, and default statistics configurations.
observe:Gauge localGauge = new ("local_operations");
//Increment the local gauge by default value 1.0.
localGauge.increment();
//Increment the value of the gauge by 20.
localGauge.increment(20.0);
//Decrement the local gauge by default value 1.0.
localGauge.decrement();
//Decrement the value of the gauge by 20.
localGauge.decrement(10.0);
//Log the current state of local gauge.
printGauge(localGauge);
//Create a gauge with optional fields description, and tags defined.
observe:Gauge registeredGaugeWithTags =
new ("registered_gauge_with_tags", "RegisteredGauge",
{property: "gaugeProperty", gaugeType: "RegisterType"});
//Register the gauge instance, therefore it is stored in the global registry and can be reported to the
//metrics server such as Prometheus. Additionally, this operation will register to the global registry for the
//first invocation and will throw an error if there is already a registration of different metrics instance
//or type. And subsequent invocations of register() will simply retrieve the stored metrics instance
//for the provided name and tags fields, and use that instance for the subsequent operations on the
//Counter instance.
error? result = registeredGaugeWithTags.register();
if (result is error) {
log:printError("Error in registering gauge", 'error = result);
}
//Set the value of the gauge with the new value.
registeredGaugeWithTags.increment();
float value = registeredGaugeWithTags.getValue();
float newValue = value * 12.0;
registeredGaugeWithTags.setValue(newValue);
//Log the current state of registered gauge with tags.
printGauge(registeredGaugeWithTags);
//Create a gauge with statistics disabled by passing empty statistics config array.
observe:StatisticConfig[] statsConfigs = [];
observe:Gauge gaugeWithNoStats = new ("gauge_with_no_stats",
"Some description", (), statsConfigs);
gaugeWithNoStats.setValue(100);
printGauge(gaugeWithNoStats);
//Create gauge with custom statistics config.
observe:StatisticConfig config = {
timeWindow: 30000,
percentiles: [0.33, 0.5, 0.9, 0.99],
buckets: 3
};
statsConfigs[0] = config;
observe:Gauge gaugeWithCustomStats = new ("gauge_with_custom_stats",
"Some description", (), statsConfigs);
int i = 1;
while (i < 6) {
gaugeWithCustomStats.setValue(<float>(100 * i));
i = i + 1;
}
//Log the current state of registered gauge with tags.
printGauge(gaugeWithCustomStats);
io:println("------------------------------------------");
//Send response to the client.
http:Response res = new;
// Use a util method to set a string payload.
res.setPayload("Order Processed!");
// Send the response back to the caller.
result = caller->respond(res);
if (result is error) {
log:printError("Error sending response", 'error = result);
}
}
}
function printGauge(observe:Gauge gauge) {
//Get the statistics snapshot of the gauge.
io:print("Gauge - " + gauge.name + " Snapshot: ");
observe:Snapshot[]? snapshots = gauge.getSnapshot();
json|error snapshotAsAJson = snapshots.cloneWithType(json);
if snapshotAsAJson is json {
io:println(snapshotAsAJson.toJsonString());
}
//Get the current value of the gauge.
io:println("Gauge - ", gauge.name, " Current Value: "
, gauge.getValue());
}
Gauge-based metricsBallerina supports Observability out of the box and Metrics is one of the three important aspects of the
Observability. To observe Ballerina code, the build time flag |
import ballerina/http;
import ballerina/io;
import ballerina/log;
import ballerina/observe;
import ballerinax/prometheus as _;
observe:Gauge globalGauge = new ("global_gauge", "Global gauge defined");
Create a gauge as a global variable in the service with the optional field description, default statistics configurations = { timeWindow: 600000, buckets: 5, and percentiles: [0.33, 0.5, 0.66, 0.99] }.
service /onlineStoreService on new http:Listener(9090) {
resource function get makeOrder(http:Caller caller, http:Request req) {
io:println("------------------------------------------");
globalGauge.increment(15.0);
Incrementing the global gauge defined by 15.0.
printGauge(globalGauge);
Log the current state of global gauge.
observe:Gauge localGauge = new ("local_operations");
Create a gauge with simply a name, and default statistics configurations.
localGauge.increment();
Increment the local gauge by default value 1.0.
localGauge.increment(20.0);
Increment the value of the gauge by 20.
localGauge.decrement();
Decrement the local gauge by default value 1.0.
localGauge.decrement(10.0);
Decrement the value of the gauge by 20.
printGauge(localGauge);
Log the current state of local gauge.
observe:Gauge registeredGaugeWithTags =
new ("registered_gauge_with_tags", "RegisteredGauge",
{property: "gaugeProperty", gaugeType: "RegisterType"});
Create a gauge with optional fields description, and tags defined.
error? result = registeredGaugeWithTags.register();
if (result is error) {
log:printError("Error in registering gauge", 'error = result);
}
Register the gauge instance, therefore it is stored in the global registry and can be reported to the metrics server such as Prometheus. Additionally, this operation will register to the global registry for the first invocation and will throw an error if there is already a registration of different metrics instance or type. And subsequent invocations of register() will simply retrieve the stored metrics instance for the provided name and tags fields, and use that instance for the subsequent operations on the Counter instance.
registeredGaugeWithTags.increment();
float value = registeredGaugeWithTags.getValue();
float newValue = value * 12.0;
registeredGaugeWithTags.setValue(newValue);
Set the value of the gauge with the new value.
printGauge(registeredGaugeWithTags);
Log the current state of registered gauge with tags.
observe:StatisticConfig[] statsConfigs = [];
observe:Gauge gaugeWithNoStats = new ("gauge_with_no_stats",
"Some description", (), statsConfigs);
gaugeWithNoStats.setValue(100);
printGauge(gaugeWithNoStats);
Create a gauge with statistics disabled by passing empty statistics config array.
observe:StatisticConfig config = {
timeWindow: 30000,
percentiles: [0.33, 0.5, 0.9, 0.99],
buckets: 3
};
statsConfigs[0] = config;
observe:Gauge gaugeWithCustomStats = new ("gauge_with_custom_stats",
"Some description", (), statsConfigs);
int i = 1;
while (i < 6) {
gaugeWithCustomStats.setValue(<float>(100 * i));
i = i + 1;
}
Create gauge with custom statistics config.
printGauge(gaugeWithCustomStats);
Log the current state of registered gauge with tags.
io:println("------------------------------------------");
http:Response res = new;
Send response to the client.
res.setPayload("Order Processed!");
Use a util method to set a string payload.
result = caller->respond(res);
Send the response back to the caller.
if (result is error) {
log:printError("Error sending response", 'error = result);
}
}
}
function printGauge(observe:Gauge gauge) {
io:print("Gauge - " + gauge.name + " Snapshot: ");
observe:Snapshot[]? snapshots = gauge.getSnapshot();
json|error snapshotAsAJson = snapshots.cloneWithType(json);
if snapshotAsAJson is json {
io:println(snapshotAsAJson.toJsonString());
}
Get the statistics snapshot of the gauge.
io:println("Gauge - ", gauge.name, " Current Value: "
, gauge.getValue());
}
Get the current value of the gauge.
# To start the service, navigate to the directory that contains the
# `.bal` file and execute the `bal run` command below with the `--observability-included` build time flag and the `Config.toml` runtime configuration file.
BAL_CONFIG_FILES=Config.toml bal run --observability-included gauge_metrics.bal
ballerina: started Prometheus HTTP listener 0.0.0.0:9797
------------------------------------------
Gauge - global_gauge Snapshot: [{"timeWindow":600000, "mean":15.0, "max":15.0, "min":15.0, "stdDev":0.0, "percentileValues":[{"percentile":0.33, "value":15.0}, {"percentile":0.5, "value":15.0}, {"percentile":0.66, "value":15.0}, {"percentile":0.75, "value":15.0}, {"percentile":0.95, "value":15.0}, {"percentile":0.99, "value":15.0}, {"percentile":0.999, "value":15.0}]}]
Gauge - global_gauge Current Value: 15.0
Gauge - local_operations Snapshot: [{"timeWindow":600000, "mean":13.0390625, "max":21.1171875, "min":1.0, "stdDev":8.180620171277893, "percentileValues":[{"percentile":0.33, "value":10.0546875}, {"percentile":0.5, "value":10.0546875}, {"percentile":0.66, "value":20.1171875}, {"percentile":0.75, "value":20.1171875}, {"percentile":0.95, "value":21.1171875}, {"percentile":0.99, "value":21.1171875}, {"percentile":0.999, "value":21.1171875}]}]
Gauge - local_operations Current Value: 10.0
Gauge - registered_gauge_with_tags Snapshot: [{"timeWindow":600000, "mean":6.515625, "max":12.0546875, "min":1.0, "stdDev":5.515625, "percentileValues":[{"percentile":0.33, "value":1.0}, {"percentile":0.5, "value":1.0}, {"percentile":0.66, "value":12.0546875}, {"percentile":0.75, "value":12.0546875}, {"percentile":0.95, "value":12.0546875}, {"percentile":0.99, "value":12.0546875}, {"percentile":0.999, "value":12.0546875}]}]
Gauge - registered_gauge_with_tags Current Value: 12.0
Gauge - gauge_with_no_stats Snapshot: null
Gauge - gauge_with_no_stats Current Value: 100.0
Gauge - gauge_with_custom_stats Snapshot: [{"timeWindow":30000, "mean":300.7, "max":501.5, "min":100.0, "stdDev":141.775033062948, "percentileValues":[{"percentile":0.33, "value":200.5}, {"percentile":0.5, "value":301.5}, {"percentile":0.9, "value":501.5}, {"percentile":0.99, "value":501.5}]}]
Gauge - gauge_with_custom_stats Current Value: 500.0
------------------------------------------
------------------------------------------
Gauge - global_gauge Snapshot: [{"timeWindow":600000, "mean":22.53125, "max":30.0625, "min":15.0, "stdDev":7.53125, "percentileValues":[{"percentile":0.33, "value":15.0}, {"percentile":0.5, "value":15.0}, {"percentile":0.66, "value":30.0625}, {"percentile":0.75, "value":30.0625}, {"percentile":0.95, "value":30.0625}, {"percentile":0.99, "value":30.0625}, {"percentile":0.999, "value":30.0625}]}]
Gauge - global_gauge Current Value: 30.0
Gauge - local_operations Snapshot: [{"timeWindow":600000, "mean":13.0390625, "max":21.1171875, "min":1.0, "stdDev":8.180620171277893, "percentileValues":[{"percentile":0.33, "value":10.0546875}, {"percentile":0.5, "value":10.0546875}, {"percentile":0.66, "value":20.1171875}, {"percentile":0.75, "value":20.1171875}, {"percentile":0.95, "value":21.1171875}, {"percentile":0.99, "value":21.1171875}, {"percentile":0.999, "value":21.1171875}]}]
Gauge - local_operations Current Value: 10.0
Gauge - registered_gauge_with_tags Snapshot: [{"timeWindow":600000, "mean":55.4140625, "max":156.9921875, "min":1.0, "stdDev":61.38432884406833, "percentileValues":[{"percentile":0.33, "value":12.0546875}, {"percentile":0.5, "value":12.0546875}, {"percentile":0.66, "value":52.2421875}, {"percentile":0.75, "value":52.2421875}, {"percentile":0.95, "value":156.9921875}, {"percentile":0.99, "value":156.9921875}, {"percentile":0.999, "value":156.9921875}]}]
Gauge - registered_gauge_with_tags Current Value: 156.0
Gauge - gauge_with_no_stats Snapshot: null
Gauge - gauge_with_no_stats Current Value: 100.0
Gauge - gauge_with_custom_stats Snapshot: [{"timeWindow":30000, "mean":300.7, "max":501.5, "min":100.0, "stdDev":141.775033062948, "percentileValues":[{"percentile":0.33, "value":200.5}, {"percentile":0.5, "value":301.5}, {"percentile":0.9, "value":501.5}, {"percentile":0.99, "value":501.5}]}]
Gauge - gauge_with_custom_stats Current Value: 500.0
------------------------------------------
------------------------------------------
Gauge - global_gauge Snapshot: [{"timeWindow":600000, "mean":30.0625, "max":45.1875, "min":15.0, "stdDev":12.298479750223873, "percentileValues":[{"percentile":0.33, "value":15.0}, {"percentile":0.5, "value":30.0625}, {"percentile":0.66, "value":30.0625}, {"percentile":0.75, "value":45.1875}, {"percentile":0.95, "value":45.1875}, {"percentile":0.99, "value":45.1875}, {"percentile":0.999, "value":45.1875}]}]
Gauge - global_gauge Current Value: 45.0
Gauge - local_operations Snapshot: [{"timeWindow":600000, "mean":13.0390625, "max":21.1171875, "min":1.0, "stdDev":8.180620171277893, "percentileValues":[{"percentile":0.33, "value":10.0546875}, {"percentile":0.5, "value":10.0546875}, {"percentile":0.66, "value":20.1171875}, {"percentile":0.75, "value":20.1171875}, {"percentile":0.95, "value":21.1171875}, {"percentile":0.99, "value":21.1171875}, {"percentile":0.999, "value":21.1171875}]}]
Gauge - local_operations Current Value: 10.0
Gauge - registered_gauge_with_tags Snapshot: [{"timeWindow":600000, "mean":377.1927083333333, "max":1887.9921875, "min":1.0, "stdDev":676.7534301455432, "percentileValues":[{"percentile":0.33, "value":12.0546875}, {"percentile":0.5, "value":52.2421875}, {"percentile":0.66, "value":156.9921875}, {"percentile":0.75, "value":157.9921875}, {"percentile":0.95, "value":1887.9921875}, {"percentile":0.99, "value":1887.9921875}, {"percentile":0.999, "value":1887.9921875}]}]
Gauge - registered_gauge_with_tags Current Value: 1884.0
Gauge - gauge_with_no_stats Snapshot: null
Gauge - gauge_with_no_stats Current Value: 100.0
Gauge - gauge_with_custom_stats Snapshot: [{"timeWindow":30000, "mean":300.7, "max":501.5, "min":100.0, "stdDev":141.775033062948, "percentileValues":[{"percentile":0.33, "value":200.5}, {"percentile":0.5, "value":301.5}, {"percentile":0.9, "value":501.5}, {"percentile":0.99, "value":501.5}]}]
Gauge - gauge_with_custom_stats Current Value: 500.0
------------------------------------------
curl http://localhost:9090/onlineStoreService/makeOrder
Order Processed!
curl http://localhost:9090/onlineStoreService/makeOrder
Order Processed!
curl http://localhost:9090/onlineStoreService/makeOrder
Order Processed!
Invoke the service three times using the cURL commands below.