Go SDK developer's guide - Observability
The observability section of the Temporal Developer's guide covers the many ways to view the current state of your Temporal Application—that is, ways to view which Workflow Executions are tracked by the Temporal Platform and the state of any specified Workflow Execution, either currently or at points of an execution.
This section covers features related to viewing the state of the application, including:
How to emit metrics
Each Temporal SDK is capable of emitting an optional set of metrics from either the Client or the Worker process. For a complete list of metrics capable of being emitted, see the SDK metrics reference.
Metrics can be scraped and stored in time series databases, such as:
Temporal also provides a dashboard you can integrate with graphing services like Grafana. For more information, see:
- Temporal's implementation of the Grafana dashboard
- How to export metrics in Grafana
To emit metrics from the Temporal Client in Go, create a metrics handler from the Client Options and specify a listener address to be used by Prometheus.
client.Options{
MetricsHandler: sdktally.NewMetricsHandler(newPrometheusScope(prometheus.Configuration{
ListenAddress: "0.0.0.0:9090",
TimerType: "histogram",
}
The Go SDK currently supports the Tally library; however, Tally offers extensible custom metrics reporting, which is exposed through the WithCustomMetricsReporter
API.
For more information, see the Go sample for metrics.
Tracing and Context Propagation
The Go SDK provides support for distributed tracing through OpenTracing. Tracing allows you to view the call graph of a Workflow along with its Activities and any Child Workflows.
Tracing can be configured by providing an opentracing.Tracer implementation in ClientOptions during client instantiation. For more details on how to configure and leverage tracing, see the OpenTracing documentation.
The OpenTracing support has been validated using Jaeger, but other implementations mentioned here should also work. Tracing functionality utilizes generic context propagation provided by the client.
Context Propagation
Temporal provides a standard way to propagate a custom context across a Workflow.
You can configure a context propagator in via the ClientOptions.
The context propagator extracts and passes on information present in context.Context
and workflow.Context
objects across the Workflow.
Once a context propagator is configured, you should be able to access the required values in the context objects as you would normally do in Go.
You can see how the Go SDK implements a tracing context propagator.
Server-Side Headers
On the server side, Temporal provides a mechanism for propagating context across Workflow transitions called headers.
message Header {
map<string, Payload> fields = 1;
}
Client
leverages headers to pass around additional context information.
HeaderReader and HeaderWriter are interfaces that allow reading and writing to the Temporal Server headers.
The SDK includes implementations for these interfaces.
HeaderWriter
sets a value for a header.
Headers are held as a map, so setting a value for the same key will overwrite its previous value.
HeaderReader
gets a value of a header.
It also can iterate through all headers and execute the provided handler function on each header, so that your code can operate on select headers you need.
type HeaderWriter interface {
Set(string, *commonpb.Payload)
}
type HeaderReader interface {
Get(string) (*commonpb.Payload, bool)
ForEachKey(handler func(string, *commonpb.Payload) error) error
}
Context Propagators
You can propagate additional context through Workflow Execution by using a context propagator.
A context propagator needs to implement the ContextPropagator
interface that includes the following four methods:
type ContextPropagator interface {
Inject(context.Context, HeaderWriter) error
Extract(context.Context, HeaderReader) (context.Context, error)
InjectFromWorkflow(Context, HeaderWriter) error
ExtractToWorkflow(Context, HeaderReader) (Context, error)
}
Inject
reads select context keys from a Go context.Context object and writes them into the headers using the HeaderWriter interface.InjectFromWorkflow
operates similar toInject
but reads from a workflow.Context object.Extract
picks select headers and put their values into the context.Context object.ExtractToWorkflow
operates similar toExtract
but write to a workflow.Context object.
The tracing context propagator shows a sample implementation of a context propagator.
Is there a complete example?
The context propagation sample configures a custom context propagator and shows context propagation of custom keys across a Workflow and an Activity. It also uses Jaeger for tracing.