Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable exporting spans to snowflake stage if a TruLensSnowflakeSpanExporter is provided #1708

Merged
merged 74 commits into from
Jan 17, 2025

Conversation

sfc-gh-gtokernliang
Copy link
Contributor

@sfc-gh-gtokernliang sfc-gh-gtokernliang commented Jan 4, 2025

Description

Enable exporting spans to a snowflake stage if SnowflakeConnector is provided.

Other details good to know for developers

N/A

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to
    not work as expected)
  • New Tests
  • This change includes re-generated golden test results
  • This change requires a documentation update

Important

Add TruLensSnowflakeSpanExporter to export spans to Snowflake stage and refactor OTEL tracing in TruSession.

  • New Feature:
    • Introduced TruLensSnowflakeSpanExporter in exporter/snowflake.py to export spans to Snowflake stage.
    • Added _export_to_snowflake_stage method for exporting spans as protobuf files.
  • Refactoring:
    • Removed span_context and tokens from App class in app.py.
    • Replaced OTEL context management with _prevent_invalid_otel_syntax in app.py.
    • Moved convert_to_any_value to exporter/utils.py.
  • Session Management:
    • Updated TruSession to handle SpanExporter and TracerProvider in session.py.
    • Added experimental_force_flush method to TruSession for flushing spans.
  • Testing:
    • Updated tests in test_exporter.py and test_otel_instrument.py to reflect new exporter functionality.
    • Regenerated golden test results in api.trulens.3.11.yaml and api.trulens_eval.3.11.yaml.

This description was created by Ellipsis for 4e27038. It will automatically update as commits are pushed.

Copy link

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@sfc-gh-gtokernliang sfc-gh-gtokernliang force-pushed the garett/SNOW-1871920 branch 2 times, most recently from 8d2cece to b4bbdbf Compare January 6, 2025 15:41
@sfc-gh-gtokernliang sfc-gh-gtokernliang changed the title [WIP] Exporting spans to snowflake stage Enable exporting spans to snowflake stage if a SnowflakeConnector is provided Jan 6, 2025
@sfc-gh-gtokernliang sfc-gh-gtokernliang marked this pull request as ready for review January 6, 2025 15:51
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Jan 6, 2025
@@ -972,6 +970,22 @@ async def __aexit__(self, exc_type, exc_value, exc_tb):

return

def __call__(self, *, run_name: str, input_id: str):
if not self.session.experimental_feature(
Copy link
Contributor

Choose a reason for hiding this comment

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

sorry can you explain to me what's going on in this function?

Copy link
Contributor Author

@sfc-gh-gtokernliang sfc-gh-gtokernliang Jan 14, 2025

Choose a reason for hiding this comment

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

haha - this might not have been the best way to achieve this.

The goal is to enable syntax that looks like:

    with custom_app(run_name='run_name', input_id='input_id') as recording:
        test_app.respond_to_query(input)

to achieve this - custom_app(run_name='run_name', input_id='input_id') should return an object that is a recording context (in our case a class with the __enter__ and __exit__ methods), and that the setting of the run_name and input_id shouldn't taint the object itself.

hence - the approach here is, when custom_app is called, it:

  1. Checks that OTEL tracing is enabled
  2. creates a clone of itself using model_construct + model_dump that is classed to OTELRecordingContext (see https://github.com/truera/trulens/pull/1708/files/5a555840da38b280a0b3c3cbabb40cbd8a3e93c4#diff-25f7f4954d77bc71539bcd8d1e7b3133552596b468bf53a6962b636b176de682R96)
  3. then performs the normal recording context duties

src/core/trulens/core/session.py Outdated Show resolved Hide resolved
Base automatically changed from garett/add-utils to main January 16, 2025 19:30
if not core_instruments.Instrument._have_context():
raise RuntimeError(core_endpoint._NO_CONTEXT_WARNING)

def _prevent_invalid_otel_syntax(self):
Copy link
Contributor

Choose a reason for hiding this comment

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

why did you name this function this? Like what do you mean by otel tracing syntax?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

basically trying to force the user to use syntax that looks like:

with app():
  ...

or

with app(run_name=run_name, input_id=input_id):
   ...

as opposed to the conventional

with app:
   ...

this is because we need to be able to return a different object in order to avoid the possibility of polluting the App

@sfc-gh-gtokernliang sfc-gh-gtokernliang changed the title Enable exporting spans to snowflake stage if a SnowflakeConnector is provided Enable exporting spans to snowflake stage if a TruLensSnowflakeSpanExporter is provided Jan 17, 2025
# For use as a context manager.
def __enter__(self):
if not core_instruments.Instrument._have_context():
raise RuntimeError(core_endpoint._NO_CONTEXT_WARNING)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

we want to force the user to use syntax that looks like:

with app():
 ...

which will allow us to return a wrapping class around app to hold the OTEL properties, to avoid the risk of OTEL properties being mixed between invocations

if not core_instruments.Instrument._have_context():
raise RuntimeError(core_endpoint._NO_CONTEXT_WARNING)

def _prevent_invalid_otel_syntax(self):
Copy link
Contributor Author

Choose a reason for hiding this comment

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

basically trying to force the user to use syntax that looks like:

with app():
  ...

or

with app(run_name=run_name, input_id=input_id):
   ...

as opposed to the conventional

with app:
   ...

this is because we need to be able to return a different object in order to avoid the possibility of polluting the App

@dosubot dosubot bot added size:XXL This PR changes 1000+ lines, ignoring generated files. and removed size:XL This PR changes 500-999 lines, ignoring generated files. labels Jan 17, 2025
# There might be nested records - in those scenarios use the outer one.
if not get_baggage(SpanAttributes.RECORD_ID):
self.attach_to_context(SpanAttributes.RECORD_ID, otel_record_id)

self.attach_to_context(SpanAttributes.APP_NAME, self.app.app_name)
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you do the same as RECORD_ID For the other attributes? Since I guess the APP_NAME and other stuff aren't thread safe since if you call the child LLM app then continue working the baggage will get changed on you.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed attach_to_context to check for existence + ensure that value is non null

@sfc-gh-dkurokawa sfc-gh-dkurokawa merged commit 4dc14a6 into main Jan 17, 2025
9 of 10 checks passed
@sfc-gh-dkurokawa sfc-gh-dkurokawa deleted the garett/SNOW-1871920 branch January 17, 2025 18:05
@sfc-gh-jreini sfc-gh-jreini mentioned this pull request Jan 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
size:XXL This PR changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants