package main
import (
// Import these standard libraries used in the OpenTelemetry configuration
"context"
"log"
"os"
"os/exec"
"strings"
// Import these OpenTelemetry libraries
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp"
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
"go.opentelemetry.io/otel/log/global"
"go.opentelemetry.io/otel/propagation"
sdklog "go.opentelemetry.io/otel/sdk/log"
sdkmetric "go.opentelemetry.io/otel/sdk/metric"
sdkresource "go.opentelemetry.io/otel/sdk/resource"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
)
func initOpenTelemetry() func() {
// Replace these values with your AppSignal application name, environment
// and push API key. These are used by the resource attributes configuration below.
name := "My app"
push_api_key := "0000-0000-0000-0000"
environment := "development"
// Set the name of the service that is being monitored. A common choice is the
// name of the framework used. This is used to group traces and metrics in AppSignal.
service_name := "My service name"
// Replace `localhost:8099` with the address of your AppSignal collector
// if it's running on another host.
endpoint := "localhost:8099"
hostname, err := os.Hostname()
if err != nil {
hostname = "unknown"
}
var revision string
cmd := exec.Command("git", "rev-parse", "--short", "HEAD")
output, err := cmd.Output()
if err != nil {
revision = "unknown"
} else {
revision = strings.TrimSpace(string(output))
}
resource, err := sdkresource.Merge(
sdkresource.Default(),
sdkresource.NewSchemaless(
attribute.String("appsignal.config.name", name),
attribute.String("appsignal.config.environment", environment),
attribute.String("appsignal.config.push_api_key", push_api_key),
attribute.String("appsignal.config.revision", revision),
attribute.String("appsignal.config.language_integration", "go"),
attribute.String("appsignal.config.app_path", os.Getenv("PWD")),
attribute.String("service.name", service_name),
attribute.String("host.name", hostname),
),
)
if err != nil {
log.Fatalf("Error creating OTLP resource: %v", err)
}
// Tracing
traceClient := otlptracehttp.NewClient(
otlptracehttp.WithInsecure(), // Remove if the collector is accessible via HTTPS
otlptracehttp.WithEndpoint(endpoint),
)
traceExporter, err := otlptrace.New(context.Background(), traceClient)
if err != nil {
log.Fatalf("Error creating OTLP trace exporter: %v", err)
}
tracerProvider := sdktrace.NewTracerProvider(
sdktrace.WithBatcher(traceExporter),
sdktrace.WithResource(resource),
)
otel.SetTracerProvider(tracerProvider)
otel.SetTextMapPropagator(
propagation.NewCompositeTextMapPropagator(
propagation.TraceContext{},
propagation.Baggage{},
),
)
// Metrics
metricExporter, err := otlpmetrichttp.New(
context.Background(),
otlpmetrichttp.WithInsecure(), // Remove if the collector is accessible via HTTPS
otlpmetrichttp.WithEndpoint(endpoint),
)
if err != nil {
log.Fatalf("creating OTLP metric exporter: %v", err)
}
meterProvider := sdkmetric.NewMeterProvider(
sdkmetric.WithReader(sdkmetric.NewPeriodicReader(metricExporter)),
sdkmetric.WithResource(resource),
)
otel.SetMeterProvider(meterProvider)
// Logs
logExporter, err := otlploghttp.New(
context.Background(),
otlploghttp.WithInsecure(), // Remove if the collector is accessible via HTTPS
otlploghttp.WithEndpoint(endpoint),
)
if err != nil {
log.Fatalf("creating OTLP log exporter: %v", err)
}
loggerProvider := sdklog.NewLoggerProvider(
sdklog.WithResource(resource),
sdklog.WithProcessor(
sdklog.NewBatchProcessor(logExporter),
),
)
global.SetLoggerProvider(loggerProvider)
// Cleanup
return func() {
ctx := context.Background()
if err := tracerProvider.Shutdown(ctx); err != nil {
log.Println("Error shutting down tracer provider:", err)
}
if err := meterProvider.Shutdown(ctx); err != nil {
log.Println("Error shutting down meter provider:", err)
}
if err := loggerProvider.Shutdown(ctx); err != nil {
log.Println("Error shutting down logger provider:", err)
}
}
}
func main() {
cleanup := initOpenTelemetry()
defer cleanup()
// ... your application's initialization code
}