ChangemakerStudios / serilog-sinks-mongodb

A sink for Serilog that writes events to MongoDB
Apache License 2.0
89 stars 51 forks source link

Add IntPtr, UIntPtr proper handling since they became ScalarValue #86

Open daniilBoushys opened 3 weeks ago

daniilBoushys commented 3 weeks ago

Description Initial issue created in Serilog: https://github.com/serilog/serilog/issues/2101

After updating the Serilog package from version 3.0.1 to version 3.1.0 it was noticed that some logs are not written to the MongoDB. The investigation showed that in https://github.com/serilog/serilog/pull/1959 IntPtr type in 3.1.0 is logged as ScalarValue (before it was StructureValue), leading to System.ArgumentException: .NET type System.IntPtr cannot be mapped to a BsonValue exception in Serilog.Sinks.MongoDB package

Reproduction ReproSerilogIssue.zip

Relevant package, tooling, and runtime versions .NET 8 Serilog 3.1.0 Serilog.Sinks.Console 4.1.0 Serilog.Sinks.MongoDB 5.4.1 MongoDB.Driver 2.27.0

daniilBoushys commented 3 weeks ago

It was mentioned that is an intentional change that was missed in the release notes https://github.com/serilog/serilog/issues/2101#issuecomment-2297686890

In the meantime, the following workaround was used to address the issue:

BsonTypeMapper.RegisterCustomTypeMapper(typeof(IntPtr), new CustomIntPtrMapper());
BsonTypeMapper.RegisterCustomTypeMapper(typeof(UIntPtr), new CustomIntPtrMapper());

class CustomIntPtrMapper : ICustomBsonTypeMapper
{
    public bool TryMapToBsonValue(object value, [UnscopedRef] out BsonValue bsonValue)
    {
        switch (value)
        {
            case IntPtr intPtr:
                bsonValue = intPtr.ToInt32();
                return true;
            case UIntPtr uIntPtr:
                bsonValue = uIntPtr.ToUInt32();
                return true;
            default:
                bsonValue = null;
                return false;
        }
    }
}