1

I need to send an email after a large process execution with the log file as an attachment so any problems can be identified by the users. We use log4net to handle all of our logging, and I have not been able to get log4net to release the file so it can be added as an attachment.

So far, I followed the results on this question: How to stop log4net from logging and release the last file about setting the appender threshold to "Off", but I continue to receive an exception due to the DLL not releasing the log file. I can verify in the debugger that the appender is actually in "Off", but process explorer confirms that my exe is still holding its lock on the file.

Here is the method I got from the linked question:

 private static void SetThreshold(string appenderName, log4net.Core.Level threshold)
        {
            foreach (log4net.Appender.AppenderSkeleton appender in log4net.LogManager.GetRepository().GetAppenders())
            {
                if (appender.Name == appenderName)
                {
                    appender.Threshold = threshold;
                    break;
                }
            }
        }

Any ideas how to force a release of this log would be super helpful. Thanks

samyap
  • 131
  • 1
  • 7

3 Answers3

2

Using the following code block I got from a colleague I am able to get read-only access to the log (need write access to use as an attachment in an email):

 var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            var lines = new List<string>();
            using (var sr = new StreamReader(fs))
            {
                while(!sr.EndOfStream)
                {
                    lines.Add(sr.ReadLine());
                }
            }

I am able to take this list and write to a temp file and use that to send our attachment and don't have to worry about modifying log4net and jeopardizing any dependencies of other assemblies targeting the same log4net DLL.

Thanks to the two people who shared their thoughts!

samyap
  • 131
  • 1
  • 7
1

When using the FileAppender or RollingFileAppender one can configure the log file LockingModel. Using the appropriate LockingModel should allow the needed file access privilege.
From the log4net documentation (https://logging.apache.org/log4net/release/sdk/index.html)

There are three built in locking models:

  • FileAppender.ExclusiveLock
  • FileAppender.MinimalLock
  • FileAppender.InterProcessLock

The first locks the file from the start of logging to the end, the second locks only for the minimal amount of time when logging each message and the last synchronizes processes using a named system wide Mutex.

The default locking model is the FileAppender.ExclusiveLock.

Below configuration example from https://logging.apache.org/log4net/release/config-examples.html

<appender name="FileAppender" type="log4net.Appender.FileAppender">
    <file value="${TMP}\log-file.txt" />
    <appendToFile value="true" />
    <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
    <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
    </layout>
</appender>

Edit: The LockingModel exposes a ReleaseLock method which will force the file to be released by the process. To continue logging you have to then call AcquireLock.

NicoE
  • 186
  • 7
  • This seems useful, but I was able to get readonly access to the file so I am just copying the contents to a temp file and using that for attachment. – samyap May 22 '19 at 19:30
0

The log is open for writing so the only way to release the lock is to stop the application. You do have options: 1) use maximumFileSize setting to break the log file into chunks so that only most recent log won't be available; 2) log messages to database (log4net provides such interface, see https://www.c-sharpcorner.com/article/configure-log4net-with-database-tutorial-for-beginners/).

Vasya
  • 469
  • 2
  • 6