Click here to Skip to main content
13,593,655 members
Click here to Skip to main content
Add your own
alternative version

Tagged as


50 bookmarked
Posted 10 May 2010
Licenced GPL3

Really Simple Log Writer

, 25 May 2010
Rate this:
Please Sign up or sign in to vote.
Code to write messages to a log file, in a very simple way.


Logging is one of those tools a developer resorts to, to obtain awareness about how a program is executing and eventually (and hopefully) detecting coding faults. A lot of time may be saved when good logging is available.

I was looking for a simple way to implement logging into a program I was developing for fun, and after a few Google and CodeProject searches, I couldn't find a really simple way and, therefore, I decided to develop my own.

This small bit of code (80LOC, including headers, empty lines, dummy lines, and comments) allows an application to insert a message (string) into a file. Since I created it initially to track exceptions my application was raising, it also allows to write exceptions.

My main requirements were:

  • Don't require the need to instantiate any variable to log messages (hence, all methods are static).
  • Don't require any initialization code (outside this class, obviously).
  • Keep log file(s) 'small' but don't discard messages.
  • Keep it stupid simple (just call a method to write and that's it).

The Code

This simple code consists of a main class (ReallySimpleLog) and a global (static) variable that will keep the base directory of the 'user' application. In this way, the log file is stored in the same place the executable is located (and we can be sure that the directory exists).

The necessary initialization code is contained in a static constructor. In it, the application base directory is obtained by calling AppDomain.CurrentDomain.BaseDirectory + AppDomain.CurrentDomain.RelativeSearchPath.

The initial lines of the program are as follows:

public class ReallySimpleLog
    static string m_baseDir = null;

    static ReallySimpleLog()
         m_baseDir = AppDomain.CurrentDomain.BaseDirectory +

The constructor is static and initializes m_baseDir (the static constructor executes before any method of the class is used, and is run at most once during a single program instantiation - very handy).

The next step is to make this class useful: we create the following methods to store log messages.

public static void WriteLog(String message)
public static void WriteLog(Exception ex)

Since I wanted to keep log files to an acceptable size, I opted to create a file per day (you may easily change the period to an acceptable one). Furthermore, so that I could understand to which time period the log file would correspond, I created a method that creates a filename as follows: year-month-day-suffix-extension.

The method code is the following (keep it public - who knows if others may use it):

public static string GetFilenameYYYMMDD(string suffix, string extension)
    return System.DateTime.Now.ToString("yyyy_MM_dd")+suffix + extension;

Having this as background, here follows the main methods:

  • WriteLog (string message) writes a string message to the log. Note also that the file is closed after the write operation. In this way, we ensure that the log entry is available if, for example, the application crashes.
  • public static void WriteLog(String message)
        //just in case: we protect code with try.
            string filename = m_baseDir
                + GetFilenameYYYMMDD("_LOG", ".log");
            System.IO.StreamWriter sw = new System.IO.StreamWriter(filename, true);
            XElement xmlEntry = new XElement("logEntry",
                new XElement("Date", System.DateTime.Now.ToString()),
                new XElement("Message", message));
        catch (Exception)

    The code is protected with a try-catch just for safety (we don't want to terminate the application if the log fails, but you may add an output-capability to trace the error).

    Note that the way to create (or append) to the log file is very simple: the second argument (set to true) of the StreamWriter constructor creates a file if it doesn't exist already. Then, just by calling WriteLine, a line with the message is appended.

  • WriteLog (Exception ex) is very similar to the previous method, but writes an exception (instead of a string) to the log.
  • public static void WriteLog(Exception ex)
        //just in case: we protect code with try.
            string filename = m_baseDir
                + GetFilenameYYYMMDD("_LOG", ".log");
            System.IO.StreamWriter sw = new System.IO.StreamWriter(filename, true);
            XElement xmlEntry = new XElement("logEntry",
                new XElement("Date", System.DateTime.Now.ToString()),
                new XElement("Exception",
                    new XElement("Source", ex.Source),
                    new XElement("Message", ex.Message),
                    new XElement("Stack", ex.StackTrace)
                 )//end exception
            //has inner exception?
            if (ex.InnerException != null)
                    new XElement("InnerException",
                        new XElement("Source", ex.InnerException.Source),
                        new XElement("Message", ex.InnerException.Message),
                        new XElement("Stack", ex.InnerException.StackTrace))
        catch (Exception)

    Note that an inner-exception may include more inner exceptions. A for-loop may be added if you intend to list all exceptions.

How to Use it

That's the beauty of it. If you remember, all attributes and methods are static, hence, no instances have to be created. Whenever you have something you want to log, just do (assuming you have all imports right):

For strings:

LogFile.WriteLog(message);   //where message is of type String

The following output is generated:

  <Date>17-05-2010 09:58:31</Date>

For exceptions:

LogFile.WriteLog(exception); //where exception is of type Exception

The following output is generated (I used an example I had - sorry - it's in Portuguese - but you see the point):

  <Date>15-05-2010 14:33:36</Date>
    <Message>O tempo limite da operação expirou</Message>
    <Stack>   em System.Net.HttpWebRequest.GetResponse()
      em WeAreServicesLib.HTTPSubsystemService.Download() 
      em C:\software\development\WeAre\WeAreServicesLib\HTTPSubsystemService.cs:line 120

Note that the file is generated automatically (for my example, it is named '2010_05_15_LOG.log') - and each day, a new log file is generated (so that we don't worry about size).

OK - that's it. Have fun!

(I think this article has more lines than source-code itself ...).

Updates since first edition

Although it's a simple approach, it was very rewarding for me to receive further constructive feedback from other developers towards perfecting the approach used. Hereby follows some of the updates (with my acknowledgments):

  • Sky Sanders: output log in well-formed XML.
  • Luc Pattyn: determine date as "System.DateTime.Now.ToString("yyyy_MM_dd_");"
  • abhi4u1947: add details of InnerException also.

Thank you guys!


This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)


About the Author

Marco Manso
Technical Lead
Portugal Portugal
He is the Head of R&D in a Portuguese IT Company operating in Space and Security markets.
His responsibilities include team coordination, project management and system conceptualization. He also works in close partnership with Universities and R&D Centres, promoting joint activities, common projects and transfer of knowledge and technology.
He actively cooperates in international study and advisory groups of engineers and scientists.
He is graduated in Electronics and Computer Sciences by a Portuguese University and is post-graduated in Information Warfare/Competitive Intelligence.
In his free time, he enjoys lauching new endeavors and challenges.

You may also be interested in...

Comments and Discussions

Question[Bugfix] If Excepetion.Data IDicitionary Value == null Pin
Member 124514544-Jul-16 9:54
memberMember 124514544-Jul-16 9:54 
I really like this simple logger, but when using it, it kept on crashing on me.
I was trying to catch unhandled exceptions, and to test it I threw a NotImplementedException.
The handler looks like this:
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) {
            var ex = (Exception)e.ExceptionObject;

The handler caught the exception just fine, but when the exception was being logged, it always stumbled over the following lines of code in the method
GetExceptionXElement(Exception ex)
                foreach(DictionaryEntry de in ex.Data)
                    xDataElement.Add(new XElement("Entry", new XAttribute("Key", de.Key), new XAttribute("Value", de.Value)));

The problem is that the DictionaryEntry value is null, therefore I added a null check right after "de.Value" like this
foreach(DictionaryEntry de in ex.Data)
                    xDataElement.Add(new XElement("Entry", new XAttribute("Key", de.Key), new XAttribute("Value", de.Value ?? string.Empty)));

Note the ?? string.empty at the end.

Maybe this will help someone else out.
QuestionHow to use? Pin
Member 113436188-Jan-16 3:56
memberMember 113436188-Jan-16 3:56 
Generalwhen i click on button it has to update in log file Pin
Member 1188976010-Aug-15 3:31
memberMember 1188976010-Aug-15 3:31 
SuggestionA still simple, but more elaborated alternative based on your approach Pin
Jochen Scharr8-Jul-14 0:15
memberJochen Scharr8-Jul-14 0:15 
GeneralGood..but think about this situation Pin
Yves31-May-10 18:59
memberYves31-May-10 18:59 
GeneralError when running Pin
loganj199926-May-10 2:21
memberloganj199926-May-10 2:21 
AnswerRe: Error when running Pin
Marco Manso26-May-10 3:28
memberMarco Manso26-May-10 3:28 
GeneralRe: Error when running Pin
loganj199926-May-10 3:35
memberloganj199926-May-10 3:35 
GeneralRe: Error when running Pin
Marco Manso26-May-10 3:59
memberMarco Manso26-May-10 3:59 
QuestionWhy not a method to read the Log? Pin
Rui Figueiredo25-May-10 21:10
memberRui Figueiredo25-May-10 21:10 
AnswerRe: Why not a method to read the Log? Pin
Marco Manso26-May-10 11:49
memberMarco Manso26-May-10 11:49 
GeneralSuggestion Pin
abhi4u194713-May-10 20:48
memberabhi4u194713-May-10 20:48 
GeneralRe: Suggestion Pin
Marco Manso16-May-10 23:34
memberMarco Manso16-May-10 23:34 
GeneralGreat simple and very useful code. Pin
Member 348574012-May-10 13:55
memberMember 348574012-May-10 13:55 
GeneralGood Pin
Luc Pattyn11-May-10 14:07
mvpLuc Pattyn11-May-10 14:07 
GeneralRe: Good Pin
Marco Manso12-May-10 5:17
memberMarco Manso12-May-10 5:17 
GeneralRe: Good Pin
Luc Pattyn12-May-10 5:26
mvpLuc Pattyn12-May-10 5:26 
GeneralMy vote of 1 Pin
AndyKernahan11-May-10 4:47
memberAndyKernahan11-May-10 4:47 
GeneralRe: My vote of 1 Pin
jgauffin24-May-10 20:55
memberjgauffin24-May-10 20:55 
GeneralRe: My vote of 1 Pin
AndyKernahan25-May-10 3:09
memberAndyKernahan25-May-10 3:09 
GeneralRe: My vote of 1 Pin
jgauffin25-May-10 3:47
memberjgauffin25-May-10 3:47 
GeneralRe: My vote of 1 Pin
AndyKernahan25-May-10 4:00
memberAndyKernahan25-May-10 4:00 
GeneralRe: My vote of 1 Pin
Ajay Vijayvargiya25-May-10 16:59
memberAjay Vijayvargiya25-May-10 16:59 
GeneralRe: My vote of 1 Pin
AndyKernahan25-May-10 20:44
memberAndyKernahan25-May-10 20:44 
GeneralRe: My vote of 1 Pin
Marco Manso25-May-10 22:54
memberMarco Manso25-May-10 22:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web02-2016 | 2.8.180618.1 | Last Updated 25 May 2010
Article Copyright 2010 by Marco Manso
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid