Propagate tags to child spans
Description
A logfire.span argument that allows child spans and records to inherit tags. All child spans (a relationship that looks to be defined by index in OPEN_SPANS) would inherit tags from surrounding spans that have propagate_tags=True. Spans that set the argument to False (the default) do not pass tags to child spans.
Proposal
logfire.config()
with logfire.span("first span", _tags=["one"], _propagate_tags=True): # has tag ["one"]
logfire.info("first") # has tag ["one"]
with logfire.span("second span", _tags=["two"]): # has tags ["one", "two"]
logfire.info("second", _tags=["t1"]) # has tag ["one", "t1"]
with logfire.span("third span", _tags=["three"], _propagate_tags=True) # has tags ["one", "three"]
logfire.info("third") # has tags ["one", "three"]
Try logfire.with_tags
@alexmojaki I don't think that will work across files. logfire.with_tags creates a new instance of logfire. if I create that new instance in file1.py and, within that file, create a span that encapsulates ClassInFile2().create() which exists in file2.py, I can't import the logfire instance from file1.py because of circular import issues.
Sorry if this is unclear or I am missing something
Can't you define the instance in another file that both file1 and file2 import?
I could hack this together in each of my projects.
(I would instantiate a Logfire instance (not using with_tags) in file3 and just keep updating its internal _tags attribute)
this is fine but it's not really a long term solution.
OK, I guess you're using tags in a way that's more dynamic than what with_tags was intended for.
I would recommend creating a context variable and passing the value to _tags rather than modifying a global shared logfire instance. But I understand that this is still inconvenient. We should create an API that automates this, without requiring opening a span, and that also propagates things like attributes and levels.
I usually define a convenience function in a logger config file and then use it as needed across the code base:
def get_tagged_logfire(tags: list[str] | None = None) -> logfire.Logfire :
if tags is None:
tags = []
if CONFIG.LOGFIRE_API_KEY:
logfire.configure(
token=CONFIG.LOGFIRE_API_KEY,
)
logger.configure(handlers=[logfire.loguru_handler()])
tlg = logfire.with_tags(*tags)
tlg.instrument_pydantic_ai()
return tlg
However, instruments don't consume these tags; only direct logfire statements will inherit these.
Baggage allows propagating attributes like this, but not tags yet.
Proposal: logfire.configure(baggaged_tags=['tag1', 'tag2'])
This means that if there are tag1 and tag2 keys in the baggage, then they can appear as tags in all the child spans.
This might be interesting: https://github.com/open-telemetry/opentelemetry-java/issues/11