Prometheus Metrics

Overview

OneIoT ACS 6.5.x exposes all application metrics through a single Prometheus-compatible endpoint using Micrometer. Two components publish metrics:

  • MetricsHandler — ACS device metrics (registrations, sessions, tasks, events), tagged application="acs"

  • ApiMetricsAspect — Subscription API metrics (request timing, errors, model-level breakdown), tagged application="subscription-api"

Both metric groups share the same scrape endpoint. Use the application tag to differentiate between them in Grafana dashboards and PromQL queries — for example: {application="acs"} vs {application="subscription-api"}.

Scrape Endpoint

Property Value

URL

/management/prometheus

Method

GET

Content-Type

text/plain; version=0.0.4

Authentication

Spring Boot Actuator security (configure via management.endpoints.web.exposure.include and Spring Security)

Enable the endpoint in application.yaml:

management:
  endpoints:
    web:
      exposure:
        include: prometheus,health,info
  prometheus:
    metrics:
      export:
        enabled: true

ACS Device Metrics (MetricsHandler)

These metrics are published via the internal event bus and capture device lifecycle, connectivity, and task activity.

Metric Name Type Tags Description

device_registrations_total

Counter

application, tenant, protocol

Number of new device registrations

device_removal_total

Counter

application, tenant, protocol

Number of device removals

device_connection_retries_total

Counter

application, retry

Device connection retry distribution (tag value = retry count)

device_session_duration_seconds

DistributionSummary

application, protocol

Duration of device sessions in seconds

device_message_length

DistributionSummary

application, protocol

Device message payload length in bytes

connection_failure_total

Counter

application, protocol, reason

Connection failure reasons (auth failure, license block, etc.)

task_status_distribution_total

Counter

application, tenant, status

Task status distribution (Pending, Success, Failed, etc.)

task_type_distribution_total

Counter

application, tenant, type

Task type distribution (Profile, SPV, GPV, etc.)

task_execution_method_total

Counter

application, tenant, method

How tasks were created (Device Update, API, Provisioning, etc.)

task_total_number_total

Counter

application, tenant

Total number of tasks created

event_trends_total

Counter

application, tenant

Total event count (all types)

event_distribution_total

Counter

application, tenant, type

Event distribution by event type name

Subscription API Metrics (ApiMetricsAspect)

These metrics are recorded by an AOP aspect wrapping every public method of ACSRestController.

Metric Name Type Tags Description

api_requests_seconds

Timer (histogram)

apiMethod, tenant, application, status

Request duration with histogram buckets. status is success or error.

api_errors_total

Counter

apiMethod, tenant, application, errorCode

Error count per error code

api_requests_model_total

Counter

apiMethod, tenant, application, modelName

Request count per device model (product class)

api_requests_model_duration_seconds

Timer (histogram)

apiMethod, tenant, application, modelName

Request duration per device model with histogram buckets

Timer metrics with publishPercentileHistogram() produce Prometheus histogram buckets (_bucket, _count, _sum) suitable for histogram_quantile() and bucket boundary queries.

Migration from 6.4.x to 6.5.x

In 6.4.x, the Subscription API had a custom metrics registry exposed at a separate endpoint. In 6.5.x, all metrics are unified under the standard Spring Boot Actuator Prometheus endpoint.

Endpoint Changes

In 6.4.x there were two separate metric endpoints — one for ACS device metrics and one for Subscription API metrics. In 6.5.x both are merged into a single standard Prometheus endpoint.

Metrics 6.4.x URL 6.5.x URL

ACS device metrics

http://<host>:<port>/ftacs/metrics (custom servlet, proprietary format)

http://<host>:<port>/ftacs/management/prometheus

Subscription API metrics

http://<host>:<port>/ftacs/subscription-metrics (custom registry, proprietary format)

http://<host>:<port>/ftacs/management/prometheus (same endpoint)

All metrics are now exposed in standard Prometheus exposition format (text/plain; version=0.0.4) from a single scrape target.

Update your Prometheus scrape_configs accordingly:

# 6.4.x (remove these)
- job_name: 'ftacs-device-metrics'
  metrics_path: '/ftacs/metrics'
- job_name: 'ftacs-subscription-metrics'
  metrics_path: '/ftacs/subscription-metrics'

# 6.5.x (replace with)
- job_name: 'ftacs'
  metrics_path: '/ftacs/management/prometheus'

Service Differentiation via application Tag

In 6.4.x, ACS device metrics and Subscription API metrics were separated by endpoint URL. In 6.5.x, both are served from a single endpoint. Use the application tag to distinguish between them:

Source application tag value Example PromQL filter

ACS device metrics (MetricsHandler)

acs

device_registrations_total{application="acs"}

Subscription API metrics (ApiMetricsAspect)

subscription-api

api_requests_seconds_count{application="subscription-api"}

If your 6.4.x Grafana dashboards used separate data sources or jobs for the two endpoints, replace that separation with an application label filter on the unified job.

Metric Name Mapping

Old Metric (6.4.x) New PromQL Equivalent (6.5.x)

api.requests.success.<method>

api_requests_seconds_count{status="success", apiMethod="<method>"}

api.requests.failed.<method>

api_requests_seconds_count{status="error", apiMethod="<method>"}

api.method.requests.<method>

api_requests_seconds_count{apiMethod="<method>"}

api.response.time.5s.product.class.<model>

api_requests_model_duration_seconds_bucket{apiMethod="<method>", modelName="<model>", le="5.0"}

api.response.time.10s.product.class.<model> (5s–10s range)

api_requests_model_duration_seconds_bucket{apiMethod="<method>", modelName="<model>", le="10.0"} - api_requests_model_duration_seconds_bucket{apiMethod="<method>", modelName="<model>", le="5.0"}

api.response.time.20s.product.class.<model> (10s–20s range)

api_requests_model_duration_seconds_bucket{apiMethod="<method>", modelName="<model>", le="20.0"} - api_requests_model_duration_seconds_bucket{apiMethod="<method>", modelName="<model>", le="10.0"}

api.response.time.21s.product.class.<model> (>20s)

api_requests_model_duration_seconds_count{apiMethod="<method>", modelName="<model>"} - api_requests_model_duration_seconds_bucket{apiMethod="<method>", modelName="<model>", le="20.0"}

api.response.time.5s.api.method.<method>

api_requests_seconds_bucket{apiMethod="<method>", le="5.0"}

api.response.time.10s.api.method.<method> (5s–10s range)

api_requests_seconds_bucket{apiMethod="<method>", le="10.0"} - api_requests_seconds_bucket{apiMethod="<method>", le="5.0"}

api.response.time.20s.api.method.<method> (10s–20s range)

api_requests_seconds_bucket{apiMethod="<method>", le="20.0"} - api_requests_seconds_bucket{apiMethod="<method>", le="10.0"}

api.response.time.21s.api.method.<method> (>20s)

api_requests_seconds_count{apiMethod="<method>"} - api_requests_seconds_bucket{apiMethod="<method>", le="20.0"}

api.error.code.<code>

api_errors_total{errorCode="<code>"}

api.database.requests / api.device.requests

Removed — the target tag has been eliminated. Use apiMethod tag to distinguish request types.

Prometheus histogram buckets are cumulative. le="5.0" contains all requests ≤ 5 seconds. To get requests in the 5s–10s range, subtract: bucket{le="10.0"} - bucket{le="5.0"}.