Aaron Johnson Now with 50% less caffeine!

Posted
22 August 2003 @ 9pm

Tagged
.NET

Logging in C#

I wrote up a very simple C# class that provides logging for C# applications since the C# Logger on sourceforge is still in alpha (and doesn’t appear to be active) and the .NET framework doesn’t seem to provide normal text file logging outside of the EventLog (correct me if I’m wrong):

using System;
using System.IO;
namespace com.ignitionlabs.logging {  
  public class Logger {
    private static int _ALL = 100;
    private static int _INFO = 75;
    private static int _ERROR = 50;
    private static int _OFF = 0;
    private static String logDirectory = System.Configuration.ConfigurationSettings.AppSettings["logging.directory"].ToString();
    public static int ALL {
      get { return _ALL; }
    }
    public static int ERROR {
      get { return _ERROR; }
    }
    public static int INFO {
      get { return _INFO; }
    }
    public static int OFF {
      get { return _OFF; }
    }
    public static void append(String message, int level) {
      int logLevel = _OFF;
      String strLogLevel = System.Configuration.ConfigurationSettings.AppSettings["logging.level"].ToString();
      switch(strLogLevel) {
        case “ALL”:
          logLevel = _ALL;
          break;
        case “ERROR”:
          logLevel = _ERROR;
          break;
        case “INFO”:
          logLevel = _INFO;
          break;
        default:
          logLevel = _OFF;
          break;
      }
      if (logLevel >= level) {
        DateTime dt = DateTime.Now;
        String filePath = logDirectory + dt.ToString(”yyyyMMdd”) + “.log”;
        if (!File.Exists(filePath)) {
          FileStream fs = File.Create(filePath);
          fs.Close();
        }
        try {
          StreamWriter sw = File.AppendText(filePath);
          sw.WriteLine(dt.ToString(”hh:mm:ss”) + “|” + message);
          sw.Flush();
          sw.Close();
        } catch (Exception e) {
          Console.WriteLine(e.Message.ToString());
        }
      }
    }
  }
}

After compiling, you’ll need to add 2 elements to your <appsettings> in web.config:

<add key=”logDirectory” value=”c:\myapp\logs\” />
<add key=”logLevel” value=”ALL|INFO|ERROR|OFF” />

and then you can use the class like this:

Logger.append(”your application message…”, Logger.ALL);

As always, I’m interested in any design flaws or critiques.


11 Comments

Posted by
Joe Cheng
25 August 2003 @ 10am

Looks good… just a couple of comments:

* You might want to use an enum for your levels.

* Is there a reason you’re loading the log level from the config file every time append is called? Seems like this could get expensive if there are tons of logging calls. Same with opening/closing the StreamWriter; why not keep it around?

* If you do decide to keep the StreamWriter around, you probably need to put a lock{} around the calls to it–it’s not guaranteed to be threadsafe.

* Instead of dt.ToString(”yyyy”) + dt.ToString(”MM”) + dt.ToString(”dd”), how about dt.ToString(”yyyyMMdd”)?

* It might be cool to be able to add your own log listeners (like log4j’s appenders). That way you could log to multiple sinks at once (database, event log, etc.). I’ve previously tackled this with .NET events; I declare a static event whose EventArgs include the message’s priority/level, text, and date/time, and anyone who cares can just register for that event.

* I sympathize with you but I think most C# developers would appreciate it if your append method began with a capital “A”… :)
* What’s Ignition Labs? :)
-joe


Posted by
Andrei
18 October 2003 @ 12am

Thanks a lot, it was very helpfull.


Posted by
Jeff
23 October 2003 @ 12pm

I wrote a logging package too. I did it pretty recently, and if I had known that you were interested, I probably would’ve asked if you wanted to collaborate. Anyway, if you think the code’s useful, have fun with it. It’s at http://sourceforge.net/projects/nspring . It offers good speed, multiple outputs, etc. but the configuration section is still not complete. Also in the works is a centralized logging application. The docs are in the single .zip file with all the code.


Posted by
Tony
6 February 2004 @ 5am

Is there a reason that you use static methods instead of a singleton pattern?


Posted by
Aaron Johnson
12 February 2004 @ 3pm

Tony,

If anything I useed a static method because it was easier to code and to use. If it matters, both log4j and log4net use a the Factory pattern to get an instance of a logger and then you can log. With the code snippet above, you don’t need an instance, you can simply fire log.append() whenever you want.


Posted by
mat
2 June 2004 @ 5am

Why don’t you use the Trace class provided by .NET? It provides the same functionality as your code (you can attach a TextWriterTraceListener to write to file). In addition, you can disable all trace output with a compiler flag (trace calls are included by default in Debug and Release builds).

Just look up the Trace class in the documentation, this should give you all the info you need.


Posted by
Ali Aksi
17 January 2006 @ 7am

wir sind ihr partner in sachen computer und internet. wir entwickeln fã¼r sie individuelle software nur auf sie zugeschnitten. wir machen ihr webdesign und optimieren ihre webseite, damit sie eine gute positionierung bei suchmaschinen bekommen.


Posted by
Zytan
22 March 2007 @ 4pm

“you’ll need to add 2 elements to your in web.config”? I assume you mean for web apps? ASP.NET? What about for Windows apps? It’d be great if you explain what this meant and how the code works. And, yes, capitalize Append!


Posted by
royson
14 March 2008 @ 3am

very helpfull, thanks.


Posted by
Lucian Mic
31 March 2008 @ 7am

Thanks. This is very usefull for myself.


Posted by
Nikesh
18 July 2008 @ 2am

Thanks, this is what I was looking for


Leave a Comment

Test versus Type Alternative Uses for RSS