#region Apache License
//
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to you under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion
using System;
using System.Threading;
using log4net.Appender;
using log4net.Core;
using System.Management.Instrumentation;
// This is the WMI namespace for event objects in this assembly
[assembly: Instrumented("root/log4net")]
namespace log4net.Appender
{
///
/// fires instrumented events for each
///
///
///
/// This appender fires Windows Management Instrumentation (WMI) events for
/// each .
///
///
/// By default this appender fires objects, however
/// this can be overridden by specifying a custom or by setting
/// the . to an
/// instance.
///
///
/// This assembly must be registered with WMI. Use the InstallUtil tool
/// shipped with the .NET framework to install this assembly. This will register
/// the root/log4net WMI namespace.
///
///
public sealed class WmiAppender : IAppender, IOptionHandler
{
#region Private Instance Fields
///
/// The layout of this appender.
///
///
/// See for more information.
///
private WmiLayout m_layout;
///
/// The name of this appender.
///
///
/// See for more information.
///
private string m_name;
///
/// The level threshold of this appender.
///
///
///
/// There is no level threshold filtering by default.
///
///
/// See for more information.
///
///
private Level m_threshold;
///
/// It is assumed and enforced that errorHandler is never null.
///
///
///
/// It is assumed and enforced that errorHandler is never null.
///
///
/// See for more information.
///
///
private IErrorHandler m_errorHandler = new log4net.Util.OnlyOnceErrorHandler("WmiAppender");
#endregion
#region Public Instance Properties
///
/// Gets or sets the name of this appender.
///
/// The name of the appender.
///
///
/// The name uniquely identifies the appender.
///
///
public string Name
{
get { return m_name; }
set { m_name = value; }
}
///
/// Gets or sets the threshold of this appender.
///
///
/// The threshold of the appender.
///
///
///
/// All log events with lower level than the threshold level are ignored
/// by the appender.
///
///
/// In configuration files this option is specified by setting the
/// value of the option to a level
/// string, such as "DEBUG", "INFO" and so on.
///
///
public Level Threshold
{
get { return m_threshold; }
set { m_threshold = value; }
}
///
/// Gets or sets the for this appender.
///
/// The layout of the appender.
///
///
/// The to use to format the
/// as an .
///
///
public WmiLayout Layout
{
get { return m_layout; }
set { m_layout = value; }
}
///
/// Gets or sets the for this appender.
///
/// The of the appender
///
///
/// The default value is a .
///
///
public IErrorHandler ErrorHandler
{
get { return m_errorHandler; }
set
{
if (value == null)
{
// We do not throw exception here since the cause is probably a
// bad config file.
log4net.Util.LogLog.Warn(GetType(), "WmiAppender: You have tried to set a null error-handler.");
}
else
{
m_errorHandler = value;
}
}
}
#endregion Public Instance Properties
///
/// Activate this appender
///
///
///
/// If a has not been specified then this
/// method will create a default instance.
///
///
public void ActivateOptions()
{
if (m_layout == null)
{
m_layout = new WmiLayout();
}
}
///
/// Close this appender
///
public void Close()
{
}
///
/// Process a
///
/// the containing the data
///
///
/// Uses the to format the
/// as an . This is then fired.
///
///
public void DoAppend(LoggingEvent loggingEvent)
{
if (loggingEvent == null)
{
throw new ArgumentNullException("loggingEvent");
}
try
{
if (IsAsSevereAsThreshold(loggingEvent.Level))
{
IEvent instrumentationEvent = m_layout.Format(loggingEvent);
if (instrumentationEvent != null)
{
instrumentationEvent.Fire();
}
}
}
catch(Exception ex)
{
ErrorHandler.Error("Failed in DoAppend", ex);
}
catch
{
// Catch handler for non System.Exception types
ErrorHandler.Error("Failed in DoAppend (unknown exception)");
}
}
///
/// Checks if the message level is below this appender's threshold.
///
private bool IsAsSevereAsThreshold(Level level)
{
return ((m_threshold == null) || level >= m_threshold);
}
}
}