6767
6868from ..propagate import NoExtractTraceContextPropagator , WarnOnExtractTraceContextPropagator
6969from ..types import ExceptionCallback
70+ from ..variables .config import VariablesConfig
71+ from ..variables .providers .abstract import NoOpVariableProvider , VariableProvider
72+ from ..variables .providers .local import LogfireLocalProvider
7073from .client import InvalidProjectName , LogfireClient , ProjectAlreadyExists
7174from .config_params import ParamManager , PydanticPluginRecordValues
7275from .constants import (
@@ -258,6 +261,44 @@ class CodeSource:
258261 """
259262
260263
264+ @dataclass (init = False )
265+ class VariablesOptions :
266+ """Configuration of managed variables."""
267+
268+ provider : VariableProvider
269+ include_resource_attributes_in_context : bool = True
270+ include_baggage_in_context : bool = True
271+
272+ def __init__ (
273+ self ,
274+ provider : VariableProvider | VariablesConfig | None = None ,
275+ include_resource_attributes_in_context : bool = True ,
276+ include_baggage_in_context : bool = True ,
277+ ):
278+ if isinstance (provider , VariablesConfig ):
279+ provider = LogfireLocalProvider (provider )
280+ elif not provider :
281+ provider = NoOpVariableProvider ()
282+
283+ self .provider = provider
284+ self .include_resource_attributes_in_context = include_resource_attributes_in_context
285+ self .include_baggage_in_context = include_baggage_in_context
286+
287+ # """Provider for resolving values of Variables.
288+ #
289+ # Defaults to setting an OFREP-compatible provider that hits Logfire's API."""
290+ #
291+ # create_remote_spans: bool = True
292+ # """Whether to insert OTel spans for variable resolution when using the Logfire OFREP provider.
293+ #
294+ # Has no impact if using a non-Logfire provider."""
295+ #
296+ # create_local_spans: bool | None = None
297+ # """Whether to open OTel spans for variable resolution in the process.
298+ #
299+ # Defaults to True if using a non-Logfire provider, otherwise False."""
300+
301+
261302class DeprecatedKwargs (TypedDict ):
262303 # Empty so that passing any additional kwargs makes static type checkers complain.
263304 pass
@@ -282,6 +323,7 @@ def configure( # noqa: D417
282323 min_level : int | LevelName | None = None ,
283324 add_baggage_to_attributes : bool = True ,
284325 code_source : CodeSource | None = None ,
326+ variables : VariablesOptions | None = None ,
285327 distributed_tracing : bool | None = None ,
286328 advanced : AdvancedOptions | None = None ,
287329 ** deprecated_kwargs : Unpack [DeprecatedKwargs ],
@@ -346,6 +388,7 @@ def configure( # noqa: D417
346388 add_baggage_to_attributes: Set to `False` to prevent OpenTelemetry Baggage from being added to spans as attributes.
347389 See the [Baggage documentation](https://logfire.pydantic.dev/docs/reference/advanced/baggage/) for more details.
348390 code_source: Settings for the source code of the project.
391+ variables: Options related to managed variables.
349392 distributed_tracing: By default, incoming trace context is extracted, but generates a warning.
350393 Set to `True` to disable the warning.
351394 Set to `False` to suppress extraction of incoming trace context.
@@ -482,6 +525,7 @@ def configure( # noqa: D417
482525 sampling = sampling ,
483526 add_baggage_to_attributes = add_baggage_to_attributes ,
484527 code_source = code_source ,
528+ variables = variables ,
485529 distributed_tracing = distributed_tracing ,
486530 advanced = advanced ,
487531 )
@@ -546,6 +590,9 @@ class _LogfireConfigData:
546590 code_source : CodeSource | None
547591 """Settings for the source code of the project."""
548592
593+ variables : VariablesOptions
594+ """Settings related to managed variables."""
595+
549596 distributed_tracing : bool | None
550597 """Whether to extract incoming trace context."""
551598
@@ -573,6 +620,7 @@ def _load_configuration(
573620 min_level : int | LevelName | None ,
574621 add_baggage_to_attributes : bool ,
575622 code_source : CodeSource | None ,
623+ variables : VariablesOptions | None ,
576624 distributed_tracing : bool | None ,
577625 advanced : AdvancedOptions | None ,
578626 ) -> None :
@@ -639,6 +687,8 @@ def _load_configuration(
639687 code_source = CodeSource (** code_source ) # type: ignore
640688 self .code_source = code_source
641689
690+ self .variables = variables or VariablesOptions ()
691+
642692 if isinstance (advanced , dict ):
643693 # This is particularly for deserializing from a dict as in executors.py
644694 advanced = AdvancedOptions (** advanced ) # type: ignore
@@ -682,6 +732,7 @@ def __init__(
682732 sampling : SamplingOptions | None = None ,
683733 min_level : int | LevelName | None = None ,
684734 add_baggage_to_attributes : bool = True ,
735+ variables : VariablesOptions | None = None ,
685736 code_source : CodeSource | None = None ,
686737 distributed_tracing : bool | None = None ,
687738 advanced : AdvancedOptions | None = None ,
@@ -711,6 +762,7 @@ def __init__(
711762 min_level = min_level ,
712763 add_baggage_to_attributes = add_baggage_to_attributes ,
713764 code_source = code_source ,
765+ variables = variables ,
714766 distributed_tracing = distributed_tracing ,
715767 advanced = advanced ,
716768 )
@@ -720,6 +772,7 @@ def __init__(
720772 # note: this reference is important because the MeterProvider runs things in background threads
721773 # thus it "shuts down" when it's gc'ed
722774 self ._meter_provider = ProxyMeterProvider (NoOpMeterProvider ())
775+ self ._variable_provider = NoOpVariableProvider ()
723776 self ._logger_provider = ProxyLoggerProvider (NoOpLoggerProvider ())
724777 try :
725778 from opentelemetry .sdk ._events import EventLoggerProvider as SDKEventLoggerProvider
@@ -750,6 +803,7 @@ def configure(
750803 min_level : int | LevelName | None ,
751804 add_baggage_to_attributes : bool ,
752805 code_source : CodeSource | None ,
806+ variables : VariablesOptions | None ,
753807 distributed_tracing : bool | None ,
754808 advanced : AdvancedOptions | None ,
755809 ) -> None :
@@ -772,6 +826,7 @@ def configure(
772826 min_level ,
773827 add_baggage_to_attributes ,
774828 code_source ,
829+ variables ,
775830 distributed_tracing ,
776831 advanced ,
777832 )
@@ -1103,6 +1158,9 @@ def fix_pid(): # pragma: no cover
11031158 ) # note: this may raise an Exception if it times out, call `logfire.shutdown` first
11041159 self ._meter_provider .set_meter_provider (meter_provider )
11051160
1161+ self ._variable_provider .shutdown ()
1162+ self ._variable_provider = self .variables .provider
1163+
11061164 multi_log_processor = SynchronousMultiLogRecordProcessor ()
11071165 for processor in log_record_processors :
11081166 multi_log_processor .add_log_record_processor (processor )
0 commit comments