Created
October 31, 2025 22:51
-
-
Save Apurer/66545bd58e17bb9e304a71bda656d801 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "context" | |
| "fmt" | |
| "log/slog" | |
| "os" | |
| "time" | |
| "go.opentelemetry.io/contrib/bridges/otelslog" | |
| "go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp" | |
| "go.opentelemetry.io/otel/log/global" | |
| sdklog "go.opentelemetry.io/otel/sdk/log" | |
| "go.opentelemetry.io/otel/sdk/resource" | |
| "go.opentelemetry.io/otel/semconv/v1.24.0" | |
| "go.temporal.io/sdk/client" | |
| workerlog "go.temporal.io/sdk/worker/log" | |
| ) | |
| func main() { | |
| ctx := context.Background() | |
| // --- Initialize OpenTelemetry logging --- | |
| provider, err := initOTELLogging(ctx) | |
| if err != nil { | |
| panic(fmt.Errorf("failed to init OTEL logging: %w", err)) | |
| } | |
| defer func() { | |
| _ = provider.Shutdown(context.Background()) | |
| }() | |
| // --- Run the main application logic --- | |
| runApp(ctx) | |
| } | |
| // initOTELLogging sets up and globally registers the OTEL log pipeline. | |
| func initOTELLogging(ctx context.Context) (*sdklog.LoggerProvider, error) { | |
| // Create OTLP HTTP exporter (insecure) | |
| exporter, err := otlploghttp.New(ctx, | |
| otlploghttp.WithInsecure(), // no TLS | |
| otlploghttp.WithEndpoint("localhost:4318"), | |
| ) | |
| if err != nil { | |
| return nil, fmt.Errorf("failed to create OTLP exporter: %w", err) | |
| } | |
| // Create a logger provider with resource info | |
| provider := sdklog.NewLoggerProvider( | |
| sdklog.WithResource(resource.NewWithAttributes( | |
| semconv.SchemaURL, | |
| semconv.ServiceName("temporal-client"), | |
| semconv.ServiceVersion("1.0.0"), | |
| semconv.DeploymentEnvironment("development"), | |
| )), | |
| sdklog.WithProcessor(sdklog.NewBatchProcessor(exporter)), | |
| ) | |
| // Register globally | |
| global.SetLoggerProvider(provider) | |
| return provider, nil | |
| } | |
| // runApp creates the Temporal client and emits logs. | |
| func runApp(ctx context.Context) { | |
| // Retrieve the global provider explicitly | |
| provider := global.GetLoggerProvider() | |
| // Create a slog.Logger backed by OTEL | |
| otelSlog := otelslog.NewLogger( | |
| "example/temporal", | |
| otelslog.WithLoggerProvider(provider), | |
| ) | |
| // Log to both stdout and OTEL | |
| handler := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}) | |
| logger := slog.New(slog.NewMultiHandler(handler, otelSlog.Handler())) | |
| // Temporal StructuredLogger adapter | |
| temporalLogger := workerlog.NewStructuredLogger(logger) | |
| // --- Connect to Temporal --- | |
| c, err := client.Dial(client.Options{ | |
| HostPort: "localhost:7233", | |
| Namespace: "default", | |
| Logger: temporalLogger, | |
| }) | |
| if err != nil { | |
| panic(fmt.Errorf("unable to create Temporal client: %w", err)) | |
| } | |
| defer c.Close() | |
| // Emit logs | |
| logger.Info("Temporal client started") | |
| runWorkflowExample(ctx, c, logger) | |
| } | |
| // Example fake workflow logic | |
| func runWorkflowExample(ctx context.Context, c client.Client, logger *slog.Logger) { | |
| logger.Info("Running fake workflow", "workflow", "ExampleWorkflow") | |
| time.Sleep(2 * time.Second) | |
| logger.Info("Workflow completed successfully") | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment