FieldLog

Fast and comprehensive logging tool for .NET applications. Designed for high-performance, storage-efficient, always-on logging and comes with a useful log viewer application.

Please bring about 8 minutes to read this page in peace.

tl;dr: Overview of the advantages and features:

  • Trace, data and error logging for .NET applications
  • Very easy to use, no configuration required
  • High time resolution and timer support, also good for performance measurements
  • Log viewer with helpful visualisations, details view, filter and live monitoring
  • Automatically logs unhandled exceptions
  • Complete solution for worry-free drop-in logging for independent developers and small businesses (free open source)
  • Log methods optimised for high performance multi-threaded operation
  • Deletes old log items based on priority and configurable keep time
  • Storage-efficient log file format, avoids string repetition, using NTFS compression
  • Source code lookup in stack traces without deploying .pdb files
  • Stack trace de-obfuscation using a obfuscator map file
  • WPF TraceSource events (e. g. DataBinding), more easily readable than in Visual Studio
  • Creates screenshots of the window or screen on errors
  • Log configuration with an optional robust text file
  • Submit tool that guides the user through sending logs

FieldLog is a fast and comprehensive logging tool for .NET applications. It allows applications to write events, data and errors to managed and efficient log files. The logging methods are optimised for high performance multi-threaded operation and a single log method call takes as little as half a microsecond on modern hardware. There’s no comparison to OutputDebugString, Debug.WriteLine or appending to a file each time! This logging can be used in performance-critical loops without noticeably slowing down the application.

Compatibility: .NET Version 2.0 or newer

Always-on logging

The general idea is to always leave debug logging enabled to be able to analyse it in case of an application failure. Traditional log systems can only append to log files but never delete old data. This leads to constantly increasing log size with the debug level enabled. FieldLog can manage its log files and only keep items of each priority for a specific time, then delete it to save space and remove unnecessary data. The low latency and good storage efficiency allow you to keep logging enabled. When an error occurs, all the relevant information is already here to be analysed.

You don’t need to instruct your users to enable logging by tinkering with hidden XML files and wait for the error to happen again. Instead, the user is guided through collecting the relevant logs and submitting them directly to the developer.

File compression

The log items are written in a binary format that minimises the amount of bytes per information and reuses any previous text strings for storage efficiency. If the same message string is logged over and over again, it will hardly increase the log size. The files are separated by log priority and a new file is started after a certain file size or time. If available, NTFS compression is used and considered in file size decisions. Old log items are automatically deleted. The maximum log size and keep time is configurable by an easy to understand and robust text file in the application directory.

Log viewer

The log viewer application, FieldLogViewer, loads a set of related log files and displays the log items in a list. The user can select any item to view all the details like thread ID, additional exception data, stack traces or system environment data at that time. Items are colour-coded by their priority and icons display the type of event.

A powerful filter editor allows you to quickly find the interesting events and concentrate on what matters. The viewer can even keep reading at the end of the log files and show new log items as they are written by the running application. This allows a developer to monitor the application in real-time. The selected filter remains in effect.

You can also use FieldLogViewer as a DebugOutputString listener (like Sysinternals’ DbgView) and read limited debug output from other processes as well.

Submit tool

An easy to use log sumit tool guides the user through the process of selecting the relevant log files and screenshots, packaging them for transport and choosing a suitable transport method. The transport methods are currently HTTP webservice upload, sending an e-mail and copying the package to a local directory like a USB flash drive. Future methods are using an FTP server and sending to Bluetooth devices. This tool can be started in response to an unhandled or unrecoverable application error (crash reporting) so that the user is prompted with the right information and can submit trace logs while they’re fresh.

Example

The following C# example shows several usage possibilities of FieldLog.

using Unclassified.FieldLog;

