Documentation
¶
Overview ¶
Package maping is the framework-agnostic Core of the mAPI-ng client: hosted, zero-config API observability for Go services (see docs/context.md). It owns config/env parsing, the in-process Summary aggregation (counters + a latency DDSketch per series), and the background Connect uploader.
The guiding contract is zero-config (CONFIG.md): the only required input is the ingest key. With no key resolved, NewRecorder returns a no-op recorder so adding mAPI-ng to a codebase is always safe — activation is a matter of flipping an env var, decoupled from the code change. The client fails open: setup and upload problems are logged (rate-limited) and surfaced in the dashboard, but never panic or block the host.
A framework adapter (e.g. client/gin) extracts the route template and final status after each request and calls Observe with a neutral Record.
Index ¶
Constants ¶
const SdkVersion = "0.1.0"
SdkVersion is the client SDK version reported in every Envelope/Handshake for server-side compatibility handling.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
Key string
Endpoint string
Service string
Instance string
FlushWindow time.Duration
}
Config is the resolved recorder configuration.
type Option ¶
type Option func(*Config)
Option configures a Recorder. Options follow the functional-options pattern; a code option always beats the matching env var, which beats the default (CONFIG.md precedence).
func WithEndpoint ¶
WithEndpoint overrides the collector URL (beats MAPING_ENDPOINT).
func WithFlushWindow ¶
WithFlushWindow overrides the flush window (beats MAPING_FLUSH_SECONDS).
func WithInstance ¶
WithInstance overrides the instance id (beats MAPING_INSTANCE).
func WithService ¶
WithService overrides the logical service name (beats MAPING_SERVICE).
type Record ¶
type Record struct {
Method string
RouteTemplate string
Status int
Duration time.Duration
ReqBytes int64
RespBytes int64
}
Record is the neutral, framework-agnostic input to Observe. An adapter builds one from a completed request.
type Recorder ¶
type Recorder struct {
// contains filtered or unexported fields
}
Recorder aggregates request Records in process and ships Summaries on a flush cycle. A recorder with no resolved key is a no-op: every method is safe and does nothing, and no goroutine runs.
func NewRecorder ¶
NewRecorder resolves config and returns a Recorder. If the resolved key is empty (zero-config safety), it returns a no-op recorder with no goroutine. On a transport construction failure it logs once at Warn and also returns the no-op recorder — the host is never affected (CONFIG.md fail-open).
func NewRecorderForTest ¶
NewRecorderForTest returns a running Recorder wired to an injected Uploader, with a minimal config. It is the seam adapter tests use to substitute a fake transport and assert what was observed, without a live collector.
func (*Recorder) Observe ¶
Observe records one completed request. It is safe on a no-op recorder and safe for concurrent use.
The whole body is wrapped in a panic recovery: a bug in aggregation must be invisible to the host request (the core "mAPI-ng failing is invisible to the host" guarantee, docs/context.md). A recovered panic is logged once at Warn (rate-limited) and the observation is dropped.
Steady state (the series already exists) is allocation-free: shard select + lock + in-place counter increments + sketch.Add (itself alloc-free). Only the first sighting of a new series allocates (map insert + sketch.New).
func (*Recorder) Shutdown ¶
Shutdown stops the uploader goroutine, does a final flush (pushing the last window onto the ring), then synchronously drains the ring — attempting to send every pending request, bounded by ctx. A graceful shutdown therefore does not lose buffered summaries: it best-effort ships them before returning (this is what the E2E test relies on). Once ctx expires it stops retrying and returns; any still-pending requests are abandoned. It is synchronous and idempotent. Hosts must call it AFTER their http.Server.Shutdown so no request is still writing a Record.
type Uploader ¶
type Uploader interface {
Upload(ctx context.Context, req *mapingv1.UploadRequest) error
Register(ctx context.Context, hs *mapingv1.Handshake) error
}
Uploader is the transport dependency the Recorder needs. The concrete implementation lives in internal/transport; adapters and tests may inject a fake to observe uploads without a live collector (lang-go DI).
Directories
¶
| Path | Synopsis |
|---|---|
|
gin
module
|
|
|
internal
|
|
|
buffer
Package buffer implements a bounded, drop-oldest ring of pending UploadRequests for the mAPI-ng client's fail-open uploader (docs/context.md).
|
Package buffer implements a bounded, drop-oldest ring of pending UploadRequests for the mAPI-ng client's fail-open uploader (docs/context.md). |
|
transport
Package transport wraps the generated Connect IngestService client with the wire policy mAPI-ng requires: the gRPC protocol (ADR-0002) over a dedicated HTTP client with an explicit timeout, zstd send-compression, and cleartext HTTP/2 (H2C) for local/dev http:// endpoints.
|
Package transport wraps the generated Connect IngestService client with the wire policy mAPI-ng requires: the gRPC protocol (ADR-0002) over a dedicated HTTP client with an explicit timeout, zstd send-compression, and cleartext HTTP/2 (H2C) for local/dev http:// endpoints. |
|
Package sketch implements a hand-rolled DDSketch specialised for request latency aggregation, as decided in ADR-0001.
|
Package sketch implements a hand-rolled DDSketch specialised for request latency aggregation, as decided in ADR-0001. |