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:
Egutierrez
2026-06-07 14:25:45 +02:00
parent 8742cb25be
commit d996542f88
14 changed files with 1055 additions and 2 deletions
+64
View File
@@ -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.