# How to Configure Logging with Zap in Gorig's utils/logger Package

> Learn to configure centralized Zap logging in Gorig's utils logger package for development and production modes. Inject logger easily via HTTP middleware for efficient log management.

- Repository: [Jom/gorig](https://github.com/jom-io/gorig)
- Tags: how-to-guide
- Published: 2026-03-04

---

**Gorig's `utils/logger` package provides a centralized Zap-based logging system that supports development and production modes, configurable via the `utils/cofigure` package and injectable through HTTP middleware.**

Gorig is an open-source Go framework that leverages Uber's Zap library for high-performance structured logging. The `utils/logger` package serves as the central logging facility, offering configurable encoders, dynamic log levels, and seamless integration with the framework's configuration and middleware systems.

## Understanding Gorig's Logger Architecture

### Core Components in utils/logger/logger.go

The heart of the logging system resides in [`utils/logger/logger.go`](https://github.com/jom-io/gorig/blob/main/utils/logger/logger.go). This file defines the `New` function that constructs a Zap `Logger` instance from a configuration struct. The initialization routine supports toggling between development encoders (human-readable, colorized console output) and production encoders (structured JSON), setting log levels, and enabling caller information or stack traces.

### Configuration Integration with utils/cofigure

Logger settings are loaded through Gorig's configuration system in [`utils/cofigure/cfg.go`](https://github.com/jom-io/gorig/blob/main/utils/cofigure/cfg.go). The package reads environment variables or configuration files and maps them to the logger's initialization parameters. This separation of concerns allows you to change logging behavior without modifying application code.

## How to Initialize and Configure the Zap Logger

### Creating a Logger Instance

To create a configured logger, invoke the `New` function with a configuration map or struct. The function returns a `*zap.Logger` that you can assign to the package's global `Default` variable.

```go
package main

import (
    "github.com/jom-io/gorig/utils/logger"
    "github.com/spf13/viper"
    "go.uber.org/zap"
)

func main() {
    // Load configuration using Viper or Gorig's configure package
    viper.SetDefault("log.level", "debug")
    viper.SetDefault("log.format", "json")
    viper.SetDefault("log.development", false)

    // Initialize the logger
    zapLogger, err := logger.New(viper.AllSettings())
    if err != nil {
        panic(err)
    }

    // Set as the global default
    logger.Default = zapLogger

    // Log application startup
    logger.Default.Info("application started",
        zap.String("mode", "production"),
    )
}

```

### Configuration Options and Environment Variables

The logger recognizes several configuration keys, typically prefixed with `log.`:

- `log.level` – Sets the minimum log level (`debug`, `info`, `warn`, `error`).
- `log.format` – Chooses the output format (`json` for production, `console` for development).
- `log.development` – Boolean flag that enables development mode with human-readable output and stack traces.
- `log.outputPaths` – Array of output destinations (e.g., `["stdout"]` or file paths).

These values are typically defined in [`utils/cofigure/cfg.go`](https://github.com/jom-io/gorig/blob/main/utils/cofigure/cfg.go) and passed to the logger during initialization.

## Using the Logger in Your Application

### Global Logger Access

Once initialized, the `logger.Default` variable provides package-level access to the configured Zap instance. Import `github.com/jom-io/gorig/utils/logger` and call methods like `logger.Info()`, `logger.Error()`, or `logger.Debug()` directly.

```go
import "github.com/jom-io/gorig/utils/logger"

func ProcessData() {
    logger.Info("starting data processing")
    
    if err := validate(); err != nil {
        logger.Error("validation failed", zap.Error(err))
        return
    }
    
    logger.Info("processing completed successfully")
}

```

### Request-Scoped Logging with HTTP Middleware

For web applications, Gorig's HTTP middleware in [`httpx/mid.logger.go`](https://github.com/jom-io/gorig/blob/main/httpx/mid.logger.go) injects the logger into request contexts. This enables request-scoped logging without manual parameter passing.

```go
import (
    "github.com/gin-gonic/gin"
    "github.com/jom-io/gorig/utils/logger"
    "go.uber.org/zap"
)

func MyHandler(c *gin.Context) {
    // Retrieve logger from request context
    log := logger.FromContext(c.Request.Context())
    
    log.Debug("handling request", zap.String("path", c.Request.URL.Path))
    
    // Business logic
    if err := doWork(); err != nil {
        log.Error("work failed", zap.Error(err))
        c.JSON(500, gin.H{"error": "internal server error"})
        return
    }
    
    log.Info("request completed successfully")
    c.JSON(200, gin.H{"status": "ok"})
}

```

## Testing Logger Output

When writing unit tests, you can capture log output using a custom `zapcore.Core` that writes to a buffer. The test suite in [`test/logger_test.go`](https://github.com/jom-io/gorig/blob/main/test/logger_test.go) demonstrates this pattern.

```go
import (
    "bytes"
    "strings"
    "testing"
    
    "github.com/jom-io/gorig/utils/logger"
    "go.uber.org/zap"
    "go.uber.org/zapcore"
)

func TestLoggerOutput(t *testing.T) {
    var buf bytes.Buffer
    
    // Create a custom core that writes to our buffer
    cfg := logger.Config{
        Level:  "debug",
        Format: "console",
        Output: []string{"stderr"},
        Writer: &buf, // Direct output to buffer for inspection
    }
    
    l, err := logger.New(cfg)
    if err != nil {
        t.Fatalf("failed to create logger: %v", err)
    }
    
    l.Info("test message", zap.String("key", "value"))
    
    output := buf.String()
    if !strings.Contains(output, "test message") {
        t.Fatalf("unexpected log output: %s", output)
    }
}

```

## Summary

- Gorig's `utils/logger` package wraps Uber's Zap library to provide structured, high-performance logging.
- Initialize the logger using `logger.New()` with configuration from `utils/cofigure`, supporting JSON and console formats.
- Store the instance in `logger.Default` for global access across your application.
- Use [`httpx/mid.logger.go`](https://github.com/jom-io/gorig/blob/main/httpx/mid.logger.go) middleware to inject loggers into HTTP request contexts for request-scoped logging.
- Test logging behavior by directing output to a buffer using a custom `zapcore.Core` as shown in [`test/logger_test.go`](https://github.com/jom-io/gorig/blob/main/test/logger_test.go).

## Frequently Asked Questions

### What is the default log format in Gorig?

By default, Gorig uses JSON encoding for production environments to facilitate log aggregation and parsing. When `log.development` is set to `true` in the configuration, the logger switches to a console encoder that outputs human-readable, colorized text suitable for local development.

### How do I change the log level at runtime?

The log level is set during initialization via the `log.level` configuration key (accepted values: `debug`, `info`, `warn`, `error`). To change levels at runtime, you must reinitialize the logger with `logger.New()` and update the `logger.Default` reference. Gorig does not currently support dynamic level changes without reinitialization.

### Can I write logs to a file instead of stdout?

Yes. Configure the `log.outputPaths` array in your configuration to include file paths instead of or in addition to `stdout`. For example, setting `log.outputPaths` to `["/var/log/app.log", "stdout"]` directs logs to both a file and standard output simultaneously.

### How does the logger handle panic recovery?

While the `utils/logger` package provides the logging facility itself, panic recovery is typically handled by the HTTP middleware in [`httpx/mid.logger.go`](https://github.com/jom-io/gorig/blob/main/httpx/mid.logger.go). This middleware catches panics during request handling, logs the error with stack traces using the configured Zap logger, and returns an appropriate HTTP error response to the client.