You can use the com.snowflake.telemetry.Telemetry class in the Snowflake Telemetry API library to emit trace events from a function or
procedure handler written in Scala. The Telemetry class is included with Snowflake.
Snowflake currently supports the following versions of Scala:
Using the Snowflake Telemetry Library adds other libraries to your function or procedure’s execution environment. For more information,
see Snowflake telemetry package dependencies.
To use Telemetry methods, you must make the open source Snowflake telemetry package available to your handler code.
In the PACKAGES clause in your CREATE PROCEDURE or CREATE FUNCTION statement, include the com.snowflake:telemetry package. The
PACKAGES clause makes the included Snowflake Telemetry API available to your code.
Code in the following example uses the PACKAGES clause to reference the Telemetry library as well as the Snowpark library (which is
required for stored procedures written in Scala – for more information, see Writing Scala handlers for stored procedures created with SQL).
You can add trace events by calling the Telemetry.addEvent method, passing a name for the event. You can also optionally associate
attributes – key-value pairs – with an event.
Code in the following example adds an event called testEvent, associating with the event two attributes: key and
result.
// Adding an event without attributes.Telemetry.addEvent("testEvent")// Adding an event with attributes.AttributeseventAttributes=Attributes.of(AttributeKey.stringKey("key"),"run",AttributeKey.longKey("result"),Long.valueOf(123))Telemetry.addEvent("testEventWithAttributes",eventAttributes)
Adding these events results in two rows in the event table, each with a different value in the RECORD column:
{"name":"testEvent"}
{"name":"testEventWithAttributes"}
The testEventWithAttributes event row includes the following attributes in the row’s RECORD_ATTRIBUTES column:
You can add custom spans that are separate from the default span created by Snowflake. For details on custom spans, see
Adding custom spans to a trace.
Code in the following example uses the OpenTelemetry API and OpenTelemetry context propagation API to create a new my.span
span. It then adds an event to the new span. Finally, the code ends the span to have the span’s event data captured in the event table.
If the code doesn’t call the Span.end method, data is not captured in the event table.
CREATEORREPLACEFUNCTIONtestScalaUserSpans(xVARCHAR)RETURNSVARCHARLANGUAGESCALARUNTIME_VERSION=2.12PACKAGES=('com.snowflake:telemetry:latest')HANDLER='TestScalaClass.run'AS$$classTestScalaClass{importcom.snowflake.telemetry.Telemetryimportio.opentelemetry.api.GlobalOpenTelemetryimportio.opentelemetry.api.trace.Tracerimportio.opentelemetry.api.trace.Spanimportio.opentelemetry.context.Scopedefrun(x:String):String={valtracer:Tracer=GlobalOpenTelemetry.getTracerProvider().get("my.tracer")valspan:Span=tracer.spanBuilder("my.span").startSpan()span.addEvent("test event from scala")span.end()returnx}} $$;
CREATEORREPLACEFUNCTIONtestScalaUserSpans(xVARCHAR)RETURNSVARCHARLANGUAGESCALARUNTIME_VERSION=2.13PACKAGES=('com.snowflake:telemetry:latest')HANDLER='TestScalaClass.run'AS$$classTestScalaClass{importcom.snowflake.telemetry.Telemetryimportio.opentelemetry.api.GlobalOpenTelemetryimportio.opentelemetry.api.trace.Tracerimportio.opentelemetry.api.trace.Spanimportio.opentelemetry.context.Scopedefrun(x:String):String={valtracer:Tracer=GlobalOpenTelemetry.getTracerProvider().get("my.tracer")valspan:Span=tracer.spanBuilder("my.span").startSpan()span.addEvent("test event from scala")span.end()returnx}} $$;
CREATEORREPLACEPROCEDUREdo_tracing()RETURNSSTRINGLANGUAGESCALARUNTIME_VERSION='2.12'PACKAGES=('com.snowflake:snowpark_2.12:latest','com.snowflake:telemetry:latest')HANDLER='ProcedureHandler.run'AS$$importcom.snowflake.snowpark_java.Sessionimportcom.snowflake.telemetry.Telemetryimportio.opentelemetry.api.common.AttributeKeyimportio.opentelemetry.api.common.AttributesclassProcedureHandler{defrun(session:Session):String={// Set span attribute.Telemetry.setSpanAttribute("example.proc.do_tracing","begin")// Add an event without attributes.Telemetry.addEvent("run_method_start")// Add an event with attributes.valeventAttributes:Attributes=Attributes.of(AttributeKey.stringKey("example.method.name"),"run")Telemetry.addEvent("event_with_attributes",eventAttributes)// Set span attribute.Telemetry.setSpanAttribute("example.proc.do_tracing","complete")return"SUCCESS"}} $$;
CREATEORREPLACEPROCEDUREdo_tracing()RETURNSSTRINGLANGUAGESCALARUNTIME_VERSION='2.13'PACKAGES=('com.snowflake:snowpark_2.13:latest','com.snowflake:telemetry:latest')HANDLER='ProcedureHandler.run'AS$$importcom.snowflake.snowpark_java.Sessionimportcom.snowflake.telemetry.Telemetryimportio.opentelemetry.api.common.AttributeKeyimportio.opentelemetry.api.common.AttributesclassProcedureHandler{defrun(session:Session):String={// Set span attribute.Telemetry.setSpanAttribute("example.proc.do_tracing","begin")// Add an event without attributes.Telemetry.addEvent("run_method_start")// Add an event with attributes.valeventAttributes:Attributes=Attributes.of(AttributeKey.stringKey("example.method.name"),"run")Telemetry.addEvent("event_with_attributes",eventAttributes)// Set span attribute.Telemetry.setSpanAttribute("example.proc.do_tracing","complete")return"SUCCESS"}} $$;