6

私は現在、Common.Loggingを使用するために大規模なプロジェクトを移行する作業を行っており、ロギングイベントを複数のサードパーティのロギング実装に出力できることを望んでいました。

現在、メッセージのトレースとデバッグに引き続き使用したい、社内で開発されたトレースライブラリがあります。また、log4netを使用して、レポート用にデータベースにメッセージを送信したり、いくつかのレベルで電子メール通知を送信したりしたいと思います。

私が探しているのは次のようなものです。

<common>
<logging>
  <factoryAdapter type="CustomTraceFactoryAdapter, MyAssembly">
    <arg key="configType" value="INLINE"/>
  </factoryAdapter>
  <factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4Net">
    <arg key="configType" value="INLINE"/>
  </factoryAdapter>
</logging>
</common>

すぐに使用できる構成オプションを使用してこれを行う方法はありますか?

4

3 に答える 3

5

AFAIK、Commonには何も存在しません。必要なものを探します。ここにいくつかの選択肢があります。

1) http://netcommon.sourceforge.net/docs/2.1.0/reference/html/ch01.html#logging-advanced-customfactoryadapterで説明されているように、いくつかのカスタムロガーファクトリアダプターを開発します。すでに開発したと思われるカスタムファクトリの1つは、内部トレースライブラリ用です。2番目のカスタムファクトリは、1つ以上の他のファクトリのロガーを組み合わせて複合ロガーオブジェクトを作成します。

2)トレースライブラリ用のカスタムlog4netアペンダー(http://logging.apache.org/log4net/release/faq.html#custom-appender )を開発し、log4netファクトリのみを使用するようにCommon.Loggingを構成します。

Common.Loggingの構成動作を変更する必要がないため、2番目のオプションが最も簡単だと思います。これにより、他の構成済みファクトリから複合ファクトリを構成できます。

于 2012-07-06T13:04:25.417 に答える
4

質問が古いことは知っていますが、これに対するすぐに使える解決策がまだないようです。そのため、ここに私のために機能するカスタムロガーがあります(https://github.com/ramonsmits/common-loggingからインスピレーションを得ています)しかし、私は最終的にほとんどすべてを変更しました)。Common.Loggingバージョン3.1.0でテスト済み。

FactoryAdapter

/// <summary>
/// Adapter hub for Common.Logging that can send logs to multiple other adapters
/// </summary>
public class MultiLoggerFactoryAdapter : AbstractCachingLoggerFactoryAdapter
{
    private readonly List<ILoggerFactoryAdapter> LoggerFactoryAdapters;

    /// <summary>
    /// Initializes a new instance of the <see cref="MultiFactoryLoggerFactoryAdapter"/> class.
    /// </summary>
    public MultiLoggerFactoryAdapter(CommonLogging.Configuration.NameValueCollection properties)
    {
        LoggerFactoryAdapters = new List<ILoggerFactoryAdapter>();

        foreach(var factoryAdapter in properties.Where(e => e.Key.EndsWith(".factoryAdapter")))
        {
            string adapterName = factoryAdapter.Key.Substring(0, factoryAdapter.Key.Length - 15);
            string adapterType = factoryAdapter.Value;

            var adapterConfig = new CommonLogging.Configuration.NameValueCollection();
            foreach(var entry in properties.Where(e1 => e1.Key.StartsWith(adapterName + ".")))
            {
                adapterConfig.Add(entry.Key.Substring(adapterName.Length + 1), entry.Value);
            }

            var adapter = (ILoggerFactoryAdapter)Activator.CreateInstance(Type.GetType(adapterType), adapterConfig);
            LoggerFactoryAdapters.Add(adapter);
        }
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="MultiFactoryLoggerFactoryAdapter"/> class.
    /// </summary>
    /// <param name="factoryAdapters">The factory adapters.</param>
    public MultiLoggerFactoryAdapter(List<ILoggerFactoryAdapter> factoryAdapters)
    {
        LoggerFactoryAdapters = factoryAdapters;
    }

    protected override ILog CreateLogger(string name)
    {
        var loggers = new List<ILog>(LoggerFactoryAdapters.Count);

        foreach (var f in LoggerFactoryAdapters)
        {
            loggers.Add(f.GetLogger(name));
        }

        return new MultiLogger(loggers);
    }
}

ロガー

/// <summary>
/// Adapter hub for Common.Logging that can send logs to multiple other adapters
/// </summary>
public class MultiLogger : AbstractLogger
{
    private readonly List<ILog> Loggers;

    public static readonly IDictionary<LogLevel, Action<ILog, object, Exception>> LogActions = new Dictionary<LogLevel, Action<ILog, object, Exception>>()
    {
        { LogLevel.Debug, (logger, message, exception) => logger.Debug(message, exception) },
        { LogLevel.Error, (logger, message, exception) => logger.Error(message, exception) },
        { LogLevel.Fatal, (logger, message, exception) => logger.Fatal(message, exception) },
        { LogLevel.Info, (logger, message, exception) => logger.Info(message, exception) },
        { LogLevel.Trace, (logger, message, exception) => logger.Trace(message, exception) },
        { LogLevel.Warn, (logger, message, exception) => logger.Warn(message, exception) },
    };

    /// <summary>
    /// Initializes a new instance of the <see cref="MultiLogger"/> class.
    /// </summary>
    /// <param name="loggers">The loggers.</param>
    public MultiLogger(List<ILog> loggers)
    {
        Loggers = loggers;
    }

    public override bool IsDebugEnabled { get { return Loggers.Any(l => l.IsDebugEnabled); } }
    public override bool IsErrorEnabled { get { return Loggers.Any(l => l.IsErrorEnabled); } }
    public override bool IsFatalEnabled { get { return Loggers.Any(l => l.IsFatalEnabled); } }
    public override bool IsInfoEnabled { get { return Loggers.Any(l => l.IsInfoEnabled); } }
    public override bool IsTraceEnabled { get { return Loggers.Any(l => l.IsTraceEnabled); } }
    public override bool IsWarnEnabled { get { return Loggers.Any(l => l.IsWarnEnabled); } }

    protected override void WriteInternal(LogLevel level, object message, Exception exception)
    {
        List<Exception> exceptions = null;
        foreach(var logger in Loggers)
        {
            try
            {
                LogActions[level](logger, message, exception);
            }
            catch(Exception e)
            {
                if(exceptions == null)
                    exceptions = new List<Exception>();
                exceptions.Add(e);
            }
        }

        if(exceptions != null)
            throw new AggregateException("One or more exceptions occured while forwarding log message to multiple loggers", exceptions);
    }
}

そして、次のように構成できます。

<common>
  <logging>
    <factoryAdapter type="MultiLoggerFactoryAdapter, YourAssemblyName">
      <arg key="Log4Net.factoryAdapter" value="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4Net1213" />
      <arg key="Log4Net.configType" value="INLINE" />

      <arg key="Debug.factoryAdapter" value="Common.Logging.Simple.TraceLoggerFactoryAdapter, Common.Logging" />
    </factoryAdapter>
  </logging>
</common>

つまり、ロガーごとに、キーを使用して行を追加しますLoggerName.factoryAdapter。次に、キーに同じ名前(。など)を使用して、このロガーのプロパティを追加できますLoggerName.someProperty

于 2015-12-21T13:22:44.593 に答える
4

現在、複数のアダプターをサポートする組み込みの方法があります。Common.Logging.MultipleLoggerを確認してください。ここApp.configにそれを使用する方法を示す例があります。

于 2017-10-20T21:41:26.853 に答える