---
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.
