Skip to content

Warning

Deprecation Notice: The Coralogix Go SDK (go-coralogix-sdk) will be deprecated in favor of the OpenTelemetry SDK and will no longer be supported after June 30, 2026. See the end-of-life notice for migration details.

Go

This guide shows how to send logs from Go applications to Coralogix using the OpenTelemetry Go SDK 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:

mkdir go-otel-logs-sample
cd go-otel-logs-sample
go mod init go-otel-logs-sample
go get go.opentelemetry.io/[email protected] \
  go.opentelemetry.io/otel/[email protected] \
  go.opentelemetry.io/otel/[email protected] \
  go.opentelemetry.io/otel/sdk/[email protected] \
  go.opentelemetry.io/otel/exporters/otlp/otlplog/[email protected]

Select the https://ingress. endpoint that corresponds to your Coralogix domain 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.
  2. Add an OTLP/gRPC exporter (otlploggrpc) with WithEndpoint(...) and WithInsecure() for local testing.
  3. Emit one INFO record, one WARN record in a manual span, then ERROR records with Hello World Coralogix.
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:

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.

Logging output

With the OpenTelemetry SDK, you can send logs either to a local OpenTelemetry Collector 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, then point the exporter at your Coralogix OTLP endpoint.

OTEL_EXPORTER_OTLP_ENDPOINT=ingress.: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 GoOpenTelemetry Go docs
Go instrumentation guideGo OpenTelemetry instrumentation
Coralogix EndpointsCoralogix Endpoints

Support

For help, use in-app chat or email [email protected].