Skip to content
This repository was archived by the owner on Jun 2, 2018. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
1bcffa5
Updated refernces versions
May 19, 2014
128e259
Delete packages.config
May 19, 2014
1151243
updated to use userAgent
May 19, 2014
34ac964
Code Formatting Updated
May 21, 2014
591a117
Added more instructions
May 21, 2014
6834ddb
Updated Dump() to ToJson()
May 23, 2014
b64dc99
Update LogglyFormatter.cs
May 23, 2014
a27a316
Support to send both plain text and custom object
Jun 2, 2014
187d465
Updated comments
Jun 2, 2014
f93b3ed
Updated to Newtonsoft.Json
Aug 23, 2014
ec6f214
Updated to Newtonsoft.Json
Aug 23, 2014
403d42b
Merge pull request #1 from psquickitjayant/loggly-dev
Aug 27, 2014
caf5c33
Update README.md
Aug 28, 2014
f12dab1
Update README.md
Aug 28, 2014
44bcdd9
Added support to tag
Nov 10, 2014
6304d66
Added support to send X-Forwarded-For Header
Nov 13, 2014
7cb4f3a
Async Http Request
Nov 20, 2014
ad5dc7c
Added Support for Aysnchronous Logging and Retry upto 5 times
Dec 18, 2014
91e11aa
Fixed timestamp format to be parsed in Loggly.
Dec 30, 2014
13b607c
Now sending RenderedMessage to Loggly. Should cover both string messa…
urigrumble Jan 14, 2015
38351b5
Revert "Now sending RenderedMessage to Loggly. Should cover both stri…
urigrumble Jan 15, 2015
6fb5551
Special treatment for Common.Logging formatted messages in LogglyForm…
urigrumble Jan 15, 2015
8eaa9c8
Merge pull request #3 from RumbleInc/devs/urig/formatted_messages
varshneyjayant Jan 19, 2015
323dd10
Sends objects having value.
Jan 19, 2015
a86d9db
Added support to NDC Stack
Jan 19, 2015
a6d0af9
Bug Fixes
Jan 21, 2015
a08d520
Added support for log4net.ThreadContext.Properties
Jan 23, 2015
033c784
Re-factored Code
Jan 24, 2015
c117134
Merge pull request #4 from psquickitjayant/BOptimization
varshneyjayant Jan 28, 2015
0b703a5
fix for self refrencing bug :
giladwe Jan 28, 2015
599e295
test self referencing bug
giladwe Jan 28, 2015
d85ce02
Merge pull request #5 from giladwe/master
varshneyjayant Jan 28, 2015
8dd7ae7
Merge pull request #6 from psquickitjayant/optimization
varshneyjayant Jan 28, 2015
af87be2
Added Support to log4net.Util.ThreadStack
Jan 28, 2015
9cd25fa
Ignoring Reference Loop
Jan 29, 2015
863eb87
Adding custom object properties to main event
Jan 29, 2015
2487cb9
Merge pull request #7 from psquickitjayant/objectEvents
varshneyjayant Jan 30, 2015
38cacdd
Fixed null message issue
Feb 9, 2015
91042cd
Added check to make sure _threadContextProperties is not null
jgarcilazo Feb 19, 2015
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
32 changes: 31 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,34 @@
log4net-loggly
==============

Custom log4net appenders for importing logging events to loggly.
Custom log4net appenders for importing logging events to loggly.

Download log4net-loggly package from NuGet. Use the following command.

Install-Package log4net-loggly

Add the following code in your web.config to configure LogglyAppender in your application

<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net>
<root>
<level value="ALL" />
<appender-ref ref="LogglyAppender" />
</root>
<appender name="LogglyAppender" type="log4net.loggly.LogglyAppender, log4net-loggly">
<rootUrl value="http://logs-01.loggly.com/" />
<inputKey value="your-customer-token" />
<tag value="your-custom-tag" />
</appender>
</log4net>


Create an object of the Log class using LogManager

var logger = LogManager.GetLogger(typeof(Class));

Send logs to Loggly using the following code

