Documentation
¶
Overview ¶
Package telemetry is the OpenTelemetry metrics both processes publish.
Push, over OTLP, and only when a collector is named. Neither process grows a listener for it: the GitHub controller holds App keys and must not have a port, and the service's ports are the issuer's. Where nothing names a collector, nothing is exported and every instrument records into a no-op — metrics cost nothing where nobody collects them.
Configuration is OpenTelemetry's own environment, read by its SDK: OTEL_EXPORTER_OTLP_ENDPOINT (or OTEL_EXPORTER_OTLP_METRICS_ENDPOINT and OTEL_EXPORTER_OTLP_TRACES_ENDPOINT), OTEL_EXPORTER_OTLP_HEADERS, OTEL_METRIC_EXPORT_INTERVAL, OTEL_TRACES_SAMPLER, OTEL_TRACES_SAMPLER_ARG, OTEL_SERVICE_NAME and OTEL_RESOURCE_ATTRIBUTES. Nothing here restates it.
Traces carry no personal data, and this package enforces that rather than hoping: see FilterExporter.
Index ¶
- Constants
- Variables
- func ConnectClientOptions() []connect.ClientOption
- func ConnectOptions() []connect.HandlerOption
- func Enabled() bool
- func FilterExporter(next sdktrace.SpanExporter) sdktrace.SpanExporter
- func HTTPHandler(next http.Handler, service string, route func(*http.Request) string) http.Handler
- func Start(ctx context.Context, service string, log *slog.Logger) (func(context.Context) error, error)
- func Tracer() trace.Tracer
- func TracesEnabled() bool
Constants ¶
const ( // AttrTargetKind is what a reconciler's tick is over: `github-tick`, // `slack-tick`, `github-links`. AttrTargetKind = "access_roster.target.kind" // AttrTargetID is the target's own name: a GitHub organisation or a Slack // workspace the policy declares. The one identifier a span may carry, and // never a person's. AttrTargetID = "access_roster.target.id" // AttrOutcome is how a tick ended: ok or failed. AttrOutcome = "access_roster.outcome" // AttrPort and AttrOperation name a storage port and the call on it. The // KEY of the call is never an attribute: it names a person. AttrPort = "access_roster.port" AttrOperation = "access_roster.operation" )
The span attribute names this repository sets itself.
const TracerName = "github.com/truvity/access-roster"
TracerName is the instrumentation scope of the spans this repository starts itself.
Variables ¶
var SpanAttributeAllowlist = map[attribute.Key]bool{ AttrTargetKind: true, AttrTargetID: true, AttrOutcome: true, AttrPort: true, AttrOperation: true, "rpc.system.name": true, "rpc.method": true, "rpc.response.status_code": true, "error.type": true, "http.request.method": true, "http.response.status_code": true, "http.route": true, }
SpanAttributeAllowlist is every attribute a span leaving this process may carry. The first group is ours: what a tick is over, how it ended, which port operation. The second is the shape of an RPC or an HTTP request, which names a method, a route and a status and nothing about the caller.
Everything else is dropped on the way out by FilterExporter, whoever set it: the HTTP instrumentation records the client's address, the user agent and the raw URL path, the RPC instrumentation records the peer, and a recorded error carries a message that may quote an address or a group. Spans are read by everyone with any grant on the trace store, so the rule that they hold no personal data (docs/decisions/0026-0032, docs/explanation/ports.md) has to be a property of the exporter and not a promise by each caller. Never an email, a subject, a group name, a token or its hash.
Functions ¶
func ConnectClientOptions ¶
func ConnectClientOptions() []connect.ClientOption
ConnectClientOptions is the same for a client: one client span per call, and the traceparent carried to the server.
func ConnectOptions ¶
func ConnectOptions() []connect.HandlerOption
ConnectOptions instruments a Connect handler: one server span per call, continuing the caller's trace. Its metrics are off: the HTTP handler's route metrics carry the request rate and latency under this service's own names.
func Enabled ¶
func Enabled() bool
Enabled reports whether a collector is named in the environment for metrics.
func FilterExporter ¶
func FilterExporter(next sdktrace.SpanExporter) sdktrace.SpanExporter
FilterExporter wraps an exporter so that only SpanAttributeAllowlist leaves the process. Span events (a recorded error's message is one), links' attributes and a status description are removed outright: they are free text.
func HTTPHandler ¶
HTTPHandler wraps a server's handler in a server span, continuing the caller's traceparent, and records the request count and duration per route.
route turns a request into one of a SMALL FIXED SET of names: it is the span's name, `http.route` and the metrics' `route` label, and a raw path must never reach any of them (a path carries callback codes, state and, on a console, names). The set is the caller's to keep bounded.
func Start ¶
func Start(ctx context.Context, service string, log *slog.Logger) (func(context.Context) error, error)
Start installs the global meter provider when a collector is named for metrics, and the global tracer provider (with the W3C trace-context propagator) when one is named for traces, and returns what flushes and stops them. Without a collector it installs nothing and the returned function does nothing.
func Tracer ¶
Tracer is the repository's tracer, on whatever provider is global: a no-op until Start installs one.
func TracesEnabled ¶
func TracesEnabled() bool
TracesEnabled reports whether a collector is named for traces: the same rule as for metrics, with the traces-specific variable. Unset means nothing is exported and the tracer is the API's no-op, which costs nothing.
Types ¶
This section is empty.