# Tracing your code (/docs/go/tracing-your-code)

Tracepanel records requests, SQL, logs and calls on its own. To see your own
code in a trace, wrap it in `tracepanel.Span`. To trace work that isn't a
request, use `tracepanel.Go` for a task and `tracepanel.Command` for a job.
To look at values while you work, print them with `tracepanel.Dump`.

## Span [#span]

`Span` starts a step of the trace in the context, until you call the
function it returns. The SQL, calls and logs made with the context it
returns go inside the step in the call tree:

```go
ctx, end := tracepanel.Span(ctx, "render invoice")
defer end()
```

Outside a trace, `Span` returns the context as it is.

## Go [#go]

`Go` runs a function on a goroutine of its own, as a task. The task is a
trace of its own, which the console lists under **Tasks**. The request that
started it shows the start as a step, and the task links back to it:

```go
tracepanel.Go(ctx, "send welcome email", func(ctx context.Context) error {
	return mailer.Send(ctx, user)
})
```

The task's context keeps the request's values, but isn't canceled when the
request ends. An error the function returns, or a panic, fails the task.

## Command [#command]

`Command` runs a function as a trace of its own, such as a scheduled job, a
command or a migration. The console lists it under **Jobs**:

```go
err := tracepanel.Command(ctx, "nightly report", func(ctx context.Context) error {
	return report.Build(ctx, db)
})
```

It returns what the function returns. An error or a panic fails the trace,
and the panic goes on.

## Programs without a server [#programs-without-a-server]

A worker or a command-line tool has no handler to wrap. Call
`tracepanel.Setup` first, and `tracepanel.Flush` before the program exits,
so its traces reach the agent:

```go
func main() {
	tracepanel.Setup(tracepanel.Config{Service: "shop-worker"})
	defer tracepanel.Flush(time.Second)

	_ = tracepanel.Command(context.Background(), "import feed", importFeed)
}
```

## SetUser [#setuser]

`SetUser` names the signed-in user on the trace in the context. Call it
where the app knows who is signed in, such as its auth middleware:

```go
tracepanel.SetUser(r.Context(), strconv.FormatInt(user.ID, 10), user.Email)
```

The trace gets `user.id`, and `user.username` when the username isn't
empty. The console shows whose request it was, and finds a user's traces.
The username stays on your machine. Outside a trace, `SetUser` does nothing.

## Dump [#dump]

`Dump` is a debug print. It prints each value with the expression that gave
it, as Go syntax, its type and its length, under the line that called it, on
stderr:

```go
tracepanel.Dump(ctx, order, user.Roles)
```

```text
handlers.go:42 checkout
    order: &main.Order{
        ID:    7,
        Items: []main.Item{},
    } (*main.Order)
    user.Roles: []string{"admin"} ([]string) len=1
```

When the context carries a trace, the dump is recorded too, on the span it
ran in, and the call tree always shows it, as a DUMP row. See
[Dumps](/docs/logs#dumps). It prints in every build, recorded or not. A
value whose expression names a secret, such as `password`, `token` or
`apiKey`, is masked, and so is a value inside one under such a name: a
struct's field, such as `Password` or `APIKey`, or a map's key, such as
`"session_id"`. It is masked printed and recorded alike. A name is read word
by word, as for a request: `authToken` is masked, `Author` isn't. A value is
cut at 16 KB.