logger.Info("log message");
48 changes: 24 additions & 24 deletions source/log4net-loggly-console/App.config
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net>
<root>
<level value="ALL" />
<appender-ref ref="LogglyAppender" />
<appender-ref ref="ColoredConsoleAppender" />
</root>
<appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
<mapping>
<level value="ERROR" />
<foreColor value="White" />
<backColor value="Red, HighIntensity" />
</mapping>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
<appender name="LogglyAppender" type="log4net.loggly.LogglyAppender, log4net-loggly">
<rootUrl value="https://logs.loggly.com/" />
<inputKey value="eb952942-e7c0-4f37-9746-8f018d329595" />
</appender>
<appender name="LogglyBufferringAppender" type="log4net.loggly.LogglyBufferringAppender, log4net-loggly">
<rootUrl value="https://logs.loggly.com/" />
<inputKey value="eb952942-e7c0-4f37-9746-8f018d329595" />
</appender>
<root>
<level value="ALL" />
<appender-ref ref="LogglyAppender" />
<appender-ref ref="ConsoleAppender" />
</root>
<appender name="LogglyAppender" type="log4net.loggly.LogglyAppender, log4net-loggly">
<rootUrl value="http://logs-01.loggly.com/" />
<inputKey value="Your-Customer-Token" />
<tag value="log4net-test" />
</appender>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
</log4net>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.2.11.0" newVersion="1.2.11.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
109 changes: 57 additions & 52 deletions source/log4net-loggly-console/Program.cs
Original file line number Diff line number Diff line change
@@ -1,66 +1,71 @@
using System;
using System.Collections.Generic;
using System.Threading;
using log4net;

namespace log4net_loggly_console
{
class Program
{
static void Main(string[] argArray)
{
log4net.Config.XmlConfigurator.Configure();

var log = LogManager.GetLogger(typeof (Program));
static void Main(string[] argArray)
{
log4net.Config.XmlConfigurator.Configure();

var log = LogManager.GetLogger(typeof(Program));

Thread thread = Thread.CurrentThread;
thread.Name = "Main Thread";
ThreadContext.Properties["MainThreadContext"] = "MainThreadContextValue";
log.Info("Thread test");
log.Error("oops", new ArgumentOutOfRangeException("argArray"));
log.Warn("hmmm", new ApplicationException("app exception"));
log.Info("yawn");

Thread newThread1 = new Thread(() =>
{
Thread curntThread = Thread.CurrentThread;
curntThread.Name = "Inner thread 1";
ThreadContext.Properties["InnerThread1Context"] = "InnerThreadContext1Values";

using (ThreadContext.Stacks["NDC1"].Push("StackValue1"))
{
log.Info("this is an inner thread 1");

var args = ParseArgs(argArray);
for (int i = 0; i < args.Repeat; i++)
{
try
{
log.Error("oops", new ArgumentOutOfRangeException("argArray"));
log.Warn("hmmm", new ApplicationException("app exception"));
log.Info("yawn");
log.Debug("zzzz");
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
using (ThreadContext.Stacks["NDC1"].Push("StackValue2"))
{
log.Info("inner ndc of inner thread 1");
}
}

Thread.Sleep(10000);
}
log.Info("without ndc of inner thread 1");
});

newThread1.Start();

Thread newThread2 = new Thread(() =>
{
Thread curntThread = Thread.CurrentThread;
curntThread.Name = "Inner thread 2";
ThreadContext.Properties["InnerThread2Context"] = "InnerThreadContext2Values";
log.Info("this is an inner thread 2");
});

newThread2.Start();

//Test self referencing
var parent = new Person { Name = "John Smith" };
var child1 = new Person { Name = "Bob Smith", Parent = parent };
var child2 = new Person { Name = "Suzy Smith", Parent = parent };
parent.Children = new List<Person> { child1, child2 };
log.Info(parent);

private static Args ParseArgs(string[] argArray)
{
var args = new Args{Repeat = 1};
Action<string> nextArg = null;
foreach (var a in argArray)
{
if (nextArg != null)
{
nextArg(a);
nextArg = null;
continue;
}
if (a.StartsWith("-") || a.StartsWith("/"))
{
switch (a.Substring(1))
{
case "r":
nextArg = s => args.Repeat = int.Parse(s);
break;
default:
throw new ArgumentOutOfRangeException("unknown arg: " + a);
}
}
}
return args;
}
log.Debug("zzzz");
log.InfoFormat("Loggly is the best {0} to collect Logs.", "service");
log.Info(new { type1 = "newcustomtype", value1 = "newcustomvalue" });
log.Info(new TestObject());
log.Info(null);

public class Args
{
public int Repeat { get; set; }
}
Console.ReadKey();
}
}
}
36 changes: 36 additions & 0 deletions source/log4net-loggly-console/TestObject.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace log4net_loggly_console
{
class TestObject
{
public string TField1 { get; set; }
public string TField2 { get; set; }
public string TField3 { get; set; }
public object TOField4 { get; set; }

public TestObject()
{
TField1 = "testValue1";
TField2 = "testValue2";
TField3 = string.Empty;
TOField4 = new { TOFF1 = "TOFFValue1", TOFF2 = "TOFFValue2" };
}
}
//test self referencing
class Person
{
public string Name;
public Person Parent;
public List<Person> Children;
}

class Child : Person
{
public string Name;

}
}
6 changes: 2 additions & 4 deletions source/log4net-loggly-console/log4net-loggly-console.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,7 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net">
<HintPath>..\packages\log4net.2.0.0\lib\net40-client\log4net.dll</HintPath>
</Reference>
<Reference Include="ServiceStack.Text">
<HintPath>..\packages\ServiceStack.Text.3.8.5\lib\net35\ServiceStack.Text.dll</HintPath>
<HintPath>..\packages\log4net.2.0.3\lib\net40-client\log4net.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
Expand All @@ -51,6 +48,7 @@
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TestObject.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config">
Expand Down
1 change: 0 additions & 1 deletion source/log4net-loggly-console/packages.config
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.0" targetFramework="net40-Client" />
<package id="ServiceStack.Text" version="3.8.5" targetFramework="net40-Client" />
</packages>
1 change: 1 addition & 0 deletions source/log4net-loggly/ILogglyAppenderConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ public interface ILogglyAppenderConfig
string InputKey { get; set; }
string UserAgent { get; set; }
int TimeoutInSeconds { get; set; }
string Tag { get; set; }
}
}
2 changes: 1 addition & 1 deletion source/log4net-loggly/ILogglyClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ namespace log4net.loggly
{
public interface ILogglyClient
{
void Send(ILogglyAppenderConfig config, string inputKey, string message);
void Send(ILogglyAppenderConfig config, string message);
}
}
26 changes: 21 additions & 5 deletions source/log4net-loggly/LogglyAppender.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
using log4net.Appender;
using log4net.Core;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;


