nexlog is a high-performance, flexible, and feature-rich logging library for Zig applications. Designed with both power and ease-of-use in mind, nexlog offers asynchronous logging, file rotation, structured logging, and much more โ making it a perfect fit for projects of any size.
- Features
- Installation
- Quick Start
- Examples
- Advanced Features
- Configuration
- Benchmarks
- Contributing
- License
- Multiple Log Levels: Supports debug, info, warning, and error levels
- Asynchronous Logging: High-performance async mode minimizes impact on application performance
- File Rotation: Automatic log file rotation with configurable size and backup counts
- Structured Logging: Multiple output formats (JSON, logfmt, custom) for machine-readable logs
- Rich Metadata: Automatic inclusion of timestamps, thread IDs, file names, and function names
- Custom Handlers: Built-in handlers for console, file, and JSON outputs; extensible for custom needs
- Color Support: Terminal color coding for different log levels
- Configurable Buffer Size: Adjustable buffer size for optimal performance
- Context Tracking: Support for department- or component-specific logging contexts
- High Performance: Benchmarked at 40K+ logs per second
- Type Safety: Full Zig type safety and compile-time checks
Add nexlog as a dependency in your build.zig.zon
file:
.{
.name = "my-project",
.version = "0.1.0",
.dependencies = .{
.nexlog = .{
.url = "git+https://github.com/chrischtel/nexlog/",
.hash = "...", // Run `zig fetch` to get the hash
},
},
}
zig fetch --save git+https://github.com/chrischtel/nexlog/
Note: For development versions, append
#develop
to the URL.
Here's a simple example to get you started:
const std = @import("std");
const nexlog = @import("nexlog");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
// Initialize logger
var builder = nexlog.LogBuilder.init();
try builder
.setMinLevel(.debug)
.enableColors(true)
.enableFileLogging(true, "logs/app.log")
.build(allocator);
defer nexlog.deinit();
// Get the default logger
const logger = nexlog.getDefaultLogger() orelse return error.LoggerNotInitialized;
// Log messages
logger.info("Application starting", .{}, null);
logger.debug("Debug information", .{}, null);
logger.warn("Warning message", .{}, null);
logger.err("Error occurred", .{}, null);
}
The examples/
directory contains comprehensive examples for all features:
basic_usage.zig
: Simple logging setup and usagestructured_logging.zig
: Advanced structured logging with JSON and logfmtfile_rotation.zig
: File rotation configuration and managementcustom_handler.zig
: Creating custom log handlersjson_logging.zig
: JSON-specific logging featureslogger_integration.zig
: Integrating with existing applicationsbenchmark.zig
: Performance benchmarking examples
const fields = [_]nexlog.StructuredField{
.{
.name = "user_id",
.value = "12345",
},
.{
.name = "action",
.value = "login",
},
};
logger.info("User logged in", .{}, &fields);
try builder
.enableFileLogging(true, "logs/app.log")
.setMaxFileSize(5 * 1024 * 1024) // 5MB
.setMaxRotatedFiles(3)
.enableRotation(true)
.build(allocator);
nexlog supports multiple structured logging formats:
-
JSON Format
{ "timestamp": "2024-03-19T10:42:00Z", "level": "info", "message": "User logged in", "fields": { "user_id": "12345", "action": "login" } }
-
Logfmt Format
timestamp=2024-03-19T10:42:00Z level=info message="User logged in" user_id=12345 action=login
-
Custom Format
[2024-03-19T10:42:00Z] INFO | User logged in | user_id=12345 | action=login
Configure file rotation with size limits and backup counts:
try builder
.enableFileLogging(true, "logs/app.log")
.setMaxFileSize(5 * 1024 * 1024) // 5MB
.setMaxRotatedFiles(3)
.enableRotation(true)
.build(allocator);
This creates rotated files like:
app.log
app.log.1
app.log.2
app.log.3
Create custom log handlers for specialized needs:
const CustomHandler = struct {
pub fn handle(level: nexlog.LogLevel, message: []const u8, fields: ?[]const nexlog.StructuredField) !void {
// Custom handling logic
}
};
Advanced configuration using the builder pattern:
try builder
.setMinLevel(.debug)
.enableColors(true)
.setBufferSize(8192)
.enableFileLogging(true, "logs/app.log")
.setMaxFileSize(5 * 1024 * 1024)
.setMaxRotatedFiles(3)
.enableRotation(true)
.enableAsyncMode(true)
.enableMetadata(true)
.build(allocator);
Option | Description | Default |
---|---|---|
minLevel |
Minimum log level to process | .info |
bufferSize |
Size of the log buffer | 4096 |
maxFileSize |
Maximum size before rotation | 10MB |
maxRotatedFiles |
Number of backup files to keep | 5 |
asyncMode |
Enable asynchronous logging | false |
colors |
Enable terminal colors | true |
metadata |
Include metadata in logs | true |
Recent benchmark results (Windows, Release mode):
Format | Logs/Second | Notes |
---|---|---|
JSON | 26,790 | Base structured format |
Logfmt | 39,284 | ~47% faster than JSON |
Custom | 41,297 | Fastest format |
Large Fields | 8,594 | With 100-field JSON payload |
Many Fields | 7,333 | With 50 separate fields |
With Attributes | 20,776 | Including field attributes |
Full Integration | 5,878 | Complete logging pipeline |
Run benchmarks with:
zig build bench
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Commit your changes
- Open a Pull Request
For major changes, please open an issue first to discuss your ideas.
This project is licensed under the BSD 3-Clause License. See the LICENSE file for details.
Happy logging with nexlog! ๐