#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); } } }