From 4563a11bb20a6ed2d19f8a97c2091655b2b44f21 Mon Sep 17 00:00:00 2001 From: shweta Date: Fri, 20 Jan 2017 19:10:56 +0530 Subject: [PATCH 1/4] initial commit for buffer support in log4net-loggly library --- source/log4net-loggly/ILogglyClient.cs | 3 +- source/log4net-loggly/LogglyAppender.cs | 163 +++++++++--------- source/log4net-loggly/LogglyClient.cs | 99 ++++++++--- source/log4net-loggly/LogglyFormatter.cs | 8 + .../log4net-loggly/LogglySendBufferedLogs.cs | 53 ++++++ .../log4net-loggly/LogglyStoreLogsInBuffer.cs | 30 ++++ source/log4net-loggly/log4net-loggly.csproj | 3 + 7 files changed, 257 insertions(+), 102 deletions(-) create mode 100644 source/log4net-loggly/LogglySendBufferedLogs.cs create mode 100644 source/log4net-loggly/LogglyStoreLogsInBuffer.cs diff --git a/source/log4net-loggly/ILogglyClient.cs b/source/log4net-loggly/ILogglyClient.cs index 2be295e..e82bf69 100644 --- a/source/log4net-loggly/ILogglyClient.cs +++ b/source/log4net-loggly/ILogglyClient.cs @@ -2,6 +2,7 @@ namespace log4net.loggly { public interface ILogglyClient { - void Send(ILogglyAppenderConfig config, string message); + void Send(ILogglyAppenderConfig config, string message); + void Send(ILogglyAppenderConfig config, string message, bool isBulk); } } \ No newline at end of file diff --git a/source/log4net-loggly/LogglyAppender.cs b/source/log4net-loggly/LogglyAppender.cs index f9eaf67..44d8c89 100644 --- a/source/log4net-loggly/LogglyAppender.cs +++ b/source/log4net-loggly/LogglyAppender.cs @@ -8,95 +8,96 @@ namespace log4net.loggly { - public class LogglyAppender : AppenderSkeleton - { - List lstLogs = new List(); - string[] arr = new string[100]; - public static readonly string InputKeyProperty = "LogglyInputKey"; - public static ILogglyFormatter Formatter = new LogglyFormatter(); - public static ILogglyClient Client = new LogglyClient(); - 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 string LogMode { set { Config.LogMode = value; } } - public int TimeoutInSeconds { set { Config.TimeoutInSeconds = value; } } - public string Tag { set { Config.Tag = value; } } - public string LogicalThreadContextKeys { set { Config.LogicalThreadContextKeys = value; } } - public string GlobalContextKeys { set { Config.GlobalContextKeys = value; } } + public class LogglyAppender : AppenderSkeleton + { + List lstLogs = new List(); + string[] arr = new string[100]; + public static readonly string InputKeyProperty = "LogglyInputKey"; + public static ILogglyFormatter Formatter = new LogglyFormatter(); + public static ILogglyClient Client = new LogglyClient(); + 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 string LogMode { set { Config.LogMode = value; } } + public int TimeoutInSeconds { set { Config.TimeoutInSeconds = value; } } + public string Tag { set { Config.Tag = value; } } + public string LogicalThreadContextKeys { set { Config.LogicalThreadContextKeys = value; } } + public string GlobalContextKeys { set { Config.GlobalContextKeys = value; } } - private LogglyAsyncHandler LogglyAsync; + private LogglyAsyncHandler LogglyAsync; - public LogglyAppender() - { - LogglyAsync = new LogglyAsyncHandler(); - Timer.Timer t = new Timer.Timer(); - t.Interval = 5000; - t.Enabled = true; - t.Elapsed += t_Elapsed; - } + public LogglyAppender() + { + LogglyAsync = new LogglyAsyncHandler(); + Timer.Timer t = new Timer.Timer(); + t.Interval = 5000; + t.Enabled = true; + t.Elapsed += t_Elapsed; + } - void t_Elapsed(object sender, Timer.ElapsedEventArgs e) - { - if (lstLogs.Count != 0) - { - SendAllEvents(lstLogs.ToArray()); - } - } + void t_Elapsed(object sender, Timer.ElapsedEventArgs e) + { + if (lstLogs.Count != 0) + { + SendAllEvents(lstLogs.ToArray()); + } + LogglySendBufferedLogs.sendBufferedLogsToLoggly(Config, Config.LogMode == "bulk/"); + } - protected override void Append(LoggingEvent loggingEvent) - { - SendLogAction(loggingEvent); - } + protected override void Append(LoggingEvent loggingEvent) + { + SendLogAction(loggingEvent); + } - private void SendLogAction(LoggingEvent 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. + private void SendLogAction(LoggingEvent 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. - //initializing a string for the formatted log - string _formattedLog = string.Empty; + //initializing a string for the formatted log + string _formattedLog = string.Empty; - //if Layout is null then format the log from the Loggly Client - if (this.Layout == null) - { - Formatter.AppendAdditionalLoggingInformation(Config, loggingEvent); - _formattedLog = Formatter.ToJson(loggingEvent); - } - else - { - _formattedLog = Formatter.ToJson(RenderLoggingEvent(loggingEvent), loggingEvent.TimeStamp); - } + //if Layout is null then format the log from the Loggly Client + if (this.Layout == null) + { + Formatter.AppendAdditionalLoggingInformation(Config, loggingEvent); + _formattedLog = Formatter.ToJson(loggingEvent); + } + else + { + _formattedLog = Formatter.ToJson(RenderLoggingEvent(loggingEvent), loggingEvent.TimeStamp); + } - //check if logMode is bulk or inputs - if (Config.LogMode == "bulk/") - { - addToBulk(_formattedLog); - } - else if (Config.LogMode == "inputs/") - { - //sending _formattedLog to the async queue - LogglyAsync.PostMessage(_formattedLog, Config); - } - } + //check if logMode is bulk or inputs + if (Config.LogMode == "bulk/") + { + addToBulk(_formattedLog); + } + else if (Config.LogMode == "inputs/") + { + //sending _formattedLog to the async queue + LogglyAsync.PostMessage(_formattedLog, Config); + } + } - public void addToBulk(string log) - { - // store all events into a array max lenght is 100 - lstLogs.Add(log.Replace("\n", "")); - if (lstLogs.Count == 100) - { - SendAllEvents(lstLogs.ToArray()); - } - } + public void addToBulk(string log) + { + // store all events into a array max lenght is 100 + lstLogs.Add(log.Replace("\n", "")); + if (lstLogs.Count == 100) + { + SendAllEvents(lstLogs.ToArray()); + } + } - private void SendAllEvents(string[] events) - { - lstLogs.Clear(); - String bulkLog = String.Join(System.Environment.NewLine, events); - LogglyAsync.PostMessage(bulkLog, Config); - } + private void SendAllEvents(string[] events) + { + lstLogs.Clear(); + String bulkLog = String.Join(System.Environment.NewLine, events); + LogglyAsync.PostMessage(bulkLog, Config); + } - } -} \ No newline at end of file + } + } \ No newline at end of file diff --git a/source/log4net-loggly/LogglyClient.cs b/source/log4net-loggly/LogglyClient.cs index efc0e65..ff0c54d 100644 --- a/source/log4net-loggly/LogglyClient.cs +++ b/source/log4net-loggly/LogglyClient.cs @@ -1,46 +1,105 @@ using System; +using System.Collections.Generic; using System.Net; using System.Text; +using System.Linq; namespace log4net.loggly { public class LogglyClient : ILogglyClient { - public virtual void Send(ILogglyAppenderConfig config, string message) - { + static bool isValidToken = true; + public static void setValidInvalidFlag(bool flag) + { + isValidToken = flag; + } + + public virtual void Send(ILogglyAppenderConfig config, string message) + { int maxRetryAllowed = 5; int totalRetries = 0; string _tag = config.Tag; - + bool isBulk = config.LogMode.Contains("bulk"); + + List messageBulk = new List(); //keeping userAgent backward compatible if (!string.IsNullOrWhiteSpace(config.UserAgent)) { _tag = _tag + "," + config.UserAgent; } - while (totalRetries < maxRetryAllowed) + while (isValidToken && totalRetries < maxRetryAllowed) { totalRetries++; try { - var bytes = Encoding.UTF8.GetBytes(message); - var webRequest = CreateWebRequest(config, _tag); - - using (var dataStream = webRequest.GetRequestStream()) - { - dataStream.Write(bytes, 0, bytes.Length); - dataStream.Flush(); - dataStream.Close(); - } - - var webResponse = webRequest.GetResponse(); - webResponse.Close(); - break; + var bytes = Encoding.UTF8.GetBytes(message); + var webRequest = CreateWebRequest(config, _tag); + + using (var dataStream = webRequest.GetRequestStream()) + { + dataStream.Write(bytes, 0, bytes.Length); + dataStream.Flush(); + dataStream.Close(); + } + + var webResponse = webRequest.GetResponse(); + webResponse.Close(); + break; + } + + catch (WebException e) { + var response = (HttpWebResponse)e.Response; + if (response != null) + { + if (response.StatusCode == HttpStatusCode.Forbidden) //Check for bad token + { + setValidInvalidFlag(false); + } + if (totalRetries == 1) Console.WriteLine("Loggly error: {0}", e.Message); + } + + else if (totalRetries == 1) + { + if (isBulk) + { + messageBulk = message.Split('\n').ToList(); + LogglyStoreLogsInBuffer.storeBulkLogs(config, messageBulk, isBulk); + } + else + { + LogglyStoreLogsInBuffer.storeInputLogs(config, message, isBulk); + } + } + } + } + } + + public void Send(ILogglyAppenderConfig config, string message, bool isbulk) + { + if (isValidToken) + { + string _tag = config.Tag; + + //keeping userAgent backward compatible + if (!string.IsNullOrWhiteSpace(config.UserAgent)) + { + _tag = _tag + "," + config.UserAgent; } - catch { } + var bytes = Encoding.UTF8.GetBytes(message); + var webRequest = CreateWebRequest(config, _tag); + + using (var dataStream = webRequest.GetRequestStream()) + { + dataStream.Write(bytes, 0, bytes.Length); + dataStream.Flush(); + dataStream.Close(); + } + var webResponse = (HttpWebResponse)webRequest.GetResponse(); + webResponse.Close(); } - } + } protected virtual HttpWebRequest CreateWebRequest(ILogglyAppenderConfig config, string tag) { @@ -55,5 +114,5 @@ protected virtual HttpWebRequest CreateWebRequest(ILogglyAppenderConfig config, request.ContentType = "application/json"; return request; } - } + } } diff --git a/source/log4net-loggly/LogglyFormatter.cs b/source/log4net-loggly/LogglyFormatter.cs index bbc76ab..fd4986f 100644 --- a/source/log4net-loggly/LogglyFormatter.cs +++ b/source/log4net-loggly/LogglyFormatter.cs @@ -6,6 +6,7 @@ using Newtonsoft.Json; using System.Dynamic; using Newtonsoft.Json.Linq; +using System.Text; namespace log4net.loggly { @@ -13,6 +14,7 @@ public class LogglyFormatter : ILogglyFormatter { private Process _currentProcess; private ILogglyAppenderConfig _config; + public int EVENT_SIZE = 1000 * 1000; public LogglyFormatter() { @@ -219,6 +221,7 @@ private string GetMessageAndObjectInfo(LoggingEvent loggingEvent, out object obj { string message = string.Empty; objInfo = null; + int bytesLengthAllowdToLoggly = EVENT_SIZE; if (loggingEvent.MessageObject != null) { @@ -228,6 +231,11 @@ private string GetMessageAndObjectInfo(LoggingEvent loggingEvent, out object obj || loggingEvent.MessageObject.GetType().FullName.Contains("StringFormatFormattedMessage")) { message = loggingEvent.MessageObject.ToString(); + int messageSizeInBytes = Encoding.Default.GetByteCount(message); + if (messageSizeInBytes > bytesLengthAllowdToLoggly) + { + message = message.Substring(0, bytesLengthAllowdToLoggly); + } } else { diff --git a/source/log4net-loggly/LogglySendBufferedLogs.cs b/source/log4net-loggly/LogglySendBufferedLogs.cs new file mode 100644 index 0000000..9cfc008 --- /dev/null +++ b/source/log4net-loggly/LogglySendBufferedLogs.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; + +namespace log4net.loggly +{ + public class LogglySendBufferedLogs + { + public static string message; + public static List arrayMessage = new List(); + public static ILogglyClient Client = new LogglyClient(); + + public static void sendBufferedLogsToLoggly(ILogglyAppenderConfig config, bool isBulk) + { + if (LogglyStoreLogsInBuffer.arrBufferedMessage.Count > 0) + { + + int bulkModeBunch = 100; + int inputModeBunch = 1; + int logInBunch = isBulk ? bulkModeBunch : inputModeBunch; + arrayMessage = LogglyStoreLogsInBuffer.arrBufferedMessage.Take(logInBunch).ToList(); + message = isBulk ? String.Join(System.Environment.NewLine, arrayMessage) : arrayMessage[0]; + try + { + Client.Send(config, message, isBulk); + var tempList = LogglyStoreLogsInBuffer.arrBufferedMessage; + if (LogglyStoreLogsInBuffer.arrBufferedMessage.Count < arrayMessage.Count) + { + LogglyStoreLogsInBuffer.arrBufferedMessage.Clear(); + } + else + { + tempList.RemoveRange(0, arrayMessage.Count); + } + LogglyStoreLogsInBuffer.arrBufferedMessage = tempList; + } + catch (WebException e) + { + var response = (HttpWebResponse)e.Response; + if (response != null && response.StatusCode == HttpStatusCode.Forbidden) + { + LogglyClient.setValidInvalidFlag(false); + Console.WriteLine("Loggly error: {0}", e.Message); + return; + } + } + } + } + + } +} + diff --git a/source/log4net-loggly/LogglyStoreLogsInBuffer.cs b/source/log4net-loggly/LogglyStoreLogsInBuffer.cs new file mode 100644 index 0000000..157482f --- /dev/null +++ b/source/log4net-loggly/LogglyStoreLogsInBuffer.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace log4net.loggly +{ + class LogglyStoreLogsInBuffer + { + public static int bufferSize = 500; + public static List arrBufferedMessage = new List(); + public static List tempList = new List(); + + public static void storeBulkLogs(ILogglyAppenderConfig config, List logs, bool isBulk) + { + if (logs.Count == 0) return; + int numberOfLogsToBeRemoved = (arrBufferedMessage.Count + logs.Count) - bufferSize; + if (numberOfLogsToBeRemoved > 0) arrBufferedMessage.RemoveRange(0, numberOfLogsToBeRemoved); + + arrBufferedMessage = logs.Concat(arrBufferedMessage).ToList(); + } + + public static void storeInputLogs(ILogglyAppenderConfig config, string message, bool isBulk) + { + if (message == String.Empty) return; + int numberOfLogsToBeRemoved = (arrBufferedMessage.Count + 1) - bufferSize; + if (numberOfLogsToBeRemoved > 0) arrBufferedMessage.RemoveRange(0, numberOfLogsToBeRemoved); + arrBufferedMessage.Add(message); + } + } +} diff --git a/source/log4net-loggly/log4net-loggly.csproj b/source/log4net-loggly/log4net-loggly.csproj index d38cbc4..7291aa3 100644 --- a/source/log4net-loggly/log4net-loggly.csproj +++ b/source/log4net-loggly/log4net-loggly.csproj @@ -50,6 +50,7 @@ + @@ -58,7 +59,9 @@ + + From 2bc79d508ee352fc3c7ce473a189ba40ed88ccb6 Mon Sep 17 00:00:00 2001 From: shweta Date: Tue, 24 Jan 2017 18:00:25 +0530 Subject: [PATCH 2/4] make buffer option configurable --- source/log4net-loggly/ILogglyAppenderConfig.cs | 1 + source/log4net-loggly/LogglyAppender.cs | 1 + source/log4net-loggly/LogglyAppenderConfig.cs | 2 ++ source/log4net-loggly/LogglyBufferringAppender.cs | 1 + source/log4net-loggly/LogglyStoreLogsInBuffer.cs | 7 +++---- source/log4net-loggly/log4net-loggly.csproj | 1 - 6 files changed, 8 insertions(+), 5 deletions(-) diff --git a/source/log4net-loggly/ILogglyAppenderConfig.cs b/source/log4net-loggly/ILogglyAppenderConfig.cs index 4317c58..56155c8 100644 --- a/source/log4net-loggly/ILogglyAppenderConfig.cs +++ b/source/log4net-loggly/ILogglyAppenderConfig.cs @@ -10,5 +10,6 @@ public interface ILogglyAppenderConfig string Tag { get; set; } string LogicalThreadContextKeys { get; set; } string GlobalContextKeys { get; set; } + int BufferSize { get; set; } } } \ No newline at end of file diff --git a/source/log4net-loggly/LogglyAppender.cs b/source/log4net-loggly/LogglyAppender.cs index 44d8c89..ad12ee8 100644 --- a/source/log4net-loggly/LogglyAppender.cs +++ b/source/log4net-loggly/LogglyAppender.cs @@ -24,6 +24,7 @@ public class LogglyAppender : AppenderSkeleton public string Tag { set { Config.Tag = value; } } public string LogicalThreadContextKeys { set { Config.LogicalThreadContextKeys = value; } } public string GlobalContextKeys { set { Config.GlobalContextKeys = value; } } + public int BufferSize { set { Config.BufferSize = value; } } private LogglyAsyncHandler LogglyAsync; diff --git a/source/log4net-loggly/LogglyAppenderConfig.cs b/source/log4net-loggly/LogglyAppenderConfig.cs index 8ff01e4..70cde4a 100644 --- a/source/log4net-loggly/LogglyAppenderConfig.cs +++ b/source/log4net-loggly/LogglyAppenderConfig.cs @@ -43,6 +43,7 @@ public string LogMode public string GlobalContextKeys { get; set; } + public int BufferSize { get; set; } public LogglyAppenderConfig() { UserAgent = "loggly-log4net-appender"; @@ -51,6 +52,7 @@ public LogglyAppenderConfig() LogMode = "bulk"; LogicalThreadContextKeys = null; GlobalContextKeys = null; + BufferSize = 500; } } } \ No newline at end of file diff --git a/source/log4net-loggly/LogglyBufferringAppender.cs b/source/log4net-loggly/LogglyBufferringAppender.cs index 744868f..6dad2f4 100644 --- a/source/log4net-loggly/LogglyBufferringAppender.cs +++ b/source/log4net-loggly/LogglyBufferringAppender.cs @@ -18,6 +18,7 @@ public class LogglyBufferringAppender : BufferingAppenderSkeleton public string LogMode { set { Config.LogMode = value; } } public int TimeoutInSeconds { set { Config.TimeoutInSeconds = value; } } public string Tag { set { Config.Tag = value; } } + public int BufferSize { set { Config.BufferSize = value; } } protected override void Append(LoggingEvent loggingEvent) { diff --git a/source/log4net-loggly/LogglyStoreLogsInBuffer.cs b/source/log4net-loggly/LogglyStoreLogsInBuffer.cs index 157482f..6feebdf 100644 --- a/source/log4net-loggly/LogglyStoreLogsInBuffer.cs +++ b/source/log4net-loggly/LogglyStoreLogsInBuffer.cs @@ -6,14 +6,13 @@ namespace log4net.loggly { class LogglyStoreLogsInBuffer { - public static int bufferSize = 500; public static List arrBufferedMessage = new List(); public static List tempList = new List(); - + public static void storeBulkLogs(ILogglyAppenderConfig config, List logs, bool isBulk) { if (logs.Count == 0) return; - int numberOfLogsToBeRemoved = (arrBufferedMessage.Count + logs.Count) - bufferSize; + int numberOfLogsToBeRemoved = (arrBufferedMessage.Count + logs.Count) - config.BufferSize; if (numberOfLogsToBeRemoved > 0) arrBufferedMessage.RemoveRange(0, numberOfLogsToBeRemoved); arrBufferedMessage = logs.Concat(arrBufferedMessage).ToList(); @@ -22,7 +21,7 @@ public static void storeBulkLogs(ILogglyAppenderConfig config, List logs public static void storeInputLogs(ILogglyAppenderConfig config, string message, bool isBulk) { if (message == String.Empty) return; - int numberOfLogsToBeRemoved = (arrBufferedMessage.Count + 1) - bufferSize; + int numberOfLogsToBeRemoved = (arrBufferedMessage.Count + 1) - config.BufferSize; if (numberOfLogsToBeRemoved > 0) arrBufferedMessage.RemoveRange(0, numberOfLogsToBeRemoved); arrBufferedMessage.Add(message); } diff --git a/source/log4net-loggly/log4net-loggly.csproj b/source/log4net-loggly/log4net-loggly.csproj index 7291aa3..c1c2d0f 100644 --- a/source/log4net-loggly/log4net-loggly.csproj +++ b/source/log4net-loggly/log4net-loggly.csproj @@ -50,7 +50,6 @@ - From ec9c3517e5a06af65c59944e38e2d911b788268c Mon Sep 17 00:00:00 2001 From: shweta Date: Tue, 24 Jan 2017 18:14:09 +0530 Subject: [PATCH 3/4] refactor: convert spaces to tab space --- .../log4net-loggly/ILogglyAppenderConfig.cs | 2 +- source/log4net-loggly/ILogglyClient.cs | 4 +- source/log4net-loggly/ILogglyFormatter.cs | 16 +- source/log4net-loggly/LogglyAppender.cs | 166 +++--- source/log4net-loggly/LogglyAppenderConfig.cs | 4 +- .../LogglyBufferringAppender.cs | 2 +- source/log4net-loggly/LogglyClient.cs | 170 +++--- source/log4net-loggly/LogglyFormatter.cs | 550 +++++++++--------- .../log4net-loggly/LogglySendBufferedLogs.cs | 86 +-- .../log4net-loggly/LogglyStoreLogsInBuffer.cs | 42 +- source/log4net-loggly/log4net-loggly.csproj | 146 ++--- source/log4net-loggly/log4net-loggly.nuspec | 34 +- source/log4net-loggly/packages.config | 4 +- 13 files changed, 613 insertions(+), 613 deletions(-) diff --git a/source/log4net-loggly/ILogglyAppenderConfig.cs b/source/log4net-loggly/ILogglyAppenderConfig.cs index 56155c8..6a63d1e 100644 --- a/source/log4net-loggly/ILogglyAppenderConfig.cs +++ b/source/log4net-loggly/ILogglyAppenderConfig.cs @@ -10,6 +10,6 @@ public interface ILogglyAppenderConfig string Tag { get; set; } string LogicalThreadContextKeys { get; set; } string GlobalContextKeys { get; set; } - int BufferSize { get; set; } + int BufferSize { get; set; } } } \ No newline at end of file diff --git a/source/log4net-loggly/ILogglyClient.cs b/source/log4net-loggly/ILogglyClient.cs index e82bf69..7ebc8bd 100644 --- a/source/log4net-loggly/ILogglyClient.cs +++ b/source/log4net-loggly/ILogglyClient.cs @@ -2,7 +2,7 @@ namespace log4net.loggly { public interface ILogglyClient { - void Send(ILogglyAppenderConfig config, string message); - void Send(ILogglyAppenderConfig config, string message, bool isBulk); + void Send(ILogglyAppenderConfig config, string message); + void Send(ILogglyAppenderConfig config, string message, bool isBulk); } } \ No newline at end of file diff --git a/source/log4net-loggly/ILogglyFormatter.cs b/source/log4net-loggly/ILogglyFormatter.cs index 1e535d1..83f99f3 100644 --- a/source/log4net-loggly/ILogglyFormatter.cs +++ b/source/log4net-loggly/ILogglyFormatter.cs @@ -10,13 +10,13 @@ public interface ILogglyFormatter string ToJson(LoggingEvent loggingEvent); string ToJson(IEnumerable loggingEvents); - /// - /// Merged Layout formatted log with the formatted timestamp - /// - /// - /// - /// - string ToJson(string renderedLog, DateTime timeStamp); - + /// + /// Merged Layout formatted log with the formatted timestamp + /// + /// + /// + /// + string ToJson(string renderedLog, DateTime timeStamp); + } } \ No newline at end of file diff --git a/source/log4net-loggly/LogglyAppender.cs b/source/log4net-loggly/LogglyAppender.cs index ad12ee8..c7fcd32 100644 --- a/source/log4net-loggly/LogglyAppender.cs +++ b/source/log4net-loggly/LogglyAppender.cs @@ -8,97 +8,97 @@ namespace log4net.loggly { - public class LogglyAppender : AppenderSkeleton - { - List lstLogs = new List(); - string[] arr = new string[100]; - public static readonly string InputKeyProperty = "LogglyInputKey"; - public static ILogglyFormatter Formatter = new LogglyFormatter(); - public static ILogglyClient Client = new LogglyClient(); - 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 string LogMode { set { Config.LogMode = value; } } - public int TimeoutInSeconds { set { Config.TimeoutInSeconds = value; } } - public string Tag { set { Config.Tag = value; } } - public string LogicalThreadContextKeys { set { Config.LogicalThreadContextKeys = value; } } - public string GlobalContextKeys { set { Config.GlobalContextKeys = value; } } - public int BufferSize { set { Config.BufferSize = value; } } + public class LogglyAppender : AppenderSkeleton + { + List lstLogs = new List(); + string[] arr = new string[100]; + public static readonly string InputKeyProperty = "LogglyInputKey"; + public static ILogglyFormatter Formatter = new LogglyFormatter(); + public static ILogglyClient Client = new LogglyClient(); + 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 string LogMode { set { Config.LogMode = value; } } + public int TimeoutInSeconds { set { Config.TimeoutInSeconds = value; } } + public string Tag { set { Config.Tag = value; } } + public string LogicalThreadContextKeys { set { Config.LogicalThreadContextKeys = value; } } + public string GlobalContextKeys { set { Config.GlobalContextKeys = value; } } + public int BufferSize { set { Config.BufferSize = value; } } - private LogglyAsyncHandler LogglyAsync; + private LogglyAsyncHandler LogglyAsync; - public LogglyAppender() - { - LogglyAsync = new LogglyAsyncHandler(); - Timer.Timer t = new Timer.Timer(); - t.Interval = 5000; - t.Enabled = true; - t.Elapsed += t_Elapsed; - } + public LogglyAppender() + { + LogglyAsync = new LogglyAsyncHandler(); + Timer.Timer t = new Timer.Timer(); + t.Interval = 5000; + t.Enabled = true; + t.Elapsed += t_Elapsed; + } - void t_Elapsed(object sender, Timer.ElapsedEventArgs e) - { - if (lstLogs.Count != 0) - { - SendAllEvents(lstLogs.ToArray()); - } - LogglySendBufferedLogs.sendBufferedLogsToLoggly(Config, Config.LogMode == "bulk/"); - } + void t_Elapsed(object sender, Timer.ElapsedEventArgs e) + { + if (lstLogs.Count != 0) + { + SendAllEvents(lstLogs.ToArray()); + } + LogglySendBufferedLogs.sendBufferedLogsToLoggly(Config, Config.LogMode == "bulk/"); + } - protected override void Append(LoggingEvent loggingEvent) - { - SendLogAction(loggingEvent); - } + protected override void Append(LoggingEvent loggingEvent) + { + SendLogAction(loggingEvent); + } - private void SendLogAction(LoggingEvent 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. + private void SendLogAction(LoggingEvent 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. - //initializing a string for the formatted log - string _formattedLog = string.Empty; + //initializing a string for the formatted log + string _formattedLog = string.Empty; - //if Layout is null then format the log from the Loggly Client - if (this.Layout == null) - { - Formatter.AppendAdditionalLoggingInformation(Config, loggingEvent); - _formattedLog = Formatter.ToJson(loggingEvent); - } - else - { - _formattedLog = Formatter.ToJson(RenderLoggingEvent(loggingEvent), loggingEvent.TimeStamp); - } + //if Layout is null then format the log from the Loggly Client + if (this.Layout == null) + { + Formatter.AppendAdditionalLoggingInformation(Config, loggingEvent); + _formattedLog = Formatter.ToJson(loggingEvent); + } + else + { + _formattedLog = Formatter.ToJson(RenderLoggingEvent(loggingEvent), loggingEvent.TimeStamp); + } - //check if logMode is bulk or inputs - if (Config.LogMode == "bulk/") - { - addToBulk(_formattedLog); - } - else if (Config.LogMode == "inputs/") - { - //sending _formattedLog to the async queue - LogglyAsync.PostMessage(_formattedLog, Config); - } - } + //check if logMode is bulk or inputs + if (Config.LogMode == "bulk/") + { + addToBulk(_formattedLog); + } + else if (Config.LogMode == "inputs/") + { + //sending _formattedLog to the async queue + LogglyAsync.PostMessage(_formattedLog, Config); + } + } - public void addToBulk(string log) - { - // store all events into a array max lenght is 100 - lstLogs.Add(log.Replace("\n", "")); - if (lstLogs.Count == 100) - { - SendAllEvents(lstLogs.ToArray()); - } - } + public void addToBulk(string log) + { + // store all events into a array max lenght is 100 + lstLogs.Add(log.Replace("\n", "")); + if (lstLogs.Count == 100) + { + SendAllEvents(lstLogs.ToArray()); + } + } - private void SendAllEvents(string[] events) - { - lstLogs.Clear(); - String bulkLog = String.Join(System.Environment.NewLine, events); - LogglyAsync.PostMessage(bulkLog, Config); - } + private void SendAllEvents(string[] events) + { + lstLogs.Clear(); + String bulkLog = String.Join(System.Environment.NewLine, events); + LogglyAsync.PostMessage(bulkLog, Config); + } - } - } \ No newline at end of file + } + } \ No newline at end of file diff --git a/source/log4net-loggly/LogglyAppenderConfig.cs b/source/log4net-loggly/LogglyAppenderConfig.cs index 70cde4a..3d2b316 100644 --- a/source/log4net-loggly/LogglyAppenderConfig.cs +++ b/source/log4net-loggly/LogglyAppenderConfig.cs @@ -43,7 +43,7 @@ public string LogMode public string GlobalContextKeys { get; set; } - public int BufferSize { get; set; } + public int BufferSize { get; set; } public LogglyAppenderConfig() { UserAgent = "loggly-log4net-appender"; @@ -52,7 +52,7 @@ public LogglyAppenderConfig() LogMode = "bulk"; LogicalThreadContextKeys = null; GlobalContextKeys = null; - BufferSize = 500; + BufferSize = 500; } } } \ No newline at end of file diff --git a/source/log4net-loggly/LogglyBufferringAppender.cs b/source/log4net-loggly/LogglyBufferringAppender.cs index 6dad2f4..0edf281 100644 --- a/source/log4net-loggly/LogglyBufferringAppender.cs +++ b/source/log4net-loggly/LogglyBufferringAppender.cs @@ -18,7 +18,7 @@ public class LogglyBufferringAppender : BufferingAppenderSkeleton public string LogMode { set { Config.LogMode = value; } } public int TimeoutInSeconds { set { Config.TimeoutInSeconds = value; } } public string Tag { set { Config.Tag = value; } } - public int BufferSize { set { Config.BufferSize = value; } } + public int BufferSize { set { Config.BufferSize = value; } } protected override void Append(LoggingEvent loggingEvent) { diff --git a/source/log4net-loggly/LogglyClient.cs b/source/log4net-loggly/LogglyClient.cs index ff0c54d..c1a4c52 100644 --- a/source/log4net-loggly/LogglyClient.cs +++ b/source/log4net-loggly/LogglyClient.cs @@ -8,104 +8,104 @@ namespace log4net.loggly { public class LogglyClient : ILogglyClient { - static bool isValidToken = true; - public static void setValidInvalidFlag(bool flag) - { - isValidToken = flag; - } + static bool isValidToken = true; + public static void setValidInvalidFlag(bool flag) + { + isValidToken = flag; + } - public virtual void Send(ILogglyAppenderConfig config, string message) - { - int maxRetryAllowed = 5; - int totalRetries = 0; + public virtual void Send(ILogglyAppenderConfig config, string message) + { + int maxRetryAllowed = 5; + int totalRetries = 0; - string _tag = config.Tag; - bool isBulk = config.LogMode.Contains("bulk"); + string _tag = config.Tag; + bool isBulk = config.LogMode.Contains("bulk"); - List messageBulk = new List(); - //keeping userAgent backward compatible - if (!string.IsNullOrWhiteSpace(config.UserAgent)) - { - _tag = _tag + "," + config.UserAgent; - } + List messageBulk = new List(); + //keeping userAgent backward compatible + if (!string.IsNullOrWhiteSpace(config.UserAgent)) + { + _tag = _tag + "," + config.UserAgent; + } - while (isValidToken && totalRetries < maxRetryAllowed) - { - totalRetries++; - try - { - var bytes = Encoding.UTF8.GetBytes(message); - var webRequest = CreateWebRequest(config, _tag); - - using (var dataStream = webRequest.GetRequestStream()) - { - dataStream.Write(bytes, 0, bytes.Length); - dataStream.Flush(); - dataStream.Close(); - } + while (isValidToken && totalRetries < maxRetryAllowed) + { + totalRetries++; + try + { + var bytes = Encoding.UTF8.GetBytes(message); + var webRequest = CreateWebRequest(config, _tag); + + using (var dataStream = webRequest.GetRequestStream()) + { + dataStream.Write(bytes, 0, bytes.Length); + dataStream.Flush(); + dataStream.Close(); + } - var webResponse = webRequest.GetResponse(); - webResponse.Close(); - break; - } + var webResponse = webRequest.GetResponse(); + webResponse.Close(); + break; + } - catch (WebException e) { - var response = (HttpWebResponse)e.Response; - if (response != null) - { - if (response.StatusCode == HttpStatusCode.Forbidden) //Check for bad token - { - setValidInvalidFlag(false); - } - if (totalRetries == 1) Console.WriteLine("Loggly error: {0}", e.Message); - } + catch (WebException e) { + var response = (HttpWebResponse)e.Response; + if (response != null) + { + if (response.StatusCode == HttpStatusCode.Forbidden) //Check for bad token + { + setValidInvalidFlag(false); + } + if (totalRetries == 1) Console.WriteLine("Loggly error: {0}", e.Message); + } - else if (totalRetries == 1) - { - if (isBulk) - { - messageBulk = message.Split('\n').ToList(); - LogglyStoreLogsInBuffer.storeBulkLogs(config, messageBulk, isBulk); - } - else - { - LogglyStoreLogsInBuffer.storeInputLogs(config, message, isBulk); - } - } - } - } - } + else if (totalRetries == 1) + { + if (isBulk) + { + messageBulk = message.Split('\n').ToList(); + LogglyStoreLogsInBuffer.storeBulkLogs(config, messageBulk, isBulk); + } + else + { + LogglyStoreLogsInBuffer.storeInputLogs(config, message, isBulk); + } + } + } + } + } - public void Send(ILogglyAppenderConfig config, string message, bool isbulk) - { - if (isValidToken) - { - string _tag = config.Tag; + public void Send(ILogglyAppenderConfig config, string message, bool isbulk) + { + if (isValidToken) + { + string _tag = config.Tag; - //keeping userAgent backward compatible - if (!string.IsNullOrWhiteSpace(config.UserAgent)) - { - _tag = _tag + "," + config.UserAgent; - } - var bytes = Encoding.UTF8.GetBytes(message); - var webRequest = CreateWebRequest(config, _tag); + //keeping userAgent backward compatible + if (!string.IsNullOrWhiteSpace(config.UserAgent)) + { + _tag = _tag + "," + config.UserAgent; + } + var bytes = Encoding.UTF8.GetBytes(message); + var webRequest = CreateWebRequest(config, _tag); - using (var dataStream = webRequest.GetRequestStream()) - { - dataStream.Write(bytes, 0, bytes.Length); - dataStream.Flush(); - dataStream.Close(); - } - var webResponse = (HttpWebResponse)webRequest.GetResponse(); - webResponse.Close(); - } - } + using (var dataStream = webRequest.GetRequestStream()) + { + dataStream.Write(bytes, 0, bytes.Length); + dataStream.Flush(); + dataStream.Close(); + } + var webResponse = (HttpWebResponse)webRequest.GetResponse(); + webResponse.Close(); + } + } protected virtual HttpWebRequest CreateWebRequest(ILogglyAppenderConfig config, string tag) { var url = String.Concat(config.RootUrl, config.LogMode, config.InputKey); - //adding userAgent as tag in the log - url = String.Concat(url, "/tag/" + tag); + //adding userAgent as tag in the log + url = String.Concat(url, "/tag/" + tag); var request = (HttpWebRequest)WebRequest.Create(url); request.Method = "POST"; request.ReadWriteTimeout = request.Timeout = config.TimeoutInSeconds * 1000; @@ -114,5 +114,5 @@ protected virtual HttpWebRequest CreateWebRequest(ILogglyAppenderConfig config, request.ContentType = "application/json"; return request; } - } + } } diff --git a/source/log4net-loggly/LogglyFormatter.cs b/source/log4net-loggly/LogglyFormatter.cs index fd4986f..a67b48b 100644 --- a/source/log4net-loggly/LogglyFormatter.cs +++ b/source/log4net-loggly/LogglyFormatter.cs @@ -10,303 +10,303 @@ namespace log4net.loggly { - public class LogglyFormatter : ILogglyFormatter - { - private Process _currentProcess; - private ILogglyAppenderConfig _config; - public int EVENT_SIZE = 1000 * 1000; + public class LogglyFormatter : ILogglyFormatter + { + private Process _currentProcess; + private ILogglyAppenderConfig _config; + public int EVENT_SIZE = 1000 * 1000; - public LogglyFormatter() - { - _currentProcess = Process.GetCurrentProcess(); - } + public LogglyFormatter() + { + _currentProcess = Process.GetCurrentProcess(); + } - public virtual void AppendAdditionalLoggingInformation(ILogglyAppenderConfig config, LoggingEvent loggingEvent) - { - this._config = config; - } + public virtual void AppendAdditionalLoggingInformation(ILogglyAppenderConfig config, LoggingEvent loggingEvent) + { + this._config = config; + } - public virtual string ToJson(LoggingEvent loggingEvent) - { - return PreParse(loggingEvent); - } + public virtual string ToJson(LoggingEvent loggingEvent) + { + return PreParse(loggingEvent); + } - public virtual string ToJson(IEnumerable loggingEvents) - { - return JsonConvert.SerializeObject(loggingEvents.Select(PreParse),new JsonSerializerSettings(){ - ReferenceLoopHandling = ReferenceLoopHandling.Ignore - }); - } + public virtual string ToJson(IEnumerable loggingEvents) + { + return JsonConvert.SerializeObject(loggingEvents.Select(PreParse),new JsonSerializerSettings(){ + ReferenceLoopHandling = ReferenceLoopHandling.Ignore + }); + } - public virtual string ToJson(string renderedLog, DateTime timeStamp) - { - return ParseRenderedLog(renderedLog, timeStamp); - } + public virtual string ToJson(string renderedLog, DateTime timeStamp) + { + return ParseRenderedLog(renderedLog, timeStamp); + } - /// - /// Formats the log event to various JSON fields that are to be shown in Loggly. - /// - /// - /// - private string PreParse(LoggingEvent loggingEvent) - { - //formating base logging info - dynamic _loggingInfo = new ExpandoObject(); - _loggingInfo.timestamp = loggingEvent.TimeStamp.ToString(@"yyyy-MM-ddTHH\:mm\:ss.fffzzz"); - _loggingInfo.level = loggingEvent.Level.DisplayName; - _loggingInfo.hostName = Environment.MachineName; - _loggingInfo.process = _currentProcess.ProcessName; - _loggingInfo.threadName = loggingEvent.ThreadName; - _loggingInfo.loggerName = loggingEvent.LoggerName; + /// + /// Formats the log event to various JSON fields that are to be shown in Loggly. + /// + /// + /// + private string PreParse(LoggingEvent loggingEvent) + { + //formating base logging info + dynamic _loggingInfo = new ExpandoObject(); + _loggingInfo.timestamp = loggingEvent.TimeStamp.ToString(@"yyyy-MM-ddTHH\:mm\:ss.fffzzz"); + _loggingInfo.level = loggingEvent.Level.DisplayName; + _loggingInfo.hostName = Environment.MachineName; + _loggingInfo.process = _currentProcess.ProcessName; + _loggingInfo.threadName = loggingEvent.ThreadName; + _loggingInfo.loggerName = loggingEvent.LoggerName; - //handling messages - object _loggedObject = null; - string _message = GetMessageAndObjectInfo(loggingEvent, out _loggedObject); + //handling messages + object _loggedObject = null; + string _message = GetMessageAndObjectInfo(loggingEvent, out _loggedObject); - if (_message != string.Empty) - { - _loggingInfo.message = _message; - } + if (_message != string.Empty) + { + _loggingInfo.message = _message; + } - //handling exceptions - dynamic _exceptionInfo = GetExceptionInfo(loggingEvent); - if (_exceptionInfo != null) - { - _loggingInfo.exception = _exceptionInfo; - } + //handling exceptions + dynamic _exceptionInfo = GetExceptionInfo(loggingEvent); + if (_exceptionInfo != null) + { + _loggingInfo.exception = _exceptionInfo; + } - //handling threadcontext properties - string[] _threadContextProperties = ThreadContext.Properties.GetKeys(); - if (_threadContextProperties != null && _threadContextProperties.Any()) - { - var p = _loggingInfo as IDictionary; - foreach (string key in _threadContextProperties) - { - if ((ThreadContext.Properties[key] as IFixingRequired) != null - && (ThreadContext.Properties[key] as IFixingRequired).GetFixedObject() != null) - { - p[key] = (ThreadContext.Properties[key] as IFixingRequired).GetFixedObject(); - } - else - { - p[key] = ThreadContext.Properties[key].ToString(); - } - } - } + //handling threadcontext properties + string[] _threadContextProperties = ThreadContext.Properties.GetKeys(); + if (_threadContextProperties != null && _threadContextProperties.Any()) + { + var p = _loggingInfo as IDictionary; + foreach (string key in _threadContextProperties) + { + if ((ThreadContext.Properties[key] as IFixingRequired) != null + && (ThreadContext.Properties[key] as IFixingRequired).GetFixedObject() != null) + { + p[key] = (ThreadContext.Properties[key] as IFixingRequired).GetFixedObject(); + } + else + { + p[key] = ThreadContext.Properties[key].ToString(); + } + } + } - //handling logicalthreadcontext properties - if (this._config.LogicalThreadContextKeys != null) - { - var ltp = _loggingInfo as IDictionary; - string[] _LogicalThreadContextProperties = this._config.LogicalThreadContextKeys.Split(','); - foreach (string key in _LogicalThreadContextProperties) - { - if (LogicalThreadContext.Properties[key] != null) - { - if ((LogicalThreadContext.Properties[key] as IFixingRequired) != null - && (LogicalThreadContext.Properties[key] as IFixingRequired).GetFixedObject() != null) - { - ltp[key] = (LogicalThreadContext.Properties[key] as IFixingRequired).GetFixedObject(); - } - else - { - ltp[key] = LogicalThreadContext.Properties[key].ToString(); - } - } - } - } + //handling logicalthreadcontext properties + if (this._config.LogicalThreadContextKeys != null) + { + var ltp = _loggingInfo as IDictionary; + string[] _LogicalThreadContextProperties = this._config.LogicalThreadContextKeys.Split(','); + foreach (string key in _LogicalThreadContextProperties) + { + if (LogicalThreadContext.Properties[key] != null) + { + if ((LogicalThreadContext.Properties[key] as IFixingRequired) != null + && (LogicalThreadContext.Properties[key] as IFixingRequired).GetFixedObject() != null) + { + ltp[key] = (LogicalThreadContext.Properties[key] as IFixingRequired).GetFixedObject(); + } + else + { + ltp[key] = LogicalThreadContext.Properties[key].ToString(); + } + } + } + } - //handling globalcontext properties - if (this._config.GlobalContextKeys != null) - { - var gcp = _loggingInfo as IDictionary; - string[] _globalContextProperties = this._config.GlobalContextKeys.Split(','); - foreach (string key in _globalContextProperties) - { - if (GlobalContext.Properties[key] != null) - { - if ((GlobalContext.Properties[key] as IFixingRequired) != null - && (GlobalContext.Properties[key] as IFixingRequired).GetFixedObject() != null) - { - gcp[key] = (GlobalContext.Properties[key] as IFixingRequired).GetFixedObject(); - } - else - { - gcp[key] = GlobalContext.Properties[key].ToString(); - } - } - } - } + //handling globalcontext properties + if (this._config.GlobalContextKeys != null) + { + var gcp = _loggingInfo as IDictionary; + string[] _globalContextProperties = this._config.GlobalContextKeys.Split(','); + foreach (string key in _globalContextProperties) + { + if (GlobalContext.Properties[key] != null) + { + if ((GlobalContext.Properties[key] as IFixingRequired) != null + && (GlobalContext.Properties[key] as IFixingRequired).GetFixedObject() != null) + { + gcp[key] = (GlobalContext.Properties[key] as IFixingRequired).GetFixedObject(); + } + else + { + gcp[key] = GlobalContext.Properties[key].ToString(); + } + } + } + } - string jsonMessage = string.Empty; - if (TryGetParsedJsonFromLog(_loggingInfo, _loggedObject, out jsonMessage)) - { - return jsonMessage; - } - else - { - //converting event info to Json string - return JsonConvert.SerializeObject(_loggingInfo, - new JsonSerializerSettings() - { - ReferenceLoopHandling = ReferenceLoopHandling.Ignore, - }); - } - } + string jsonMessage = string.Empty; + if (TryGetParsedJsonFromLog(_loggingInfo, _loggedObject, out jsonMessage)) + { + return jsonMessage; + } + else + { + //converting event info to Json string + return JsonConvert.SerializeObject(_loggingInfo, + new JsonSerializerSettings() + { + ReferenceLoopHandling = ReferenceLoopHandling.Ignore, + }); + } + } - /// - /// Merged Rendered log and formatted timestamp in the single Json object - /// - /// - /// - /// - private string ParseRenderedLog(string log, DateTime timeStamp) - { - dynamic _loggingInfo = new ExpandoObject(); - _loggingInfo.timestamp = timeStamp.ToString(@"yyyy-MM-ddTHH\:mm\:ss.fffzzz"); + /// + /// Merged Rendered log and formatted timestamp in the single Json object + /// + /// + /// + /// + private string ParseRenderedLog(string log, DateTime timeStamp) + { + dynamic _loggingInfo = new ExpandoObject(); + _loggingInfo.timestamp = timeStamp.ToString(@"yyyy-MM-ddTHH\:mm\:ss.fffzzz"); - string jsonMessage = string.Empty; - if (TryGetParsedJsonFromLog(_loggingInfo, log, out jsonMessage)) - { - return jsonMessage; - } - else - { - _loggingInfo.message = log; - return JsonConvert.SerializeObject(_loggingInfo, - new JsonSerializerSettings() - { - PreserveReferencesHandling = PreserveReferencesHandling.Arrays, - ReferenceLoopHandling = ReferenceLoopHandling.Ignore, - }); - } - } + string jsonMessage = string.Empty; + if (TryGetParsedJsonFromLog(_loggingInfo, log, out jsonMessage)) + { + return jsonMessage; + } + else + { + _loggingInfo.message = log; + return JsonConvert.SerializeObject(_loggingInfo, + new JsonSerializerSettings() + { + PreserveReferencesHandling = PreserveReferencesHandling.Arrays, + ReferenceLoopHandling = ReferenceLoopHandling.Ignore, + }); + } + } - /// - /// Returns the exception information. Also takes care of the InnerException. - /// - /// - /// - private object GetExceptionInfo(LoggingEvent loggingEvent) - { - if (loggingEvent.ExceptionObject == null) - return null; + /// + /// Returns the exception information. Also takes care of the InnerException. + /// + /// + /// + private object GetExceptionInfo(LoggingEvent loggingEvent) + { + if (loggingEvent.ExceptionObject == null) + return null; - dynamic exceptionInfo = new ExpandoObject(); - exceptionInfo.exceptionType = loggingEvent.ExceptionObject.GetType().FullName; - exceptionInfo.exceptionMessage = loggingEvent.ExceptionObject.Message; - exceptionInfo.stacktrace = loggingEvent.ExceptionObject.StackTrace; + dynamic exceptionInfo = new ExpandoObject(); + exceptionInfo.exceptionType = loggingEvent.ExceptionObject.GetType().FullName; + exceptionInfo.exceptionMessage = loggingEvent.ExceptionObject.Message; + exceptionInfo.stacktrace = loggingEvent.ExceptionObject.StackTrace; - //most of the times dotnet exceptions contain important messages in the inner exceptions - if (loggingEvent.ExceptionObject.InnerException != null) - { - dynamic innerException = new - { - innerExceptionType = loggingEvent.ExceptionObject.InnerException.GetType().FullName, - innerExceptionMessage = loggingEvent.ExceptionObject.InnerException.Message, - innerStacktrace = loggingEvent.ExceptionObject.InnerException.StackTrace - }; - exceptionInfo.innerException = innerException; - } - return exceptionInfo; - } + //most of the times dotnet exceptions contain important messages in the inner exceptions + if (loggingEvent.ExceptionObject.InnerException != null) + { + dynamic innerException = new + { + innerExceptionType = loggingEvent.ExceptionObject.InnerException.GetType().FullName, + innerExceptionMessage = loggingEvent.ExceptionObject.InnerException.Message, + innerStacktrace = loggingEvent.ExceptionObject.InnerException.StackTrace + }; + exceptionInfo.innerException = innerException; + } + return exceptionInfo; + } - /// - /// Returns a string type message if it is not a custom object, - /// otherwise returns custom object details - /// - /// - /// - private string GetMessageAndObjectInfo(LoggingEvent loggingEvent, out object objInfo) - { - string message = string.Empty; - objInfo = null; - int bytesLengthAllowdToLoggly = EVENT_SIZE; + /// + /// Returns a string type message if it is not a custom object, + /// otherwise returns custom object details + /// + /// + /// + private string GetMessageAndObjectInfo(LoggingEvent loggingEvent, out object objInfo) + { + string message = string.Empty; + objInfo = null; + int bytesLengthAllowdToLoggly = EVENT_SIZE; - if (loggingEvent.MessageObject != null) - { - if (loggingEvent.MessageObject.GetType() == typeof(string) - //if it is sent by using InfoFormat method then treat it as a string message - || loggingEvent.MessageObject.GetType().FullName == "log4net.Util.SystemStringFormat" - || loggingEvent.MessageObject.GetType().FullName.Contains("StringFormatFormattedMessage")) - { - message = loggingEvent.MessageObject.ToString(); - int messageSizeInBytes = Encoding.Default.GetByteCount(message); - if (messageSizeInBytes > bytesLengthAllowdToLoggly) - { - message = message.Substring(0, bytesLengthAllowdToLoggly); - } - } - else - { - objInfo = loggingEvent.MessageObject; - } - } - else - { - //adding message as null so that the Loggly user - //can know that a null object is logged. - message = "null"; - } - return message; - } + if (loggingEvent.MessageObject != null) + { + if (loggingEvent.MessageObject.GetType() == typeof(string) + //if it is sent by using InfoFormat method then treat it as a string message + || loggingEvent.MessageObject.GetType().FullName == "log4net.Util.SystemStringFormat" + || loggingEvent.MessageObject.GetType().FullName.Contains("StringFormatFormattedMessage")) + { + message = loggingEvent.MessageObject.ToString(); + int messageSizeInBytes = Encoding.Default.GetByteCount(message); + if (messageSizeInBytes > bytesLengthAllowdToLoggly) + { + message = message.Substring(0, bytesLengthAllowdToLoggly); + } + } + else + { + objInfo = loggingEvent.MessageObject; + } + } + else + { + //adding message as null so that the Loggly user + //can know that a null object is logged. + message = "null"; + } + return message; + } - /// - /// Tries to merge log with the logged object or rendered log - /// and converts to JSON - /// - /// - /// - /// - /// - private bool TryGetParsedJsonFromLog(dynamic loggingInfo, object loggingObject, out string _loggingEventJSON) - { - //serialize the dynamic object to string - _loggingEventJSON = JsonConvert.SerializeObject(loggingInfo, - new JsonSerializerSettings() - { - ReferenceLoopHandling = ReferenceLoopHandling.Ignore, - }); - - //if loggingObject is null then we need to go to further step - if (loggingObject == null) - return false; - - try - { - string _loggedObjectJSON = string.Empty; - if (loggingObject.GetType() == typeof(string)) - { - _loggedObjectJSON = loggingObject.ToString(); - } - else - { - _loggedObjectJSON = JsonConvert.SerializeObject(loggingObject, - new JsonSerializerSettings() - { - PreserveReferencesHandling = PreserveReferencesHandling.Arrays, - ReferenceLoopHandling = ReferenceLoopHandling.Ignore, - }); - } + /// + /// Tries to merge log with the logged object or rendered log + /// and converts to JSON + /// + /// + /// + /// + /// + private bool TryGetParsedJsonFromLog(dynamic loggingInfo, object loggingObject, out string _loggingEventJSON) + { + //serialize the dynamic object to string + _loggingEventJSON = JsonConvert.SerializeObject(loggingInfo, + new JsonSerializerSettings() + { + ReferenceLoopHandling = ReferenceLoopHandling.Ignore, + }); + + //if loggingObject is null then we need to go to further step + if (loggingObject == null) + return false; + + try + { + string _loggedObjectJSON = string.Empty; + if (loggingObject.GetType() == typeof(string)) + { + _loggedObjectJSON = loggingObject.ToString(); + } + else + { + _loggedObjectJSON = JsonConvert.SerializeObject(loggingObject, + new JsonSerializerSettings() + { + PreserveReferencesHandling = PreserveReferencesHandling.Arrays, + ReferenceLoopHandling = ReferenceLoopHandling.Ignore, + }); + } - //try to parse the logging object - JObject jObject = JObject.Parse(_loggedObjectJSON); - JObject jEvent = JObject.Parse(_loggingEventJSON); + //try to parse the logging object + JObject jObject = JObject.Parse(_loggedObjectJSON); + JObject jEvent = JObject.Parse(_loggingEventJSON); - //merge these two objects into one JSON string - jEvent.Merge(jObject, new JsonMergeSettings - { - MergeArrayHandling = MergeArrayHandling.Union - }); + //merge these two objects into one JSON string + jEvent.Merge(jObject, new JsonMergeSettings + { + MergeArrayHandling = MergeArrayHandling.Union + }); - _loggingEventJSON = jEvent.ToString(); - - return true; - } - catch - { - return false; - } - } - } + _loggingEventJSON = jEvent.ToString(); + + return true; + } + catch + { + return false; + } + } + } } diff --git a/source/log4net-loggly/LogglySendBufferedLogs.cs b/source/log4net-loggly/LogglySendBufferedLogs.cs index 9cfc008..8b6476e 100644 --- a/source/log4net-loggly/LogglySendBufferedLogs.cs +++ b/source/log4net-loggly/LogglySendBufferedLogs.cs @@ -5,49 +5,49 @@ namespace log4net.loggly { - public class LogglySendBufferedLogs - { - public static string message; - public static List arrayMessage = new List(); - public static ILogglyClient Client = new LogglyClient(); - - public static void sendBufferedLogsToLoggly(ILogglyAppenderConfig config, bool isBulk) - { - if (LogglyStoreLogsInBuffer.arrBufferedMessage.Count > 0) - { - - int bulkModeBunch = 100; - int inputModeBunch = 1; - int logInBunch = isBulk ? bulkModeBunch : inputModeBunch; - arrayMessage = LogglyStoreLogsInBuffer.arrBufferedMessage.Take(logInBunch).ToList(); - message = isBulk ? String.Join(System.Environment.NewLine, arrayMessage) : arrayMessage[0]; - try - { - Client.Send(config, message, isBulk); - var tempList = LogglyStoreLogsInBuffer.arrBufferedMessage; - if (LogglyStoreLogsInBuffer.arrBufferedMessage.Count < arrayMessage.Count) - { - LogglyStoreLogsInBuffer.arrBufferedMessage.Clear(); - } - else - { - tempList.RemoveRange(0, arrayMessage.Count); - } - LogglyStoreLogsInBuffer.arrBufferedMessage = tempList; - } - catch (WebException e) - { - var response = (HttpWebResponse)e.Response; - if (response != null && response.StatusCode == HttpStatusCode.Forbidden) - { - LogglyClient.setValidInvalidFlag(false); - Console.WriteLine("Loggly error: {0}", e.Message); - return; - } - } - } - } + public class LogglySendBufferedLogs + { + public static string message; + public static List arrayMessage = new List(); + public static ILogglyClient Client = new LogglyClient(); + + public static void sendBufferedLogsToLoggly(ILogglyAppenderConfig config, bool isBulk) + { + if (LogglyStoreLogsInBuffer.arrBufferedMessage.Count > 0) + { + + int bulkModeBunch = 100; + int inputModeBunch = 1; + int logInBunch = isBulk ? bulkModeBunch : inputModeBunch; + arrayMessage = LogglyStoreLogsInBuffer.arrBufferedMessage.Take(logInBunch).ToList(); + message = isBulk ? String.Join(System.Environment.NewLine, arrayMessage) : arrayMessage[0]; + try + { + Client.Send(config, message, isBulk); + var tempList = LogglyStoreLogsInBuffer.arrBufferedMessage; + if (LogglyStoreLogsInBuffer.arrBufferedMessage.Count < arrayMessage.Count) + { + LogglyStoreLogsInBuffer.arrBufferedMessage.Clear(); + } + else + { + tempList.RemoveRange(0, arrayMessage.Count); + } + LogglyStoreLogsInBuffer.arrBufferedMessage = tempList; + } + catch (WebException e) + { + var response = (HttpWebResponse)e.Response; + if (response != null && response.StatusCode == HttpStatusCode.Forbidden) + { + LogglyClient.setValidInvalidFlag(false); + Console.WriteLine("Loggly error: {0}", e.Message); + return; + } + } + } + } - } + } } diff --git a/source/log4net-loggly/LogglyStoreLogsInBuffer.cs b/source/log4net-loggly/LogglyStoreLogsInBuffer.cs index 6feebdf..8b63930 100644 --- a/source/log4net-loggly/LogglyStoreLogsInBuffer.cs +++ b/source/log4net-loggly/LogglyStoreLogsInBuffer.cs @@ -4,26 +4,26 @@ namespace log4net.loggly { - class LogglyStoreLogsInBuffer - { - public static List arrBufferedMessage = new List(); - public static List tempList = new List(); - - public static void storeBulkLogs(ILogglyAppenderConfig config, List logs, bool isBulk) - { - if (logs.Count == 0) return; - int numberOfLogsToBeRemoved = (arrBufferedMessage.Count + logs.Count) - config.BufferSize; - if (numberOfLogsToBeRemoved > 0) arrBufferedMessage.RemoveRange(0, numberOfLogsToBeRemoved); - - arrBufferedMessage = logs.Concat(arrBufferedMessage).ToList(); - } + class LogglyStoreLogsInBuffer + { + public static List arrBufferedMessage = new List(); + public static List tempList = new List(); + + public static void storeBulkLogs(ILogglyAppenderConfig config, List logs, bool isBulk) + { + if (logs.Count == 0) return; + int numberOfLogsToBeRemoved = (arrBufferedMessage.Count + logs.Count) - config.BufferSize; + if (numberOfLogsToBeRemoved > 0) arrBufferedMessage.RemoveRange(0, numberOfLogsToBeRemoved); + + arrBufferedMessage = logs.Concat(arrBufferedMessage).ToList(); + } - public static void storeInputLogs(ILogglyAppenderConfig config, string message, bool isBulk) - { - if (message == String.Empty) return; - int numberOfLogsToBeRemoved = (arrBufferedMessage.Count + 1) - config.BufferSize; - if (numberOfLogsToBeRemoved > 0) arrBufferedMessage.RemoveRange(0, numberOfLogsToBeRemoved); - arrBufferedMessage.Add(message); - } - } + public static void storeInputLogs(ILogglyAppenderConfig config, string message, bool isBulk) + { + if (message == String.Empty) return; + int numberOfLogsToBeRemoved = (arrBufferedMessage.Count + 1) - config.BufferSize; + if (numberOfLogsToBeRemoved > 0) arrBufferedMessage.RemoveRange(0, numberOfLogsToBeRemoved); + arrBufferedMessage.Add(message); + } + } } diff --git a/source/log4net-loggly/log4net-loggly.csproj b/source/log4net-loggly/log4net-loggly.csproj index c1c2d0f..8a7dbcf 100644 --- a/source/log4net-loggly/log4net-loggly.csproj +++ b/source/log4net-loggly/log4net-loggly.csproj @@ -1,76 +1,76 @@  - - Debug - AnyCPU - 8.0.30703 - 2.0 - {ABE2B1B6-A83C-4604-AF87-FAAC3976530D} - Library - Properties - log4net.loggly - log4net-loggly - v4.0 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - False - ..\packages\log4net.2.0.3\lib\net40-full\log4net.dll - - - ..\packages\Newtonsoft.Json.8.0.1\lib\net40\Newtonsoft.Json.dll - True - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + Debug + AnyCPU + 8.0.30703 + 2.0 + {ABE2B1B6-A83C-4604-AF87-FAAC3976530D} + Library + Properties + log4net.loggly + log4net-loggly + v4.0 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + ..\packages\log4net.2.0.3\lib\net40-full\log4net.dll + + + ..\packages\Newtonsoft.Json.8.0.1\lib\net40\Newtonsoft.Json.dll + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/source/log4net-loggly/log4net-loggly.nuspec b/source/log4net-loggly/log4net-loggly.nuspec index 3819367..753bfbb 100644 --- a/source/log4net-loggly/log4net-loggly.nuspec +++ b/source/log4net-loggly/log4net-loggly.nuspec @@ -1,20 +1,20 @@ - - log4net-loggly - 7.2.3 - Loggly - Loggly - http://opensource.org/licenses/MIT - http://github.com/loggly/log4net-loggly - false - Custom log4Net Appender to send logs to Loggly - Decrease wait time interval for bulk mode. - Copyright 2016 - Loggly-log4net log4net appender logs - - - - - + + log4net-loggly + 7.2.3 + Loggly + Loggly + http://opensource.org/licenses/MIT + http://github.com/loggly/log4net-loggly + false + Custom log4Net Appender to send logs to Loggly + Decrease wait time interval for bulk mode. + Copyright 2016 + Loggly-log4net log4net appender logs + + + + + \ No newline at end of file diff --git a/source/log4net-loggly/packages.config b/source/log4net-loggly/packages.config index 65f8cb4..cb0f1f4 100644 --- a/source/log4net-loggly/packages.config +++ b/source/log4net-loggly/packages.config @@ -1,5 +1,5 @@  - - + + \ No newline at end of file From a4b203ffd0b9cc1890dd934f782a683d7f560b69 Mon Sep 17 00:00:00 2001 From: shweta Date: Wed, 25 Jan 2017 16:46:03 +0530 Subject: [PATCH 4/4] method name correction and exception logic modification --- source/log4net-loggly/LogglyClient.cs | 61 +++++++++++++------ .../log4net-loggly/LogglySendBufferedLogs.cs | 2 +- 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/source/log4net-loggly/LogglyClient.cs b/source/log4net-loggly/LogglyClient.cs index c1a4c52..052447d 100644 --- a/source/log4net-loggly/LogglyClient.cs +++ b/source/log4net-loggly/LogglyClient.cs @@ -9,9 +9,29 @@ namespace log4net.loggly public class LogglyClient : ILogglyClient { static bool isValidToken = true; - public static void setValidInvalidFlag(bool flag) + + public static void setTokenValid(bool flag) + { + isValidToken = flag; + } + + void storeLogs(string message, ILogglyAppenderConfig config, bool isBulk) + { + List messageBulk = new List(); + if (isBulk) + { + messageBulk = message.Split('\n').ToList(); + LogglyStoreLogsInBuffer.storeBulkLogs(config, messageBulk, isBulk); + } + else + { + LogglyStoreLogsInBuffer.storeInputLogs(config, message, isBulk); + } + } + + void printErrorMessage(string message) { - isValidToken = flag; + Console.WriteLine("Loggly error: {0}", message); } public virtual void Send(ILogglyAppenderConfig config, string message) @@ -22,7 +42,6 @@ public virtual void Send(ILogglyAppenderConfig config, string message) string _tag = config.Tag; bool isBulk = config.LogMode.Contains("bulk"); - List messageBulk = new List(); //keeping userAgent backward compatible if (!string.IsNullOrWhiteSpace(config.UserAgent)) { @@ -43,33 +62,35 @@ public virtual void Send(ILogglyAppenderConfig config, string message) dataStream.Flush(); dataStream.Close(); } - var webResponse = webRequest.GetResponse(); webResponse.Close(); break; } - catch (WebException e) { - var response = (HttpWebResponse)e.Response; - if (response != null) - { - if (response.StatusCode == HttpStatusCode.Forbidden) //Check for bad token - { - setValidInvalidFlag(false); - } - if (totalRetries == 1) Console.WriteLine("Loggly error: {0}", e.Message); - } - - else if (totalRetries == 1) + catch (WebException e) + { + if (totalRetries == 1) { - if (isBulk) + var response = (HttpWebResponse)e.Response; + if (response != null) { - messageBulk = message.Split('\n').ToList(); - LogglyStoreLogsInBuffer.storeBulkLogs(config, messageBulk, isBulk); + // Check for bad token + if (response.StatusCode == HttpStatusCode.Forbidden) + { + // set valid token flag to false + setTokenValid(false); + } + else + { + // store logs to buffer + storeLogs(message, config, isBulk); + } + printErrorMessage(e.Message); } else { - LogglyStoreLogsInBuffer.storeInputLogs(config, message, isBulk); + // store logs to buffer + storeLogs(message, config, isBulk); } } } diff --git a/source/log4net-loggly/LogglySendBufferedLogs.cs b/source/log4net-loggly/LogglySendBufferedLogs.cs index 8b6476e..ff92266 100644 --- a/source/log4net-loggly/LogglySendBufferedLogs.cs +++ b/source/log4net-loggly/LogglySendBufferedLogs.cs @@ -40,7 +40,7 @@ public static void sendBufferedLogsToLoggly(ILogglyAppenderConfig config, bool i var response = (HttpWebResponse)e.Response; if (response != null && response.StatusCode == HttpStatusCode.Forbidden) { - LogglyClient.setValidInvalidFlag(false); + LogglyClient.setTokenValid(false); Console.WriteLine("Loggly error: {0}", e.Message); return; }