---
url: /logly.zig/guide/formatting.md
description: >-
  Customize your log output with Logly.zig. Learn about default formats, custom
  themes, JSON formatting, and flexible timestamp placeholders for any scenario.
---

# Formatting

Logly-Zig provides flexible formatting options for your logs.

## Default Format

The default format includes the timestamp, level, module (optional), and message.

```
[2024-03-20 10:30:45] [INFO] [main] Application started
```

## Whole-Line Coloring

Logly colors the **entire log line** based on the log level, not just the level tag:

```
\x1b[37m[2024-03-20 10:30:45] [INFO] Application started\x1b[0m     <- All white
\x1b[33m[2024-03-20 10:30:45] [WARNING] Low disk space\x1b[0m       <- All yellow
\x1b[31m[2024-03-20 10:30:45] [ERROR] Connection failed\x1b[0m      <- All red
```

This makes it easier to scan logs visually.

## Level Colors

| Level | Color Code | Color |
|-------|------------|-------|
| TRACE | 36 | Cyan |
| DEBUG | 34 | Blue |
| INFO | 37 | White |
| SUCCESS | 32 | Green |
| WARNING | 33 | Yellow |
| ERROR | 31 | Red |
| FAIL | 35 | Magenta |
| CRITICAL | 91 | Bright Red |

## Custom Themes

You can override the default colors for each log level by creating a custom `Theme`.

```zig
const neon_theme = logly.Formatter.Theme{
    .trace = "90", // Bright Black
    .debug = "35", // Magenta
    .info = "36", // Cyan
    .success = "92", // Bright Green
    .warning = "93", // Bright Yellow
    .err = "91", // Bright Red
    .fail = "31;1", // Red Bold
    .critical = "41;37;1", // White on Red Background
};

// Apply to a specific sink (e.g., the console sink)
logger.sinks.items[0].formatter.setTheme(neon_theme);
```

## Enabling Colors on Windows

Windows requires enabling Virtual Terminal Processing:

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

pub fn main() !void {
    // Enable ANSI colors on Windows (no-op on Linux/macOS)
     _ = logly.Terminal.enableAnsiColors();
    
    // ... rest of initialization
}
```

## Custom Format Strings

You can customize the log output format using the `logFormat` option in `Config` or `SinkConfig`.

Use `Formatter.validateTemplate(...)` to check brace balance before deploying a custom format string.

Supported tags:

* `{time}`: Timestamp
* `{level}`: Log level
* `{message}`: Log message
* `{module}`: Module name
* `{function}`: Function name
* `{file}`: Source filename
* `{line}`: Source line number
* `{thread}`: Thread ID

Example:

```zig
config.logFormat = "[{time}] [{level}] [TID:{thread}] {message}";
```

## JSON Formatting

You can enable JSON formatting globally or per-sink.

```zig
var config = logly.Config.default();
config.format = .json;
logger.configure(config);
```

Output:

```json
{
  "timestamp": 1710930645000,
  "level": "INFO",
  "module": "main",
  "message": "Application started"
}
```

Custom levels show their actual names in JSON:

```zig
try logger.addCustomLevel("audit", 35, "35");
try logger.custom("audit", "Security event", @src());
```

```json
{
  "timestamp": 1710930645000,
  "level": "AUDIT",
  "message": "Security event"
}
```

## Pretty JSON

For development, you might prefer pretty-printed JSON.

```zig
config.prettyJson = true;
```

## Customizing Output

You can control which fields are displayed using the configuration:

```zig
config.showTime = true;
config.showModule = true;
config.showFunction = true;
config.showFilename = true;
config.showLineno = true;
```

## Disabling Colors

To disable colors (for file output or compatibility):

```zig
config.color = false;
```

Or per-sink:

```zig
 _ = try logger.add(.{  // Short alias for addSink()
    .path = "app.log",
    .color = false,  // No colors in file
});
```

## Custom Format Strings

You can define a custom format string to control the exact layout of your log messages.

```zig
config.logFormat = "{time} | {level} | {message}";
```

Supported placeholders:

* `{time}`
* `{level}`
* `{message}`
* `{module}`
* `{function}`
* `{file}`
* `{line}`

## Time Formatting

Logly supports flexible timestamp formats with any separator. You can use predefined formats or create custom ones.

### Predefined Formats

```zig
// ISO 8601 format
config.timeFormat = "ISO8601";
// Output: 2025-12-04T06:39:53.091Z

// RFC 3339 format
config.timeFormat = "RFC3339";
// Output: 2025-12-04T06:39:53+00:00

// Unix timestamp (seconds)
config.timeFormat = "unix";
// Output: 1764830393

