Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an option to easy set the output log infos #93

Merged
merged 1 commit into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 28 additions & 17 deletions src/ZLogger.MessagePack/MessagePackZLoggerFormatter.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Buffers;
using System.Numerics;
using MessagePack;
using Microsoft.Extensions.Logging;

Expand Down Expand Up @@ -73,9 +74,8 @@ public MessagePackZLoggerFormatter(ZLoggerOptions options)
public void FormatLogEntry<TEntry>(IBufferWriter<byte> writer, TEntry entry) where TEntry : IZLoggerEntry
{
var messagePackWriter = new MessagePackWriter(writer);

var propCount = 6 + entry.ParameterCount;

var propCount = BitOperations.PopCount((uint)options.IncludeProperties) + entry.ParameterCount;
if (entry.LogInfo.Exception != null)
propCount++;

Expand All @@ -92,21 +92,32 @@ public void FormatLogEntry<TEntry>(IBufferWriter<byte> writer, TEntry entry) whe

messagePackWriter.WriteMapHeader(propCount);

messagePackWriter.WriteRaw(CategoryNameKey);
messagePackWriter.Write(entry.LogInfo.CategoryName);

messagePackWriter.WriteRaw(LogLevelKey);
messagePackWriter.WriteRaw(EncodedLogLevel(entry.LogInfo.LogLevel));

messagePackWriter.WriteRaw(EventIdKey);
messagePackWriter.WriteInt32(entry.LogInfo.EventId.Id);

messagePackWriter.WriteRaw(EventIdNameKey);
messagePackWriter.Write(entry.LogInfo.EventId.Name);

messagePackWriter.WriteRaw(TimestampKey);
MessagePackSerializerOptions.Resolver.GetFormatterWithVerify<DateTime>()
.Serialize(ref messagePackWriter, entry.LogInfo.Timestamp.UtcDateTime, MessagePackSerializerOptions);
if ((options.IncludeProperties & LogInfoProperties.CategoryName) != 0)
{
messagePackWriter.WriteRaw(CategoryNameKey);
messagePackWriter.Write(entry.LogInfo.CategoryName);
}
if ((options.IncludeProperties & LogInfoProperties.LogLevel) != 0)
{
messagePackWriter.WriteRaw(LogLevelKey);
messagePackWriter.WriteRaw(EncodedLogLevel(entry.LogInfo.LogLevel));
}
if ((options.IncludeProperties & LogInfoProperties.EventIdValue) != 0)
{
messagePackWriter.WriteRaw(EventIdKey);
messagePackWriter.WriteInt32(entry.LogInfo.EventId.Id);
}
if ((options.IncludeProperties & LogInfoProperties.EventIdName) != 0)
{
messagePackWriter.WriteRaw(EventIdNameKey);
messagePackWriter.Write(entry.LogInfo.EventId.Name);
}
if ((options.IncludeProperties & LogInfoProperties.Timestamp) != 0)
{
messagePackWriter.WriteRaw(TimestampKey);
MessagePackSerializerOptions.Resolver.GetFormatterWithVerify<DateTime>()
.Serialize(ref messagePackWriter, entry.LogInfo.Timestamp.UtcDateTime, MessagePackSerializerOptions);
}

messagePackWriter.Write(MessagePropertyName);
var buffer = GetThreadStaticBufferWriter();
Expand Down
31 changes: 23 additions & 8 deletions src/ZLogger/Formatters/SystemTextJsonZLoggerFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public class SystemTextJsonZLoggerFormatter : IZLoggerFormatter
static readonly JsonEncodedText None = JsonEncodedText.Encode(nameof(LogLevel.None));

public JsonEncodedText MessagePropertyName { get; set; } = JsonEncodedText.Encode("Message");
public Action<Utf8JsonWriter, LogInfo> MetadataFormatter { get; set; } = DefaultMetadataFormatter;
public Action<Utf8JsonWriter, LogInfo, ZLoggerOptions> MetadataFormatter { get; set; } = DefaultMetadataFormatter;

public JsonSerializerOptions JsonSerializerOptions { get; set; } = new()
{
Expand All @@ -68,7 +68,7 @@ public void FormatLogEntry<TEntry>(IBufferWriter<byte> writer, TEntry entry) whe

jsonWriter.WriteStartObject();

MetadataFormatter.Invoke(jsonWriter, entry.LogInfo);
MetadataFormatter.Invoke(jsonWriter, entry.LogInfo, options);

var bufferWriter = ArrayBufferWriterPool.GetThreadStaticInstance();
entry.ToString(bufferWriter);
Expand Down Expand Up @@ -125,13 +125,28 @@ static JsonEncodedText LogLevelToEncodedText(LogLevel logLevel)
}
}