class Program
{
    static void Main(string[] args)
    {
        // Indicate that we're not waiting for a custom log path to be configured.
        // If one is provided by the Program.flconfig file, it will be used first.
        // Otherwise, the default path strategy is applied.
        FL.AcceptLogFileBasePath();
       
        // Write out a first trace message that tells what's about to happen in the
        // application.
        FL.Trace("Initialising database");
        // Do the actual initialisation for the application
        try
        {
            InitializeApp();
        }
        catch (IOException ex)
        {
            // An Error event means that something has severely failed but the
            // situation could be handled.
            FL.Error(ex, "App initialisation");
        }
        if (!Initialized())
        {
            // A Critical event is when the application cannot continue to work.
            FL.Critical("Application was not initialised");
            return;
        }
        // A Checkpoint is a more important Trace message.
        FL.Checkpoint("Initialisation complete");

        // Another way to log messages
        FL.Text(FieldLogPriority.Notice, "A notice message");

        // Main application logic here...

        // Measure how long a function takes, averaging multiple iterations
        foreach (var record in GetRecords())
        {
            PrepareSomething();
            // ...
           
            using (FL.Timer("Long operation"))
            {
                LongOperation();
            }
        }
       
        // Some bonus features:
        // Information about the application (reading assembly attributes)
        Console.WriteLine("I am " + FL.AppName + " version " + FL.AppVersion);
        // Current time using high-precision timer
        Console.WriteLine("Now it's precisely " + FL.UtcNow + " (UTC)");
        // App uptime using high-precision timer
        Console.WriteLine("App is running for " + FL.AppUptime);
        // System information: Windows version and edition
        Console.WriteLine(OSInfo.Version + " " + OSInfo.Edition);
        // System information: Windows installed language
        Console.WriteLine(OSInfo.Language);
        // System information: User is administrator (does not show UAC dialog)
        if (OSInfo.IsCurrentUserLocalAdministrator())
        {
            // Write something to the system settings
        }
    }
   
    static void SectionA()
    {
        // Log the scope of this method. The method name is set automatically.
        using (FL.NewScope())
        {
            // Do interesting stuff here.
            int count = 23;
            SectionB(count);
            // ...
        }
    }
   
    static void SectionB(int count)
    {
        // Log the scope of this method. The method name is set automatically.
        using (FL.NewScope())
        {
            // Log the variable name and value with Trace priority.
            FL.TraceData("count", count);
            // ...
        }
    }
   
    static void LongOperation()
    {
        // ...
    }
}

Developer guideThe developer guide explains all logging methods in greater detail. This is the recommended starting point for those who intend to use the library.

You can also take a look at and play with the ConsoleDemo application included in the source code to learn about the logging API.

Screenshots

Here are several screenshots of the FieldLogViewer application:

Image
FieldLogViewer with exception details
Image
Indenting
Image
Same thread highlighting
Image
Relative time
Image
Filter editor
Image
Scrollmap and quick filters
Image
Application error dialog
Image
Error details
Image
Web error page

Download

Note: Releases after 2016-01-09 are no longer digitally signed because there are no more free code signing certificates available for open source developers. A commercial certificate from 100 € per year doesn’t pay for me. I’m sorry for the confusion this may cause with your next download.

FieldLogSetup-1.775.59_dd3ff3.exe1.0 MiBInstallation package with FieldLogViewer, FieldLog assembly, and code reference
Version 1.775.59 of 2017-02-14, Commit dd3ff3

FieldLogChanges.txt6.9 KiBChange log of published versions

master.zipLatest source code directly from GitHub

Previous versions

FieldLogSetup-1.525.41_5ab537.exe1.0 MiBVersion 1.525.41 of 2016-06-09, Commit 5ab537

FieldLogSetup-1.481.54_5f3e57.exe1.0 MiBVersion 1.481.54 of 2016-04-26, Commit 5f3e57

FieldLogSetup-1.433.85_17032a.exe1.0 MiBVersion 1.433.85 of 2016-03-09, Commit 17032a

FieldLogSetup-1.415.87_d327d0.exe1.0 MiBVersion 1.415.87 of 2016-02-20, Commit d327d0

FieldLogSetup-1.395.92_5af04a.exe1.0 MiBVersion 1.395.92 of 2016-01-31, Commit 5af04a

FieldLogSetup-1.383.75_4097f2.exe1.0 MiBVersion 1.383.75 of 2016-01-19, Commit 4097f2

FieldLogSetup-1.336.83_5cd1bb.exe1.0 MiBVersion 1.336.83 of 2015-12-03, Commit 5cd1bb

FieldLogSetup-1.334.92_0fb50c.exe1.0 MiBVersion 1.334.92 of 2015-12-01, Commit 0fb50c

