-
Notifications
You must be signed in to change notification settings - Fork 7
/
Log4NetLogger.cs
120 lines (102 loc) · 4.48 KB
/
Log4NetLogger.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//-----------------------------------------------------------------------
// <copyright file="Log4NetLogger.cs" company="Akka.NET Project">
// Copyright (C) 2013-2017 Akka.NET Project <https://github.com/AkkaNetContrib>
// </copyright>
//-----------------------------------------------------------------------
using Akka.Actor;
using Akka.Event;
using Akka.Dispatch;
using log4net;
using log4net.Core;
using System.Globalization;
namespace Akka.Logger.log4net
{
/// <summary>
/// This class is used to receive log events and sends them to
/// the configured log4net logger. The following log events are
/// recognized: <see cref="Debug"/>, <see cref="Info"/>,
/// <see cref="Warning"/> and <see cref="Error"/>.
/// </summary>
public sealed class Log4NetLogger : ReceiveActor, IRequiresMessageQueue<ILoggerMessageQueueSemantics>
{
// Used when location information is not available.
internal const string NA = "?";
private readonly ILoggingAdapter _log = Logging.GetLogger(
loggingBus: Context.System.EventStream,
logSourceObj: nameof(Log4NetLogger));
/// <summary>
/// Gets or sets the function that will be used to get the logger.
/// </summary>
/// <remarks>
/// This property is solely there to allow unit tests to set a different logger factory.
/// </remarks>
internal Func<LogEvent, ILogger> GetLogger { get; set; } = GetLoggerFromLogManager;
private void Log(Level level, LogEvent logEvent)
{
var logger = GetLogger(logEvent);
var logEventSenderPath = Context.Sender.Path;
var loggingEvent = CreateLoggingEvent(logger, level, logEvent, logEventSenderPath);
logger.Log(loggingEvent);
}
private static ILogger GetLoggerFromLogManager(LogEvent logEvent)
{
#if NET472
var logger = LogManager.GetLogger(logEvent.LogClass.FullName);
#else
var logger = LogManager.GetLogger(logEvent.LogClass);
#endif
return logger.Logger;
}
internal static LoggingEvent CreateLoggingEvent(
ILogger logger, Level level, LogEvent logEvent, ActorPath logEventSenderPath)
{
var (message, properties) = logEvent.Message is Log4NetPayload log4NetPayload
? (log4NetPayload.Message, log4NetPayload.Properties)
: (logEvent.Message, Log4NetPayload.Empty.Properties);
var className = properties.GetDeclaringTypeName() ?? logEvent.LogClass.FullName;
var methodName = properties.GetMethodName() ?? NA;
var fileName = properties.GetFileName() ?? NA;
var lineNumber = properties.GetLineNumber() ?? NA;
var logginEventData = new LoggingEventData
{
Level = level,
LoggerName = logEvent.LogClass.FullName,
TimeStampUtc = logEvent.Timestamp,
Message = message?.ToString(),
ThreadName = logEvent.Thread.ManagedThreadId.ToString(NumberFormatInfo.InvariantInfo),
ExceptionString = logEvent.Cause?.ToString(),
LocationInfo = new(className, methodName, fileName, lineNumber),
Properties = Properties.Create()
.SetProperties(actorPath: logEventSenderPath, logSource: logEvent.LogSource)
.SetProperties(properties.AsEnumerable()),
};
return new(
callerStackBoundaryDeclaringType: logEvent.LogClass,
repository: logger.Repository,
data: logginEventData);
}
private void Handle(Error logEvent)
=> Log(Level.Error, logEvent);
private void Handle(Warning logEvent)
=> Log(Level.Warn, logEvent);
private void Handle(Info logEvent)
=> Log(Level.Info, logEvent);
private void Handle(Debug logEvent)
=> Log(Level.Debug, logEvent);
/// <summary>
/// Initializes a new instance of the <see cref="Log4NetLogger"/> class.
/// </summary>
public Log4NetLogger()
{
Receive<Error>(Handle);
Receive<Warning>(Handle);
Receive<Info>(Handle);
Receive<Debug>(Handle);
Receive<InitializeLogger>(m =>
{
_log.Info("log4net started");
Sender.Tell(new LoggerInitialized());
});
}
}
}