Compare commits
2 Commits
eb7e78697c
...
7889a6ec7a
| Author | SHA1 | Date | |
|---|---|---|---|
| 7889a6ec7a | |||
| b03c770b59 |
17
README.md
17
README.md
@@ -89,3 +89,20 @@ This will result in the following output:
|
||||
For more details about the output customization see the configuration options of the `zlog` module. Following options are available:
|
||||
|
||||
- _timestamp_ (default: `true`): Prepend the current timestamp before each log message.
|
||||
- _stderr_ (default: `true`): Print log messages to stderr. **NOTE**: Currently not working as log output is not appended and only the last log message will be in the resulting log file! This is a not-yet-implemented feature of the standard library of zig 0.13.0! See this [issue](https://github.com/ziglang/zig/issues/14375) for more details.
|
||||
|
||||
## Tips
|
||||
|
||||
The following list shows some tips on how to use logging more effectively. These tips do not apply just to `zlog` (and not even only to zig code).
|
||||
|
||||
- Use `errdefer` to directly print messages on failures in the same function they occur:
|
||||
```zig
|
||||
// assume log is already defined before (with the corresponding scope)
|
||||
const port = port: {
|
||||
errdefer |err| log.err("failed to read the port number: {}", .{err});
|
||||
|
||||
var buf: [fmt.count("{}\n", .{maxInt(u16)})]u8 = undefined;
|
||||
const len = try process.stdout.?.readAll(&buf);
|
||||
break :port try fmt.parseInt(u16, buf[0 .. len -| 1], 10);
|
||||
};
|
||||
```
|
||||
|
||||
@@ -6,9 +6,13 @@ const std = @import("std");
|
||||
pub fn build(b: *std.Build) void {
|
||||
// build options to customize the log message formating
|
||||
const include_timestamp = b.option(bool, "timestamp", "Enable inclusion of timestamps in log messages (default: true)") orelse true;
|
||||
const stderr = b.option(bool, "stderr", "Print all log messages to stderr (default: true)") orelse true;
|
||||
const file = b.option([]const u8, "file", "Print all log messages to the provided file.") orelse "";
|
||||
|
||||
const options = b.addOptions();
|
||||
options.addOption(bool, "timestamp", include_timestamp);
|
||||
options.addOption(bool, "stderr", stderr);
|
||||
options.addOption([]const u8, "file", file);
|
||||
|
||||
const options_module = options.createModule();
|
||||
|
||||
|
||||
48
src/zlog.zig
48
src/zlog.zig
@@ -15,26 +15,52 @@ fn logFn(
|
||||
) void {
|
||||
// TODO: provide build time configuration to allow tweaking corresponding output
|
||||
// - change output file for writing messages to (default `stderr`)
|
||||
// write into own file for each level?
|
||||
const level_txt = comptime message_level.asText();
|
||||
const prefix = if (scope == .default) ": " else "(" ++ @tagName(scope) ++ "): ";
|
||||
const stderr = std.io.getStdErr().writer();
|
||||
var bw = std.io.bufferedWriter(stderr);
|
||||
const writer = bw.writer();
|
||||
const fmt = level_txt ++ prefix ++ format ++ "\n";
|
||||
if (comptime build_options.file.len != 0) blk: {
|
||||
// NOTE: with zig 0.13.0 there is currently no way to open files to append (except to use libc or talk directly to posix, which this lib should not have to do)
|
||||
const file = std.fs.openFileAbsolute(build_options.file, .{
|
||||
.mode = .read_write,
|
||||
}) catch std.fs.createFileAbsolute(build_options.file, .{
|
||||
.truncate = false,
|
||||
}) catch break :blk;
|
||||
defer file.close();
|
||||
|
||||
var buffer = std.io.bufferedWriter(file.writer());
|
||||
defer buffer.flush() catch {};
|
||||
|
||||
const writer = buffer.writer();
|
||||
log_writing(writer, fmt, args);
|
||||
}
|
||||
|
||||
if (comptime build_options.stderr) {
|
||||
var buffer = std.io.bufferedWriter(std.io.getStdErr().writer());
|
||||
defer buffer.flush() catch {};
|
||||
|
||||
std.debug.lockStdErr();
|
||||
defer std.debug.unlockStdErr();
|
||||
|
||||
const writer = buffer.writer();
|
||||
log_writing(writer, fmt, args);
|
||||
}
|
||||
}
|
||||
|
||||
fn log_writing(writer: anytype, comptime fmt: []const u8, args: anytype) void {
|
||||
nosuspend {
|
||||
if (build_options.timestamp) {
|
||||
if (build_options.timestamp) log_timestamp(writer);
|
||||
writer.print(fmt, args) catch return;
|
||||
}
|
||||
}
|
||||
|
||||
fn log_timestamp(writer: anytype) void {
|
||||
const curtime = c_time.time(null);
|
||||
const tm = c_time.localtime(&curtime);
|
||||
|
||||
var buf: [32]u8 = undefined;
|
||||
_ = c_time.strftime(@ptrCast(&buf), 32, "%F %R", tm);
|
||||
writer.print("[{s}] ", .{buf}) catch return;
|
||||
}
|
||||
writer.print(level_txt ++ prefix ++ format ++ "\n", args) catch return;
|
||||
bw.flush() catch return;
|
||||
}
|
||||
var buffer: [32]u8 = undefined;
|
||||
_ = c_time.strftime(@ptrCast(&buffer), 32, "%F %R", tm);
|
||||
writer.print("[{s}] ", .{buffer}) catch return;
|
||||
}
|
||||
|
||||
pub fn pretty_format(object: anytype, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
|
||||
|
||||
Reference in New Issue
Block a user