> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apitally.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Sampling

> Sample request logs and traces and exclude requests with the Apitally SDK for Go.

The Apitally SDK provides options for sampling request logs and traces and excluding requests you don't want to capture.

<Note>
  Requests excluded or sampled out won't be logged, but are still counted in metrics. To exclude endpoints from metrics, you can mark them as excluded in the [dashboard](/api-metrics/traffic#exclude-endpoints).
</Note>

## Default exclusions

The SDK automatically excludes common static assets and health check endpoints, such as `/robots.txt` or `/healthz`.

See the [data privacy](/data-privacy#data-filtering) page for more information about default exclusions.

## Sample rate

If your application receives a lot of traffic, you may want to sample requests to stay within your request logs quota.

Use `SampleRate` to capture only a fraction of requests. The default is `1.0`, which captures all requests.

```go theme={null}
cfg := apitally.NewConfig()
cfg.WriteToken = "your-write-token"
cfg.SampleRate = 0.1 // capture logs and traces for 10% of requests
apitally.Init(r, cfg)
```

To apply different sample rates based on custom criteria, see [Custom sampling](#custom-sampling) below.

## Custom sampling

For more control over which requests are captured, provide a callback function via `SampleOnRequest` or `SampleOnResponse`. Each callback receives the request span, with metadata available through [`span.Attributes()`](/sdk-reference/go/v1/attributes).

Choose the callback based on when the information you need is available:

* `SampleOnRequest` runs when the request starts, before it is handled. Request attributes such as `http.request.method`, `url.path`, `url.query` and `user_agent.original` are available at this point. Dropped requests are discarded immediately, so this has less overhead.
* `SampleOnResponse` runs after the response is complete. Use it when the decision depends on attributes such as `http.route`, `http.response.status_code`, `apitally.consumer.identifier`, or custom attributes set with `SetRequestAttributes`. It can't recover requests that `SampleRate` or `SampleOnRequest` already sampled out.

The callback should return `0, true` to discard the request, `1, true` to capture it, or a probability between `0.0` and `1.0` with `true`. Returning `false` as the second value from `SampleOnRequest` applies `SampleRate`, and from `SampleOnResponse` preserves the earlier sampling decision.

<CodeGroup>
  ```go Sample on request theme={null}
  import (
      "github.com/gin-gonic/gin"
      "go.opentelemetry.io/otel/attribute"
      sdktrace "go.opentelemetry.io/otel/sdk/trace"

      apitally "github.com/apitally/apitally-go/gin-v1"
  )

  func shouldCaptureRequest(span sdktrace.ReadOnlySpan) (float64, bool) {
      attrs := attribute.NewSet(span.Attributes()...)
      userAgent, _ := attrs.Value("user_agent.original")
      if userAgent.AsString() == "my-company-monitor" {
          return 0, true
      }
      return 1, true
  }

  func main() {
      r := gin.Default()

      cfg := apitally.NewConfig()
      cfg.WriteToken = "your-write-token"
      cfg.Env = "dev"
      cfg.SampleOnRequest = shouldCaptureRequest
      apitally.Init(r, cfg)
  }
  ```

  ```go Sample on response theme={null}
  import (
      "github.com/gin-gonic/gin"
      "go.opentelemetry.io/otel/attribute"
      sdktrace "go.opentelemetry.io/otel/sdk/trace"

      apitally "github.com/apitally/apitally-go/gin-v1"
  )

  func shouldCaptureRequest(span sdktrace.ReadOnlySpan) (float64, bool) {
      attrs := attribute.NewSet(span.Attributes()...)
      if consumer, _ := attrs.Value("apitally.consumer.identifier"); consumer.AsString() == "internal-service" {
          return 0, true
      }
      if statusCode, _ := attrs.Value("http.response.status_code"); statusCode.AsInt64() < 400 {
          return 0, true
      }
      return 1, true
  }

  func main() {
      r := gin.Default()

      cfg := apitally.NewConfig()
      cfg.WriteToken = "your-write-token"
      cfg.Env = "dev"
      cfg.SampleOnResponse = shouldCaptureRequest
      apitally.Init(r, cfg)
  }
  ```
</CodeGroup>

## Exclude paths

To exclude requests based on their path, provide regular expressions via the `ExcludePaths` option. These match the actual request path (e.g. `/users/123`), not the endpoint route pattern (e.g. `/users/:id`). Query parameters are ignored. Patterns are case-insensitive and match anywhere within the path. Use `^` and `$` anchors for exact matches.

```go theme={null}
cfg := apitally.NewConfig()
cfg.WriteToken = "your-write-token"
cfg.ExcludePaths = []string{`/admin/`, `/internal/`}
apitally.Init(r, cfg)
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.