---
title: "Estratégias de Error Logging em Zig"
url: "https://ziglang.com.br/receitas/estrat%C3%A9gias-de-error-logging-em-zig/"
markdown_url: "https://ziglang.com.br/receitas/estrat%C3%A9gias-de-error-logging-em-zig.MD"
description: "Receita prática de estratégias de logging de erros em Zig. Uso de std.log, níveis de log, formatação, logging condicional e boas práticas para produção."
date: "2026-02-21"
author: "Zig Brasil"
---

# Estratégias de Error Logging em Zig

Receita prática de estratégias de logging de erros em Zig. Uso de std.log, níveis de log, formatação, logging condicional e boas práticas para produção.


## Introdução

Logging eficiente de erros é essencial para diagnosticar problemas em produção. Zig oferece `std.log` como mecanismo de logging integrado, com níveis configuráveis e output customizável. Esta receita cobre os padrões mais úteis.

Para tratamento de erros em geral, veja [Padrões Try/Catch](/receitas/zig-try-catch-erros/) e [Error Sets Customizados](/receitas/zig-error-set-customizado/).

## Pré-requisitos

- Zig instalado (versão 0.13+). Veja o [guia de instalação](/tutoriais/como-instalar-zig/)
- Conhecimento básico de Zig. Consulte a [introdução ao Zig](/tutoriais/introducao-ao-zig/)

## std.log Básico

```zig
const std = @import("std");

pub fn main() void {
    std.log.info("Servidor iniciado na porta {}", .{8080});
    std.log.warn("Conexão lenta: {}ms", .{500});
    std.log.err("Falha na conexão com banco", .{});
    std.log.debug("Variável x = {}", .{42});
}
```

### Níveis de Log

| Nível | Função | Uso |
|-------|--------|-----|
| `err` | `std.log.err` | Erros que impedem operação |
| `warn` | `std.log.warn` | Situações anormais mas recuperáveis |
| `info` | `std.log.info` | Informações operacionais |
| `debug` | `std.log.debug` | Detalhes para desenvolvimento |

## Logging com Contexto de Erro

```zig
fn processarRequisicao(req: Requisicao) !Resposta {
    const dados = parsearBody(req.body) catch |err| {
        std.log.err("Falha ao parsear body: {s} - erro: {}", .{ req.path, err });
        return err;
    };

    const resultado = executarQuery(dados) catch |err| {
        std.log.err("Query falhou para {s}: {}", .{ req.path, err });
        return err;
    };

    std.log.info("Requisição {s} processada com sucesso", .{req.path});
    return resultado;
}
```

## Log Escopado (Scoped Logging)

```zig
const log = std.log.scoped(.servidor);

fn iniciar() void {
    log.info("Servidor iniciando...", .{});
    // Output: info(servidor): Servidor iniciando...
}

// Outro módulo
const db_log = std.log.scoped(.database);

fn conectar() void {
    db_log.info("Conectando ao banco...", .{});
    // Output: info(database): Conectando ao banco...
}
```

## Customizar Log Handler

```zig
const std = @import("std");

pub const std_options = struct {
    pub const log_level = .info; // Nível mínimo

    pub const logFn = meuLogHandler;
};

fn meuLogHandler(
    comptime level: std.log.Level,
    comptime scope: @TypeOf(.enum_literal),
    comptime format: []const u8,
    args: anytype,
) void {
    const scope_prefix = if (scope != .default)
        "(" ++ @tagName(scope) ++ ") "
    else
        "";

    const prefix = comptime level.asText() ++ ": " ++ scope_prefix;

    const stderr = std.io.getStdErr().writer();
    nosuspend stderr.print(prefix ++ format ++ "\n", args) catch return;
}
```

## Logging para Arquivo

