Documentation Index
Fetch the complete documentation index at: https://docs.logwiz.io/llms.txt
Use this file to discover all available pages before exploring further.
The opentelemetry-sdk for Zig is in alpha (v0.1.1, Zig 0.15.2). It has not been
battle-tested in production environments. Expect breaking changes between releases.
Logwiz accepts OpenTelemetry logs over OTLP HTTP. The Zig SDK’s std.log bridge routes all
standard library log calls to OpenTelemetry without changing a single call site. Records land in
the OTEL logs index pinned by your ingest token (default: otel-logs-v0_9).
Setup
Add the SDK to your project
Requires Zig ≥ 0.15.2. Run this in your project root:zig fetch --save "git+https://github.com/zig-o11y/opentelemetry-sdk#v0.1.1"
Then add these lines to build.zig after your exe declaration:const otel_sdk = b.dependency("opentelemetry", .{
.target = target,
.optimize = optimize,
});
exe.root_module.addImport("opentelemetry-sdk", otel_sdk.module("sdk"));
The dependency key opentelemetry matches the SDK’s package name in its
build.zig.zon; the import alias opentelemetry-sdk is what your code will
@import. Set environment variables
export OTEL_SERVICE_NAME=my-zig-service
export OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=https://<your-logwiz>/api/otlp/v1/logs
export OTEL_EXPORTER_OTLP_LOGS_HEADERS=Authorization=Bearer%20<your-ingest-token>
The %20 after Bearer is required — OTEL expects URL-encoded header values.
Minimal working example
const std = @import("std");
const sdk = @import("opentelemetry-sdk");
pub const std_options: std.Options = .{
.logFn = sdk.logs.std_log_bridge.logFn,
};
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
// OTLP exporter — reads OTEL_EXPORTER_OTLP_* env vars
var otlp_config = try sdk.otlp.ConfigOptions.init(allocator);
defer otlp_config.deinit();
var otlp_exporter = try sdk.logs.OTLPExporter.init(allocator, otlp_config);
defer otlp_exporter.deinit();
const exporter = otlp_exporter.asLogRecordExporter();
// Wire the exporter into a processor
var simple_processor = sdk.logs.SimpleLogRecordProcessor.init(allocator, exporter);
const processor = simple_processor.asLogRecordProcessor();
// Logger provider with the processor attached
var provider = try sdk.logs.LoggerProvider.init(allocator, null);
defer provider.deinit();
try provider.addLogRecordProcessor(processor);
// Route std.log calls through OpenTelemetry
try sdk.logs.std_log_bridge.configure(.{
.provider = provider,
.also_log_to_stderr = true,
});
defer sdk.logs.std_log_bridge.shutdown();
std.log.info("Hello from Zig to Logwiz", .{});
try provider.shutdown();
}
Save as src/main.zig and run zig build run. The bridge reads the endpoint and auth header
from the environment variables above.Verify in Logwiz
Open Search, filter on service_name:my-zig-service, and your record should appear within
~2 seconds.
Structured logging
The std.log bridge maps Zig log levels to OpenTelemetry severity numbers automatically:
| Zig level | OTel severity |
|---|
debug | DEBUG (5) |
info | INFO (9) |
warn | WARN (13) |
err | ERROR (17) |
Log messages and their format arguments become the log record body. Unlike Go’s slog.With,
the std.log API does not support structured key/value attributes — format args are interpolated
into the message string.
std.log.info("user signed up: {s} plan={s}", .{ user_id, plan });
For structured attributes, use the direct SDK API — see the
examples/logs/ folder
in the SDK repository.