Metrics in Apps
The ArconQ Metrics module, in addition to monitoring the cluster and services, also enables monitoring of the apps running in ArconQ.
Prerequisites
Enable the Metrics module
To enable the Metrics module, refer to the Installation Guide.
Enable the metrics exposure in Apps
To allow scraping of app metrics, a specific feature flag must be enabled in the ArconQ Helm chart.
Add the following line to your installation script to enable this feature:
helm upgrade --install arconq-prod arconq/arconq \
--namespace arq-prod \
--set "arconq.advanced.featureFlags.isAppMetricsExposureEnabled=true"
Enabling this flag configures ArconQ to expose metrics endpoints for your applications, allowing Prometheus (or similar tools) to scrape app-specific metrics for monitoring.
Adding custom metrics to Apps
Necessary libraries
- .Net
- Python
In Program.cs, add these lines to enable HTTP metrics and configure the /metrics endpoint:
// Expose default HTTP metrics
app.UseHttpMetrics();
// Configure the metrics endpoint
app.UseEndpoints(endpoints => endpoints.MapMetrics(settings => settings.EnableOpenMetrics = false));
There's no need to add anything in the projects main file. To add custom metrics, follow the example below.
Example of adding custom metrics
In this example we'll add two custom metrics to a MessageHandler
- Received Messages Counter - Increments by 1 every time a message is handled by this
MessageHandler. - Message Exchange Duration Gauge - Stores the time difference (in milliseconds) between when a message is sent and when it is received.
- .Net
- Python
using ArconQ.SDK.Messaging;
using Prometheus;
public class MessageHandlerWithMetrics : IMessageHandler<ExampleMessage>
{
private static readonly Counter _receivedMessagesCount = Metrics.CreateCounter("received_messages_count_total", "Number of received messages");
private static readonly Gauge _messageExchangeDurationGauge = Metrics.CreateGauge("message_exchange_duration_milliseconds", "Time between sending a message and receiving it");
public MessageHandlerWithMetrics() {}
public Task HandleAsync(ExampleMessage message)
{
_receivedMessagesCount.Inc();
var timeOfReceiving = DateTime.UtcNow;
var exchangeTime = timeOfReceiving - message.SendTime;
_messageExchangeDurationGauge.Set(exchangeTime.TotalMilliseconds)
}
}
from arconq_sdk import MessageHandler
from prometheus_client import Counter, Gauge
from time import perf_counter_ns
MESSAGE_EXCHANGE_DURATION_GAUGE = Gauge("message_exchange_duration_milliseconds", "Time between sending a message and receiving it")
RECEIVED_MESSAGES_COUNT = Counter("received_messages_count", "Number of received messages")
handler = MessageHandler()
@handler.handle("/example-handler", message_type=ExampleMessage)
async def example_message_handler(message: ExampleMessage):
RECEIVED_MESSAGES_COUNT.inc()
time_of_receiving = perf_counter_ns()
exchange_time = (time_of_receiving - message.SendTime) / 1_000_000 # this division is a conversion from nanoseconds to milliseconds
MESSAGE_EXCHANGE_DURATION_GAUGE.set(exchange_time)
Note that message.SendTime is a field of the custom class ExampleMessage. It's not a part of ArconQ SDK.
Exploring the Prometheus libraries
For more information about used libraries please refer to their documentation:
- .Net
- Python
- prometheus-net documentation: Learn how to instrument .NET applications for Prometheus monitoring.
- python-client documentation: Explore features for custom metrics and integrations.