Nlog: file target keepFileOpen prevents another process from reading

Created on 23 Oct 2018  路  3Comments  路  Source: NLog/NLog

file target keepFileOpen=true is holding the log file opened in some exclusive mode. Is there another option for good performance, where NLog file target opens logging file in Shared Read mode?

My scenario is this:
NLog file target to ~/App_Data/Logs/log with keepFileOpen=true
A logviewer MVC controller tries to display last 1000 characters of App_Data/Logs/log but can't because any File.Open attempts, even when using FileMode.Read, FileShare.Read, fails with

IOException: The process cannot access the file "D:\wwwroot\webapplication1\App_Data\Logs\log" because it is being used by another process.]
   System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) +893
   System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost) +1217
   System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share) +123
   System.Web.HttpResponse.TransmitFile(String filename, Int64 offset, Int64 length) +136
   ASP.logview_aspx.__Render__control1(HtmlTextWriter __w, Control parameterContainer) +590
   System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +117
   System.Web.UI.Page.Render(HtmlTextWriter writer) +39
   System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +79
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +8753

keepFileOpen=false can be used, but is there a high performance way to still read from the log file, or should I submit a Feature Request for this? (Surprised others haven't mentioned this problem)

file-target question

All 3 comments

NLog doesn't lock the file in exclusive mode when having keepFileOpen=true. The problem is that TransmitFile requires no one has the file opened in write-mode:

https://github.com/Microsoft/referencesource/blob/master/System.Web/HttpResponse.cs#L2816

Try to find a different method for reading the file.

Ok I thought I had tried a different way, but still used FileShare.Read. Using the following works now:

c# Response.Clear(); string filePath = Server.MapPath("~/App_Data/Logs/log"); using(var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { fs.CopyTo(Response.OutputStream); } Response.End();

And that works. Thanks. I figured I was doing something wrong.

@ericnewton76 Glad you were able to figure it out yourself. As your first attempt was just repeating the error of TransmitFile

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ErcinDedeoglu picture ErcinDedeoglu  路  3Comments

sszost picture sszost  路  3Comments

JustArchi picture JustArchi  路  3Comments

linmasaki picture linmasaki  路  3Comments

carkov1990 picture carkov1990  路  3Comments