Implement planned topic: 0023-buffered-metrics#218
Open
skill-temporal-developer-updater[bot] wants to merge 2 commits into
Open
Implement planned topic: 0023-buffered-metrics#218skill-temporal-developer-updater[bot] wants to merge 2 commits into
skill-temporal-developer-updater[bot] wants to merge 2 commits into
Conversation
Adds TypeScript reference for the MetricMeter API and MetricsBuffer, covering all four instrument types (Counter, UpDownCounter, Gauge, Histogram), how to access the meter from worker/workflow/activity contexts, and how to drain BufferedMetricUpdate events for custom export. Grounded against the TS SDK typedoc since the local docs clone is silent on these APIs. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Validation Report —
buffered-metricsBranch:
draft/0023-buffered-metricsAuthored files:
references/typescript/buffered-metrics.md(new, 221 lines, 29 typedoc citation tags)references/typescript/observability.md(4-line cross-link block added)Source of truth used: TypeScript SDK source (
https://github.com/temporalio/sdk-typescriptmain branch, especiallypackages/common/src/metrics.ts,packages/worker/src/runtime.ts,packages/worker/src/runtime-metrics.ts,packages/worker/src/runtime-options.ts, andpackages/test/src/test-runtime-buffered-metrics.ts) and the published typedoc attypescript.temporal.io. The skill's<!-- typedoc: … -->citation form requires this, since the APIs covered (MetricMeter,MetricsBuffer, etc.) do not appear indocumentation/docs/.Go / no-go
references/integrations.mduntouchedOverall verdict: MINOR FIXES. All four required checks meet their numerical thresholds. One substantive code-correctness issue was found while auditing the setup pattern; it appears in two code blocks and is a targeted fix that does not require re-authoring. Per the template's verdict rubric (§5), the formal sample passing at ≥ 95% and Checks 1/3 clean would normally be GO, but the issue is significant enough to call out and fix before merge.
Check 1 — Citation audit
All 29
<!-- typedoc: … -->tags resolve to real symbols in the SDK source.common.MetricMeter(and#withTags,#createUpDownCounter)packages/common/src/metrics.tsMetricMeterinterfacecreateUpDownCounteris declared optional (?) on the interface; the skill doesn't note this, but it's only relevant if a user implementsMetricMeterthemselves, which is not the documented path.common.MetricCounter,common.MetricUpDownCounter,common.MetricGauge,common.MetricHistogramextends Metricand pins its ownkindand (for counter/up-down-counter)valueType.common.MetricKindtype MetricKind = 'counter' | 'histogram' | 'gauge' | 'up-down-counter'common.MetricTagstype MetricTags = Record<string, string | number | boolean>common.NumericMetricValueTypetype NumericMetricValueType = 'int' | 'float'common namespace#noopMetricMeterexport const noopMetricMeter = new NoopMetricMeter()worker.MetricsBuffer(and#retrieveUpdates)packages/worker/src/runtime-metrics.tsclass MetricsBufferretrieveUpdates(): ArrayIterator<BufferedMetricUpdate>.worker.MetricsBufferOptions(and#maxBufferSize)maxBufferSize ?? 10000,useSecondsForDurations ?? false.worker.BufferedMetricUpdatemetric,value,attributesworker.Runtime(and#install,#metricMeter,#metricsBuffer)packages/worker/src/runtime.tsinstall(options)andinstance()are static methods;metricMeteris apublic readonlyinstance property;metricsBuffer: MetricsBuffer | undefinedis apublic readonlyinstance property.worker.RuntimeOptions,worker.PrometheusMetricsExporter,worker.OtelCollectorExporterpackages/worker/src/runtime-options.tsworkflow namespace#metricMeterpackages/workflow/src/metrics.tsexport const metricMeter: MetricMeter = …const, not a function.activity namespace#metricMeterpackages/activity/src/index.tsexport const metricMeter: MetricMeter = { … }const.activity namespace#metricMeteradjacent toActivityOutboundCallsInterceptor.getMetricTags()(line 93)metricMeterresolves correctly; the adjacentActivityOutboundCallsInterceptorsymbol resolves to theworkernamespace (worker.ActivityOutboundCallsInterceptor), notactivity.metricMeter— but a reader trying to importActivityOutboundCallsInterceptorwon't find it in@temporalio/activity. Not flagged as a finding because the tag's stated subject (metricMeter) is correct; flagged here for awareness.Citation count: 29 typedoc tags. Unresolved citations: 0.
Check 2 — Reverse-grep audit
Every factual token from the authored file was located in the SDK source.
MetricMeter,MetricCounter,MetricUpDownCounter,MetricGauge,MetricHistogram,MetricsBuffer,MetricsBufferOptions,BufferedMetricUpdate,MetricKind,MetricTags,NumericMetricValueType,Runtime,RuntimeOptions,TelemetryOptions,PrometheusMetricsExporter,OtelCollectorExporter,ActivityOutboundCallsInterceptor,Metric— all present.createCounter,createUpDownCounter,createGauge,createHistogram,add,set,record,withTags,retrieveUpdates,install,instance,getMetricTags— all present, on the symbols claimed.maxBufferSize,useSecondsForDurations,valueType,attributes,metric,value,kind,name,unit,description,metricMeter,metricsBuffer— all present."counter","histogram","gauge","up-down-counter","int","float"— all present.maxBufferSizedefault10000✓,useSecondsForDurationsdefaultfalse✓.RuntimeMetricMeterexported type" — verified, no such symbol is exported.@temporalio/worker,@temporalio/workflow,@temporalio/activity,@temporalio/common— each package'sindex.tsre-exports the claimed symbols.Unexplained misses: 0.
Check 3 — Regression on known bugs
No universal-regression patterns appear anywhere in the skill (no
--profileflag, noTEMPORAL_TLS_CLIENT_*_PATHvariants, notcld service-account, no--output text/jsonl, nosaas-api.tmprl.cloud:7233). Topic-specific regressions also clean:"upDownCounter"(camelCase) appears once on line 178 — inside the "Common mistakes" table, correctly identified as the wrong literal. Not a regression hit.retrieveBufferedMetrics()appears once on line 179 — inside the "Common mistakes" table, correctly identified as nonexistent. Confirmed againstpackages/worker/src/runtime.ts: no such method onRuntime.import { MetricsBuffer } from '@temporalio/common'appears once on line 180 — inside the "Common mistakes" table, correctly identified as wrong.MetricsBufferis in@temporalio/worker.valueTypeargument — flagged correctly as wrong in the table.Hits: 0.
Check 4 — Independent re-verification
Sampled claims (10 / 10 = 100% match)
valueType: "int")" (line 35)MetricCounter extends Metric { … valueType: 'int'; }andMetricUpDownCounter extends Metric { … valueType: 'int'; }inpackages/common/src/metrics.tsMetricKindis"counter" | "histogram" | "gauge" | "up-down-counter"" (line 37)export type MetricKind = 'counter' | 'histogram' | 'gauge' | 'up-down-counter'(same file)createGauge(name, valueType?, unit?, description?)(line 32)createGauge(name: string, valueType?: NumericMetricValueType, unit?: string, description?: string): MetricGaugewithTags(tags: MetricTags): <SameInstrument>" (line 49)withTags(tags: MetricTags)returning the same instrument type (e.g.MetricCounter)metricMeter… is a property, not a function" (line 53)workflow.metricMeterandactivity.metricMeterare exported asconst;Runtime#metricMeterispublic readonlyMetricsBuffer(exported from@temporalio/worker)" (line 99)export class MetricsBuffer { … }inpackages/worker/src/runtime-metrics.ts, re-exported frompackages/worker/src/index.tsmaxBufferSizedefault10000(line 120)this.maxBufferSize = options.maxBufferSize ?? 10000inMetricsBufferconstructoruseSecondsForDurationsdefaultfalse(line 121)this.useSecondsForDurations = options.useSecondsForDurations ?? falseretrieveUpdates()returns anArrayIterator<BufferedMetricUpdate>" (line 138)public retrieveUpdates(): ArrayIterator<BufferedMetricUpdate>inMetricsBuffernoopMetricMeter— calls are silently dropped" (line 95)noopMetricMeteris aNoopMetricMeterinstance with empty-body methods (add(_value, _extraTags) {}etc.); workflow / activity export fall back to it when no runtime is installedSubstantive out-of-sample finding
The sample passed at 100%, but during the broader audit I found one claim that is substantively wrong and will affect every reader who follows the skill's setup code.
Location:
references/typescript/buffered-metrics.mdlines 103–113 (Setup) and 187–192 (Worked example).Authored code:
What the source requires:
TelemetryOptions.metricshas typeMetricsExporterConfig, defined inpackages/worker/src/runtime-options.tsas:The SDK discriminates between exporters at runtime by checking property names:
'prometheus' in metrics(Prometheus),'otel' in metrics(OTel),'buffer' in metrics(buffered). The skill'smetrics: buffer(passing aMetricsBufferinstance directly) will (a) fail to typecheck against the union and (b) fail the runtime discriminator — none of'prometheus','otel', or'buffer'isinaMetricsBufferinstance.Correct form (confirmed by the SDK's own test in
packages/test/src/test-runtime-buffered-metrics.ts):Impact: every reader who copies the setup or worked-example code will produce non-compiling TypeScript and, if they bypass type checking, code that the SDK silently ignores (no metrics buffered). This is functionally a high-impact correctness defect even though it's localized.
Suggested fix: change two code blocks. Setup section: wrap
metrics: bufferinmetrics: { buffer }. Worked example: same. Optionally add one sentence to "Setup" noting the shape: "MetricsBufferis wired in via theBufferedMetricsExportershape —{ buffer }— alongside the Prometheus and OTel shapes."Check 6 — Tone and scope audit
End-to-end read of
buffered-metrics.md.Wrong | Fixform — the acceptable "don't do X, do Y" pattern, not a workaround disclosure.[!NOTE]admonition at the top (lines 3–4) noting the API is "experimental in the TypeScript SDK; the APIs may change", which matches the typedoc description's "experimental feature and may be subject to change". Phrasing is acceptable.Statistics
metrics: buffershape, in two code blocks)Suggested follow-up
A single small commit fixes the only substantive finding:
references/typescript/buffered-metrics.mdline ~110: changemetrics: buffer,tometrics: { buffer },.references/typescript/buffered-metrics.mdline ~192: same change in the worked example.No re-authoring pass required. After the fix, the skill should be GO.