Hi, I have created a simple Appender that dumps to the Growl notification system. Requires the Growl.Connector and Growl.CoreLibrary from the Growl for Windows SDK.
GPLv2
/*
GrowlAppender - log4net appender that dumps notification messages to the Growl
notification system
Copyright (C) 2009 Dimension4, Eric Zeitler
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Growl.Connector;
using log4net.Appender;
using log4net.Core;
namespace Dimension4
{
/// <summary>
/// Provides Growl notifications from log4net events.
///
/// <appender name="Growl" type="GrowlAppender, GrowlAppender">
/// <Password value="***************"/>
/// <Hostname value="localhost"/>
/// <Port value="9887"/>
/// <layout type="log4net.Layout.PatternLayout">
/// <conversionPattern value="%5level - %message%newline" />
/// </layout>
/// </appender>
///
/// </summary>
public class GrowlAppender : AppenderSkeleton
{
private readonly IDictionary<Level, NotificationType> _levelMap = new
Dictionary<Level, NotificationType>();
private readonly Application application;
private readonly NotificationType GENERAL = new
NotificationType("GENERAL");
private readonly GrowlConnector growl;
private int? _port;
public GrowlAppender()
{
foreach (FieldInfo field in typeof
(Level).GetFields(BindingFlags.Public | BindingFlags.Static))
{
if (field.FieldType != typeof (Level)) continue;
var level = (Level) field.GetValue(null);
if (!_levelMap.ContainsKey(level))
{
_levelMap.Add(level, new NotificationType(field.Name));
}
}
if (!String.IsNullOrEmpty(Hostname))
{
growl = new GrowlConnector(Password, Hostname, _port ??
ConnectorBase.TCP_PORT);
}
else if (!String.IsNullOrEmpty(Password))
{
growl = new GrowlConnector(Password);
}
else
{
growl = new GrowlConnector();
}
string fullName = Assembly.GetEntryAssembly().FullName;
string name = fullName == null? "" : fullName.Split(',')[0];
application = new Application(name);
growl.ErrorResponse += growl_ErrorResponse;
NotificationType[] notificationTypes = _levelMap.Values.ToArray();
Array.Resize(ref notificationTypes, notificationTypes.Length + 1);
notificationTypes[notificationTypes.Length - 1] = GENERAL;
growl.Register(application, notificationTypes);
}
public string Password { get; set; }
public string Hostname { get; set; }
public string Port
{
get { return _port.ToString(); }
set { _port = int.Parse(value); }
}
protected override void Append(LoggingEvent loggingEvent)
{
NotificationType notificationType;
if (!_levelMap.TryGetValue(loggingEvent.Level, out
notificationType))
{
notificationType = GENERAL;
}
string text = RenderLoggingEvent(loggingEvent);
text = text.Replace('\n', '\r');
//set callback id if you need information about the specific
callback being called
string callbackId = text;
growl.Notify(new Notification(application.Name,
notificationType.Name, callbackId,
notificationType.DisplayName, text));
}
private static void growl_ErrorResponse(Response response)
{
log4net.LogManager.GetLogger(typeof(GrowlAppender)).Error(String.Format("Error-Code:
{0}\nError-Description: {1}", response.ErrorCode,
response.ErrorDescription));
}
}
}
signature.asc
Description: OpenPGP digital signature
