-
[OPIK-4909] [BE] fix: use pre-computed gen_ai.usage.cost from OTel (#6893)
发布于
2026-06-01 10:53:46 +00:00 - [OPIK-4909] [BE] fix: use pre-computed gen_ai.usage.cost from OTel spans
LiteLLM and similar integrations send the exact request cost as the float
OTel attribute gen_ai.usage.cost. It matched the broad gen_ai.usage. prefix
rule and was routed to the integer-only usage map, where the double value
was silently dropped; Opik then recalculated cost from its bundled price
table, diverging from the value LiteLLM/Langfuse/PostHog report.Route gen_ai.usage.cost to a new COST outcome (registered before the
gen_ai.usage. prefix rule) that sets the span's totalEstimatedCost
directly, so the SDK/DAO treats it as authoritative and does not overwrite
it with a recalculated estimate.Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
- [OPIK-4909] [BE] fix: guard non-finite cost; consolidate cost tests
Address Baz review:
extractCostnow skips non-finiteDOUBLE_VALUEinputs (NaN, +/-
Infinity).BigDecimal.valueOfthrowsNumberFormatExceptionfor
those, which would abort the whole span-enrichment loop instead of
just dropping the cost.- Replace the two cost tests with one
@ParameterizedTest+
@MethodSourcecovering double, int, numeric string, non-numeric
string, NaN, +Infinity, and -Infinity. Keep the regression test that
guards against the original bug (cost leaking into the integer-only
usage map).
Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
- [OPIK-4909] [BE] refactor: address cost extractor review feedback
- Extract parseCostDouble / parseCostInt / parseCostString aux methods,
each with a RuntimeException catch so cost extraction never aborts
span enrichment. - Drop the explicit Double.isFinite guard; the try/catch now covers
NaN/Infinity uniformly with the same Optional.empty() outcome. - Switch trim() to strip() (Unicode-aware) and bump the string-parse
log to warn for consistency with the other branches. - Test: add newSpanBuilder() helper, fold the no-pollution regression
into the parameterized test (now exercises the usage-map guard for
every cost shape), and add a whitespace-strip case.
- [OPIK-4909] [BE] chore: log exception in cost parse warnings
Pass the caught RuntimeException to log.warn in parseCostDouble /
parseCostInt / parseCostString so the stack trace is preserved for
non-NumberFormatException cases now reachable via the wider catch.Keeps the RuntimeException catch per the prior review thread
(comment 3324055545); only the logging gap is closed.- [OPIK-4909] [BE] test: build cost-test span via Podam
Switch newSpanBuilder() to PodamFactoryUtils.newPodamFactory() +
.manufacturePojo(Span.class).toBuilder() per the test guidelines,
nulling out totalEstimatedCost so malformed-cost cases don't inherit
PODAM's random BigDecimal (enrich only writes the field on a
successful parse).
Co-authored-by: Claude Opus 4.7 (1M context) noreply@anthropic.com
下载附件