public static void DefaultMetadataFormatter(Utf8JsonWriter jsonWriter, LogInfo info)
public static void DefaultMetadataFormatter(Utf8JsonWriter jsonWriter, LogInfo info, ZLoggerOptions options)
{
jsonWriter.WriteString(CategoryNameText, info.CategoryName);
jsonWriter.WriteString(LogLevelText, LogLevelToEncodedText(info.LogLevel));
jsonWriter.WriteNumber(EventIdText, info.EventId.Id);
jsonWriter.WriteString(EventIdNameText, info.EventId.Name);
jsonWriter.WriteString(TimestampText, info.Timestamp);
if ((options.IncludeProperties & LogInfoProperties.CategoryName) != 0)
{
jsonWriter.WriteString(CategoryNameText, info.CategoryName);
}
if ((options.IncludeProperties & LogInfoProperties.LogLevel) != 0)
{
jsonWriter.WriteString(LogLevelText, LogLevelToEncodedText(info.LogLevel));
}
if ((options.IncludeProperties & LogInfoProperties.EventIdValue) != 0)
{
jsonWriter.WriteNumber(EventIdText, info.EventId.Id);
}
if ((options.IncludeProperties & LogInfoProperties.EventIdName) != 0)
{
jsonWriter.WriteString(EventIdNameText, info.EventId.Name);
}
if ((options.IncludeProperties & LogInfoProperties.Timestamp) != 0)
{
jsonWriter.WriteString(TimestampText, info.Timestamp);
}

// Write Exception
if (info.Exception is { } ex)
Expand Down
7 changes: 3 additions & 4 deletions src/ZLogger/LogInfo.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging;

namespace ZLogger
{
Expand All @@ -19,5 +18,5 @@ public LogInfo(string categoryName, DateTimeOffset timestamp, LogLevel logLevel,
LogLevel = logLevel;
Exception = exception;
}
}
}
}
}
13 changes: 12 additions & 1 deletion src/ZLogger/ZLoggerOptions.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
using ZLogger.Formatters;
using Microsoft.Extensions.Logging;
using ZLogger.Formatters;

namespace ZLogger
{
[Flags]
public enum LogInfoProperties
{
Timestamp = 1 << 0,
LogLevel = 1 << 1,
CategoryName = 1 << 2,
EventIdValue = 1 << 3,
EventIdName = 1 << 4,
All = Timestamp | LogLevel | CategoryName | EventIdValue | EventIdName
}

public class ZLoggerOptions
{
public Action<LogInfo, Exception>? InternalErrorLogger { get; set; }
Expand All @@ -12,6 +22,7 @@ public class ZLoggerOptions
public bool IncludeScopes { get; set; }
public IKeyNameMutator? KeyNameMutator { get; set; }
public LogLevel LogToErrorThreshold { get; set; } = LogLevel.None;
public LogInfoProperties IncludeProperties { get; set; } = LogInfoProperties.All;

Func<IZLoggerFormatter> formatterFactory = DefaultFormatterFactory;

Expand Down
41 changes: 31 additions & 10 deletions tests/ZLogger.MessagePack.Tests/FormatterTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,28 @@ public void LowercaseMutator()
};

options.UseMessagePackFormatter();

var XyzAbc = 100;
var fOo = 200;
logger.ZLogInformation($"AAA {XyzAbc} {fOo}");

var msgpack = processor.Dequeue();
((string)msgpack["CategoryName"]).Should().Be("test");
((string)msgpack["LogLevel"]).Should().Be("Information");
((string)msgpack["Message"]).Should().Be("AAA 100 200");
((int)msgpack["xyzAbc"]).Should().Be(100);
((int)msgpack["fOo"]).Should().Be(200);
}

[Fact]
public void ExcludeLogInfoProperties()
{
var options = new ZLoggerOptions
{
IncludeProperties = LogInfoProperties.LogLevel |
LogInfoProperties.Timestamp |
LogInfoProperties.EventIdValue
}.UseMessagePackFormatter();

processor = new TestProcessor(options);

Expand All @@ -135,18 +157,17 @@ public void LowercaseMutator()
x.AddZLoggerLogProcessor(processor);
});
logger = loggerFactory.CreateLogger("test");


var XyzAbc = 100;
var fOo = 200;
logger.ZLogInformation($"AAA {XyzAbc} {fOo}");


var now = DateTime.UtcNow;
logger.ZLogInformation(new EventId(1, "TEST"), $"HELLO!");

