Skip to main 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/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. 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.eu2.coralogix.com: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 support@coralogix.com.

Was this page helpful?
On this page