Skip to content

Commit b649ed2

Browse files
committed
add lambda serlialization json converters to support lambda event logging
1 parent 4dc1a81 commit b649ed2

File tree

7 files changed

+221
-4
lines changed

7 files changed

+221
-4
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
using System;
17+
using System.Text.Json;
18+
using System.Text.Json.Serialization;
19+
20+
namespace AWS.Lambda.Powertools.Logging.Internal.Converters;
21+
22+
/// <summary>
23+
/// Converts an byte[] to JSON.
24+
/// </summary>
25+
internal class ByteArrayConverter : JsonConverter<byte[]>
26+
{
27+
/// <summary>
28+
/// Converter throws NotSupportedException. Deserializing ByteArray is not allowed.
29+
/// </summary>
30+
/// <param name="reader">Reference to the JsonReader</param>
31+
/// <param name="typeToConvert">The type which should be converted.</param>
32+
/// <param name="options">The Json serializer options.</param>
33+
/// <returns></returns>
34+
/// <exception cref="NotSupportedException"></exception>
35+
public override byte[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
36+
{
37+
throw new NotSupportedException("Deserializing ByteArray is not allowed");
38+
}
39+
40+
/// <summary>
41+
/// Write the exception value as JSON.
42+
/// </summary>
43+
/// <param name="writer">The unicode JsonWriter.</param>
44+
/// <param name="values">The byte array.</param>
45+
/// <param name="options">The JsonSerializer options.</param>
46+
public override void Write(Utf8JsonWriter writer, byte[] values, JsonSerializerOptions options)
47+
{
48+
if (values == null)
49+
{
50+
writer.WriteNullValue();
51+
}
52+
else
53+
{
54+
writer.WriteStartArray();
55+
56+
foreach (var value in values)
57+
{
58+
writer.WriteNumberValue(value);
59+
}
60+
61+
writer.WriteEndArray();
62+
}
63+
}
64+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
using System;
17+
using System.Collections.Generic;
18+
using System.Text.Json;
19+
using System.Text.Json.Serialization;
20+
21+
namespace AWS.Lambda.Powertools.Logging.Internal.Converters;
22+
23+
/// <summary>
24+
/// JsonConvert to handle the AWS SDK for .NET custom enum classes that derive from the class called ConstantClass.
25+
/// </summary>
26+
public class ConstantClassConverter : JsonConverter<object>
27+
{
28+
private static readonly HashSet<string> ConstantClassNames = new()
29+
{
30+
"Amazon.S3.EventType",
31+
"Amazon.DynamoDBv2.OperationType",
32+
"Amazon.DynamoDBv2.StreamViewType"
33+
};
34+
35+
/// <summary>
36+
/// Check to see if the type is derived from ConstantClass.
37+
/// </summary>
38+
/// <param name="typeToConvert">The type which should be converted.</param>
39+
/// <returns>True if the type is derived from ConstantClass, False otherwise.</returns>
40+
public override bool CanConvert(Type typeToConvert)
41+
{
42+
return ConstantClassNames.Contains(typeToConvert.FullName);
43+
}
44+
45+
/// <summary>
46+
/// Converter throws NotSupportedException. Deserializing ConstantClass is not allowed.
47+
/// </summary>
48+
/// <param name="reader">Reference to the JsonReader</param>
49+
/// <param name="typeToConvert">The type which should be converted.</param>
50+
/// <param name="options">The Json serializer options.</param>
51+
/// <returns></returns>
52+
/// <exception cref="NotSupportedException"></exception>
53+
public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
54+
{
55+
throw new NotSupportedException("Deserializing ConstantClass is not allowed");
56+
}
57+
58+
/// <summary>
59+
/// Write the ConstantClass instance as JSON.
60+
/// </summary>
61+
/// <param name="writer">The unicode JsonWriter.</param>
62+
/// <param name="value">The exception instance.</param>
63+
/// <param name="options">The JsonSerializer options.</param>
64+
public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options)
65+
{
66+
writer.WriteStringValue(value.ToString());
67+
}
68+
}

libraries/src/AWS.Lambda.Powertools.Logging/Internal/ExceptionConverter.cs renamed to libraries/src/AWS.Lambda.Powertools.Logging/Internal/Converters/ExceptionConverter.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
using System.Text.Json;
1919
using System.Text.Json.Serialization;
2020

21-
namespace AWS.Lambda.Powertools.Logging.Internal;
21+
namespace AWS.Lambda.Powertools.Logging.Internal.Converters;
2222

2323
/// <summary>
2424
/// Converts an exception to JSON.
@@ -36,7 +36,7 @@ public override bool CanConvert(Type typeToConvert)
3636
}
3737

3838
/// <summary>
39-
/// Converter throws NotSupportedException. Deserializing exception is not allowed.
39+
/// Converter throws NotSupportedException. Deserializing Exception is not allowed.
4040
/// </summary>
4141
/// <param name="reader">Reference to the JsonReader</param>
4242
/// <param name="typeToConvert">The type which should be converted.</param>
@@ -45,7 +45,7 @@ public override bool CanConvert(Type typeToConvert)
4545
/// <exception cref="NotSupportedException"></exception>
4646
public override Exception Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
4747
{
48-
throw new NotSupportedException("Deserializing exception is not allowed");
48+
throw new NotSupportedException("Deserializing Exception is not allowed");
4949
}
5050

