# Set Up Logs in Go | Sentry for Iris

##### Now in Beta

Sentry Logs is currently in Beta. Features are still in-progress and may have bugs. We recognize the irony. For any questions or feedback, you can reach us on [Discord](https://discord.gg/sentry.md) or [GitHub](https://github.com/getsentry/sentry/discussions/86804.md).

With Sentry Structured Logs, you can send text based log information from your applications to Sentry. Once in Sentry, these logs can be viewed alongside relevant errors, searched by text-string, or searched using their individual attributes.

## [Requirements](https://docs.sentry.io/.md#requirements)

Logs in Go are supported in Sentry Go SDK version `0.33.0` and above.

## [Setup](https://docs.sentry.io/.md#setup)

To enable logging, you need to initialize the SDK with the `EnableLogs` option set to true.

```go
package main

import (
	"context"
	"github.com/getsentry/sentry-go"
	"time"
)

func main() {
  if err := sentry.Init(sentry.ClientOptions{
    Dsn:        "https://examplePublicKey@o0.ingest.sentry.io/0",
    EnableLogs: true,
	}); err != nil {
  	fmt.Printf("Sentry initialization failed: %v\n", err)
  }
  // Flush buffered events before the program terminates.
  // Set the timeout to the maximum duration the program can afford to wait.
  defer sentry.Flush(2 * time.Second)
}
```

## [Usage](https://docs.sentry.io/.md#usage)

Once the feature is enabled on the SDK and the SDK is initialized, you can send logs by using the `sentry.Logger` API.

The `Sentry.Logger` API exposes methods that support six different log levels: `trace`, `debug`, `info`, `warn`, `error` and `fatal`. The methods support both `fmt.Print` and `fmt.Printf` like syntax. If you pass in format specifiers like `%v`, these will be sent to Sentry, and can be searched from within the Logs UI, and even added to the Logs views as a dedicated column.

```go
ctx := context.Background()
logger := sentry.NewLogger(ctx)

// You can use the logger like [fmt.Print]
logger.Info(ctx, "Hello ", "world!")
// Or like [fmt.Printf]
logger.Infof(ctx, "Hello %v!", "world")
```

You can also pass additional attributes to the logger via the `SetAttributes` function. These attributes will also be searchable in the Logs UI.

```go
package main

import (
	"context"
	"github.com/getsentry/sentry-go"
	"github.com/getsentry/sentry-go/attribute"
	"time"
)

func main() {
	err := sentry.Init(sentry.ClientOptions{
		Dsn:        "https://examplePublicKey@o0.ingest.sentry.io/0",
		EnableLogs: true,
	})
	if err != nil {
		panic(err)
	}
	defer sentry.Flush(2 * time.Second)

	ctx := context.Background()
	logger := sentry.NewLogger(ctx)

	logger.SetAttributes(
		attribute.Int("key.int", 42),
		attribute.Bool("key.boolean", true),
		attribute.Float64("key.float", 42.4),
		attribute.String("key.string", "string"),
	)
	logger.Warnf(ctx, "I have params: %v and attributes", "example param")
}
```

Currently the `attribute` API supports only these value types: `int`, `string`, `bool`, and `float`.

## [Integrations](https://docs.sentry.io/.md#integrations)

### [`io.Writer` interface](https://docs.sentry.io/.md#iowriter-interface)

The `sentry.Logger` implements the `io.Writer` interface, so you can easily inject the logger into your existing setup.

```go
sentryLogger := sentry.NewLogger(ctx)
logger := log.New(sentryLogger, "", log.LstdFlags)
logger.Println("Implementing log.Logger")

slogger := slog.New(slog.NewJSONHandler(sentryLogger, nil))
slogger.Info("Implementing slog.Logger")
```

In order to properly attach the correct trace with each Log entry, a `context.Context` is required. The `Write` function of the `io.Writer` interface doesn't provide `context`, so wrapping the custom logger will not get the trace and current span attached. We recommend using the `sentry.Logger` to ensure your logs are connected to spans and errors in the Sentry UI.

### [Integrations](https://docs.sentry.io/.md#integrations-1)

* [Slog](https://docs.sentry.io/platforms/go/guides/slog.md)
* [Logrus](https://docs.sentry.io/platforms/go/guides/logrus.md)

### [Upcoming Integrations](https://docs.sentry.io/.md#upcoming-integrations)

We're actively working on adding more integration support for Logs. Currently, we are looking at adding support for [`zerolog`](https://pkg.go.dev/github.com/rs/zerolog.md). You can follow this [GitHub issue](https://github.com/getsentry/sentry-go/issues/1015.md) to track progress.

## [Options](https://docs.sentry.io/.md#options)

### [BeforeSendLog](https://docs.sentry.io/.md#beforesendlog)

To filter logs, or update them before they are sent to Sentry, you can use the `BeforeSendLog` client option.

```go
if err := sentry.Init(sentry.ClientOptions{
  Dsn:        "https://examplePublicKey@o0.ingest.sentry.io/0",
  EnableLogs: true,
  BeforeSendLog: func(log *Log) *Log {
    // filter out all trace logs
    if log.Level == sentry.LogLevelTrace {
      return nil
    }

    // filter all logs below warning
    if log.Severity <= LogSeverityInfo {
      return nil
    }
  },
}); err != nil {
  fmt.Printf("Sentry initialization failed: %v\n", err)
}
```

### [Debug](https://docs.sentry.io/.md#debug)

If the `Debug` init option is set to true, calls to the `sentry.Logger` will also print to the console with the appropriate log level.
