Last active
February 16, 2018 17:49
-
-
Save gubenkoved/ed52ac9abc9c9ff412aced92239ebc9e to your computer and use it in GitHub Desktop.
log4net layout to write logs in JSON format
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class JsonLayout : LayoutSkeleton | |
{ | |
private class Container | |
{ | |
public DateTime Timestamp { get; set; } | |
public string Level { get; set; } | |
public string Logger { get; set; } | |
public object Message { get; set; } | |
public string ThreadName { get; set; } | |
public int ThreadId { get; set; } | |
public string Domain { get; set; } | |
public string Identity { get; set; } | |
public string UserName { get; set; } | |
public string Exception { get; set; } | |
public Dictionary<string, object> Properties { get; set; } | |
public LocationInfo LocationInfo { get; set; } | |
} | |
private string[] _properties = new string[] { "NDC" }; | |
public override bool IgnoresException | |
{ | |
get | |
{ | |
return base.IgnoresException; | |
} | |
set | |
{ | |
base.IgnoresException = value; | |
} | |
} | |
/// <summary> | |
/// Gets or sets comma or semicolon delimited string that specifies which properties | |
/// will be added to the properties of each log event. | |
/// Properties looked up via loggingEvent.LookupProperty() method that covers | |
/// inherited properties as well (Global, Thread contexts, etc). | |
/// </summary> | |
public string Properties { get; set; } | |
public bool LocationInfo { get; set; } | |
public JsonLayout() | |
{ | |
// this layout will write exception itself, indicate it to appenders | |
IgnoresException = false; | |
} | |
public override void ActivateOptions() | |
{ | |
if (Properties != null) | |
_properties = Properties.Split(',', ';').Select(x => x.Trim()).ToArray(); | |
} | |
public override void Format(TextWriter writer, LoggingEvent loggingEvent) | |
{ | |
var properties = new Dictionary<string, object>(); | |
foreach (var propName in loggingEvent.Properties.GetKeys()) | |
properties[propName] = loggingEvent.Properties[propName]; | |
foreach (var propName in _properties) | |
{ | |
object propValue = loggingEvent.LookupProperty(propName); | |
// special case for log4net internal property, it does not make sense to log it as object | |
// as it will be like {Count: 1} w/o any string key at all | |
if (propName == "NDC") | |
propValue = propValue?.ToString(); | |
properties[propName] = propValue; | |
} | |
var data = new Container() | |
{ | |
Timestamp = loggingEvent.TimeStamp.ToUniversalTime(), | |
ThreadName = loggingEvent.ThreadName, | |
ThreadId = Thread.CurrentThread.ManagedThreadId, | |
Level = loggingEvent.Level.Name, | |
Logger = loggingEvent.LoggerName, | |
Domain = loggingEvent.Domain, | |
Identity = loggingEvent.Identity, | |
UserName = loggingEvent.UserName, | |
Message = loggingEvent.MessageObject, | |
Exception = loggingEvent.GetExceptionString(), | |
Properties = properties, | |
}; | |
if (LocationInfo) | |
data.LocationInfo = loggingEvent.LocationInformation; | |
var json = JsonConvert.SerializeObject(data); | |
writer.WriteLine(json); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment