The start of the story is my implementing log4net in an ASP.NET application hosted on godaddy. Now godaddy.com has the speciality of running ASP.NET apps under medium trust IIS. That poses some restrictions but its pretty straightforward to get log4net running using by using the log4net documentation. For a rolling log file appender you must remember that access is limited to folders under your application root. You'll have to set permissions to read/write for that folder in the godaddy.com hosting control panel.
The stumbling block for me came when I tried to use FileZilla to download the log files. FileZilla was erroring out with a "file in use, access denied error" no matter what. I went back to the log4net appender config and set up MinimalLock. Which means a lock on the file is held only for the period of a write by log4net. I thought great that would be the end of that, but I was still getting issues trying to download with FileZilla.
I then decided to switch to take a different tack and wrote an ASP.NET webpage that displayed the contents of the log file. My thinking was that it would be the same process accessing the file so it should be all good.
Now my code to access the log file from the webpage essentially boiled down to
File.ReadAllText(path)I still got the access denied problem. I now decided to eliminate godaddy from the equation. I thought it would be a simple exercise initially, famous last words, so I ran the logging code directly on godaddy.com at first. To my surprise I could reproduce this locally.
It then occurred to me that I didnt really know in what mode File.ReadAllText was opening the file, though I had hoped it was with minimal restrictions; "read only". I took the file access into my own hands by doing something akin to:
new StreamReader(new FileStream(path, FileAccess, FileShare))keeping to my idea of a minimalist thread I put in FileShare.Read. Even with the IntelliSense help it seems like a good idea -> all I want is to read, write ?
The problem still did not go away. I then decided to pull out the big guns and see whats really going on cause I was getting frustrated by this point. So I reached for procmon and monitored the file access calls. After looking at the output for a bit it dawned on me something I had cause to encounter a couple of years back.
The semantics of FileShare are that it defines how else you allow another component to open the file you are working with. Now log4net, the first open of the file, opened it with FileShare.ReadWrite. This means the file can be opened a subsequent time for reading or writing. The issue arose because of my paranoiac Read only view which was my initial knee jerk reaction to the access denied errors.
I was trying to open the file with FileShare.Read which meant that I tried (from the perspective of the OS) to mandate others could only open the file read only, which of course clashes with what is already set on the file initially by log4net i.e. FileShare.ReadWrite.
To summarize, if you get access denied errors accessing files from code that you are the author of then do not forget your sharing semantics.