Serilog File Sink无法写入仅拥有写入权限的日志文件问题咨询
问题描述
公司内部桌面应用需在共享驱动器的公共日志文件记录使用情况与错误,为防止用户查看日志,已将日志文件及父文件夹设为仅写入权限,但使用Serilog写入时失败。通过Serilog.Debugging.SelfLog.Enable(...)确认是权限问题,而此前用StreamWriter.WriteLine()或File.AppendText()写入同一位置无异常。疑问如下:
- Serilog是否在写入前检查了读取权限?
- 是否有设置可让Serilog写入仅写入权限的文件?
解决方案
Serilog默认的文件写入逻辑确实会尝试读取文件(比如检查文件大小、读取现有内容执行滚动策略等),这就是它在仅写入权限下失败的核心原因——默认配置依赖读取权限完成前置操作,而StreamWriter这类基础API仅做单纯追加写入,无需额外读取权限。
要让Serilog适配仅写入权限场景,可通过两种方式调整:
- 禁用日志滚动与文件检查逻辑
配置Serilog仅往单个文件追加写入,跳过需要读取权限的文件大小检查、日志滚动等操作。示例代码:Log.Logger = new LoggerConfiguration() .WriteTo.File(@"\\shared-drive\logs\app.log", rollingInterval: RollingInterval.Infinite, fileSizeLimitBytes: null, rollOnFileSizeLimit: false) .CreateLogger(); - 自定义仅写入日志Sink
如果上述配置仍不生效,可实现自定义ILogEventSink,直接用File.AppendText()这类可靠的仅写入API处理日志,绕开Serilog默认的文件处理逻辑。简化实现示例:
注册自定义Sink:public class WriteOnlyFileSink : ILogEventSink { private readonly string _filePath; private readonly IFormatProvider _formatProvider; public WriteOnlyFileSink(string filePath, IFormatProvider formatProvider) { _filePath = filePath; _formatProvider = formatProvider; } public void Emit(LogEvent logEvent) { var message = logEvent.RenderMessage(_formatProvider); using (var writer = File.AppendText(_filePath)) { writer.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss} {message}"); } } }Log.Logger = new LoggerConfiguration() .WriteTo.Sink(new WriteOnlyFileSink(@"\\shared-drive\logs\app.log", CultureInfo.InvariantCulture)) .CreateLogger();
内容的提问来源于stack exchange,提问作者Tom667
相关产品推荐
相关产品推荐

