Skip to content

Commit 654de19

Browse files
authored
Merge pull request #503 from hjgraca/dateonly-converter
feat: Add DateOnly and TimeOnly converters
2 parents 02d0a70 + f3ad52c commit 654de19

File tree

5 files changed

+190
-0
lines changed

5 files changed

+190
-0
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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.Globalization;
18+
using System.Text.Json;
19+
using System.Text.Json.Serialization;
20+
21+
namespace AWS.Lambda.Powertools.Logging.Internal.Converters;
22+
23+
/// <summary>
24+
/// DateOnly JSON converter
25+
/// </summary>
26+
public class DateOnlyConverter : JsonConverter<DateOnly>
27+
{
28+
private const string DateFormat = "yyyy-MM-dd";
29+
30+
/// <summary>
31+
/// Converts DateOnly from JSON.
32+
/// </summary>
33+
/// <param name="reader"></param>
34+
/// <param name="typeToConvert"></param>
35+
/// <param name="options"></param>
36+
/// <returns></returns>
37+
public override DateOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
38+
{
39+
return DateOnly.ParseExact(reader.GetString()!, DateFormat, CultureInfo.InvariantCulture);
40+
}
41+
42+
/// <summary>
43+
/// Converts DateOnly to JSON.
44+
/// </summary>
45+
/// <param name="writer"></param>
46+
/// <param name="value"></param>
47+
/// <param name="options"></param>
48+
public override void Write(Utf8JsonWriter writer, DateOnly value, JsonSerializerOptions options)
49+
{
50+
writer.WriteStringValue(value.ToString(DateFormat, CultureInfo.InvariantCulture));
51+
}
52+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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.Globalization;
18+
using System.Text.Json;
19+
using System.Text.Json.Serialization;
20+
21+
namespace AWS.Lambda.Powertools.Logging.Internal.Converters;
22+
23+
/// <summary>
24+
/// TimeOnly JSON converter
25+
/// </summary>
26+
internal class TimeOnlyConverter : JsonConverter<TimeOnly>
27+
{
28+
private const string TimeFormat = "HH:mm:ss.FFFFFFF";
29+
30+
/// <summary>
31+
/// Converts TimeOnly from JSON.
32+
/// </summary>
33+
/// <param name="reader"></param>
34+
/// <param name="typeToConvert"></param>
35+
/// <param name="options"></param>
36+
/// <returns></returns>
37+
public override TimeOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
38+
{
39+
return TimeOnly.ParseExact(reader.GetString()!, TimeFormat, CultureInfo.InvariantCulture);
40+
}
41+
42+
/// <summary>
43+
/// Converts TimeOnly to JSON.
44+
/// </summary>
45+
/// <param name="writer"></param>
46+
/// <param name="value"></param>
47+
/// <param name="options"></param>
48+
public override void Write(Utf8JsonWriter writer, TimeOnly value, JsonSerializerOptions options)
49+
{
50+
writer.WriteStringValue(value.ToString(TimeFormat, CultureInfo.InvariantCulture));
51+
}
52+
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,8 @@ private static JsonSerializerOptions BuildJsonSerializerOptions()
288288
jsonOptions.Converters.Add(new ExceptionConverter());
289289
jsonOptions.Converters.Add(new MemoryStreamConverter());
290290
jsonOptions.Converters.Add(new ConstantClassConverter());
291+
jsonOptions.Converters.Add(new DateOnlyConverter());
292+
jsonOptions.Converters.Add(new TimeOnlyConverter());
291293
return jsonOptions;
292294
}
293295

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,8 @@ private JsonSerializerOptions BuildJsonSerializerOptions()
466466
jsonOptions.Converters.Add(new ExceptionConverter());
467467
jsonOptions.Converters.Add(new MemoryStreamConverter());
468468
jsonOptions.Converters.Add(new ConstantClassConverter());
469+
jsonOptions.Converters.Add(new DateOnlyConverter());
470+
jsonOptions.Converters.Add(new TimeOnlyConverter());
469471

470472
jsonOptions.Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping;
471473

libraries/tests/AWS.Lambda.Powertools.Logging.Tests/PowertoolsLoggerTest.cs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,5 +1219,87 @@ public void Log_Set_Execution_Environment_Context()
12191219
$"{Constants.FeatureContextIdentifier}/Logger/{assemblyVersion}");
12201220
env.Received(1).GetEnvironmentVariable("AWS_EXECUTION_ENV");
12211221
}
1222+
1223+
[Fact]
1224+
public void Log_Should_Serialize_DateOnly()
1225+
{
1226+
// Arrange
1227+
var loggerName = Guid.NewGuid().ToString();
1228+
var service = Guid.NewGuid().ToString();
1229+
var logLevel = LogLevel.Information;
1230+
var randomSampleRate = 0.5;
1231+
1232+
var configurations = Substitute.For<IPowertoolsConfigurations>();
1233+
configurations.Service.Returns(service);
1234+
configurations.LogLevel.Returns(logLevel.ToString());
1235+
1236+
var systemWrapper = Substitute.For<ISystemWrapper>();
1237+
systemWrapper.GetRandom().Returns(randomSampleRate);
1238+
1239+
var logger = new PowertoolsLogger(loggerName, configurations, systemWrapper, () =>
1240+
new LoggerConfiguration
1241+
{
1242+
Service = null,
1243+
MinimumLevel = null,
1244+
LoggerOutputCase = LoggerOutputCase.CamelCase
1245+
});
1246+
1247+
var message = new
1248+
{
1249+
PropOne = "Value 1",
1250+
PropTwo = "Value 2",
1251+
Date = new DateOnly(2022, 1, 1)
1252+
};
1253+
1254+
logger.LogInformation(message);
1255+
1256+
// Assert
1257+
systemWrapper.Received(1).LogLine(
1258+
Arg.Is<string>(s =>
1259+
s.Contains("\"message\":{\"propOne\":\"Value 1\",\"propTwo\":\"Value 2\",\"date\":\"2022-01-01\"}")
1260+
)
1261+
);
1262+
}
1263+
1264+
[Fact]
1265+
public void Log_Should_Serialize_TimeOnly()
1266+
{
1267+
// Arrange
1268+
var loggerName = Guid.NewGuid().ToString();
1269+
var service = Guid.NewGuid().ToString();
1270+
var logLevel = LogLevel.Information;
1271+
var randomSampleRate = 0.5;
1272+
1273+
var configurations = Substitute.For<IPowertoolsConfigurations>();
1274+
configurations.Service.Returns(service);
1275+
configurations.LogLevel.Returns(logLevel.ToString());
1276+
1277+
var systemWrapper = Substitute.For<ISystemWrapper>();
1278+
systemWrapper.GetRandom().Returns(randomSampleRate);
1279+
1280+
var logger = new PowertoolsLogger(loggerName, configurations, systemWrapper, () =>
1281+
new LoggerConfiguration
1282+
{
1283+
Service = null,
1284+
MinimumLevel = null,
1285+
LoggerOutputCase = LoggerOutputCase.CamelCase
1286+
});
1287+
1288+
var message = new
1289+
{
1290+
PropOne = "Value 1",
1291+
PropTwo = "Value 2",
1292+
Time = new TimeOnly(12, 0, 0)
1293+
};
1294+
1295+
logger.LogInformation(message);
1296+
1297+
// Assert
1298+
systemWrapper.Received(1).LogLine(
1299+
Arg.Is<string>(s =>
1300+
s.Contains("\"message\":{\"propOne\":\"Value 1\",\"propTwo\":\"Value 2\",\"time\":\"12:00:00\"}")
1301+
)
1302+
);
1303+
}
12221304
}
12231305
}

0 commit comments

Comments
 (0)