--- name: push_prom_remote kind: function lang: go domain: infra version: "1.0.0" purity: impure signature: "func PushPromRemote(endpoint string, user string, pass string, body string, extraLabels map[string]string) error" description: "Hace POST de un body en formato Prometheus exposition a un endpoint remoto (ej VictoriaMetrics /api/v1/import/prometheus). Soporta Basic Auth (si user!=\"\"), adjunta extraLabels como query params repetidos extra_label=clave=valor (VictoriaMetrics los añade a todas las series del push), Content-Type text/plain, http.Client con Timeout 10s y TLS verificado. Exito = status 2xx; si no, error con codigo + primeros 200 bytes del cuerpo de respuesta." tags: [prometheus, push, victoriametrics, remote-write, fleet-metrics, infra, monitoring, http] uses_functions: [] uses_types: [] returns: [] returns_optional: false error_type: "error_go_core" imports: ["fmt", "io", "net/http", "net/url", "strings", "time"] params: - name: endpoint desc: "URL completa del endpoint de ingestion, ej https://metrics-xxxx.organic-machine.com/api/v1/import/prometheus" - name: user desc: "usuario para Basic Auth; si es cadena vacia no se envia Authorization" - name: pass desc: "password para Basic Auth; se ignora si user esta vacio" - name: body desc: "texto en formato Prometheus exposition (tipicamente salida de format_prom_exposition)" - name: extraLabels desc: "labels a adjuntar a todas las series via extra_label, ej {\"instance\":\"lucas\"}; puede ser nil" output: "nil si el push devuelve status 2xx (VictoriaMetrics responde 204). Error si la request falla, el endpoint es invalido, o el status no es 2xx (con codigo y snippet del cuerpo)." tested: true tests: - "TestPushPromRemote" test_file_path: "functions/infra/push_prom_remote_test.go" file_path: "functions/infra/push_prom_remote.go" --- ## Ejemplo ```go body := FormatPromExposition(samples, time.Now().UnixMilli()) err := PushPromRemote( "https://metrics-xxxx.organic-machine.com/api/v1/import/prometheus", "ingest-user", "ingest-pass", body, map[string]string{"instance": "lucas-pc"}, ) if err != nil { log.Printf("push fallo: %v", err) } ``` ## Cuando usarla Cuando un nodo de la flota tiene que **empujar** sus metricas a un backend central (VictoriaMetrics, Mimir, pushgateway) en vez de exponer un /metrics para scraping. Es el paso final del capability group `fleet-metrics`: collect_host_metrics -> format_prom_exposition -> push_prom_remote. Tipica en nodos detras de NAT, moviles (Termux) o cualquier host al que el servidor central no puede alcanzar para hacer pull. ## Gotchas - **extra_label es clave=valor como un solo valor de query**: para {"instance":"lucas"} produce `?extra_label=instance%3Dlucas` (el `=` interno se URL-encodea a `%3D`). VictoriaMetrics lo aplica a todas las series del push; otros backends pueden no soportar este parametro. - **Secretos**: nunca hardcodees `user`/`pass` — resuelvelos desde `pass`/vault. - **TLS verificado** (sin InsecureSkipVerify): un endpoint con certificado autofirmado fallara. Usa un certificado valido o un proxy de confianza. - **Timeout 10s**: un backend lento o un body enorme puede dar timeout. Trocea pushes muy grandes si es necesario. - **204 No Content es exito**: VictoriaMetrics no devuelve 200. La funcion acepta cualquier 2xx; no asumas 200 al testear contra el real. - **El cuerpo de error se trunca a 200 bytes**: suficiente para diagnostico rapido, no para el detalle completo del backend.