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 (
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:
- All metrics start with the prefix:
p6core_scripts_
- If attached to an app, the
is inserted:
p6core_scripts_<appKey>_<metricName>
- Otherwise, only the metric name is used:
p6core_scripts_<metricName>
- 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"}
andmetric.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