My applications are only used within our company and I have one common log file on a shared drive. I want to log each use of my desktop applications for statistics and also log errors thrown.
Also the users should not be able to open the log files and parent folders.
Therefore the log file and parent folders are set to write-only permission:
Serilog is not writing to that write-only log file.
With Serilog.Debugging.SelfLog.Enable(...)
I can observe Serilog has a problem with the permissions set:
Before I knew Serilog I was writing logs to the same write-only folders with StreamWriter.WriteLine()
or File.AppendText()
.
=> Both methods write logs to the write-only folders/files without problems.
Could it be, that Serilog is checking read-permissions before writing?
Is there a setting enabling Serilog to write to a write-only file?
I sadly think this is not possible with the File Sink you are using. The sink opens a file stream to the file like this:
Stream outputStream = _underlyingStream = System.IO.File.Open(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read);
As you can see it also wants FileShare.Read
access to the file.
I think they do this, because you can set a file size limit.
So they need read access to check if this file size limit is reached.
You could write your own custom sink as described here: https://github.com/serilog/serilog/wiki/Developing-a-sink
An example for your use case could look like this:
MyCustomFileSink.cs
public class MyCustomFileSink : ILogEventSink
{
private readonly IFormatProvider _formatProvider;
private readonly string _path;
public MyCustomFileSink(IFormatProvider formatProvider, string path)
{
_formatProvider = formatProvider;
_path = path;
if (!File.Exists(_path))
throw new FileNotFoundException();
}
public void Emit(LogEvent logEvent)
{
var message = logEvent.RenderMessage(_formatProvider);
using StreamWriter sw = File.AppendText(_path);
sw.WriteLine(message);
}
}
MyCustomFileSinkExtension.cs
public static class MyCustomFileSinkExtension
{
public static LoggerConfiguration MyCustomFileSink(
this LoggerSinkConfiguration loggerConfiguration,
IFormatProvider formatProvider,string path)
{
return loggerConfiguration.Sink(new MyCustomFileSink(formatProvider,path));
}
}
After that you can use your custom sink something like this:
var log = new LoggerConfiguration()
.MinimumLevel.Information()
.WriteTo.MyCustomFileSink(null,"path/to/file")
.CreateLogger();
This is only a very simple example but I think you get the idea behind it.