# Interceptors

> For the complete documentation index, see [llms.txt](https://docs.temporal.io/llms.txt).
> Any documentation page is available as raw Markdown by appending `.md` to its URL.
> For related questions, query https://docs.temporal.io/api/retrieve?q=<question>&jtb=<job-to-be-done>&src=md-page&agent=<your-name> (no auth; returns JSON `{content, source_url, page_url}`, with `source_url` pointing to Markdown for docs pages). Don't include personal data or credentials.

Interceptors wrap inbound and outbound Temporal calls so you can apply shared behavior such as tracing, logging, or
authorization. See [Interceptors](/encyclopedia/interceptors) for the inbound vs outbound model.

Register them on the Client (`client.Options.Interceptors`), the Worker (`worker.Options.Interceptors`), or both. Full
API: [`go.temporal.io/sdk/interceptor`](https://pkg.go.dev/go.temporal.io/sdk/interceptor).

## Implement a Client interceptor

Embed `ClientInterceptorBase` on a type that implements `InterceptClient`, and embed
`ClientOutboundInterceptorBase` on a type that overrides the calls you want to intercept. Forward every call you don't
override to `Next` so the rest of the chain still runs.

<!--SNIPSTART go-interceptor-client-->
[go-sandbox/workers/interceptors/interceptor.go](https://github.com/temporalio/documentation-sdk-code-examples/blob/main/go-sandbox/workers/interceptors/interceptor.go)
```go
type loggingClientInterceptor struct {
	interceptor.ClientInterceptorBase
}

func (loggingClientInterceptor) InterceptClient(
	next interceptor.ClientOutboundInterceptor,
) interceptor.ClientOutboundInterceptor {
	return &loggingClientOutboundInterceptor{
		ClientOutboundInterceptorBase: interceptor.ClientOutboundInterceptorBase{Next: next},
	}
}

type loggingClientOutboundInterceptor struct {
	interceptor.ClientOutboundInterceptorBase
}

func (l *loggingClientOutboundInterceptor) ExecuteWorkflow(
	ctx context.Context,
	in *interceptor.ClientExecuteWorkflowInput,
) (client.WorkflowRun, error) {
	log.Printf("starting workflow %q (%s)", in.Options.ID, in.WorkflowType)
	return l.Next.ExecuteWorkflow(ctx, in)
}
```
<!--SNIPEND-->

Register the interceptor when you create the Client:

<!--SNIPSTART go-interceptor-client-register-->
[go-sandbox/workers/interceptors/interceptor.go](https://github.com/temporalio/documentation-sdk-code-examples/blob/main/go-sandbox/workers/interceptors/interceptor.go)
```go
c, err := client.Dial(client.Options{
	Interceptors: []interceptor.ClientInterceptor{&loggingClientInterceptor{}},
})
```
<!--SNIPEND-->

Worker interceptors follow the same pattern for `WorkerInterceptorBase`, `WorkflowInboundInterceptorBase` /
`WorkflowOutboundInterceptorBase`, and `ActivityInboundInterceptorBase` / `ActivityOutboundInterceptorBase`. See the
[Logging Interceptor sample](https://github.com/temporalio/samples-go/tree/main/logger-interceptor) for a complete
Worker interceptor and its registration.

> **⚠️ Warning:**
> Workflow interceptors and replay
>
> Workflow interceptor methods also run during [replay](/develop/go/best-practices/testing-suite#replay). Use replay-safe
> APIs for logging, randomness, and time.
>

## Related

- [Observability - Tracing](/develop/go/platform/observability#tracing)
- [Context propagation](/develop/go/best-practices/context-propagation)
- [Logging Interceptor sample](https://github.com/temporalio/samples-go/tree/main/logger-interceptor)
- [Plugins - Interceptors](/develop/plugins-guide#interceptors)
