32

I'm looking for a good TraceListener for .Net that supports rolling over the log file based on size limits.

Constraints

  • Uses .Net built in Trace logging
  • Independent class or binary that's not part of some gigantic library
  • Allows rolling over a log file based on size
user17222
  • 1,691
  • 3
  • 15
  • 17

9 Answers9

32

You could use Microsoft.VisualBasic.Logging.FileLogTraceListener, which comes built-in with the .NET Framework. Don't let the VisualBasic in the namespace scare you, you'll just have to reference the microsoft.visualbasic.dll assembly and it should work fine with C#.

Mark Foreman
  • 2,190
  • 18
  • 16
csgero
  • 2,753
  • 17
  • 15
  • 1
    Found this thread via Google... thanks csgero for pointing out the built in option... looking at the docs for FileLogTraceListener, it sounds perfect, and no need to deploy a 3rd party assembly. Being a C# programmer I never even knew about the Microsoft.VisualBasic namespace. –  Oct 09 '08 at 17:42
  • 4
    FileLogTraceListener, i.e. the base .NET Framework, covers what you need. If you want more advanced listener options, check out the Essential Diagnostics extensions (http://essentialdiagnostics.codeplex.com/) – Sly Gryphon Nov 25 '11 at 01:57
  • 10
    FileLogTraceListener can not work as "rollover log file". It only can create a new file daily, for example or skip writing new messages when size of the log file is too big. – Viacheslav Ivanov Sep 19 '12 at 09:22
  • We just hit this 'skip writing' issue - the workaround is to set DiskSpaceExhaustedBehavior to ThrowException rather than DiscardMessages. Then when you get the exception, set the listener to Append = false, then write one log event to create a new file, then set Append back to true. Only problem is this deletes the old log file, rather than renaming it... – Surfbutler Sep 28 '15 at 11:01
  • We got bit by the fact that **this does not, in fact, "[allow] rolling over a log file based on size"** – Mark Sowul Jan 20 '17 at 16:00
  • Downvoted because Microsoft.VisualBasic.Logging.FileLogTraceListener can't do rollover based on size. – user3285954 Aug 13 '20 at 19:27
13

I keep this config snippet handy for whenever I need to do the network trace. I don't have to have a project built with explicit reference to VB DLL added as this does by adding the reference in App.config at runtime.

<system.diagnostics>
  <sources>
    <source name="System.Net">
      <listeners>
        <add name="System.Net"/>
      </listeners>
    </source>
    <source name="System.Net.Http">
      <listeners>
        <add name="System.Net"/>
      </listeners>
    </source>
    <source name="System.Net.Sockets">
      <listeners>
        <add name="System.Net"/>
      </listeners>
    </source>
  </sources>
  <switches>
    <add name="System.Net" value="Verbose"/>
    <add name="System.Net.Http" value="Verbose"/>
    <add name="System.Net.Sockets" value="Verbose"/>
  </switches>
  <sharedListeners>
    <add name="System.Net"
          type="Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
          traceOutputOptions="DateTime,ProcessId,ThreadId"
          customLocation="c:\temp"
          location="Custom"
          logFileCreationSchedule="Daily"
          baseFileName="NetworkTrace"/>
  </sharedListeners>
  <trace autoflush="true"/>
</system.diagnostics>

And add the reference at runtime

  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.VisualBasic"  culture="neutral" publicKeyToken="b03f5f7f11d50a3a"/>
        <codeBase version="10.0.0.0" href="file://C:/Program Files (x86)/Reference Assemblies/Microsoft/Framework/.NETFramework/v4.5/Microsoft.VisualBasic.dll"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
Ostati
  • 4,623
  • 3
  • 44
  • 48
4

I'm a big fan of log4net (http://logging.apache.org/log4net/index.html), it's very easy to configure and supports just about any log type you want, but can have custom ones written as well.

It can also do different actions depending on the log level. We log all messages to a text file and Error -> Fatal send emails

Aaron Powell
  • 24,927
  • 18
  • 98
  • 150
  • problem is I prefer to use the integrated .Net trace logging – user17222 Oct 01 '08 at 07:36
  • Then check out the TraceAppender in it, that'll log to the trace of the app – Aaron Powell Oct 01 '08 at 07:54
  • 2
    TraceAppender allows you to redirect log4net traces to the Framework (and does a very basic Trace.Write so no levels, filtering, event ID's etc, basically a pretty crap job). If, however, you are already tracing using the .NET Framework (i.e. traceSource.TraceEvent()) then it doesn't help, or help with WCF, WIF, or if you turn on any other Framework tracing. – Sly Gryphon Apr 21 '13 at 05:33
4

I am using NLog and I am very satisfied. Source code is well written and it is easy to extend and modify. Documentation is good and it is very easy to configure.

Some Links:

Robert Vuković
  • 4,677
  • 6
  • 31
  • 47
4

FileLogTraceListener is a common suggestion but it throws away events or throws an exception when the file exceeds the given max size.

We created a class that extends it, and overrides the Write/WriteLine methods.

There's a try/catch (InvalidOperationException), and if that happens, we call base.Close and rename the file (FullLogFileName) as follows (we need the base.Close or else we'll get a 'file in use' error):

In a loop, we add a number to the end, and see if that file exists; if not, use File.Move(FullLogFileName, newFileWithNumber), otherwise we keep incrementing the number until we find a file name that works. There's also a lock to ensure that the given instance is thread safe.

Mark Sowul
  • 10,244
  • 1
  • 45
  • 51
3

I have used both Log4Net and Nlog. I prefer NLog but really once they are setup you forget they are there anyway (untill something breaks, then your glad it is there!). there should be plenty of documentation on both out in the interweb

RhysC
  • 1,644
  • 1
  • 15
  • 23
0

As given in one of the comments:

FileLogTraceListener Class

Writes to a rolling text file.

Remarks

A new file is used when the maxFileSize is reached, as well as a daily or weekly basis as specified by logFileCreationSchedule.

Each file has a name in the format "\(-)(-).log", with the local date included for daily and weekly rotation, and a sequence number appended if the file already exists.

Chris S
  • 64,770
  • 52
  • 221
  • 239
0

Consider Enterprise Library Logging Application Block

Make sure to install only the Logging block, since EntLib installer checks all blocks by default.

Grigori Melnik
  • 4,067
  • 2
  • 34
  • 40
  • EntLib Logging Application Block is complex to configure, slow, and has less functionality than the base System.Diagnostics in some cases! – Sly Gryphon Nov 25 '11 at 01:59
0

I had the same issue. Secure environment, no open source allowed. Painful. Here's what worked for us.

Derive from TextWriterTraceListener that adds members for max log size, max rolls to keep, and uses a FileStream with Share and Access set to ReadWrite and set OpenOrCreate. It should also create and hold a mutex with a name based on the filename.

Override TraceEvent method, wait for the mutex, seek the stream to end, call Write, check the size and roll if necessary. Release the mutex.

For rolling, rotate the previous rolls via file move and delete, copy the current file to the first level roll name, call SetLength(0) on the stream. All done within the mutex grab, but hopefully not often. This will work across processes and will avoid that crappy {GUID}mylog.log stuff.