#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 // .NET Compact Framework 1.0 has no support for System.Runtime.Remoting #if !NETCF using System; using System.Runtime.Remoting; using log4net.Util; using log4net.Repository; using log4net.Core; using IRemoteLoggingSink = log4net.Appender.RemotingAppender.IRemoteLoggingSink; namespace log4net.Plugin { /// /// Plugin that listens for events from the /// /// /// /// This plugin publishes an instance of /// on a specified . This listens for logging events delivered from /// a remote . /// /// /// When an event is received it is relogged within the attached repository /// as if it had been raised locally. /// /// /// Nicko Cadell /// Gert Driesen public class RemoteLoggingServerPlugin : PluginSkeleton { #region Public Instance Constructors /// /// Default constructor /// /// /// /// Initializes a new instance of the class. /// /// /// The property must be set. /// /// public RemoteLoggingServerPlugin() : base("RemoteLoggingServerPlugin:Unset URI") { } /// /// Construct with sink Uri. /// /// The name to publish the sink under in the remoting infrastructure. /// See for more details. /// /// /// Initializes a new instance of the class /// with specified name. /// /// public RemoteLoggingServerPlugin(string sinkUri) : base("RemoteLoggingServerPlugin:"+sinkUri) { m_sinkUri = sinkUri; } #endregion Public Instance Constructors #region Public Instance Properties /// /// Gets or sets the URI of this sink. /// /// /// The URI of this sink. /// /// /// /// This is the name under which the object is marshaled. /// /// /// public virtual string SinkUri { get { return m_sinkUri; } set { m_sinkUri = value; } } #endregion Public Instance Properties #region Override implementation of PluginSkeleton /// /// Attaches this plugin to a . /// /// The that this plugin should be attached to. /// /// /// A plugin may only be attached to a single repository. /// /// /// This method is called when the plugin is attached to the repository. /// /// #if NET_4_0 || MONO_4_0 [System.Security.SecuritySafeCritical] #endif override public void Attach(ILoggerRepository repository) { base.Attach(repository); // Create the sink and marshal it m_sink = new RemoteLoggingSinkImpl(repository); try { RemotingServices.Marshal(m_sink, m_sinkUri, typeof(IRemoteLoggingSink)); } catch(Exception ex) { LogLog.Error(declaringType, "Failed to Marshal remoting sink", ex); } } /// /// Is called when the plugin is to shutdown. /// /// /// /// When the plugin is shutdown the remote logging /// sink is disconnected. /// /// #if NET_4_0 || MONO_4_0 [System.Security.SecuritySafeCritical] #endif override public void Shutdown() { // Stops the sink from receiving messages RemotingServices.Disconnect(m_sink); m_sink = null; base.Shutdown(); } #endregion Override implementation of PluginSkeleton #region Private Instance Fields private RemoteLoggingSinkImpl m_sink; private string m_sinkUri; #endregion Private Instance Fields #region Private Static Fields /// /// The fully qualified type of the RemoteLoggingServerPlugin class. /// /// /// Used by the internal logger to record the Type of the /// log message. /// private readonly static Type declaringType = typeof(RemoteLoggingServerPlugin); #endregion Private Static Fields /// /// Delivers objects to a remote sink. /// /// /// /// Internal class used to listen for logging events /// and deliver them to the local repository. /// /// private class RemoteLoggingSinkImpl : MarshalByRefObject, IRemoteLoggingSink { #region Public Instance Constructors /// /// Constructor /// /// The repository to log to. /// /// /// Initializes a new instance of the for the /// specified . /// /// public RemoteLoggingSinkImpl(ILoggerRepository repository) { m_repository = repository; } #endregion Public Instance Constructors #region Implementation of IRemoteLoggingSink /// /// Logs the events to the repository. /// /// The events to log. /// /// /// The events passed are logged to the /// /// public void LogEvents(LoggingEvent[] events) { if (events != null) { foreach(LoggingEvent logEvent in events) { if (logEvent != null) { m_repository.Log(logEvent); } } } } #endregion Implementation of IRemoteLoggingSink #region Override implementation of MarshalByRefObject /// /// Obtains a lifetime service object to control the lifetime /// policy for this instance. /// /// null to indicate that this instance should live forever. /// /// /// Obtains a lifetime service object to control the lifetime /// policy for this instance. This object should live forever /// therefore this implementation returns null. /// /// #if NET_4_0 || MONO_4_0 [System.Security.SecurityCritical] #endif public override object InitializeLifetimeService() { return null; } #endregion Override implementation of MarshalByRefObject #region Private Instance Fields /// /// The underlying that events should /// be logged to. /// private readonly ILoggerRepository m_repository; #endregion Private Instance Fields } } } #endif // !NETCF