You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In some cases, the second process trying to open a shared file (shared: true) throws exception on mutex creation, and no log events are registered. This is registered in SelfLog:
2023-07-13T14:56:59.4806193Z Caught exception while emitting to sink Serilog.Sinks.File.RollingFileSink: System.UnauthorizedAccessException: Access to the path 'C::logs:log-20230713.txt.serilog' isdenied.atSystem.Threading.Mutex.CreateMutexCore(BooleaninitiallyOwned,Stringname,Boolean&createdNew)
at System.Threading.Mutex..ctor(BooleaninitiallyOwned,Stringname)
at Serilog.Sinks.File.SharedFileSink..ctor(Stringpath,ITextFormattertextFormatter, Nullable`1fileSizeLimitBytes,Encodingencoding)
at Serilog.Sinks.File.RollingFileSink.OpenFile(DateTimenow, Nullable`1minSequence)
at Serilog.Sinks.File.RollingFileSink.AlignCurrentFileTo(DateTimenow,BooleannextSequence)
at Serilog.Sinks.File.RollingFileSink.Emit(LogEventlogEvent)
at Serilog.Core.Sinks.SafeAggregateSink.Emit(LogEventlogEvent)
UnauthorizedAccessException: The named mutex exists and has access control security, but the user does not have FullControl."
My enviroment is: ASP.NET Core 6 app hosted in IIS in-process in Windows Server 2012 R2 (I know, it's old). I deploy using Blue/Green deployment applied to the apppool level, that is, for a small period of time, I have two appools simultaneously trying to log to the same file.
In .NET Framework, there is a Mutex constructor that accepts an MutexSecurity with an ACL to specify the FullControl permission required. In .NET Core there is no such construtor, but instead the method MutexAcl.Create in System.Threading.AccessControl nuget package can be used. This way of creating the mutex, posted in NLog issue #5244, resolves the problem:
privatestaticMutexForceCreateSharableMutex(stringname){if(System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(OSPlatform.Windows)){// Creates a mutex sharable by more than one process varmutexSecurity=newMutexSecurity();vareveryoneSid=newSecurityIdentifier(WellKnownSidType.WorldSid,null);mutexSecurity.AddAccessRule(newMutexAccessRule(everyoneSid,MutexRights.FullControl,AccessControlType.Allow));
#if NET48// The constructor will either create new mutex or open// an existing one, in a thread-safe mannerreturnnewMutex(false,name,out_,mutexSecurity);
#else
returnMutexAcl.Create(false,name,out_,mutexSecurity);
#endif
}returnnewMutex(false,name,out_);}
I have tested it, replacing the mutex creation in SharedFileSink.OSMutex.cs, and it worked for me.
In case of .NET Core, using MutexAcl.Create adds a dependency to System.Threading.AccessControl package. If that is not desirable, I suggest to include a way to pass to Serilog a factory method to create mutexes, and talk about the problem and solution in the documentation of Shared log files.
The text was updated successfully, but these errors were encountered:
ATOMIC_APPEND has been possible in .NET (Core) for a few versions now, I think we'd be better off enabling that feature and taking the necessary NUPKG dependency on the versions that support it.
(Changing access rights to the mutex would probably need a breaking change, since it would allow a low-privilege user to disrupt logging by a higher-privileged user by taking and never releasing the mutex.)
Closing on the basis that #221 can track the issue/need
If this is incorrect and there is something separately actionable here, I'm not opposed to having an issue; I just don't see what it is...
In some cases, the second process trying to open a shared file (
shared: true
) throws exception on mutex creation, and no log events are registered. This is registered inSelfLog
:The documentation for System.Threading.Mutex says
My enviroment is: ASP.NET Core 6 app hosted in IIS in-process in Windows Server 2012 R2 (I know, it's old). I deploy using Blue/Green deployment applied to the apppool level, that is, for a small period of time, I have two appools simultaneously trying to log to the same file.
In .NET Framework, there is a
Mutex
constructor that accepts anMutexSecurity
with an ACL to specify theFullControl
permission required. In .NET Core there is no such construtor, but instead the methodMutexAcl.Create
inSystem.Threading.AccessControl
nuget package can be used. This way of creating the mutex, posted in NLog issue #5244, resolves the problem:I have tested it, replacing the mutex creation in
SharedFileSink.OSMutex.cs
, and it worked for me.In case of .NET Core, using
MutexAcl.Create
adds a dependency toSystem.Threading.AccessControl
package. If that is not desirable, I suggest to include a way to pass to Serilog a factory method to create mutexes, and talk about the problem and solution in the documentation of Shared log files.The text was updated successfully, but these errors were encountered: