mirror of
https://github.com/jetzig-framework/jetzig.git
synced 2025-05-14 14:06:08 +00:00
Never sync stdout/stderr
Detecting if stdout/stderr is tty seems to cause issues when running in Docker (in particular with fly.io)
This commit is contained in:
parent
b7c3c0045a
commit
dee5701b4a
@ -196,15 +196,15 @@ pub fn init(parent_allocator: std.mem.Allocator, env_options: EnvironmentOptions
|
|||||||
|
|
||||||
const env_file = std.fs.cwd().openFile(options.options.@"env-file", .{}) catch |err|
|
const env_file = std.fs.cwd().openFile(options.options.@"env-file", .{}) catch |err|
|
||||||
switch (err) {
|
switch (err) {
|
||||||
error.FileNotFound => null,
|
error.FileNotFound => null,
|
||||||
else => return err,
|
else => return err,
|
||||||
};
|
};
|
||||||
|
|
||||||
const vars = try Vars.init(allocator, env_file);
|
const vars = try Vars.init(allocator, env_file);
|
||||||
|
|
||||||
var launch_logger = LaunchLogger{
|
var launch_logger = LaunchLogger{
|
||||||
.stdout = stdout,
|
.stdout = stdout.file,
|
||||||
.stderr = stderr,
|
.stderr = stderr.file,
|
||||||
.silent = env_options.silent,
|
.silent = env_options.silent,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -213,8 +213,8 @@ pub fn init(parent_allocator: std.mem.Allocator, env_options: EnvironmentOptions
|
|||||||
.development_logger = jetzig.loggers.DevelopmentLogger.init(
|
.development_logger = jetzig.loggers.DevelopmentLogger.init(
|
||||||
allocator,
|
allocator,
|
||||||
resolveLogLevel(options.options.@"log-level", jetzig.environment),
|
resolveLogLevel(options.options.@"log-level", jetzig.environment),
|
||||||
stdout,
|
stdout.file,
|
||||||
stderr,
|
stderr.file,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
.production => jetzig.loggers.Logger{
|
.production => jetzig.loggers.Logger{
|
||||||
@ -304,23 +304,26 @@ pub fn deinit(self: Environment) void {
|
|||||||
self.parent_allocator.destroy(self.arena);
|
self.parent_allocator.destroy(self.arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getLogFile(stream: enum { stdout, stderr }, options: Options) !std.fs.File {
|
fn getLogFile(stream: enum { stdout, stderr }, options: Options) !jetzig.loggers.LogFile {
|
||||||
const path = switch (stream) {
|
const path = switch (stream) {
|
||||||
.stdout => options.log,
|
.stdout => options.log,
|
||||||
.stderr => options.@"log-error",
|
.stderr => options.@"log-error",
|
||||||
};
|
};
|
||||||
|
|
||||||
if (std.mem.eql(u8, path, "-")) return switch (stream) {
|
if (std.mem.eql(u8, path, "-")) return switch (stream) {
|
||||||
.stdout => std.io.getStdOut(),
|
.stdout => .{ .file = std.io.getStdOut(), .sync = false },
|
||||||
.stderr => if (std.mem.eql(u8, options.log, "-"))
|
.stderr => if (std.mem.eql(u8, options.log, "-"))
|
||||||
std.io.getStdErr()
|
.{ .file = std.io.getStdErr(), .sync = false }
|
||||||
else
|
else
|
||||||
try std.fs.createFileAbsolute(options.log, .{ .truncate = false }),
|
.{
|
||||||
|
.file = try std.fs.createFileAbsolute(options.log, .{ .truncate = false }),
|
||||||
|
.sync = true,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const file = try std.fs.createFileAbsolute(path, .{ .truncate = false });
|
const file = try std.fs.createFileAbsolute(path, .{ .truncate = false });
|
||||||
try file.seekFromEnd(0);
|
try file.seekFromEnd(0);
|
||||||
return file;
|
return .{ .file = file, .sync = true };
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getSecret(
|
fn getSecret(
|
||||||
|
@ -12,6 +12,11 @@ pub const NullLogger = @import("loggers/NullLogger.zig");
|
|||||||
|
|
||||||
pub const LogQueue = @import("loggers/LogQueue.zig");
|
pub const LogQueue = @import("loggers/LogQueue.zig");
|
||||||
|
|
||||||
|
pub const LogFile = struct {
|
||||||
|
file: std.fs.File,
|
||||||
|
sync: bool = false,
|
||||||
|
};
|
||||||
|
|
||||||
pub const LogLevel = enum(u4) { TRACE, DEBUG, INFO, WARN, ERROR, FATAL };
|
pub const LogLevel = enum(u4) { TRACE, DEBUG, INFO, WARN, ERROR, FATAL };
|
||||||
pub const LogFormat = enum { development, production, json, null };
|
pub const LogFormat = enum { development, production, json, null };
|
||||||
|
|
||||||
|
@ -70,7 +70,11 @@ pub fn deinit(self: *LogQueue) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Set the stdout and stderr outputs. Must be called before `print`.
|
/// Set the stdout and stderr outputs. Must be called before `print`.
|
||||||
pub fn setFiles(self: *LogQueue, stdout_file: std.fs.File, stderr_file: std.fs.File) !void {
|
pub fn setFiles(
|
||||||
|
self: *LogQueue,
|
||||||
|
stdout_file: jetzig.loggers.LogFile,
|
||||||
|
stderr_file: jetzig.loggers.LogFile,
|
||||||
|
) !void {
|
||||||
self.writer = Writer{
|
self.writer = Writer{
|
||||||
.queue = self,
|
.queue = self,
|
||||||
.mutex = std.Thread.Mutex{},
|
.mutex = std.Thread.Mutex{},
|
||||||
@ -80,11 +84,11 @@ pub fn setFiles(self: *LogQueue, stdout_file: std.fs.File, stderr_file: std.fs.F
|
|||||||
.stderr_file = stderr_file,
|
.stderr_file = stderr_file,
|
||||||
.queue = self,
|
.queue = self,
|
||||||
};
|
};
|
||||||
self.stdout_is_tty = stdout_file.isTty();
|
self.stdout_is_tty = stdout_file.file.isTty();
|
||||||
self.stderr_is_tty = stderr_file.isTty();
|
self.stderr_is_tty = stderr_file.file.isTty();
|
||||||
|
|
||||||
self.stdout_colorize = std.io.tty.detectConfig(stdout_file) != .no_color;
|
self.stdout_colorize = std.io.tty.detectConfig(stdout_file.file) != .no_color;
|
||||||
self.stderr_colorize = std.io.tty.detectConfig(stderr_file) != .no_color;
|
self.stderr_colorize = std.io.tty.detectConfig(stderr_file.file) != .no_color;
|
||||||
|
|
||||||
self.state = .ready;
|
self.state = .ready;
|
||||||
}
|
}
|
||||||
@ -147,8 +151,8 @@ pub const Writer = struct {
|
|||||||
/// Reader for `LogQueue`. Reads log events from the queue and writes them to the designated
|
/// Reader for `LogQueue`. Reads log events from the queue and writes them to the designated
|
||||||
/// target (stdout or stderr).
|
/// target (stdout or stderr).
|
||||||
pub const Reader = struct {
|
pub const Reader = struct {
|
||||||
stdout_file: std.fs.File,
|
stdout_file: jetzig.loggers.LogFile,
|
||||||
stderr_file: std.fs.File,
|
stderr_file: jetzig.loggers.LogFile,
|
||||||
queue: *LogQueue,
|
queue: *LogQueue,
|
||||||
|
|
||||||
pub const PublishOptions = struct {
|
pub const PublishOptions = struct {
|
||||||
@ -160,8 +164,8 @@ pub const Reader = struct {
|
|||||||
pub fn publish(self: *Reader, options: PublishOptions) !void {
|
pub fn publish(self: *Reader, options: PublishOptions) !void {
|
||||||
std.debug.assert(self.queue.state == .ready);
|
std.debug.assert(self.queue.state == .ready);
|
||||||
|
|
||||||
const stdout_writer = self.stdout_file.writer();
|
const stdout_writer = self.stdout_file.file.writer();
|
||||||
const stderr_writer = self.stderr_file.writer();
|
const stderr_writer = self.stderr_file.file.writer();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
self.queue.condition_mutex.lock();
|
self.queue.condition_mutex.lock();
|
||||||
@ -181,13 +185,13 @@ pub const Reader = struct {
|
|||||||
.stdout => {
|
.stdout => {
|
||||||
stdout_written = true;
|
stdout_written = true;
|
||||||
if (builtin.os.tag == .windows) {
|
if (builtin.os.tag == .windows) {
|
||||||
file = self.stdout_file;
|
file = self.stdout_file.file;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.stderr => {
|
.stderr => {
|
||||||
stderr_written = true;
|
stderr_written = true;
|
||||||
if (builtin.os.tag == .windows) {
|
if (builtin.os.tag == .windows) {
|
||||||
file = self.stderr_file;
|
file = self.stderr_file.file;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -220,8 +224,8 @@ pub const Reader = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stdout_written and !self.queue.stdout_is_tty) try self.stdout_file.sync();
|
if (stdout_written and self.stdout_file.sync) try self.stdout_file.file.sync();
|
||||||
if (stderr_written and !self.queue.stderr_is_tty) try self.stderr_file.sync();
|
if (stderr_written and self.stderr_file.sync) try self.stderr_file.file.sync();
|
||||||
|
|
||||||
if (options.oneshot) break;
|
if (options.oneshot) break;
|
||||||
}
|
}
|
||||||
@ -289,7 +293,7 @@ test "print to stdout and stderr" {
|
|||||||
const stderr = try tmp_dir.dir.createFile("stderr.log", .{ .read = true });
|
const stderr = try tmp_dir.dir.createFile("stderr.log", .{ .read = true });
|
||||||
defer stderr.close();
|
defer stderr.close();
|
||||||
|
|
||||||
try log_queue.setFiles(stdout, stderr);
|
try log_queue.setFiles(.{ .file = stdout }, .{ .file = stderr });
|
||||||
try log_queue.print("foo {s}\n", .{"bar"}, .stdout);
|
try log_queue.print("foo {s}\n", .{"bar"}, .stdout);
|
||||||
try log_queue.print("baz {s}\n", .{"qux"}, .stderr);
|
try log_queue.print("baz {s}\n", .{"qux"}, .stderr);
|
||||||
try log_queue.print("quux {s}\n", .{"corge"}, .stdout);
|
try log_queue.print("quux {s}\n", .{"corge"}, .stdout);
|
||||||
@ -333,7 +337,7 @@ test "long messages" {
|
|||||||
const stderr = try tmp_dir.dir.createFile("stderr.log", .{ .read = true });
|
const stderr = try tmp_dir.dir.createFile("stderr.log", .{ .read = true });
|
||||||
defer stderr.close();
|
defer stderr.close();
|
||||||
|
|
||||||
try log_queue.setFiles(stdout, stderr);
|
try log_queue.setFiles(.{ .file = stdout }, .{ .file = stderr });
|
||||||
try log_queue.print("foo" ** buffer_size, .{}, .stdout);
|
try log_queue.print("foo" ** buffer_size, .{}, .stdout);
|
||||||
|
|
||||||
try log_queue.reader.publish(.{ .oneshot = true });
|
try log_queue.reader.publish(.{ .oneshot = true });
|
||||||
|
Loading…
x
Reference in New Issue
Block a user