#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
|
{
|
/// <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="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>
|
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);
|
}
|
}
|
|
/// <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
|
[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
|
|
/// <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 readonly static 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
|
[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 // !NETCF
|