47 lines
1.2 KiB
Go
47 lines
1.2 KiB
Go
|
|
package adapter
|
||
|
|
|
||
|
|
import (
|
||
|
|
"bytes"
|
||
|
|
"context"
|
||
|
|
"encoding/json"
|
||
|
|
"net/http"
|
||
|
|
"time"
|
||
|
|
)
|
||
|
|
|
||
|
|
// HTTPTelemetry POSTs to the control plane, per docs/adapter-contract.md.
|
||
|
|
// It must never carry subscriber identity or post body text; callers control
|
||
|
|
// that by what they put in fields.
|
||
|
|
type HTTPTelemetry struct {
|
||
|
|
ControlURL string
|
||
|
|
hc *http.Client
|
||
|
|
}
|
||
|
|
|
||
|
|
// NewHTTPTelemetry builds a telemetry emitter posting to
|
||
|
|
// <controlURL>/control/v1/telemetry.
|
||
|
|
func NewHTTPTelemetry(controlURL string) *HTTPTelemetry {
|
||
|
|
return &HTTPTelemetry{ControlURL: controlURL, hc: &http.Client{Timeout: 10 * time.Second}}
|
||
|
|
}
|
||
|
|
|
||
|
|
func (t *HTTPTelemetry) Emit(ctx context.Context, event string, fields map[string]any) {
|
||
|
|
if t.ControlURL == "" {
|
||
|
|
return
|
||
|
|
}
|
||
|
|
payload := map[string]any{"event": event, "fields": fields}
|
||
|
|
body, err := json.Marshal(payload)
|
||
|
|
if err != nil {
|
||
|
|
return
|
||
|
|
}
|
||
|
|
req, err := http.NewRequestWithContext(ctx, http.MethodPost, t.ControlURL+"/control/v1/telemetry", bytes.NewReader(body))
|
||
|
|
if err != nil {
|
||
|
|
return
|
||
|
|
}
|
||
|
|
req.Header.Set("Content-Type", "application/json")
|
||
|
|
// Best-effort: a dropped telemetry event must never fail the publication
|
||
|
|
// it describes.
|
||
|
|
resp, err := t.hc.Do(req)
|
||
|
|
if err != nil {
|
||
|
|
return
|
||
|
|
}
|
||
|
|
_ = resp.Body.Close()
|
||
|
|
}
|