Warning

**Deprecation Notice**: The Coralogix Go SDK (`go-coralogix-sdk`) will be deprecated in favor of the [OpenTelemetry SDK](https://opentelemetry.io/docs/languages/go/) and will no longer be supported after **June 30, 2026**. See the [end-of-life notice](https://coralogix.com/docs/user-guides/latest-updates/deprecations/go-sdk/index.md) for migration details.

# Go

This guide shows how to send logs from Go applications to Coralogix using the [OpenTelemetry Go SDK](https://opentelemetry.io/docs/languages/go/) with the OTLP/gRPC log exporter and an `slog` bridge. This replaces shipping logs through the legacy `go-coralogix-sdk` package.

Use a recent Go release (Go 1.22+ recommended) and current OpenTelemetry Go modules.

## Package dependencies setup

Create a module and add the OpenTelemetry logs SDK modules used in the sample:

```bash
mkdir go-otel-logs-sample
cd go-otel-logs-sample
go mod init go-otel-logs-sample
go get go.opentelemetry.io/otel@v1.43.0 \
  go.opentelemetry.io/otel/sdk@v1.43.0 \
  go.opentelemetry.io/otel/log@v0.19.0 \
  go.opentelemetry.io/otel/sdk/log@v0.19.0 \
  go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc@v0.19.0
```

Select the https://ingress.\[[DOMAIN_VALUE]\] endpoint that corresponds to your Coralogix [domain](https://coralogix.com/docs/user-guides/account-management/account-settings/coralogix-domain/index.md) using the domain selector at the top of the page.

## Application implementation

1. Build a logs `LoggerProvider` with a `Resource` that sets `service.name`, `cx.application.name`, and `cx.subsystem.name`.
1. Add an OTLP/gRPC exporter (`otlploggrpc`) with `WithEndpoint(...)` and `WithInsecure()` for local testing.
1. Emit one INFO record, one WARN record in a manual span, then ERROR records with `Hello World Coralogix`.

```go
package main

import (
    "context"
    "fmt"
    "net/url"
    "os"
    "strings"
    "time"

    otelapi "go.opentelemetry.io/otel/log"
    "go.opentelemetry.io/otel/log/global"
    "go.opentelemetry.io/otel/attribute"
    "go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc"
    sdklog "go.opentelemetry.io/otel/sdk/log"
    "go.opentelemetry.io/otel/sdk/resource"
    semconv "go.opentelemetry.io/otel/semconv/v1.37.0"
    sdktrace "go.opentelemetry.io/otel/sdk/trace"
)

func normalizeEndpoint(raw string) string {
    if strings.Contains(raw, "://") {
        parsed, err := url.Parse(raw)
        if err == nil && parsed.Host != "" {
            return parsed.Host
        }
    }
    return raw
}

func main() {
    ctx := context.Background()
    endpoint := os.Getenv("OTEL_EXPORTER_OTLP_ENDPOINT")
    if endpoint == "" {
        endpoint = "host.docker.internal:4317"
    }

    serviceName := os.Getenv("OTEL_SERVICE_NAME")
    if serviceName == "" {
        serviceName = "go-otel-logs-sample"
    }

    applicationName := os.Getenv("CORALOGIX_APPLICATION")
    if applicationName == "" {
        applicationName = "go-otel-app"
    }

    subsystemName := os.Getenv("CORALOGIX_SUBSYSTEM")
    if subsystemName == "" {
        subsystemName = "worker"
    }

    res, err := resource.New(
        ctx,
        resource.WithAttributes(
            semconv.ServiceName(serviceName),
            attribute.String("cx.application.name", applicationName),
            attribute.String("cx.subsystem.name", subsystemName),
        ),
    )
    if err != nil {
        panic(err)
    }

    exporter, err := otlploggrpc.New(
        ctx,
        otlploggrpc.WithEndpoint(normalizeEndpoint(endpoint)),
        otlploggrpc.WithInsecure(),
    )
    if err != nil {
        panic(err)
    }

    loggerProvider := sdklog.NewLoggerProvider(
        sdklog.WithResource(res),
        sdklog.WithProcessor(sdklog.NewBatchProcessor(exporter)),
    )
    defer func() {
        shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
        defer cancel()
        _ = loggerProvider.Shutdown(shutdownCtx)
    }()

    global.SetLoggerProvider(loggerProvider)
    logger := global.GetLoggerProvider().Logger("My class")

    tracerProvider := sdktrace.NewTracerProvider(sdktrace.WithResource(res))
    defer func() {
        shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
        defer cancel()
        _ = tracerProvider.Shutdown(shutdownCtx)
    }()
    tracer := tracerProvider.Tracer("go-otel-example")

    fmt.Printf("OTLP logs endpoint: %s\n", endpoint)

    infoRecord := otelapi.Record{}
    infoRecord.SetTimestamp(time.Now())
    infoRecord.SetSeverity(otelapi.SeverityInfo)
    infoRecord.SetBody(otelapi.StringValue("hello go logging with OpenTelemetry"))
    logger.Emit(ctx, infoRecord)

    spanCtx, span := tracer.Start(ctx, "manual-span")
    warnRecord := otelapi.Record{}
    warnRecord.SetTimestamp(time.Now())
    warnRecord.SetSeverity(otelapi.SeverityWarn)
    warnRecord.SetBody(otelapi.StringValue("go log with trace correlation"))
    logger.Emit(spanCtx, warnRecord)
    span.End()

    for i := 0; i < 10; i++ {
        record := otelapi.Record{}
        record.SetTimestamp(time.Now())
        record.SetSeverity(otelapi.SeverityError)
        record.SetBody(otelapi.StringValue("Hello World Coralogix"))
        logger.Emit(ctx, record)
        time.Sleep(time.Second)
    }

    flushCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    if err := loggerProvider.ForceFlush(flushCtx); err != nil {
        fmt.Printf("ForceFlush warning: %v\n", err)
    }

    fmt.Println("Done: flush + shutdown completed")
}
```

Run the sample:

```bash
go run .
```

**Notes**

- The OpenTelemetry logs signal in Go is still evolving; check release notes when updating dependencies.
- The internal example defaults to `host.docker.internal:4317`; for local non-Docker runs you can use `localhost:4317`.
- For broader setup (shared resource and traces/metrics), see [Go OpenTelemetry instrumentation](https://coralogix.com/docs/opentelemetry/instrumentation-options/golang-opentelemetry-instrumentation/index.md).

### Logging output

With the OpenTelemetry SDK, you can send logs either to a local [OpenTelemetry Collector](https://coralogix.com/docs/opentelemetry/kubernetes-observability/kubernetes-observability-using-opentelemetry/index.md) or directly to Coralogix using an OTLP endpoint.

#### OpenTelemetry Collector

Set `OTEL_EXPORTER_OTLP_ENDPOINT` to your collector OTLP/gRPC endpoint (for example `http://localhost:4317`).

#### Coralogix OpenTelemetry endpoint

Authenticate with your [Send-Your-Data API key](https://coralogix.com/docs/user-guides/account-management/api-keys/send-your-data-api-key/index.md), then point the exporter at your Coralogix OTLP endpoint.

```bash
OTEL_EXPORTER_OTLP_ENDPOINT=ingress.[[DOMAIN_VALUE]]:443
OTEL_SERVICE_NAME=go-otel-logs-sample
CORALOGIX_APPLICATION=hello
CORALOGIX_SUBSYSTEM=world
```

If you send directly to Coralogix from this Go sample, add `otlploggrpc.WithHeaders(...)` and TLS options in code (for example `Authorization=Bearer <send_your_data_key>`), or send through a local collector that handles authentication upstream.

### Additional resources

|                          |                                                                                                                                                    |
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| OpenTelemetry Go         | [OpenTelemetry Go docs](https://opentelemetry.io/docs/languages/go/)                                                                               |
| Go instrumentation guide | [Go OpenTelemetry instrumentation](https://coralogix.com/docs/opentelemetry/instrumentation-options/golang-opentelemetry-instrumentation/index.md) |
| Coralogix Endpoints      | [Coralogix Endpoints](https://coralogix.com/docs/integrations/coralogix-endpoints/index.md)                                                        |

### Support

For help, use in-app chat or email [support@coralogix.com](mailto:support@coralogix.com).
