Generates the exposition format using the basic Prometheus text format. Params: registry: Collector to export data from. escaping: Escaping scheme used for metric and label names. Returns: UTF-8 encoded string containing the metrics in text format.
(registry: Collector = REGISTRY, escaping: str = openmetrics.UNDERSCORES)
| 263 | |
| 264 | |
| 265 | def generate_latest(registry: Collector = REGISTRY, escaping: str = openmetrics.UNDERSCORES) -> bytes: |
| 266 | """ |
| 267 | Generates the exposition format using the basic Prometheus text format. |
| 268 | |
| 269 | Params: |
| 270 | registry: Collector to export data from. |
| 271 | escaping: Escaping scheme used for metric and label names. |
| 272 | |
| 273 | Returns: UTF-8 encoded string containing the metrics in text format. |
| 274 | """ |
| 275 | |
| 276 | def sample_line(samples): |
| 277 | if samples.labels: |
| 278 | labelstr = '{0}'.format(','.join( |
| 279 | # Label values always support UTF-8 |
| 280 | ['{}="{}"'.format( |
| 281 | openmetrics.escape_label_name(k, escaping), openmetrics._escape(v, openmetrics.ALLOWUTF8, False)) |
| 282 | for k, v in sorted(samples.labels.items())])) |
| 283 | else: |
| 284 | labelstr = '' |
| 285 | timestamp = '' |
| 286 | if samples.timestamp is not None: |
| 287 | # Convert to milliseconds. |
| 288 | timestamp = f' {int(float(samples.timestamp) * 1000):d}' |
| 289 | if escaping != openmetrics.ALLOWUTF8 or openmetrics._is_valid_legacy_metric_name(samples.name): |
| 290 | if labelstr: |
| 291 | labelstr = '{{{0}}}'.format(labelstr) |
| 292 | return f'{openmetrics.escape_metric_name(samples.name, escaping)}{labelstr} {floatToGoString(samples.value)}{timestamp}\n' |
| 293 | maybe_comma = '' |
| 294 | if labelstr: |
| 295 | maybe_comma = ',' |
| 296 | return f'{{{openmetrics.escape_metric_name(samples.name, escaping)}{maybe_comma}{labelstr}}} {floatToGoString(samples.value)}{timestamp}\n' |
| 297 | |
| 298 | output = [] |
| 299 | for metric in registry.collect(): |
| 300 | try: |
| 301 | mname = metric.name |
| 302 | mtype = metric.type |
| 303 | # Munging from OpenMetrics into Prometheus format. |
| 304 | if mtype == 'counter': |
| 305 | mname = mname + '_total' |
| 306 | elif mtype == 'info': |
| 307 | mname = mname + '_info' |
| 308 | mtype = 'gauge' |
| 309 | elif mtype == 'stateset': |
| 310 | mtype = 'gauge' |
| 311 | elif mtype == 'gaugehistogram': |
| 312 | # A gauge histogram is really a gauge, |
| 313 | # but this captures the structure better. |
| 314 | mtype = 'histogram' |
| 315 | elif mtype == 'unknown': |
| 316 | mtype = 'untyped' |
| 317 | |
| 318 | output.append('# HELP {} {}\n'.format( |
| 319 | openmetrics.escape_metric_name(mname, escaping), metric.documentation.replace('\\', r'\\').replace('\n', r'\n'))) |
| 320 | output.append(f'# TYPE {openmetrics.escape_metric_name(mname, escaping)} {mtype}\n') |
| 321 | |
| 322 | om_samples: Dict[str, List[str]] = {} |