```zig
const std = @import("std");

const Logger = struct {
    arquivo: std.fs.File,
    mutex: std.Thread.Mutex,

    pub fn init(caminho: []const u8) !Logger {
        return .{
            .arquivo = try std.fs.cwd().createFile(caminho, .{ .truncate = false }),
            .mutex = .{},
        };
    }

    pub fn deinit(self: *Logger) void {
        self.arquivo.close();
    }

    pub fn logErr(self: *Logger, comptime fmt: []const u8, args: anytype) void {
        self.mutex.lock();
        defer self.mutex.unlock();

        const writer = self.arquivo.writer();
        const timestamp = std.time.timestamp();
        nosuspend writer.print("[{d}] ERRO: " ++ fmt ++ "\n", .{timestamp} ++ args) catch {};
    }

    pub fn logInfo(self: *Logger, comptime fmt: []const u8, args: anytype) void {
        self.mutex.lock();
        defer self.mutex.unlock();

        const writer = self.arquivo.writer();
        const timestamp = std.time.timestamp();
        nosuspend writer.print("[{d}] INFO: " ++ fmt ++ "\n", .{timestamp} ++ args) catch {};
    }
};
```

## Logging Condicional em Comptime

```zig
const builtin = @import("builtin");

fn logDebug(comptime fmt: []const u8, args: anytype) void {
    if (builtin.mode == .Debug) {
        std.debug.print("[DEBUG] " ++ fmt ++ "\n", args);
    }
    // Em release, esta função compila para noop (zero overhead)
}

fn logPerformance(comptime operacao: []const u8, inicio: i64) void {
    if (builtin.mode == .Debug or builtin.mode == .ReleaseSafe) {
        const duracao = std.time.milliTimestamp() - inicio;
        std.log.info("{s}: {}ms", .{ operacao, duracao });
    }
}
```

## Log de Stack Trace em Erros

```zig
fn operacaoPerigosa() !void {
    return error.FalhaInterna;
}

fn executar() void {
    operacaoPerigosa() catch |err| {
        std.log.err("Erro: {}", .{err});

        // Em debug, imprimir stack trace
        if (@errorReturnTrace()) |trace| {
            std.debug.dumpStackTrace(trace.*);
        }
    };
}
```

## Boas Práticas

### 1. Use o nível correto

```zig
// ERR: operação falhou, ação necessária
std.log.err("Banco de dados inacessível: {}", .{err});

// WARN: anomalia, mas recuperável
std.log.warn("Tentativa {}/3 falhou, retrying...", .{tentativa});

// INFO: operação normal que vale registrar
std.log.info("Usuário {} autenticado", .{user_id});

// DEBUG: detalhes para desenvolvimento
std.log.debug("Buffer alocado: {} bytes", .{tamanho});
```

### 2. Inclua contexto suficiente

```zig
// RUIM: sem contexto
std.log.err("Erro ao processar", .{});

// BOM: com contexto
std.log.err("Erro ao processar requisição {s} do user {}: {}", .{
    req.path, req.user_id, err,
});
```

### 3. Não logue dados sensíveis

```zig
// RUIM: expõe senha
std.log.info("Login: user={s} pass={s}", .{ user, senha });

// BOM: sem dados sensíveis
std.log.info("Login: user={s}", .{user});
```

## Testes

```zig
test "logging não causa crash" {
    std.log.info("teste de log: {}", .{42});
    std.log.err("teste de erro: {s}", .{"mensagem"});
}
```

Veja [Testes Unitários](/receitas/zig-teste-unitario-basico/) para mais sobre testes.

## Conclusão

Zig oferece ferramentas de logging simples e eficientes via `std.log`. Use scoped logging para organizar output por módulo, customize o handler para produção, e aproveite `comptime` para eliminar logging de debug em builds de release sem overhead.

Para mais sobre erros, veja [Padrões Try/Catch](/receitas/zig-try-catch-erros/), [Error Sets Customizados](/receitas/zig-error-set-customizado/) e [Padrões Errdefer](/receitas/zig-errdefer-pattern/).
