Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change, It's now possible to configure number of inner exceptions to be sent #14

Merged
merged 2 commits into from Nov 14, 2018
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -25,9 +25,11 @@ Add the following code in your web.config to configure LogglyAppender in your ap
<tag value="your-custom-tag" />
<logicalThreadContextKeys value="lkey1,lkey2" /> <!-- optional -->
<globalContextKeys value="gkey1,gkey2" /> <!-- optional -->
<numberOfInnerExceptions value="4"/> <!-- optional -->
</appender>
</log4net>
```

To send **GlobalContext** and **LogicalThreadContext** properties in your log you need define the list of used properties in the configuration.

For GlobalContext Properties use
@@ -49,6 +51,10 @@ By default, library uses Loggly /bulk end point (https://www.loggly.com/docs/htt
<logMode value="inputs" />
```
Set number of inner exceptions that should be sent to loggly, if you don't want the default value.
```
<numberOfInnerExceptions value value="4"/>
```
Add the following entry in your AssemblyInfo.cs
```
@@ -15,6 +15,7 @@
<tag value="log4net-test" />
<logicalThreadContextKeys value="LogicalThread1,InnerLogicalThreadContext" />
<globalContextKeys value="GlobalContextPropertySample" />
<numberOfInnerExceptions value="4"/>
</appender>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
@@ -94,6 +94,36 @@ static void Main(string[] argArray)
log.Info(new TestObject());
log.Info(null);

try
{
try
{
try
{
try
{
throw new Exception("1");
}
catch (Exception e)
{
throw new Exception("2", e);
}
}
catch (Exception e)
{
throw new Exception("3", e);
}
}
catch (Exception e)
{
throw new Exception("4", e);
}
}
catch (Exception e)
{
log.Error("Exception", e);
}

Console.ReadKey();
}
}
@@ -8,7 +8,7 @@
using log4net.Core;
using log4net.loggly;
using log4net.Repository;
using log4net_loggly.UnitTests.Models;
using Models;
using Moq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@@ -304,6 +304,58 @@ public void ShouldSerializeTheException()
stacktrace.Should().NotBeNull("because the exception has a stacktrace");
}

[Theory]
[InlineData(0, 0, 1)]
[InlineData(1, 1, 1)]
[InlineData(2, 1, 1)]
[InlineData(2, 2, 2)]
[InlineData(2, 2, 3)]
[InlineData(3, 3, 3)]
[InlineData(5, 5, 5)]
[InlineData(5, 5, 10)]
public void ShouldSerializeInnerExceptions(int configurationNumberOfInnerExceptions, int expectedNumberOfException, int innerExceptionsToCreate)
{
Exception ex = GetArgumentException(innerExceptionsToCreate + 1);

var evt = new LoggingEvent(
GetType(),
Mock.Of<ILoggerRepository>(),
_fixture.Create("loggerName"),
_fixture.Create<Level>(),
_fixture.Create("message"),
ex);
var instance = _fixture.Create<LogglyFormatter>();
_fixture.Freeze<Mock<ILogglyAppenderConfig>>().SetupGet(x => x.NumberOfInnerExceptions).Returns(configurationNumberOfInnerExceptions);

var result = instance.ToJson(evt);
dynamic json = JObject.Parse(result);

var exception = json.exception;

((object)exception).Should().NotBeNull("because an exception was specified in the event");

// Validate first level
var message = (string)exception.exceptionMessage;
var type = (string)exception.exceptionType;
var stacktrace = (string)exception.stacktrace;
AssertException(message, type, stacktrace, 0);

// Validate inner exceptions
var count = 0;
var innerException = exception.innerException;
while (innerException != null)
{
count++;
message = (string)innerException.innerExceptionMessage;
type = (string)innerException.innerExceptionType;
stacktrace = (string)innerException.innerStacktrace;
AssertException(message, type, stacktrace, count);
innerException = innerException.innerException;
}

count.Should().Be(expectedNumberOfException, "Expects all stacktraces");
}

[Fact]
public void ShouldSerializeThreadContextProperties()
{
@@ -355,6 +407,60 @@ public void ShouldSetMessagePropertyWhenMessageObjectIsString()

message.Should().StartWith("message", "because the MessageObject property value is used");
}

private static ArgumentException GetArgumentException(int numberOfExceptions)
{
try
{
if (--numberOfExceptions > 0)
{
try
{
GetNestedArgumentException(numberOfExceptions);
}
catch (ArgumentException e)
{
throw new ArgumentException("Exception 0", e);
}
}
else
{
throw new ArgumentException("Exception 0");
}
}
catch (ArgumentException e)
{
return e;
}
return null;
}

private static void GetNestedArgumentException(int numberOfExceptions, int deep = 0)
{
deep++;
if (--numberOfExceptions > 0)
{
try
{
GetNestedArgumentException(numberOfExceptions, deep);
}
catch (ArgumentException e)
{
throw new ArgumentException($"Exception {deep}", e);
}
}
else
{
throw new ArgumentException($"Exception {deep}");
}
}

private static void AssertException(string message, string type, string stacktrace, int stackLevel)
{
message.Should().Be($"Exception {stackLevel}", "because an argument exception has a default message");
type.Should().Be(typeof(ArgumentException).FullName, "because we logged an argument exception");
stacktrace.Should().NotBeNull("because the exception has a stacktrace");
}
}
}
}
@@ -1,15 +1,16 @@
namespace log4net.loggly
{
public interface ILogglyAppenderConfig
{
string RootUrl { get; set; }
string InputKey { get; set; }
string UserAgent { get; set; }
string LogMode { get; set; }
int TimeoutInSeconds { get; set; }
string Tag { get; set; }
string LogicalThreadContextKeys { get; set; }
string GlobalContextKeys { get; set; }
int BufferSize { get; set; }
}
namespace log4net.loggly
{
public interface ILogglyAppenderConfig
{
string RootUrl { get; set; }
string InputKey { get; set; }
string UserAgent { get; set; }
string LogMode { get; set; }
int TimeoutInSeconds { get; set; }
string Tag { get; set; }
string LogicalThreadContextKeys { get; set; }
string GlobalContextKeys { get; set; }
int BufferSize { get; set; }
int NumberOfInnerExceptions { get; set; }
}
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.