Adding custom spans to a trace¶
You can add your own custom spans to traces for finer-grained tracing within the handler for a procedure or function.
By default, when you have tracing enabled, Snowflake starts a span for you (as described in How Snowflake represents trace events) and adds all trace events to that span. (This is known internally as the “auto_instrumented” span.) Using OpenTelemetry APIs, you can create your own spans. To the new span, you can add events and attributes using either the OpenTelemetry API or Snowflake API for your language.
You might want to create your own span when, for example, you want to isolate the trace data for computation-heavy actions that happen within a procedure, such as when you’re using the code to train an ML model.
Custom spans you create match the default behavior of spans created by OpenTelemetry.
Supported languages¶
You can add custom spans from code written in the following languages, including when handler code is written with Snowpark APIs.
Language/Type |
Java |
Python |
JavaScript |
Scala |
Snowflake Scripting |
---|---|---|---|---|---|
Stored procedure handler |
✔ |
✔ |
✔ |
✔ [1] |
|
Streamlit app |
✔ |
||||
UDF handler (scalar function) |
✔ |
✔ |
✔ |
✔ [1] |
|
UDTF handler (table function) |
✔ |
✔ |
✔ |
Creating a custom span¶
To add a custom span with handler code, use the OpenTelemetry API for your handler language within the existing Snowflake telemetry environment to create a new span, add events and attributes as needed, and then close the span.
Use the OpenTelemetry API to create a tracer to manage context for the span.
From this tracer created from the existing Snowflake telemetry environment, you can create custom spans that use the existing infrastructure in which trace data is captured by the event table.
From the new tracer, create the custom span with an API that ensures that the new span is the current span.
By creating the new span in the existing context managed by Snowflake, you ensure that information from the context — including the trace_id and parent_span_id values — is passed from the Snowflake default span to other spans.
When your code finishes with the custom span, it must close the span before the handler completes execution to have trace data captured by the event table.
This behavior of custom spans matches the default behavior of OpenTelemetry.
For information on adding a custom span with a supported language, see the following topics:
Python example¶
Code in the following example uses the OpenTelemetry Python API to create the my.span
span as the current span with
start_as_current_span
. It then adds an event with attributes to the new span using the OpenTelemetry Python API.
Event data won’t be captured by the event table unless the span ends before your handler completes execution. In this example, closing the
span happens automatically when the with
statement concludes.
CREATE OR REPLACE FUNCTION customSpansPythonExample() RETURNS STRING
LANGUAGE PYTHON
RUNTIME_VERSION = 3.9
PACKAGES = ('snowflake-telemetry-python', 'opentelemetry-api')
HANDLER = 'custom_spans_function'
AS $$
from snowflake import telemetry
from opentelemetry import trace
def custom_spans_function():
tracer = trace.get_tracer("my.tracer")
with tracer.start_as_current_span("my.span") as span:
span.add_event("Event2 in custom span", {"key1": "value1", "key2": "value2"})
return "success"
$$;