FieldLogSetup-1.241.60_ad1f66.exe1.0 MiBVersion 1.241.60 of 2015-08-30, Commit ad1f66

FieldLogSetup-1.208.64_6e1888.exe1.0 MiBVersion 1.208.64 of 2015-07-28, Commit 6e1888

FieldLogSetup-1.200.38_c9395e.exe1.0 MiBVersion 1.200.38 of 2015-07-20, Commit c9395e

FieldLogSetup-1.194.66_9ffa01.exe1.0 MiBVersion 1.194.66 of 2015-07-14, Commit 9ffa01

FieldLogSetup-1.173.83_5e352f.exe1.0 MiBVersion 1.173.83 of 2015-06-23, Commit 5e352f

FieldLogSetup-1.172.86_e0c86e.exe1.0 MiBVersion 1.172.86 of 2015-06-22, Commit e0c86e

FieldLogSetup-1.171.75_b76c5b.exe1.0 MiBVersion 1.171.75 of 2015-06-21, Commit b76c5b

FieldLogSetup-1.116.62_2c0da0.exe1.0 MiBVersion 1.116.62 of 2015-04-27, Commit 2c0da0

FieldLogSetup-1.113.77_6e7f5d.exe1.0 MiBVersion 1.113.77 of 2015-04-24, Commit 6e7f5d

FieldLogSetup-1.38.77_06b662.exe0.9 MiBVersion 1.38.77 of 2015-02-08, Commit 06b662

FieldLogSetup-1.38.51_031fd0.exe911 KiBVersion 1.38.51 of 2015-02-08, Commit 031fd0

FieldLogSetup-17yn.5da7e5.exe916 KiBVersion 17yn of 2015-01-27, Commit 5da7e5

FieldLogSetup-1775.7541b5.exe910 KiBVersion 1775 of 2015-01-19, Commit 7541b5

FieldLogSetup-0v66.4f5b47.exe889 KiBVersion 0v66 of 2014-09-21, Commit 4f5b47

FieldLogSetup-0rq7.71cdec.exe879 KiBVersion 0rq7 of 2014-09-05, Commit 71cdec

FieldLogSetup-0hcn.9d63ee.exe1.0 MiBVersion 0hcn of 2014-06-17, Commit 9d63ee

You can also head over to GitHub to download any previous revision or check the issue tracker:

FieldLog repository on GitHub

This package is also available through NuGet. That way, it can be integrated and updated in a Visual Studio project very quickly. This package only includes the FieldLog assembly for all .NET versions. For installing FieldLogViewer you need to download the setup program above.

Unclassified.FieldLog package on NuGet

Current development state

FieldLog and the log file format are stable but could use some more testing. There are plans for future additional features that may change the API and file format. The file format is versioned so it is possible to continue reading old files, even in the same log file set.

FieldLogViewer is pretty stable by now. There are still lots of features and improvements planned and this is where the most changes happen now. See the Git change log for details.

The log submit tool is usable but still new and does not support all planned transport methods yet. If you need to translate it to more languages, please send me the dictionary file so I can include it. You can also keep it to yourself and use a private build.

The documentation is currently limited to the FieldLog code documentation and the developer guide page (German only). The source code reference is not ready for the public yet, use the inline comments through IntelliSense instead (original source code or .xml file as included in the NuGet package).

Changes

2017Feb14
Version 1.775.59 (Commit dd3ff31)
  • FieldLog: Don't log WPF "Cannot find governing FrameworkElement" messages
  • FieldLog: High-resolution system time using the GetSystemTimePreciseAsFileTime method (Windows 8 or later)
  • FieldLog: README file in the log directory explains that all files are necessary when copying
  • FieldLogViewer: Improved 200% high DPI image scaling (like Visual Studio once did)
  • FieldLogViewer: Added Windows 10 theme (incomplete) besides Windows 8 theme
  • FieldLogViewer: Make use of WPF 4.6 high-DPI layout improvements (App.config)
  • FieldLogViewer: Fixed: Prevent windows stuck invisible on now disconnected monitors
  • LogSubmit: Finds log files directly in the current directory
  • LogSubmit: Validates e-mail address if provided
  • LogSubmit: Saves last entered user e-mail address for the next report

