feat(infra): grupo fleet-metrics — collect_host_metrics, format_prom_exposition, push_prom_remote, push_loki_stream, collect_battery_metrics + tipo PromSample (gopsutil; Android-safe: sin exec/pidfd, procesos via /proc)
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
---
|
||||
name: format_prom_exposition
|
||||
kind: function
|
||||
lang: go
|
||||
domain: infra
|
||||
version: "1.0.0"
|
||||
purity: pure
|
||||
signature: "func FormatPromExposition(samples []PromSample, timestampMs int64) string"
|
||||
description: "Convierte un slice de PromSample en texto con formato Prometheus exposition (una linea por sample: name{k=\"v\"} value timestampMs). Ordena labels por clave (salida determinista), escapa backslash/comilla/newline en valores de label, sanitiza el nombre de metrica a [a-zA-Z0-9_:], formatea el valor con FormatFloat 'g'. Si timestampMs<=0 omite el timestamp; sin labels omite las llaves. Funcion pura."
|
||||
tags: [prometheus, exposition, metrics, format, fleet-metrics, infra, monitoring]
|
||||
uses_functions: []
|
||||
uses_types: ["PromSample_go_infra"]
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: ""
|
||||
imports: ["sort", "strconv", "strings"]
|
||||
params:
|
||||
- name: samples
|
||||
desc: "slice de PromSample a serializar; cada uno aporta una linea de exposition"
|
||||
- name: timestampMs
|
||||
desc: "timestamp en milisegundos epoch a adjuntar a cada linea; si es <=0 se omite el campo timestamp"
|
||||
output: "string con el texto exposition Prometheus, una linea por sample terminada en \\n. String vacio si samples esta vacio."
|
||||
tested: true
|
||||
tests:
|
||||
- "TestFormatPromExposition"
|
||||
test_file_path: "functions/infra/format_prom_exposition_test.go"
|
||||
file_path: "functions/infra/format_prom_exposition.go"
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```go
|
||||
samples := []PromSample{
|
||||
{Name: "node_load1", Value: 0.42},
|
||||
{Name: "node_cpu_core_percent", Labels: map[string]string{"core": "0"}, Value: 12.5},
|
||||
{Name: "node_disk_used_bytes", Labels: map[string]string{"mount": "/"}, Value: 1024},
|
||||
}
|
||||
text := FormatPromExposition(samples, 1700000000000)
|
||||
// node_load1 0.42 1700000000000
|
||||
// node_cpu_core_percent{core="0"} 12.5 1700000000000
|
||||
// node_disk_used_bytes{mount="/"} 1024 1700000000000
|
||||
```
|
||||
|
||||
## Cuando usarla
|
||||
|
||||
Cuando tengas un slice de PromSample (tipicamente de collect_host_metrics) y
|
||||
necesites serializarlo al formato de texto que entienden los endpoints de
|
||||
ingestion Prometheus (`/api/v1/import/prometheus` de VictoriaMetrics, pushgateway,
|
||||
etc.). Es el paso intermedio del capability group `fleet-metrics`: colecta ->
|
||||
formatea -> empuja. Al ser pura y determinista, tambien sirve para snapshots
|
||||
reproducibles y golden tests.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- El timestamp es **milisegundos** epoch (Prometheus exposition usa ms), no
|
||||
segundos. Pasa `time.Now().UnixMilli()`.
|
||||
- `timestampMs <= 0` (incluido 0) omite el campo timestamp por completo.
|
||||
- La label `instance` NO se gestiona aqui: si esta en `Labels` se serializa tal
|
||||
cual, pero la convencion del grupo es dejarla fuera y añadirla en el push via
|
||||
extra_label.
|
||||
- No agrupa por nombre ni emite lineas `# HELP` / `# TYPE`: salida cruda de
|
||||
series, suficiente para ingestion pero no para un endpoint /metrics canonico.
|
||||
- El nombre de metrica se sanitiza de forma destructiva: `node.cpu-percent!` se
|
||||
convierte en `node_cpu_percent_`. Nombra bien los samples en origen.
|
||||
Reference in New Issue
Block a user