@@ -181,6 +181,7 @@ def _span(
181
181
_span_name : str | None = None ,
182
182
_level : LevelName | int | None = None ,
183
183
_links : Sequence [tuple [SpanContext , otel_types .Attributes ]] = (),
184
+ _warn_if_inside_generator : bool = True ,
184
185
) -> LogfireSpan :
185
186
try :
186
187
if _level is not None :
@@ -191,6 +192,20 @@ def _span(
191
192
else :
192
193
level_attributes = None
193
194
195
+ # we go two levels back to find the caller frame, as this method is called by logfire.span() method
196
+ caller_frame = inspect .currentframe ().f_back .f_back # type: ignore
197
+ # check if the caller is a generator function by checking the co_flags attribute of the code object
198
+ # and doing bit-wise AND checking for CO_GENERATOR or CO_ASYNC_GENERATOR value match
199
+ caller_is_generator = bool (
200
+ caller_frame and caller_frame .f_code .co_flags & (inspect .CO_GENERATOR | inspect .CO_ASYNC_GENERATOR )
201
+ )
202
+
203
+ if caller_is_generator and _warn_if_inside_generator :
204
+ warnings .warn (
205
+ 'Span is inside a generator function. See https://logfire.pydantic.dev/docs/reference/advanced/generators/#move-the-span-outside-the-generator.' ,
206
+ RuntimeWarning ,
207
+ )
208
+
194
209
stack_info = get_user_stack_info ()
195
210
merged_attributes = {** stack_info , ** attributes }
196
211
@@ -533,6 +548,7 @@ def span(
533
548
_span_name : str | None = None ,
534
549
_level : LevelName | None = None ,
535
550
_links : Sequence [tuple [SpanContext , otel_types .Attributes ]] = (),
551
+ _warn_if_inside_generator : bool = True ,
536
552
** attributes : Any ,
537
553
) -> LogfireSpan :
538
554
"""Context manager for creating a span.
@@ -552,18 +568,21 @@ def span(
552
568
_tags: An optional sequence of tags to include in the span.
553
569
_level: An optional log level name.
554
570
_links: An optional sequence of links to other spans. Each link is a tuple of a span context and attributes.
571
+ _warn_if_inside_generator: Set to `False` to prevent a warning when instrumenting a generator function.
555
572
attributes: The arguments to include in the span and format the message template with.
556
573
Attributes starting with an underscore are not allowed.
557
574
"""
558
575
if any (k .startswith ('_' ) for k in attributes ):
559
576
raise ValueError ('Attribute keys cannot start with an underscore.' )
577
+
560
578
return self ._span (
561
579
msg_template ,
562
580
attributes ,
563
581
_tags = _tags ,
564
582
_span_name = _span_name ,
565
583
_level = _level ,
566
584
_links = _links ,
585
+ _warn_if_inside_generator = _warn_if_inside_generator ,
567
586
)
568
587
569
588
@overload
0 commit comments