Skip to content

perf(span-processor): defer span_formatter serialization behind DEBUG guard#1779

Open
samib6 wants to merge 1 commit into
langfuse:mainfrom
samib6:perf/defer-span-formatter-debug-logging
Open

perf(span-processor): defer span_formatter serialization behind DEBUG guard#1779
samib6 wants to merge 1 commit into
langfuse:mainfrom
samib6:perf/defer-span-formatter-debug-logging

Conversation

@samib6

@samib6 samib6 commented Jul 23, 2026

Copy link
Copy Markdown

What does this PR do?

LangfuseSpanProcessor.on_end logs the full span at DEBUG level with an f-string:

langfuse_logger.debug(f"... {span_formatter(span)}")

Because f-strings are built before the call, span_formatter(span) (a full span serialization) runs on every span even when DEBUG logging is off — and logger.debug then discards the string. Since on_end runs once per span, that's wasted work on the hot path when debug isn't enabled. See #15339 for the profiling details.

This guards the log behind isEnabledFor(logging.DEBUG) so the serialization only happens when the output would actually be emitted. I kept the change to this one hot call — the other debug logs in on_end are in rarely-hit early-return/error branches, so I left them alone to keep the diff small.

Fixes langfuse/langfuse#15339

Type of change

  • Bug fix

Verification

uv run --frozen pytest tests/unit/test_span_processor.py
uv run --frozen ruff check .
uv run --frozen mypy langfuse --no-error-summary

Added two tests: one checks span_formatter isn't called when the logger is above DEBUG (fails without this change), the other checks it still runs when DEBUG is on.

Checklist

  • I self-reviewed the diff using code_review.md.
  • I added or updated tests for behavior changes.
  • I updated docs, examples, or .env.template if needed. — n/a, internal-only change
  • I did not hand-edit generated files.
  • I did not commit secrets or credentials.

Greptile Summary

This PR avoids unnecessary span serialization when DEBUG logging is disabled.

  • Guards the hot-path debug log with isEnabledFor(logging.DEBUG).
  • Adds tests confirming formatting is skipped above DEBUG and retained at DEBUG.

Confidence Score: 5/5

The PR appears safe to merge with no actionable defects identified.

The new guard uses the standard logger’s effective-level check and preserves formatting whenever DEBUG is enabled while removing unnecessary serialization otherwise.

Reviews (1): Last reviewed commit: "perf(span-processor): defer span_formatt..." | Re-trigger Greptile

… guard

on_end evaluated span_formatter(span) via an f-string on every span regardless of log level, running a full serialization that was discarded when DEBUG was disabled. Guard it with isEnabledFor(DEBUG). Adds regression tests asserting span_formatter is not called when the logger is above DEBUG.

Fixes langfuse/langfuse#15339

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@CLAassistant

CLAassistant commented Jul 23, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

perf: span_processor.on_end evaluates span_formatter(span) eagerly via f-string regardless of log level

2 participants