OtlpMetrics exports unit "1" for metrics with no declared unit, so Prometheus backends rename gauges to *_ratio
メンテナーはふだん 1 日以内に返信
@effect-bot がすでに取り組んでいます。
2026年11月4日 から。
評価
この issue はまだ評価されていません。
説明
What version of Effect is running?
effect 4.1.2. We first hit this on 4.0.2.
What steps can reproduce the bug?
import { createServer } from 'node:http';
import { Effect, Layer, Metric } from 'effect';
import { OtlpMetrics, OtlpSerialization } from 'effect/observability';
import { FetchHttpClient } from 'effect/http';
const seen = new Map();
const server = createServer((req, res) => {
let body = '';
req.on('data', (chunk) => (body += chunk));
req.on('end', () => {
for (const rm of JSON.parse(body).resourceMetrics ?? [])
for (const sm of rm.scopeMetrics ?? [])
for (const m of sm.metrics ?? []) {
const dp = (m.gauge ?? m.sum ?? m.histogram)?.dataPoints?.[0];
seen.set(m.name, { unit: m.unit, attributes: dp?.attributes?.map((a) => a.key) });
}
res.setHeader('content-type', 'application/json');
res.end('{}');
});
});
await new Promise((r) => server.listen(4399, '127.0.0.1', r));
const telemetry = OtlpMetrics.layer({
url: 'http://127.0.0.1:4399/v1/metrics',
resource: { serviceName: 'probe' },
exportInterval: '200 millis',
}).pipe(Layer.provide(OtlpSerialization.layerJson), Layer.provide(FetchHttpClient.layer));
const program = Effect.gen(function* () {
yield* Metric.update(Metric.gauge('app_build_info'), 1);
yield* Metric.update(Metric.counter('app_events'), 1);
yield* Metric.update(Metric.gauge('app_workaround', { attributes: { unit: '' } }), 1);
yield* Effect.sleep('1 second');
});
await Effect.runPromise(program.pipe(Effect.provide(telemetry)));
console.log(Object.fromEntries(seen));
process.exit(0);
What is the expected behavior?
A metric with no declared unit is exported with an empty unit. unit is optional in the OpenTelemetry metrics API, and "1" is a claim the author never made: it means dimensionless.
What do you see instead?
app_build_info: { unit: '1', attributes: [] }
app_events: { unit: '1', attributes: [] }
app_workaround: { unit: '', attributes: [ 'unit' ] }
The default is in toUcumUnit, packages/effect/src/observability/OtlpMetrics.ts:533:
const toUcumUnit = (unit: string | undefined): string => unit === undefined ? "1" : ucumUnits.get(unit) ?? unit
Additional information
prometheus/otlptranslator appends _ratio to gauges whose unit is "1" (metric_namer.go). So app_build_info is stored as app_build_info_ratio. We found this in production on Mimir: alert rules written from the source name read an absent series, and no test in the emitting repo could see it.
The only workaround we found is attributes: { unit: '' }, as in app_workaround above. It also adds unit to the data point attributes.
Changing the default renames stored series for anyone already querying the _ratio names, so it may deserve a release note.
- 主要言語
- TypeScript
- スター
- 16.7k
- フォーク
- 808
- 平均マージ
- 11時間 29分
- マージ済み PR(30日)
- 837
環境構築
このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
Effect-TS/effect のほかの issue
-
A `SqlClient` layer satisfies a `PgClient` requirement at the type level, then fails with "Service not found"対応中かも @effect-bot が今日担当しました。 オープンbug
Effect-TS/effect#10374 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
HttpEffect.toHandled: accept a caller-owned request scope対応中かも @effect-bot が 1 日前に担当しました。 オープン
Effect-TS/effect#10364 · コメント 1 件 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
Schema tagged unions: isAnyOf accepts keys outside the union対応中かも @effect-bot が 1 日前に担当しました。 オープン
Effect-TS/effect#10351 · コメント 1 件 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
Schema.TaggedUnion: expose `members` and `discriminants`, as `toTaggedUnion` does対応中かも @effect-bot が 1 日前に担当しました。 オープン
Effect-TS/effect#10345 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
Schema.TaggedUnion: accept existing case schemas, not only field records対応中かも @effect-bot が 1 日前に担当しました。 オープン
Effect-TS/effect#10337 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
Effect-TS/effect の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
Open-Earth-Foundation/CityCatalyst#3399 ·
メンテナーはふだん 2 日以内に返信
-
userReport
難易度 1/5 1時間未満 初心者へのやさしさ 72/100
nkprasad12/morcus-net#631 ·
メンテナーはふだん 1 日以内に返信
-
fix(app): fail closed if GetGeneralSetting fails during initialization対応中かも @kalavt が今日担当しました。 オープンbug
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
メンテナーはふだん 1 日以内に返信
-
難易度 1/5 1時間未満 初心者へのやさしさ 85/100
nekko-labs/nekko-agent#1756 ·
メンテナーはふだん 1 日以内に返信
-
needs-area-label
難易度 2/5 1〜3時間 初心者へのやさしさ 66/100
メンテナーはふだん 2 日以内に返信