Skip to content

Conditionally create server spans for falcon#867

Merged
ocelotl merged 8 commits intoopen-telemetry:mainfrom
ashu658:conditional-server-span-falcon
Jan 21, 2022
Merged

Conditionally create server spans for falcon#867
ocelotl merged 8 commits intoopen-telemetry:mainfrom
ashu658:conditional-server-span-falcon

Conversation

@ashu658
Copy link
Copy Markdown
Member

@ashu658 ashu658 commented Jan 18, 2022

Description

Adds support to make spans as INTERNAL if a span is already present in current context in falcon.

Fixes #447

Type of change

Please delete options that are not relevant.

  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
    Currently falcon only makes SERVER spans. With this PR it can make INTERNAL spans in presence of a span in current context.

How Has This Been Tested?

Added unit test for the changes.
Manually tested the scenario.
To reproduce the issue: Add two instrumentors i.e. FalconInstrumentor and OpenTelemetryMiddleware in the same app. This creates two separate traces instead of one.

Does This PR Require a Core Repo Change?

  • No.

Checklist:

See contributing.md for styleguide, changelog guidelines, and more.

  • Followed the style guidelines of this project
  • Changelogs have been updated
  • Unit tests have been added
  • Documentation has been updated

@ashu658 ashu658 requested a review from a team January 18, 2022 10:48

token = context.attach(extract(env, getter=otel_wsgi.wsgi_getter))
token = ctx = span_kind = None

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this snippet is becoming pretty common. probably could take it out as a re-usable function.

Copy link
Copy Markdown
Member Author

@ashu658 ashu658 Jan 18, 2022

Choose a reason for hiding this comment

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

Added re-usable function to get the three variables. Could not think of better name. Please suggest.

start_time = _time_ns()

token = context.attach(extract(env, getter=otel_wsgi.wsgi_getter))
token, ctx, span_kind = get_token_context_span_kind(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I was thinking more like a wrapper function for start_span which internally takes care of checking server spans something like

span = _start_internal_or_server_span(name, start_time, context_getter)

this function would accept whatever is necessary to figure out if an existing span is present or not and decide internally whether to create a server span or an internal span, and which context to use as parent.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This function will need to return token also along with span.

start_internal_or_server_span(tracer, name, start_time, env, context_getter):
    ..
    create internal/server span
    ..
    
    return span, token

I am not sure if this is okay.
thinking of putting this function in instrumentation/utils.py

Also, we can shorten the recurring snippet if we want to skip the function
as the else part in the snippet is not necessary. Something like this:

token = context = None
span_kind = SpanKind.INTERNAL
if get_current_span() is INVALID_SPAN:
       context = extract(carrier, getter=carrier_getter)
       token = attach(context)
       span_kind = SpanKind.SERVER

Please share your thoughts.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This function will need to return token also along with span.

That sounds OK. It can return the span + token and let the caller store a reference to the token and detach it at a later time.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also, we can shorten the recurring snippet if we want to skip the function

The main issue is that this is a very specific piece of logic strictly followed by all server instrumentation so I think it makes sense to encapsulate the logic in a re-usable function that is easily discoverable and changeable in a single place. Number of lines of code is not a big deal.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Makes sense
Created wrapper for start_span.


def get_token_context_span_kind(env, getter):
"""Based on presence of active span, extracts context and initializes token and span_kind
def start_internal_or_server_span(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

should be private function so prefix with _

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done

def get_token_context_span_kind(env, getter):
"""Based on presence of active span, extracts context and initializes token and span_kind
def start_internal_or_server_span(
tracer, span_name, start_time, env, context_getter
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

env should be called context

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

changed to context_carrier as context is already imported module and context is extracted from env object.
Let me know if you want me to rename it.

@ocelotl ocelotl merged commit 8bb1e74 into open-telemetry:main Jan 21, 2022
@owais
Copy link
Copy Markdown
Contributor

owais commented Jan 21, 2022

Thanks @ashu658! Would be great to update other implementations to use the same function.

sanketmehta28 pushed a commit to sanketmehta28/opentelemetry-python-contrib that referenced this pull request Jan 22, 2022
* Making span as internal for falcon in presence of a span in current context

* Updating changelog

* Fixing lint and generate build failures

* Resolving comments: Converting snippet to re-usable function

* Fixing build failures

* Resolving comments: Creating wrapper for start span to make internal/server span

* Rerun docker tests

* Resolving comments: Refactoring
@ashu658
Copy link
Copy Markdown
Member Author

ashu658 commented Jan 25, 2022

Thanks @ashu658! Would be great to update other implementations to use the same function.

Sure @owais I will update other implementations in my next PR for tornado/other framework.

@ashu658 ashu658 deleted the conditional-server-span-falcon branch January 25, 2022 06:41
owais added a commit that referenced this pull request Jan 25, 2022
* code change to resolve the bug #449

* modifying the changelog file to add entry for PR #869

* removing redundent get statement

* Conditionally create server spans for falcon (#867)

* Making span as internal for falcon in presence of a span in current context

* Updating changelog

* Fixing lint and generate build failures

* Resolving comments: Converting snippet to re-usable function

* Fixing build failures

* Resolving comments: Creating wrapper for start span to make internal/server span

* Rerun docker tests

* Resolving comments: Refactoring

* Fix Django 1.9 issue preventing use of MIDDLEWARE_CLASSES (#870)

* Update CHANGELOG.md

* Fix Django 1.9 issue preventing use of MIDDLEWARE_CLASSES

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>

* changing the import trace statement to resolve issue with unit test cases

Co-authored-by: Ashutosh Goel <39601429+ashu658@users.noreply.github.com>
Co-authored-by: Dan <pezzer55@gmail.com>
Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
Co-authored-by: Owais Lone <owais@users.noreply.github.com>
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.

Falcon: Conditionally create SERVER spans

4 participants