namespace log4net.loggly
{
Expand All @@ -16,11 +20,23 @@ public class LogglyAppender : AppenderSkeleton
public string InputKey { set { Config.InputKey = value; } }
public string UserAgent { set { Config.UserAgent = value; } }
public int TimeoutInSeconds { set { Config.TimeoutInSeconds = value; } }
public string Tag { set { Config.Tag = value; } }

protected override void Append(LoggingEvent loggingEvent)
{
SendLogAction(loggingEvent);
}

private void SendLogAction(LoggingEvent loggingEvent)
{
Formatter.AppendAdditionalLoggingInformation(Config, loggingEvent);

//we should always format event in the same thread as
//many properties used in the event are associated with the current thread
//like threadname, ndc stacks, threadcontent properties etc.
string _formattedLog = Formatter.ToJson(loggingEvent);
ThreadPool.QueueUserWorkItem(x => Client.Send(Config, _formattedLog));
}

protected override void Append(LoggingEvent loggingEvent)
{
Formatter.AppendAdditionalLoggingInformation(Config, loggingEvent);
Client.Send(Config, Config.InputKey, Formatter.ToJson(loggingEvent));
}
}
}
3 changes: 3 additions & 0 deletions source/log4net-loggly/LogglyAppenderConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@ public string RootUrl

public int TimeoutInSeconds { get; set; }

public string Tag { get; set; }

public LogglyAppenderConfig()
{
UserAgent = "loggly-log4net-appender";
TimeoutInSeconds = 30;
Tag = "log4net";
}
}
}
11 changes: 6 additions & 5 deletions source/log4net-loggly/LogglyBufferringAppender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ public class LogglyBufferringAppender : BufferingAppenderSkeleton

private ILogglyAppenderConfig Config = new LogglyAppenderConfig();

public string RootUrl { set { Config.RootUrl = value; } }
public string InputKey { set { Config.InputKey = value; } }
public string UserAgent { set { Config.UserAgent = value; } }
public int TimeoutInSeconds { set { Config.TimeoutInSeconds = value; } }
public string RootUrl { set { Config.RootUrl = value; } }
public string InputKey { set { Config.InputKey = value; } }
public string UserAgent { set { Config.UserAgent = value; } }
public int TimeoutInSeconds { set { Config.TimeoutInSeconds = value; } }
public string Tag { set { Config.Tag = value; } }

protected override void Append(LoggingEvent loggingEvent)
{
Expand All @@ -25,7 +26,7 @@ protected override void Append(LoggingEvent loggingEvent)

protected override void SendBuffer(LoggingEvent[] loggingEvents)
{
Client.Send(Config, Config.InputKey, Formatter.ToJson(loggingEvents));
Client.Send(Config, Formatter.ToJson(loggingEvents));
}
}
}
Loading