Tôi biết câu hỏi là cũ, nhưng rõ ràng vẫn không có giải pháp ngoài hộp, vì vậy đây là nhật ký tùy chỉnh phù hợp với tôi (lấy cảm hứng từ https://github.com/ramonsmits/common-logging nhưng tôi đã thay đổi hầu hết mọi thứ ở cuối). Thử nghiệm với phiên bản Common.Logging 3.1.0.
Các 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);
}
}
Các logger
/// <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);
}
}
Và bạn có thể cấu hình nó như thế này:
<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>
Đó là, đối với mỗi logger, bạn thêm một dòng với phím LoggerName.factoryAdapter
, và sau đó bạn có thể thêm thuộc tính cho trình ghi nhật ký này bằng cách sử dụng cùng tên cho t chìa khóa, chẳng hạn như LoggerName.someProperty
.
Cảm ơn, đó là những gì tôi mong đợi. Tôi đã thấy rằng một người khác đã đưa ra điều này trên [repo GitHub] (https://github.com/net-commons/common-logging/issues/8) để nó có thể được thêm vào dự án cuối cùng. – omockler
@omockler Vấn đề GitHub đã được giải quyết trong khi trở lại. Giờ đây, có nhiều bộ điều hợp có thể hiển thị. –