2016Jun9
Version 1.525.41 (Commit 5ab5375)
  • FieldLog: Simplified exception message formatting (without namespace, not for obfuscated names)

2016Apr26
Version 1.481.54 (Commit 5f3e577)
  • AppErrorDialog: Increased height for localised titles

2016Mar9
Version 1.433.85 (Commit 17032ad)
  • AppErrorDialog supports High DPI screens

2016Mar7
Version 1.431.86 (Commit 31333d8)
  • Entity Framework: EntityValidationErrors logging support
  • FieldLogViewer: Fixed problems around filter exceptions
  • FieldLogViewer: Fixed display of underscores in menu with recently loaded files
  • Don't log time recalibration if there was no log item recently

2016Feb1
Version 1.395.92 (Commit 5af04ac)
  • Fixed: Dynamic methods have no metadata token, so FieldLogStackFrame can't retrieve it
  • FieldLogViewer: Little UI enhancements (added details indicator, new enter/leave images)

2016Jan19
Version 1.383.75 (Commit 4097f29)
  • Fixed exception logging (and source resolving, deobfuscation) with dynamic or unknown modules and global functions
  • Fixed AppErrorDialog message showing horizontal scrollbar when not necessary
  • FieldLogViewer: Fixed loading of compressed obfuscation map file
  • FieldLogViewer: Optional separator line between log items that represents the time passed between two items
  • FieldLogViewer: Limited MRU items list to 15 log base paths
  • FieldLogViewer: Do not add temporary log files to the MRU list
  • Ignore more WPF trace messages about CanFreeze. These are a WPF bug and not interesting at all.
  • Shared code and build script update

2015Dec3
Version 1.336.83 (Commit 5cd1bb6)
  • Add new .mapz extension for compressed obfuscation map files
  • Improved PdbConvert /optimize performance through parallelisation
  • Fixed NullReferenceException when creating a screenshot for no window

2015Dec2
Version 1.334.92 (Commit 0fb50ca)
  • FieldLogViewer: Improved error handling for stack frame module names
  • Don't write log files until something relevant happens
  • Never try to write log files to a protected service account directory
  • Updated build script for Git for Windows 2.x
  • Obfuscation compatibility

2015Aug30
Version 1.241.60 (Commit ad1f66c)
  • FieldLogViewer: Fixed unhandled ArgumentException at Path.GetFileNameWithoutExtension
  • FieldLog: Added TextRetainedAppend method

Older versions are contained in the change log file. For a full list of changes please refer to the Git repository commit history.

What’s yet to come…

This is an unsorted list of things that are on my to-do list. There is no time schedule but I intend to implement all of these as soon as I have the time for it.

  • Localisation of the log viewer
  • Configuration API to allow log configuration from the app’s settings
  • Colour-highlight log items in the log viewer, similar to filters
  • Show statistical information when selecting multiple log items
  • Scope folding in the log viewer
  • Bookmarks in the log viewer
  • Draw graphs from numeric data log items
  • Collect statistic usage data (not specified yet, maybe a separate project)

The name

The name “FieldLog” was originally supposed to refer to “out in the field logging” which is where your applications run. It does everything it can to maintain itself out there and to provide the developer with all relevant information about any problems that might occur. The developer does not need to go where the application runs if users have sufficient internet connectivity or remote hands to submit logs and install updates.

Another interpretation might refer to the structured log items that distinguishes FieldLog from plain text log files that actually only store a single line of raw text about each event. Being able to access and understand each bit of information allows for filtering the data masses to actually see the interesting parts.

The logo merges the capital letters F and L into a combined shape (which happens to look like an E), using different colours for the parts distinct from both letters and the shared part. The horizontal bars also depict “good” and “error” rows in a log list, which is basically what you can see with FieldLog.

Licence and terms of use

The FieldLog library, which is used in applications, is released under the terms of the GNU LGPL licence, version 3. The other projects (FieldLogViewer, demos and tools) are released under the terms of the GNU GPL licence, version 3. You can find the detailed terms and conditions in the download or on the GNU website (LGPL, GPL).

Statistic data

  • Created on 2013-06-30, updated on 2017-02-14.
  • Ca. 27 000 lines of code, estimated development costs: 27 000 - 110 000 €