Skip to content

Commit

Permalink
Implement gRPC destructurer
Browse files Browse the repository at this point in the history
  • Loading branch information
olsh authored and RehanSaeed committed Aug 15, 2022
1 parent 78012bb commit 4b306d5
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 0 deletions.
7 changes: 7 additions & 0 deletions Serilog.Exceptions.sln
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serilog.Exceptions.MsSqlSer
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serilog.Exceptions.Refit", "Source\Serilog.Exceptions.Refit\Serilog.Exceptions.Refit.csproj", "{0EABF22F-F070-4F8D-B165-DD4C4AB62820}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serilog.Exceptions.Grpc", "Source\Serilog.Exceptions.Grpc\Serilog.Exceptions.Grpc.csproj", "{62CD1306-225F-4FE4-8C2C-45D457E84D36}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -130,6 +132,10 @@ Global
{0EABF22F-F070-4F8D-B165-DD4C4AB62820}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0EABF22F-F070-4F8D-B165-DD4C4AB62820}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0EABF22F-F070-4F8D-B165-DD4C4AB62820}.Release|Any CPU.Build.0 = Release|Any CPU
{62CD1306-225F-4FE4-8C2C-45D457E84D36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{62CD1306-225F-4FE4-8C2C-45D457E84D36}.Debug|Any CPU.Build.0 = Debug|Any CPU
{62CD1306-225F-4FE4-8C2C-45D457E84D36}.Release|Any CPU.ActiveCfg = Release|Any CPU
{62CD1306-225F-4FE4-8C2C-45D457E84D36}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -147,6 +153,7 @@ Global
{4F089B23-3121-4935-B24E-7A9A497BD9FE} = {2C245036-D7F6-4F7C-9BB6-5AFBCCE480F7}
{0A21D2AD-024B-4F3D-95F4-BAEFEEE95945} = {C5508012-7216-4ABE-AB2F-B166ED5FF94F}
{0EABF22F-F070-4F8D-B165-DD4C4AB62820} = {C5508012-7216-4ABE-AB2F-B166ED5FF94F}
{62CD1306-225F-4FE4-8C2C-45D457E84D36} = {C5508012-7216-4ABE-AB2F-B166ED5FF94F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BE74AFAC-AC6F-4B80-860F-15C22BEE1A38}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
namespace Serilog.Exceptions.Grpc.Destructurers;

using System;
using System.Collections.Generic;
using global::Grpc.Core;
using Serilog.Exceptions.Core;
using Serilog.Exceptions.Destructurers;

/// <summary>
/// A destructurer for <see cref="RpcException"/>.
/// </summary>
/// <seealso cref="ExceptionDestructurer" />
public class RpcExceptionDestructurer : ExceptionDestructurer
{
/// <inheritdoc />
public override Type[] TargetTypes => new[] { typeof(RpcException) };

/// <inheritdoc />
public override void Destructure(
Exception exception,
IExceptionPropertiesBag propertiesBag,
Func<Exception, IReadOnlyDictionary<string, object?>?> destructureException)
{
base.Destructure(exception, propertiesBag, destructureException);

var rpcException = (RpcException)exception;

#pragma warning disable CA1062 // Validate arguments of public methods
propertiesBag.AddProperty(nameof(RpcException.Status.StatusCode), rpcException.Status.StatusCode);
propertiesBag.AddProperty(nameof(RpcException.Status.Detail), rpcException.Status.Detail);

foreach (var trailer in rpcException.Trailers)
{
if (trailer.IsBinary)
{
continue;
}

propertiesBag.AddProperty($"{nameof(RpcException.Trailers)}.{trailer.Key}", trailer.Value);
}
#pragma warning restore CA1062 // Validate arguments of public methods
}
}
3 changes: 3 additions & 0 deletions Source/Serilog.Exceptions.Grpc/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using System;

[assembly: CLSCompliant(true)]
21 changes: 21 additions & 0 deletions Source/Serilog.Exceptions.Grpc/Serilog.Exceptions.Grpc.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup Label="Build">
<TargetFrameworks>netstandard2.1;netstandard2.0;netstandard1.5;net462</TargetFrameworks>
</PropertyGroup>

<PropertyGroup Label="Package">
<Product>Serilog Exceptions gRPC</Product>
<Description>Log exception details and custom properties that are not output in Exception.ToString(). Contains custom destructurers for gRPC exceptions.</Description>
<PackageTags>Serilog;Exception;Log;Logging;Detail;Details;gRPC</PackageTags>
</PropertyGroup>

<ItemGroup Label="Project References">
<ProjectReference Include="..\Serilog.Exceptions\Serilog.Exceptions.csproj" />
</ItemGroup>

<ItemGroup Label="Package References">
<PackageReference Include="Grpc.Core.Api" Version="2.47.0" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
namespace Serilog.Exceptions.Test.Destructurers;

using System;
using System.Net;
using global::Grpc.Core;
using Serilog.Exceptions.Core;
using Serilog.Exceptions.Grpc.Destructurers;
using Xunit;
using static LogJsonOutputUtils;

public class RpcExceptionDestructurerTest
{
[Fact]
public void RpcException_StatusCodeIsLoggedAsProperty()
{
var options = new DestructuringOptionsBuilder().WithDestructurers(new[] { new RpcExceptionDestructurer() });
var rpcException = new RpcException(new Status(StatusCode.Aborted, string.Empty));

Test_LoggedExceptionContainsProperty(rpcException, nameof(RpcException.Status.StatusCode), nameof(StatusCode.Aborted), options);
}

[Fact]
public void RpcException_StatusDetailIsLoggedAsProperty()
{
var options = new DestructuringOptionsBuilder().WithDestructurers(new[] { new RpcExceptionDestructurer() });
var testDetail = "details";
var rpcException = new RpcException(new Status(StatusCode.Aborted, testDetail));

Test_LoggedExceptionContainsProperty(rpcException, nameof(RpcException.Status.Detail), testDetail, options);
}

[Fact]
public void RpcException_TrailersAreLoggedAsProperty()
{
var options = new DestructuringOptionsBuilder().WithDestructurers(new[] { new RpcExceptionDestructurer() });
const string stringTrailerKey1 = "key1";
const string stringTrailerValue1 = "stringTrailerValue1";
const string stringTrailerKey2 = "key2";
const string stringTrailerValue2 = "stringTrailerValue2";
var metadata = new Metadata { { stringTrailerKey1, stringTrailerValue1 }, { stringTrailerKey2, stringTrailerValue2 } };

var rpcException = new RpcException(new Status(StatusCode.Aborted, string.Empty), metadata);

Test_LoggedExceptionContainsProperty(rpcException, $"{nameof(RpcException.Trailers)}.{stringTrailerKey1}", stringTrailerValue1, options);
Test_LoggedExceptionContainsProperty(rpcException, $"{nameof(RpcException.Trailers)}.{stringTrailerKey2}", stringTrailerValue2, options);
}

[Fact]
public void RpcException_BinaryTrailersAreNotLoggedAsProperty()
{
var options = new DestructuringOptionsBuilder().WithDestructurers(new[] { new RpcExceptionDestructurer() });
const string stringTrailerKey1 = "key-bin";
var metadata = new Metadata { { stringTrailerKey1, new byte[] { 1 } } };

var rpcException = new RpcException(new Status(StatusCode.Aborted, string.Empty), metadata);

Test_LoggedExceptionDoesNotContainProperty(rpcException, $"{nameof(RpcException.Trailers)}.{stringTrailerKey1}", options);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

<ItemGroup Label="Project References">
<ProjectReference Include="..\..\Source\Serilog.Exceptions.EntityFrameworkCore\Serilog.Exceptions.EntityFrameworkCore.csproj" />
<ProjectReference Include="..\..\Source\Serilog.Exceptions.Grpc\Serilog.Exceptions.Grpc.csproj" />
<ProjectReference Include="..\..\Source\Serilog.Exceptions.Refit\Serilog.Exceptions.Refit.csproj" />
<ProjectReference Include="..\..\Source\Serilog.Exceptions\Serilog.Exceptions.csproj" />
</ItemGroup>
Expand Down

0 comments on commit 4b306d5

Please sign in to comment.