# Friday, 20 February 2009

One of our applications has a Windows service in it. To make debugging and running this service easy,we have a winform in the service which can be activated by passing a command line switch. Simple enough. Our service does all its logging with log4net. I wanted to be able to put the output of the logging on our development form, but how?

After looking at various things, I realized what I needed to do was create a log4net appender, and add the appender to the log4net logger and at regular intervals, grab the contents of the logger.

Solution

I created the below appender which uses a StringBuilder as the backing store. It takes in one bool param in the contructor which allows you to specify if you want the log to be built up in reverse.  This is useful if you want to display the most recent event at the top.

public class StringBuilderAppender : log4net.Appender.AppenderSkeleton
{
    private System.Text.StringBuilder _builder = new System.Text.StringBuilder();
    private readonly bool _invert;

    public StringBuilderAppender(bool invert) { _invert = invert; }

    public string Text { get { return _builder.ToString(); } }

    protected override void Append(log4net.Core.LoggingEvent loggingEvent)
    {
        var msg = loggingEvent.RenderedMessage;
        
        if (_invert)
            _builder = new System.Text.StringBuilder().AppendLine(msg).Append(_builder);
        else
            _builder.AppendLine(msg);
    }
}

Now we need to add our new appender to the logger. I found this helper method someone wrote.

public static void AddAppender(string loggerName, IAppender appender)
{
    log4net.ILog log = log4net.LogManager.GetLogger(loggerName);
    log4net.Repository.Hierarchy.Logger l = (log4net.Repository.Hierarchy.Logger)log.Logger;

    l.AddAppender(appender);
}

Finally, lets put it all together:

StringBuilderAppender appender = new StringBuilderAppender(true);
AddAppender("MyLogger", appender);

while(true) {
    System.Threading.Thread.Sleep(5000);
    someControl.Text = appender.Text;
}
.NET | HowTo | Logging
Friday, 20 February 2009 22:18:15 (Alaskan Standard Time, UTC-09:00)
# Tuesday, 10 February 2009

At our organization, we have to globalize our software. Making sure you've gotten all the strings globalized can be a real pain. You have to create a new language resource that looks nothing like your native language, then set the Thread.CurrentThread.CurrentUICulture to the culture of the new language resource you created.  Such a pain.

While pondering that this afternoon, I came upon something better. The .NET CultureManger looks for the most specific resource file, then works its way back to the least specific. For example, given the following resource files:

  • i18n
  • i18n.en
  • i18n.en-US

If your current culture was en-GB, the CultureManger would use the resource file for i18n.en, since there is no i18n.en-GB. But, if your current culture was da-DK, it would use i18n.

In our software, we have i18n, and i18n.da-DK resource files, plus i18n.fr-FR which is a special, internal resource file. What's so special about the fr-FR resource file you ask? The fr-FR resource file is really the i18n resource file which as been transformed to replace all the localized text with dashes.

Why did we do this? Because with all the English text replaced with dashes, it makes it very easy to see which text in the application hasn't been globalized. The down side to this, is we have to change the CurrentUICulture (and CurrentCulture) to fr-FR in order to test this.

Solution

The solution is actually quite simple, rename the fr-FR resource file to i18n.en-US (or what ever the ISO code for your culture is).  Now when your testing, the CultureManager will pick the most specific resource file, and use that. But, don't forget to remove en-US folder from the final build folder before you deploy your application, lest users get your debug language resource.

kick it on DotNetKicks.com
Tuesday, 10 February 2009 14:11:48 (Alaskan Standard Time, UTC-09:00)
# Sunday, 08 February 2009

A few weeks back, I wrote about Mac blogging software. Since then, I've removed Ecto. It was way to clunky, and not a joy to use at all. I've downloaded Blogo and figured I'd give it a whirl. So far, its pretty good. But none of these are like Windows Live Writer, which is really what I want. Oh well, can't have it all unless you write it yourself.


Sunday, 08 February 2009 12:11:01 (Alaskan Standard Time, UTC-09:00)