// Unix timestamp (milliseconds)
config.timeFormat = "unix_ms";
// Output: 1764830393091
```

When `config.timezone = .local`, `ISO8601` and `RFC3339` include your local offset:

```zig
config.timezone = .local;
config.timeFormat = "ISO8601";
// Output example: 2025-12-04T07:39:53.091+01:00

config.timeFormat = "RFC3339";
// Output example: 2025-12-04T07:39:53+01:00
```

### Custom Format Placeholders

Create any format using these placeholders:

| Placeholder | Description | Example |
|-------------|-------------|---------|
| `YYYY` | 4-digit year | 2025 |
| `YY` | 2-digit year | 25 |
| `MM` | 2-digit month (01-12) | 12 |
| `M` | 1-2 digit month (1-12) | 12 |
| `DD` | 2-digit day (01-31) | 04 |
| `D` | 1-2 digit day (1-31) | 4 |
| `HH` | 2-digit hour 24h (00-23) | 14 |
| `hh` | 2-digit hour 12h (01-12) | 02 |
| `mm` | 2-digit minute (00-59) | 30 |
| `ss` | 2-digit second (00-59) | 45 |
| `SSS` | 3-digit millisecond (000-999) | 091 |
| `ZZZ` | Timezone offset (`+HH:MM`) | +01:00 |
| `ZZ` | Timezone offset compact (`+HHMM`) | +0100 |

Any other characters are output literally (-, /, ., :, space, T, etc.).

### Custom Format Examples

```zig
// Default format with milliseconds
config.timeFormat = "YYYY-MM-DD HH:mm:ss.SSS";
// Output: 2025-12-04 06:39:53.091

// US date format with slashes
config.timeFormat = "MM/DD/YYYY HH:mm:ss";
// Output: 12/04/2025 06:39:53

// European date format
config.timeFormat = "DD-MM-YYYY HH:mm:ss";
// Output: 04-12-2025 06:39:53

// Compact date with dots
config.timeFormat = "YY.MM.DD HH:mm";
// Output: 25.12.04 06:39

// Time only with milliseconds
config.timeFormat = "HH:mm:ss.SSS";
// Output: 06:39:53.091

// Date only
config.timeFormat = "YYYY-MM-DD";
// Output: 2025-12-04

// 12-hour format
config.timeFormat = "MM/DD/YYYY hh:mm:ss";
// Output: 12/04/2025 06:39:53

// Custom separator and order
config.timeFormat = "DD/MM/YY - HH:mm";
// Output: 04/12/25 - 06:39

// Include timezone offsets in custom patterns
config.timeFormat = "YYYY-MM-DD HH:mm:ss ZZZ";
// Output (local): 2025-12-04 07:39:53 +01:00

config.timeFormat = "YYYY-MM-DD HH:mm:ss ZZ";
// Output (local): 2025-12-04 07:39:53 +0100
```

### Timezone Configuration

```zig
config.timezone = .utc;    // Use UTC time
config.timezone = .local;  // Use local time (default)
```

Timezone notes:

* `.utc`: `ISO8601` ends with `Z`, `RFC3339` uses `+00:00`.
* `.local`: uses the process/system local timezone (when available) and emits `+/-HH:MM` offsets for `ISO8601`/`RFC3339`.

## Formatted Logging

Logly-Zig supports `printf`-style formatting using the `f` suffix methods (e.g., `infof`, `debugf`). This allows you to construct log messages dynamically without manual string concatenation.

```zig
// Standard logging
try logger.infof("User {s} logged in from {s}", .{ "Alice", "192.168.1.1" }, @src());

// Debugging with numbers
try logger.debugf("Processed {d} items in {d}ms", .{ 100, 50 }, @src());

// Error details (use errorf or errf)
try logger.errorf("Failed to connect: {s} (Code: {d})", .{ "Connection Refused", 403 }, @src());
```

This feature uses Zig's standard `std.fmt` syntax, so all standard format specifiers are supported.

## MessagePack Binary Format (v0.2.0)

For high-volume production logging or network sinks, Logly provides a native binary **MessagePack (msgpack)** formatter. It compresses key-value structured data, cutting typical JSON log footprint sizes in half while retaining full structured parsing compatibility.

Enable globally:

```zig
config.format = .msgpack;
```

Or on specific sinks:

```zig
 _ = try logger.add(.{
    .path = "logs/binary.mp",
    .format = .msgpack,
});
```

## See Also

* [Formatter API](/api/formatter) - Formatter reference
* [Formatted Logging Example](/examples/formatted-logging) - flat custom format example
