Observabilidade e Monitoramento com Zig

Observabilidade e Monitoramento com Zig

Observabilidade em produção requer três pilares: logs, métricas e traces. Em Zig, implementar esses pilares exige código explícito, mas o resultado é um sistema de monitoramento extremamente eficiente e com overhead mínimo.

Logging Estruturado

const std = @import("std");

const LogLevel = enum { debug, info, warn, err, fatal };

const Logger = struct {
    writer: std.fs.File.Writer,
    nivel_minimo: LogLevel,

    pub fn log(
        self: Logger,
        nivel: LogLevel,
        comptime fmt: []const u8,
        args: anytype,
    ) void {
        if (@intFromEnum(nivel) < @intFromEnum(self.nivel_minimo)) return;

        const timestamp = std.time.timestamp();
        const nivel_str = @tagName(nivel);

        self.writer.print(
            "{{\"timestamp\":{d},\"level\":\"{s}\",\"msg\":\"" ++ fmt ++ "\"}}\n",
            .{timestamp, nivel_str} ++ args,
        ) catch {};
    }
};

Métricas Prometheus

const Contador = struct {
    valor: std.atomic.Value(u64) = std.atomic.Value(u64).init(0),
    nome: []const u8,
    help: []const u8,

    pub fn incrementar(self: *Contador) void {
        _ = self.valor.fetchAdd(1, .monotonic);
    }

    pub fn exportar(self: *const Contador, writer: anytype) !void {
        try writer.print("# HELP {s} {s}\n", .{ self.nome, self.help });
        try writer.print("# TYPE {s} counter\n", .{self.nome});
        try writer.print("{s} {d}\n", .{ self.nome, self.valor.load(.monotonic) });
    }
};

var requests_total = Contador{
    .nome = "http_requests_total",
    .help = "Total de requisições HTTP recebidas",
};

var errors_total = Contador{
    .nome = "http_errors_total",
    .help = "Total de erros HTTP",
};

Health Check Endpoint

fn healthCheck(response: *http.Server.Response) !void {
    const saude = verificarSaude();
    response.status = if (saude.saudavel) .ok else .service_unavailable;
    try response.do();

    var buf: [512]u8 = undefined;
    var stream = std.io.fixedBufferStream(&buf);
    const writer = stream.writer();

    try writer.print(
        \\{{"status":"{s}","uptime_s":{d},"memoria_mb":{d}}}
    , .{
        if (saude.saudavel) "healthy" else "unhealthy",
        saude.uptime_segundos,
        saude.memoria_usada_mb,
    });

    try response.writeAll(stream.getWritten());
    try response.finish();
}

Conclusão

Observabilidade em Zig requer mais código manual do que em linguagens com ecossistemas maduros, mas o resultado é um sistema de monitoramento com overhead praticamente zero. Logging estruturado, métricas Prometheus e health checks podem ser implementados com a biblioteca padrão, sem dependências externas.

Conteúdo Relacionado

Continue aprendendo Zig

Explore mais tutoriais e artigos em português para dominar a linguagem Zig.