Conversation
ea9e0ef to
d01c936
Compare
a1249f6 to
cf7326b
Compare
4f4387b to
54a049f
Compare
sbalabanov
left a comment
There was a problem hiding this comment.
Missing pieces:
- error classification integration
- working with histograms for both status and duration and an example on custom buckets
|
|
||
| Tango is a library. Consumers wire it into their own `fx` graph with their own `tally.Scope`, and often deploy multiple flavors (long-running server, batch job, one-shot CLI) side-by-side. Without a shared convention every deployment invents its own metric names and tag layout, and dashboards devolve into per-name merges. | ||
|
|
||
| This package owns: |
There was a problem hiding this comment.
should this file be README.md under observability/metrics then?
There was a problem hiding this comment.
following https://github.com/uber-go/fx/tree/d5da5b04ac906bfbad8b400baeee9b970c1be6f3/docs/src
this is meant to be usage doc
…local metrics Rework metrics.md around the revised proposal: a concrete Tally-backed Emitter that binds and returns instruments, explicit dependency injection instead of context propagation, domain-local operation/metric names and bucket policies, controller-boundary request classification, per-series in-flight counters, and explicit no-op construction.
…ing-method errors Refine the revised metrics design: remove the gauge/in-flight tracking, drop the central shared-conventions vocabulary, and return instruments directly from the binding methods (only New surfaces a nil-scope wiring error). Add a Request-specific tags example.
|
updated based on discussion offline. |
…Params Show per-component buckets as a default owned by the package, overridable through the component's Params (zero value falls back), and add the requestMetrics constructor with the same default-and-override handling.
…ord call Collapse the Begin/Complete/requestAttempt two-phase into one deferred Record(start, err); fold the duplicated GetChangedTargets handler into a single example; align the request counter name on 'called'.
… Begin/Complete Begin increments called and returns the start time; Complete records duration and outcome. Keeps the entry-vs-exit ordering without the requestAttempt handle or sync.Once.
… Record called was redundant with succeeded + failed once Complete is deferred, so drop it and the two-phase Begin/Complete in favor of a single deferred Record(start, err).
…uest binding Build requestMetrics per request from a repo-tagged emitter so succeeded/failed/duration break down by repo; rely on tally name+tags caching to bind each (op, repo) series once. Trim request-specific tags to the cardinality rules.
…nd-once claims Make newQueryMetrics take positional emitter+buckets (drop exported MetricParams) to match newRequestMetrics, and soften the two bound-once statements so they don't over-generalize past the per-request request metrics.
| e := c.emitter.Tagged(map[string]string{ | ||
| tagRepo: common.ToShortRemote(req.GetFirstRevision().GetRemote()), | ||
| }) | ||
| m := newRequestMetrics(e, opGetChangedTargets, c.requestDurationBuckets) |
There was a problem hiding this comment.
requestmetrics need to be per-repo, so this is initialized per request.
There was a problem hiding this comment.
Is it really needed to create a metrics structure per each metric type emitted?
SubmitQueue uses simpler structure with standalone helper functions and a general scope object:
https://github.com/uber/submitqueue/blob/main/submitqueue/orchestrator/controller/start/start.go#L76-L77
https://github.com/uber/submitqueue/blob/main/submitqueue/orchestrator/controller/validate/validate.go#L92-L93
There was a problem hiding this comment.
there's a concern of scopes being tagged everywhere which is expensive.
I updated with a memoization approach in each domain, what do you think?
| // New creates an emitter for scope. A nil scope is a configuration error. | ||
| func New(scope tally.Scope) (*Emitter, error) | ||
|
|
||
| // Nop creates an explicitly disabled emitter. |
There was a problem hiding this comment.
how would it do so if Emitter is not an interface? With noop tally scope?
There was a problem hiding this comment.
Yes
func Nop() *Emitter { return &Emitter{scope: tally.NoopScope} }
| e := c.emitter.Tagged(map[string]string{ | ||
| tagRepo: common.ToShortRemote(req.GetFirstRevision().GetRemote()), | ||
| }) | ||
| m := newRequestMetrics(e, opGetChangedTargets, c.requestDurationBuckets) |
There was a problem hiding this comment.
Is it really needed to create a metrics structure per each metric type emitted?
SubmitQueue uses simpler structure with standalone helper functions and a general scope object:
https://github.com/uber/submitqueue/blob/main/submitqueue/orchestrator/controller/start/start.go#L76-L77
https://github.com/uber/submitqueue/blob/main/submitqueue/orchestrator/controller/validate/validate.go#L92-L93
…ency Address review feedback on the metrics design: - Record outcomes as one result-tagged latency histogram instead of separate success/failure counters; counts derive from the histogram. - Add a begin/complete request pattern (started counter at Begin, result- tagged latency histogram at Complete). - Restore shared vocabulary constants (operation names, tag keys, result values) in names.go so outcomes tag consistently across operations. - Fill in concise Emitter method bodies and note Nop wraps NoopScope.
…ain memoization - Move Begin/Complete out of the metrics package into each domain struct (graphRunnerMetrics, requestMetrics) — memoization is domain-local. - Metrics package exports Emitter + constants + Outcome() only. - Standardize start/finish naming convention across all operations. - Domain structs pre-build result-tagged emitters at construction; controller memoizes per (repo, result) pair. - Buckets declared at each callsite, not as package defaults. - Add ResultCancelled for context.Canceled/DeadlineExceeded. - Add M3QL query examples for start rate, outcome counts, P95 latency.
…egin/Complete - Switch domain-local example from graphrunner to orchestrator - Emitter.Tagged is stateless; memoization is per-domain struct - Each domain owns Begin/Complete, op struct, and tagged emitter cache - Metrics package exports only Emitter + constants + Outcome() - Orchestrator example shows repo-memoized Begin/Complete pattern
add Tango Metrics Inventory RFC into the repo. Covers the Emitter contract and its usage in callsites