Skip to content

Commit 21e34c0

Browse files
committed
Format exception in structured and plain logging
1 parent eb55d8f commit 21e34c0

File tree

4 files changed

+56
-15
lines changed

4 files changed

+56
-15
lines changed

Libraries/src/Amazon.Lambda.RuntimeSupport/Bootstrap/LambdaBootstrap.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
using System.Net.Http;
1919
using System.Threading;
2020
using System.Threading.Tasks;
21+
using Amazon.Lambda.Core;
2122
using Amazon.Lambda.RuntimeSupport.Bootstrap;
2223
using Amazon.Lambda.RuntimeSupport.Helpers;
2324

@@ -252,9 +253,11 @@ public static HttpClient ConstructHttpClient()
252253

253254
private void WriteUnhandledExceptionToLog(Exception exception)
254255
{
255-
// Console.Error.WriteLine are redirected to the IConsoleLoggerWriter which
256-
// will take care of writing to the function's log stream.
256+
#if NET6_0_OR_GREATER
257+
Client.ConsoleLogger.FormattedWriteLine(LogLevel.Error.ToString(), exception, null);
258+
#else
257259
Console.Error.WriteLine(exception);
260+
#endif
258261
}
259262

260263
#if NET8_0_OR_GREATER

Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/Logging/DefaultLogMessageFormatter.cs

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#if NET6_0_OR_GREATER
22

3+
using System.Text;
4+
35
namespace Amazon.Lambda.RuntimeSupport.Helpers.Logging
46
{
57
/// <summary>
@@ -48,21 +50,53 @@ public override string FormatMessage(MessageState state)
4850
message = ApplyMessageProperties(state.MessageTemplate, messageProperties, state.MessageArguments);
4951
}
5052

53+
var displayLevel = state.Level != null ? ConvertLogLevelToLabel(state.Level.Value) : null;
54+
55+
var sb = new StringBuilder(
56+
25 + // Length for timestamp
57+
(state.AwsRequestId?.Length).GetValueOrDefault() +
58+
displayLevel.Length +
59+
(message?.Length).GetValueOrDefault() +
60+
5 // Padding for tabs
61+
);
62+
5163
if (!AddPrefix)
5264
{
5365
return message;
5466
}
5567

56-
var displayLevel = state.Level != null ? ConvertLogLevelToLabel(state.Level.Value) : null;
5768

58-
if (!string.IsNullOrEmpty(displayLevel))
69+
if (AddPrefix)
70+
{
71+
sb.Append(FormatTimestamp(state));
72+
sb.Append('\t');
73+
sb.Append(state.AwsRequestId);
74+
75+
if (!string.IsNullOrEmpty(displayLevel))
76+
{
77+
sb.Append('\t');
78+
sb.Append(displayLevel);
79+
}
80+
81+
sb.Append('\t');
82+
}
83+
84+
85+
if (!string.IsNullOrEmpty(message))
5986
{
60-
return $"{FormatTimestamp(state)}\t{state.AwsRequestId}\t{displayLevel}\t{message ?? string.Empty}";
87+
sb.Append(message);
6188
}
62-
else
89+
90+
if (state.Exception != null)
6391
{
64-
return $"{FormatTimestamp(state)}\t{state.AwsRequestId}\t{message ?? string.Empty}";
92+
if (!string.IsNullOrEmpty(message))
93+
{
94+
sb.Append('\n');
95+
}
96+
sb.Append(state.Exception.ToString());
6597
}
98+
99+
return sb.ToString();
66100
}
67101

68102
/// <summary>

Libraries/src/Amazon.Lambda.RuntimeSupport/Helpers/Logging/JsonLogMessageFormatter.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -191,11 +191,10 @@ private void WriteException(Utf8JsonWriter writer, MessageState state)
191191
writer.WriteString("errorMessage", state.Exception.Message);
192192
writer.WritePropertyName("stackTrace");
193193
writer.WriteStartArray();
194-
195-
// TODO: Right now for stack trace we are just using a single array element doing a ToString to get the
196-
// inner excepions. Working with the Lambda team to figure out how they want to handle inner exceptions with
197-
// stackTrace array.
198-
writer.WriteStringValue(state.Exception.ToString());
194+
foreach(var line in state.Exception.ToString().Split('\n'))
195+
{
196+
writer.WriteStringValue(line.Trim());
197+
}
199198
writer.WriteEndArray();
200199
}
201200
}

Libraries/test/Amazon.Lambda.RuntimeSupport.Tests/Amazon.Lambda.RuntimeSupport.UnitTests/LogMessageFormatterTests.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities;
44
using System;
55
using System.Collections.Generic;
6+
using System.Linq;
67
using System.Runtime.Serialization;
78
using System.Text.Json;
89
using Xunit;
@@ -470,10 +471,14 @@ public void FormatJsonException()
470471
Assert.Equal("This Will Fail", doc.RootElement.GetProperty("errorMessage").GetString());
471472
Assert.Equal("System.ApplicationException", doc.RootElement.GetProperty("errorType").GetString());
472473
Assert.Equal(JsonValueKind.Array, doc.RootElement.GetProperty("stackTrace").ValueKind);
473-
Assert.Equal(ex.ToString(), doc.RootElement.GetProperty("stackTrace")[0].GetString());
474474

475-
// Confirm inner exceptions are being captured
476-
Assert.Contains("System.NullReferenceException", doc.RootElement.GetProperty("stackTrace")[0].GetString());
475+
var stackLines = ex.ToString().Split('\n').Select(x => x.Trim()).ToList();
476+
var jsonExArray = doc.RootElement.GetProperty("stackTrace");
477+
Assert.Equal(stackLines.Count, jsonExArray.GetArrayLength());
478+
for(var i = 0; i < stackLines.Count; i++)
479+
{
480+
Assert.Equal(stackLines[i], jsonExArray[i].GetString());
481+
}
477482
}
478483
}
479484

0 commit comments

Comments
 (0)