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