5151
/// <summary>
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
using System;
17+
using System.IO;
18+
using System.Text.Json;
19+
using System.Text.Json.Serialization;
20+
21+
namespace AWS.Lambda.Powertools.Logging.Internal.Converters;
22+
23+
/// <summary>
24+
/// Handles converting MemoryStreams to base 64 strings.
25+
/// </summary>
26+
internal class MemoryStreamConverter : JsonConverter<MemoryStream>
27+
{
28+
/// <summary>
29+
/// Converter throws NotSupportedException. Deserializing MemoryStream is not allowed.
30+
/// </summary>
31+
/// <param name="reader">Reference to the JsonReader</param>
32+
/// <param name="typeToConvert">The type which should be converted.</param>
33+
/// <param name="options">The Json serializer options.</param>
34+
/// <returns></returns>
35+
/// <exception cref="NotSupportedException"></exception>
36+
public override MemoryStream Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
37+
{
38+
throw new NotSupportedException("Deserializing MemoryStream is not allowed");
39+
}
40+
41+
/// <summary>
42+
/// Write the MemoryStream as a base 64 string.
43+
/// </summary>
44+
/// <param name="writer">The unicode JsonWriter.</param>
45+
/// <param name="value">The MemoryStream instance.</param>
46+
/// <param name="options">The JsonSerializer options.</param>
47+
public override void Write(Utf8JsonWriter writer, MemoryStream value, JsonSerializerOptions options)
48+
{
49+
writer.WriteStringValue(Convert.ToBase64String(value.ToArray()));
50+
}
51+
}

libraries/src/AWS.Lambda.Powertools.Logging/Internal/LoggingAspectHandler.cs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
using System.IO;
1818
using System.Linq;
1919
using System.Text.Json;
20+
using System.Text.Json.Serialization;
2021
using AWS.Lambda.Powertools.Common;
22+
using AWS.Lambda.Powertools.Logging.Internal.Converters;
2123
using Microsoft.Extensions.Logging;
2224

2325
namespace AWS.Lambda.Powertools.Logging.Internal;
@@ -93,6 +95,18 @@ internal class LoggingAspectHandler : IMethodAspectHandler
9395
/// Specify to clear Lambda Context on exit
9496
/// </summary>
9597
private bool _clearLambdaContext;
98+
99+
/// <summary>
100+
/// The JsonSerializer options
101+
/// </summary>
102+
private static JsonSerializerOptions _jsonSerializerOptions;
103+
104+
/// <summary>
105+
/// Get JsonSerializer options.
106+
/// </summary>
107+
/// <value>The current configuration.</value>
108+
private static JsonSerializerOptions JsonSerializerOptions =>
109+
_jsonSerializerOptions ??= BuildJsonSerializerOptions();
96110

97111
/// <summary>
98112
/// Initializes a new instance of the <see cref="LoggingAspectHandler" /> class.
@@ -259,6 +273,22 @@ private void CaptureLambdaContext(AspectEventArgs eventArgs)
259273
_systemWrapper.LogLine(
260274
"Skipping Lambda Context injection because ILambdaContext context parameter not found.");
261275
}
276+
277+
/// <summary>
278+
/// Builds JsonSerializer options.
279+
/// </summary>
280+
private static JsonSerializerOptions BuildJsonSerializerOptions()
281+
{
282+
var jsonOptions = new JsonSerializerOptions
283+
{
284+
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
285+
};
286+
jsonOptions.Converters.Add(new ByteArrayConverter());
287+
jsonOptions.Converters.Add(new ExceptionConverter());
288+
jsonOptions.Converters.Add(new MemoryStreamConverter());
289+
jsonOptions.Converters.Add(new ConstantClassConverter());
290+
return jsonOptions;
291+
}
262292

263293
/// <summary>
264294
/// Captures the correlation identifier.
@@ -286,7 +316,7 @@ private void CaptureCorrelationId(object eventArg)
286316
try
287317
{
288318
var correlationId = string.Empty;
289-
var jsonDoc = JsonDocument.Parse(JsonSerializer.Serialize(eventArg));
319+
var jsonDoc = JsonDocument.Parse(JsonSerializer.Serialize(eventArg, JsonSerializerOptions));
290320
var element = jsonDoc.RootElement;
291321

292322
for (var i = 0; i < correlationIdPaths.Length; i++)

libraries/src/AWS.Lambda.Powertools.Logging/Internal/PowertoolsLogger.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
using System.Linq;
1919
using System.Text.Json;
2020
using AWS.Lambda.Powertools.Common;
21+
using AWS.Lambda.Powertools.Logging.Internal.Converters;
2122
using Microsoft.Extensions.Logging;
2223

2324
namespace AWS.Lambda.Powertools.Logging.Internal;
@@ -350,7 +351,10 @@ private JsonSerializerOptions BuildJsonSerializerOptions()
350351
DictionaryKeyPolicy = SnakeCaseNamingPolicy.Instance
351352
}
352353
};
354+
jsonOptions.Converters.Add(new ByteArrayConverter());
353355
jsonOptions.Converters.Add(new ExceptionConverter());
356+
jsonOptions.Converters.Add(new MemoryStreamConverter());
357+
jsonOptions.Converters.Add(new ConstantClassConverter());
354358
return jsonOptions;
355359
}
356360
}

0 commit comments

Comments
 (0)