Skip to content

Metrics Export for Prometheus

This feature enables to programmatically generate custom metrics that Prometheus can scrape.

The system automatically exposes all defined metrics on the endpoint:

http://<hostname>:8091/metrics

This allows Prometheus to collect, store, and query your applicationโ€™s runtime data.

What Is Exposed

The metrics are exported in the Prometheus exposition format. Each metric has:

  • A name, prefixed automatically with p6core_scripts_
  • An optional set of labels (key/value pairs)
  • A numeric value (integer or float)

Example

p6core_scripts_request_count{method="GET",status="200"} 123
p6core_scripts_request_count{method="POST",status="500"} 5
p6core_scripts_active_users 456

Defining Metrics in a Script

All metrics must be defined inside a script named MetricsCollector in the script service.

Note

To ensure metrics can be provided with minimal load on Platform 6 runtime, script service scripts are cached for a number of milliseconds The default time to live for this cache is 60 seconds and may be customised using the configuration attribute: p6.service.scripts.metrics.cache.ttl

The DSL provides a helper function:

p6.pipeline.put('<metricNameWithOptionalLabels>', '<numericValue>')
  • <metricNameWithOptionalLabels>: must start with metric. and can include optional labels in curly braces {} using the syntax {key:"value",key2:"value2"}.
  • <numericValue>: must be a string representation of a number

Example

A simple metric without labels.

p6.pipeline.put('metric.active_users', '456')

Produces:

p6core_scripts_active_users 456.0

Labels allow you to track different dimensions of the same metric (e.g., HTTP method, status code, region).

p6.pipeline.put('metric.http_requests_total{method:"GET",status:"200"}', '1200')
p6.pipeline.put('metric.http_requests_total{method:"GET",status:"500"}', '3')

Produces:

p6core_scripts_http_requests_total{method="GET",status="200"} 1200
p6core_scripts_http_requests_total{method="GET",status="500"} 3

Notice

You can reuse the same metric name (http_requests_total) as long as the labels differ.

If the Metric script is attached to an application, then the application key () will automatically be included in the metric name.

p6.pipeline.put('metric.response_time', '250')

For an app with key o2c, this produces:

p6core_scripts_o2C_response_time 250

This ensures metrics are namespaced per application when needed.

How Metric Names Are Built

Metric names follow these rules:

  1. All metrics start with the prefix:
p6core_scripts_
  1. If attached to an app, the is inserted:
p6core_scripts_<appKey>_<metricName>
  1. Otherwise, only the metric name is used:
p6core_scripts_<metricName>
  1. Metric names should follow Prometheus best practices:
  • Lowercase letters
  • Words separated by underscores (_)
  • Use a unit suffix where applicable (e.g., _seconds, _bytes, _total)

Note

The system automatically replaces any non-alphanumeric characters in the metric name with underscores (_).

Examples of Good Metric Design

Example

Script snippet:

p6.pipeline.put('metric.http_requests_total{method:"GET",status:"200"}', '150')
p6.pipeline.put('metric.http_requests_total{method:"GET",status:"500"}', '2')
p6.pipeline.put('metric.http_requests_total{method:"POST",status:"200"}', '45')

Output:

p6core_scripts_http_requests_total{method="GET",status="200"} 150
p6core_scripts_http_requests_total{method="GET",status="500"} 2
p6core_scripts_http_requests_total{method="POST",status="200"} 45

Script snippet:

p6.pipeline.put('metric.request_duration_seconds{endpoint:"/login"}', '0.245')
p6.pipeline.put('metric.request_duration_seconds{endpoint:"/checkout"}', '1.132')

Output:

p6core_scripts_request_duration_seconds{endpoint="/login"} 0.245
p6core_scripts_request_duration_seconds{endpoint="/checkout"} 1.132

Rules & Best Practices

๐Ÿ‘‰ Always start with metric.

  • The system will ignore any metric not starting with metric.
  • The system automatically applies the p6core_scripts_ prefix.

๐Ÿ‘‰ Use labels to differentiate dimensions instead of creating many metric names.

  • Bad: metric.login_success, metric.login_failure
  • Good: metric.login_attempts{status:"success"} and metric.login_attempts{status:"failure"}

๐Ÿ‘‰ Values must be numbers.

  • Integers or floats are supported.
  • Strings, booleans, or other values are not valid.

๐Ÿ‘‰ Consistent naming conventions:

  • Use lowercase.
  • Use underscores _ instead of spaces.
  • Add unit suffixes, such as:
  • _seconds for durations
  • _bytes for sizes
  • _total for counters

๐Ÿ‘‰ Application context:

  • If the script is attached to an app, donโ€™t include the app name in the metric. It will be added automatically.

Common Mistakes & Troubleshooting

โŒ Mistake โœ… Correct Example Why?
dsl.metric.put(‘requests’, ‘100’) dsl.metric.put(‘metric.requests_total’, ‘100’) Must start with metric.
dsl.metric.put(‘metric.cpu_usage’, ‘high’) dsl.metric.put(‘metric.cpu_usage’, ‘0.87’) Value must be numeric
dsl.metric.put(‘metric.requests{status=200}’, ‘50’) dsl.metric.put(‘metric.requests{status:”200”}’, ‘50’) Labels must use key:”value” syntax
dsl.metric.put(‘metric.LoginAttempts’, ‘42’) dsl.metric.put(‘metric.login_attempts_total’, ‘42’) Must use lowercase, underscore, and unit suffix

Full Example with App Key

Script:

dsl.metric.put('metric.http_requests_total{method:"GET",status:"200"}', '1200')
dsl.metric.put('metric.http_requests_total{method:"GET",status:"500"}', '3')
dsl.metric.put('metric.memory_usage_bytes', '1048576')

If attached to an app with key billing, the exposed metrics are:

product_metric_billing_http_requests_total{method="GET",status="200"} 1200
product_metric_billing_http_requests_total{method="GET",status="500"} 3
product_metric_billing_memory_usage_bytes 1048576