Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,4 @@ $RECYCLE.BIN/

# Mac desktop service store files
.DS_Store
.vs/
46 changes: 43 additions & 3 deletions Log4Slack/SlackAppender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ public class SlackAppender : AppenderSkeleton {
/// </summary>
public bool AddExceptionTraceField { get; set; }

/// <summary>
/// Indicates whether or not to include the inner exception in the message.
/// </summary>
public bool AddInnerException { get; set; }

/// <summary>
/// Indicates whether or not to append the logger name to the Stack username.
/// </summary>
Expand Down Expand Up @@ -120,17 +125,38 @@ protected override void Append(log4net.Core.LoggingEvent loggingEvent) {
var exception = loggingEvent.ExceptionObject;
if (exception != null) {
theAttachment.Fields.Insert(0, new Field("Exception Type", Value: exception.GetType().Name, Short: true));
if (AddExceptionTraceField && !string.IsNullOrWhiteSpace(exception.StackTrace)) {
var parts = exception.StackTrace.SplitOn(1990).ToArray(); // Split call stack into consecutive fields of ~2k characters
if (AddExceptionTraceField && !string.IsNullOrWhiteSpace(exception.StackTrace))
{
var parts = SlackMessageHelper.SplitIntoChunksOf2kChars(exception.StackTrace);

for (int idx = parts.Length - 1; idx >= 0; idx--) {
var name = "Exception Trace" + (idx > 0 ? string.Format(" {0}", idx + 1) : null);
theAttachment.Fields.Insert(0, new Field(name, Value: "```" + parts[idx].Replace("```", "'''") + "```"));
theAttachment.Fields.Insert(0, new Field(name, Value: SlackMessageHelper.FormatAsPre(parts[idx])));
}
}

theAttachment.Fields.Insert(0, new Field("Exception Message", Value: exception.Message));
}

if (AddInnerException && exception != null && exception.InnerException != null)
{
theAttachment.Fields.Add(new Field("---- Inner Exception ----", Value: string.Empty, Short: false));
theAttachment.Fields.Add(new Field("Inner Exception Type", Value: exception.InnerException.GetType().Name, Short: true));
theAttachment.Fields.Add(new Field("Inner Exception Message", Value: exception.InnerException.Message));

if (AddExceptionTraceField && !string.IsNullOrWhiteSpace(exception.InnerException.StackTrace))
{

var parts = SlackMessageHelper.SplitIntoChunksOf2kChars(exception.InnerException.StackTrace);
for (int idx = parts.Length - 1; idx >= 0; idx--)
{
var name = "Inner exception Trace" + (idx > 0 ? string.Format(" {0}", idx + 1) : null);
theAttachment.Fields.Add(new Field(name, Value: SlackMessageHelper.FormatAsPre(parts[idx])));
}
}

}

attachments.Add(theAttachment);
}

Expand All @@ -140,6 +166,20 @@ protected override void Append(log4net.Core.LoggingEvent loggingEvent) {
}
}

internal static class SlackMessageHelper
{
public static string FormatAsPre(string content)
{
return $"```{content.Replace("```", "'''")}```";
}

public static string[] SplitIntoChunksOf2kChars(string content)
{
return content.SplitOn(1990).ToArray();
}

}

internal static class Extensions {
public static string Expand(this string text) {
return text != null ? Environment.ExpandEnvironmentVariables(text) : null;
Expand Down
1 change: 1 addition & 0 deletions Log4SlackTesting/App.config
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
<IconEmoji value=":ghost:" />
<AddAttachment value="true" />
<AddExceptionTraceField value="true" />
<AddInnerException value="true" />
<UsernameAppendLoggerName value="true"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="[TEST] %-5level %logger - %message" />
Expand Down