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:
|
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.
|
- _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 {
|
pub fn build(b: *std.Build) void {
|
||||||
// build options to customize the log message formating
|
// 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 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();
|
const options = b.addOptions();
|
||||||
options.addOption(bool, "timestamp", include_timestamp);
|
options.addOption(bool, "timestamp", include_timestamp);
|
||||||
|
options.addOption(bool, "stderr", stderr);
|
||||||
|
options.addOption([]const u8, "file", file);
|
||||||
|
|
||||||
const options_module = options.createModule();
|
const options_module = options.createModule();
|
||||||
|
|
||||||
|
|||||||
48
src/zlog.zig
48
src/zlog.zig
@@ -15,26 +15,52 @@ fn logFn(
|
|||||||
) void {
|
) void {
|
||||||
// TODO: provide build time configuration to allow tweaking corresponding output
|
// TODO: provide build time configuration to allow tweaking corresponding output
|
||||||
// - change output file for writing messages to (default `stderr`)
|
// - change output file for writing messages to (default `stderr`)
|
||||||
|
// write into own file for each level?
|
||||||
const level_txt = comptime message_level.asText();
|
const level_txt = comptime message_level.asText();
|
||||||
const prefix = if (scope == .default) ": " else "(" ++ @tagName(scope) ++ "): ";
|
const prefix = if (scope == .default) ": " else "(" ++ @tagName(scope) ++ "): ";
|
||||||
const stderr = std.io.getStdErr().writer();
|
const fmt = level_txt ++ prefix ++ format ++ "\n";
|
||||||
var bw = std.io.bufferedWriter(stderr);
|
if (comptime build_options.file.len != 0) blk: {
|
||||||
const writer = bw.writer();
|
// 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();
|
std.debug.lockStdErr();
|
||||||
defer std.debug.unlockStdErr();
|
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 {
|
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 curtime = c_time.time(null);
|
||||||
const tm = c_time.localtime(&curtime);
|
const tm = c_time.localtime(&curtime);
|
||||||
|
|
||||||
var buf: [32]u8 = undefined;
|
var buffer: [32]u8 = undefined;
|
||||||
_ = c_time.strftime(@ptrCast(&buf), 32, "%F %R", tm);
|
_ = c_time.strftime(@ptrCast(&buffer), 32, "%F %R", tm);
|
||||||
writer.print("[{s}] ", .{buf}) catch return;
|
writer.print("[{s}] ", .{buffer}) catch return;
|
||||||
}
|
|
||||||
writer.print(level_txt ++ prefix ++ format ++ "\n", args) catch return;
|
|
||||||
bw.flush() catch return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pretty_format(object: anytype, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
|
pub fn pretty_format(object: anytype, comptime fmt: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
|
||||||
|
|||||||
Reference in New Issue
Block a user