var msgpack = processor.Dequeue();
((string)msgpack["CategoryName"]).Should().Be("test");
((string)msgpack["LogLevel"]).Should().Be("Information");
((string)msgpack["Message"]).Should().Be("AAA 100 200");
((int)msgpack["xyzAbc"]).Should().Be(100);
((int)msgpack["fOo"]).Should().Be(200);
((int)msgpack["EventId"]).Should().Be(1);
((DateTime)msgpack["Timestamp"]).Should().BeOnOrAfter(now);
((bool)msgpack.ContainsKey("Exception")).Should().BeFalse();
((bool)msgpack.ContainsKey("CategoryName")).Should().BeFalse();
((bool)msgpack.ContainsKey("EventIdName")).Should().BeFalse();
}
}
}
129 changes: 129 additions & 0 deletions tests/ZLogger.Tests/JsonFormatTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
using FluentAssertions;
using Microsoft.Extensions.Logging;
using System;
using System.IO;
using System.Text;
using System.Text.Json;
using ZLogger.Formatters;

namespace ZLogger.Tests
{
public class JsonFormatTest
{
[Fact]
public void FormatLogEntry_CustomMetadata()
{
using var ms = new MemoryStream();

var sourceCodeHash = Guid.NewGuid().ToString();


var loggerFactory = LoggerFactory.Create(x =>
{
x.SetMinimumLevel(LogLevel.Debug);
x.AddZLoggerStream(ms, option =>
{
var hashProp = JsonEncodedText.Encode("Hash");

option.UseJsonFormatter(formatter =>
{
formatter.MetadataFormatter = (writer, info, options) =>
{
// Use default and add custom metadata
SystemTextJsonZLoggerFormatter.DefaultMetadataFormatter(writer, info, options);
writer.WriteString(hashProp, sourceCodeHash);
};
});
});
});
var logger = loggerFactory.CreateLogger("test");

var tako = 100;
var yaki = "あいうえお";
logger.ZLogDebug($"FooBar{tako} NanoNano{yaki}");

logger.LogInformation("");

loggerFactory.Dispose();

using var sr = new StreamReader(new MemoryStream(ms.ToArray()), Encoding.UTF8);
var json = sr.ReadLine();

var doc = JsonDocument.Parse(json).RootElement;

doc.GetProperty("Message").GetString().Should().Be("FooBar100 NanoNanoあいうえお");
doc.GetProperty("tako").GetInt32().Should().Be(100);
doc.GetProperty("yaki").GetString().Should().Be("あいうえお");

doc.GetProperty("Hash").GetString().Should().Be(sourceCodeHash);
doc.GetProperty("LogLevel").GetString().Should().Be("Debug");
}

[Fact]
public void FormatLogEntry_ExcludeLogInfoProperties()
{
var options = new ZLoggerOptions
{
IncludeProperties = LogInfoProperties.LogLevel |
LogInfoProperties.Timestamp |
LogInfoProperties.EventIdValue
}.UseJsonFormatter();

var processor = new TestProcessor(options);

var loggerFactory = LoggerFactory.Create(x =>
{
x.SetMinimumLevel(LogLevel.Debug);
x.AddZLoggerLogProcessor(processor);
});
var logger = loggerFactory.CreateLogger("test");

var now = DateTime.UtcNow;
logger.ZLogInformation(new EventId(1, "TEST"), $"HELLO!");

var json = processor.Dequeue();
var doc = JsonDocument.Parse(json).RootElement;

doc.GetProperty("Message").GetString().Should().Be("HELLO!");
doc.GetProperty("LogLevel").GetString().Should().Be("Information");
doc.GetProperty("Timestamp").GetDateTime().Should().BeOnOrAfter(now);
doc.GetProperty("EventId").GetInt32().Should().Be(1);
doc.TryGetProperty("EventIdName", out _).Should().BeFalse();
doc.TryGetProperty("CategoryName", out _).Should().BeFalse();
}

[Fact]
public void KeyNameMutator_Lower()
{
var options = new ZLoggerOptions
{
IncludeScopes = true
};
options.UseJsonFormatter();
options.KeyNameMutator = KeyNameMutator.LowercaseInitial;

var processor = new TestProcessor(options);

using var loggerFactory = LoggerFactory.Create(x =>
{
x.SetMinimumLevel(LogLevel.Debug);
x.AddZLoggerLogProcessor(processor, options =>
{
options.IncludeScopes = true;
});
});
var logger = loggerFactory.CreateLogger("test");

var Tako = 100;
var Yaki = "あいうえお";
logger.ZLogDebug($"tako: {Tako} yaki: {Yaki}");

var json = processor.Dequeue();
var doc = JsonDocument.Parse(json).RootElement;

doc.GetProperty("Message").GetString().Should().Be("tako: 100 yaki: あいうえお");
doc.GetProperty("tako").GetInt32().Should().Be(100);
doc.GetProperty("yaki").GetString().Should().Be("あいうえお");
}
}
}
Loading
Loading