diff --git a/src/LogentriesCore/LogentriesCore.csproj b/src/LogentriesCore/LogentriesCore.csproj index 5b3992f..f861f58 100644 --- a/src/LogentriesCore/LogentriesCore.csproj +++ b/src/LogentriesCore/LogentriesCore.csproj @@ -48,6 +48,7 @@ + diff --git a/src/LogentriesCore/SystemMetric.cs b/src/LogentriesCore/SystemMetric.cs new file mode 100644 index 0000000..c059f55 --- /dev/null +++ b/src/LogentriesCore/SystemMetric.cs @@ -0,0 +1,196 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Net.NetworkInformation; + +namespace LogentriesCore.Net +{ + public class SystemMetric + { + #region CPU Counters + + private static PerformanceCounter cpuTime = new PerformanceCounter() + { + CategoryName = "Processor", + CounterName = "% Processor Time", + InstanceName = "_Total" + }; + + private static PerformanceCounter cpuUserTime = new PerformanceCounter() + { + CategoryName = "Processor", + CounterName = "% User Time", + InstanceName = "_Total" + }; + + private static PerformanceCounter cpuIdleTime = new PerformanceCounter() + { + CategoryName = "Processor", + CounterName = "% Idle Time", + InstanceName = "_Total" + }; + + #endregion + + #region Memory Counters + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + private class MEMORYSTATUSEX + { + public uint dwLength; + public uint dwMemoryLoad; + public ulong ullTotalPhys; + public ulong ullAvailPhys; + public ulong ullTotalPageFile; + public ulong ullAvailPageFile; + public ulong ullTotalVirtual; + public ulong ullAvailVirtual; + public ulong ullAvailExtendedVirtual; + public MEMORYSTATUSEX() + { + this.dwLength = (uint)Marshal.SizeOf(typeof(MEMORYSTATUSEX)); + } + } + + + [return: MarshalAs(UnmanagedType.Bool)] + [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] + static extern bool GlobalMemoryStatusEx([In, Out] MEMORYSTATUSEX lpBuffer); + + #endregion + + #region Disk Counters + + private static PerformanceCounter diskReadCounter = new PerformanceCounter() + { + CategoryName = "PhysicalDisk", + CounterName = "Avg. Disk Bytes/Read", + InstanceName = "_Total" + }; + + private static PerformanceCounter diskWriteCounter = new PerformanceCounter() + { + CategoryName = "PhysicalDisk", + CounterName = "Avg. Disk Bytes/Write", + InstanceName = "_Total" + }; + + #endregion + + #region Network Counters + + private long networkSentInitial = 0; + private long networkReceivedInitial = 0; + + private void resetNetworkInformationCounters() + { + getNetworkInformation(out networkSentInitial, out networkReceivedInitial); + } + + private void getNetworkInformation(out long sent, out long received) + { + sent = 0; + received = 0; + + NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces(); + foreach (NetworkInterface netint in interfaces) + { + sent += netint.GetIPv4Statistics().BytesSent; + received += netint.GetIPv4Statistics().BytesReceived; + } + } + + private void getNetworkInformationDelta(out long sent, out long received) + { + long sentCurrent = 0; + long receivedCurrent = 0; + + getNetworkInformation(out sentCurrent, out receivedCurrent); + + sent = sentCurrent - networkSentInitial; + received = receivedCurrent - networkReceivedInitial; + } + + #endregion + + private static string hostName = String.Empty; + + static SystemMetric() + { + cpuTime.BeginInit(); + cpuIdleTime.BeginInit(); + cpuUserTime.BeginInit(); + diskReadCounter.BeginInit(); + diskWriteCounter.BeginInit(); + + try + { + hostName = "HostName=" + System.Environment.MachineName; + } + catch (InvalidOperationException) + { + // Do not do anything. The host name must be valid. + } + } + + private static readonly SystemMetric instance = new SystemMetric(); + + private static SystemMetric Instance + { + get + { + return instance; + } + } + + private SystemMetric() + { + resetNetworkInformationCounters(); + } + + public static string Metric() + { + StringBuilder metric = new StringBuilder(); + + #region Get Host Name + metric.Append(hostName).Append(";"); + #endregion + + #region Get CPU Information + metric.Append("CPU.system=").Append(cpuTime.NextValue() .ToString("0.00")).Append("%").Append(";"); + metric.Append("CPU.user=") .Append(cpuUserTime.NextValue().ToString("0.00")).Append("%").Append(";"); + metric.Append("CPU.idle=") .Append(cpuIdleTime.NextValue().ToString("0.00")).Append("%").Append(";"); + #endregion + + #region Get Memory Information + MEMORYSTATUSEX memStatus = new MEMORYSTATUSEX(); + if (GlobalMemoryStatusEx(memStatus)) + { + metric.Append("Mem.total=").Append(memStatus.ullTotalPhys).Append(";"); + ulong memActive = ((memStatus.ullTotalPhys - memStatus.ullAvailPhys) * 100 / memStatus.ullTotalPhys); + metric.Append("Mem.active=").Append(memActive).Append("%").Append(";"); + } + #endregion + + #region Get Disk Information + metric.Append("Disk.write=").Append(diskWriteCounter.NextValue().ToString("0.")).Append(";"); + metric.Append("Disk.read=") .Append(diskReadCounter .NextValue().ToString("0.")).Append(";"); + #endregion + + #region Get Network Sent/Received Information + long sentDelta = 0; + long receivedDelta = 0; + + SystemMetric.Instance.getNetworkInformationDelta(out sentDelta, out receivedDelta); + + metric.Append("Net.send=").Append(sentDelta).Append(";"); + metric.Append("Net.received=").Append(receivedDelta); + #endregion + + return metric.ToString(); + } + } +} diff --git a/src/LogentriesCore35/LogentriesCore35.csproj b/src/LogentriesCore35/LogentriesCore35.csproj index 1cfd4db..e0b6304 100644 --- a/src/LogentriesCore35/LogentriesCore35.csproj +++ b/src/LogentriesCore35/LogentriesCore35.csproj @@ -52,6 +52,9 @@ LeClient.cs + + SystemMetric.cs + diff --git a/src/LogentriesLog4net/LogentriesAppender.cs b/src/LogentriesLog4net/LogentriesAppender.cs index a2634b3..2f32f60 100644 --- a/src/LogentriesLog4net/LogentriesAppender.cs +++ b/src/LogentriesLog4net/LogentriesAppender.cs @@ -7,245 +7,259 @@ using LogentriesCore.Net; -namespace log4net.Appender +namespace log4net { - public class LogentriesAppender : AppenderSkeleton + namespace Appender { - private AsyncLogger logentriesAsync; - public LogentriesAppender() + public class LogentriesAppender : AppenderSkeleton { - logentriesAsync = new AsyncLogger(); - } - - #region attributeMethods + private AsyncLogger logentriesAsync; - /* Option to set LOGENTRIES_TOKEN programmatically or in appender definition. */ - public string Token - { - get - { - return logentriesAsync.getToken(); - } - set + public LogentriesAppender() { - logentriesAsync.setToken(value); + logentriesAsync = new AsyncLogger(); } - } - /* Option to set LOGENTRIES_ACCOUNT_KEY programmatically or in appender definition. */ - public String AccountKey - { - get - { - return logentriesAsync.getAccountKey(); - } - set - { - logentriesAsync.setAccountKey(value); - } - } + #region attributeMethods - /* Option to set LOGENTRIES_LOCATION programmatically or in appender definition. */ - public String Location - { - get + /* Option to set LOGENTRIES_TOKEN programmatically or in appender definition. */ + public string Token { - return logentriesAsync.getLocation(); + get + { + return logentriesAsync.getToken(); + } + set + { + logentriesAsync.setToken(value); + } } - set - { - logentriesAsync.setLocation(value); - } - } - /* Set to true to always flush the TCP stream after every written entry. */ - public bool ImmediateFlush - { - get + /* Option to set LOGENTRIES_ACCOUNT_KEY programmatically or in appender definition. */ + public String AccountKey { - return logentriesAsync.getImmediateFlush(); + get + { + return logentriesAsync.getAccountKey(); + } + set + { + logentriesAsync.setAccountKey(value); + } } - set - { - logentriesAsync.setImmediateFlush(value); - } - } - /* Debug flag. */ - public bool Debug - { - get - { - return logentriesAsync.getDebug(); - } - set + /* Option to set LOGENTRIES_LOCATION programmatically or in appender definition. */ + public String Location { - logentriesAsync.setDebug(value); + get + { + return logentriesAsync.getLocation(); + } + set + { + logentriesAsync.setLocation(value); + } } - } - - /* Set to true to use HTTP PUT logging. */ - public bool UseHttpPut - { - get + /* Set to true to always flush the TCP stream after every written entry. */ + public bool ImmediateFlush { - return logentriesAsync.getUseHttpPut(); + get + { + return logentriesAsync.getImmediateFlush(); + } + set + { + logentriesAsync.setImmediateFlush(value); + } } - set - { - logentriesAsync.setUseHttpPut(value); - } - } - /* This property exists for backward compatibility with older configuration XML. */ - [Obsolete("Use the UseHttpPut property instead.")] - public bool HttpPut - { - get - { - return logentriesAsync.getUseHttpPut(); - } - set + /* Debug flag. */ + public bool Debug { - logentriesAsync.setUseHttpPut(value); + get + { + return logentriesAsync.getDebug(); + } + set + { + logentriesAsync.setDebug(value); + } } - } - /* Set to true to use SSL with HTTP PUT logging. */ - public bool UseSsl - { - get + /* Set to true to use HTTP PUT logging. */ + public bool UseHttpPut { - return logentriesAsync.getUseSsl(); + get + { + return logentriesAsync.getUseHttpPut(); + } + set + { + logentriesAsync.setUseHttpPut(value); + } } - set + + /* This property exists for backward compatibility with older configuration XML. */ + [Obsolete("Use the UseHttpPut property instead.")] + public bool HttpPut { - logentriesAsync.setUseSsl(value); + get + { + return logentriesAsync.getUseHttpPut(); + } + set + { + logentriesAsync.setUseHttpPut(value); + } } - } - /* Is using DataHub parameter flag. - set to true to use DataHub server */ - public bool IsUsingDataHub - { - get - { - return logentriesAsync.getIsUsingDataHab(); - } - set - { - logentriesAsync.setIsUsingDataHub(value); - } - } - /* DataHub server address */ - public String DataHubAddr - { - get - { - return logentriesAsync.getDataHubAddr(); - } - set - { - logentriesAsync.setDataHubAddr(value); + /* Set to true to use SSL with HTTP PUT logging. */ + public bool UseSsl + { + get + { + return logentriesAsync.getUseSsl(); + } + set + { + logentriesAsync.setUseSsl(value); + } } - } - /* DataHub server port */ - public int DataHubPort - { - get - { - return logentriesAsync.getDataHubPort(); - } - set - { - logentriesAsync.setDataHubPort(value); + /* Is using DataHub parameter flag. - set to true to use DataHub server */ + public bool IsUsingDataHub + { + get + { + return logentriesAsync.getIsUsingDataHab(); + } + set + { + logentriesAsync.setIsUsingDataHub(value); + } } - } - /* Switch that defines whether add host name to the log message */ - public bool LogHostname - { - get + /* DataHub server address */ + public String DataHubAddr { - return logentriesAsync.getUseHostName(); + get + { + return logentriesAsync.getDataHubAddr(); + } + set + { + logentriesAsync.setDataHubAddr(value); + } } - set + + /* DataHub server port */ + public int DataHubPort { - logentriesAsync.setUseHostName(value); + get + { + return logentriesAsync.getDataHubPort(); + } + set + { + logentriesAsync.setDataHubPort(value); + } } - } - /* User-defined host name. If empty the library will try to obtain it automatically */ - public String HostName - { - get + /* Switch that defines whether add host name to the log message */ + public bool LogHostname { - return logentriesAsync.getHostName(); + get + { + return logentriesAsync.getUseHostName(); + } + set + { + logentriesAsync.setUseHostName(value); + } } - set + + /* User-defined host name. If empty the library will try to obtain it automatically */ + public String HostName { - logentriesAsync.setHostName(value); + get + { + return logentriesAsync.getHostName(); + } + set + { + logentriesAsync.setHostName(value); + } } - } - /* User-defined log message ID */ - public String LogID - { - get + /* User-defined log message ID */ + public String LogID { - return logentriesAsync.getLogID(); + get + { + return logentriesAsync.getLogID(); + } + set + { + logentriesAsync.setLogID(value); + } } - set + + /* This property exists for backward compatibility with older configuration XML. */ + [Obsolete("Use the UseSsl property instead.")] + public bool Ssl { - logentriesAsync.setLogID(value); + get + { + return logentriesAsync.getUseSsl(); + } + set + { + logentriesAsync.setUseSsl(value); + } } - } - /* This property exists for backward compatibility with older configuration XML. */ - [Obsolete("Use the UseSsl property instead.")] - public bool Ssl - { - get + #endregion + + protected override void Append(LoggingEvent loggingEvent) { - return logentriesAsync.getUseSsl(); + var renderedEvent = RenderLoggingEvent(loggingEvent); + logentriesAsync.AddLine(renderedEvent); } - set + + protected override void Append(LoggingEvent[] loggingEvents) { - logentriesAsync.setUseSsl(value); + foreach (var logEvent in loggingEvents) + { + this.Append(logEvent); + } } - } - - #endregion - protected override void Append(LoggingEvent loggingEvent) - { - var renderedEvent = RenderLoggingEvent(loggingEvent); - logentriesAsync.AddLine(renderedEvent); - } - - protected override void Append(LoggingEvent[] loggingEvents) - { - foreach (var logEvent in loggingEvents) + protected override bool RequiresLayout { - this.Append(logEvent); + get + { + return true; + } } - } - protected override bool RequiresLayout - { - get + protected override void OnClose() { - return true; + logentriesAsync.interruptWorker(); } } + } - protected override void OnClose() + public static class ILogExtension + { + public static string Metric(this log4net.ILog log) { - logentriesAsync.interruptWorker(); + string metric = SystemMetric.Metric(); + log.Info(metric); + return metric; } } } diff --git a/src/LogentriesNLog/LogentriesTarget.cs b/src/LogentriesNLog/LogentriesTarget.cs index 582551d..c470cb8 100644 --- a/src/LogentriesNLog/LogentriesTarget.cs +++ b/src/LogentriesNLog/LogentriesTarget.cs @@ -9,119 +9,133 @@ using NLog.Targets; using LogentriesCore.Net; +using LogentriesCore; -namespace NLog.Targets +namespace NLog { - [Target("Logentries")] - public sealed class LogentriesTarget : TargetWithLayout + namespace Targets { - private AsyncLogger logentriesAsync; - - public LogentriesTarget() - { - logentriesAsync = new AsyncLogger(); - } - - - /** Debug flag. */ - public bool Debug - { - get { return logentriesAsync.getDebug(); } - set { logentriesAsync.setDebug(value); } - } - - /** Is using DataHub parameter flag. - ste to true if it is needed to send messages to DataHub instance. */ - public bool IsUsingDataHub - { - get { return logentriesAsync.getIsUsingDataHab(); } - set { logentriesAsync.setIsUsingDataHub(value); } - } - - /** DataHub server address */ - public String DataHubAddr + [Target("Logentries")] + public sealed class LogentriesTarget : TargetWithLayout { - get { return logentriesAsync.getDataHubAddr(); } - set { logentriesAsync.setDataHubAddr(value); } - } - - /** DataHub server port */ - public int DataHubPort - { - get { return logentriesAsync.getDataHubPort(); } - set { logentriesAsync.setDataHubPort(value); } - } - - /** Option to set Token programmatically or in Appender Definition */ - public string Token - { - get { return logentriesAsync.getToken(); } - set { logentriesAsync.setToken(value); } - } - - /** HTTP PUT Flag */ - public bool HttpPut - { - get { return logentriesAsync.getUseHttpPut(); } - set { logentriesAsync.setUseHttpPut(value); } - } - - /** SSL/TLS parameter flag */ - public bool Ssl - { - get { return logentriesAsync.getUseSsl(); } - set { logentriesAsync.setUseSsl(value); } - } - - /** ACCOUNT_KEY parameter for HTTP PUT logging */ - public String Key - { - get { return logentriesAsync.getAccountKey(); } - set { logentriesAsync.setAccountKey(value); } - } - - /** LOCATION parameter for HTTP PUT logging */ - public String Location - { - get { return logentriesAsync.getLocation(); } - set { logentriesAsync.setLocation(value); } - } - - /* LogHostname - switch that defines whether add host name to the log message */ - public bool LogHostname - { - get { return logentriesAsync.getUseHostName(); } - set { logentriesAsync.setUseHostName(value); } - } - - /* HostName - user-defined host name. If empty the library will try to obtain it automatically */ - public String HostName - { - get { return logentriesAsync.getHostName(); } - set { logentriesAsync.setHostName(value); } - } - - /* User-defined log message ID */ - public String LogID - { - get { return logentriesAsync.getLogID(); } - set { logentriesAsync.setLogID(value); } - } - - public bool KeepConnection { get; set; } - - protected override void Write(LogEventInfo logEvent) - { - //Render message content - String renderedEvent = this.Layout.Render(logEvent); - - logentriesAsync.AddLine(renderedEvent); + private AsyncLogger logentriesAsync; + + public LogentriesTarget() + { + logentriesAsync = new AsyncLogger(); + } + + + /** Debug flag. */ + public bool Debug + { + get { return logentriesAsync.getDebug(); } + set { logentriesAsync.setDebug(value); } + } + + /** Is using DataHub parameter flag. - ste to true if it is needed to send messages to DataHub instance. */ + public bool IsUsingDataHub + { + get { return logentriesAsync.getIsUsingDataHab(); } + set { logentriesAsync.setIsUsingDataHub(value); } + } + + /** DataHub server address */ + public String DataHubAddr + { + get { return logentriesAsync.getDataHubAddr(); } + set { logentriesAsync.setDataHubAddr(value); } + } + + /** DataHub server port */ + public int DataHubPort + { + get { return logentriesAsync.getDataHubPort(); } + set { logentriesAsync.setDataHubPort(value); } + } + + /** Option to set Token programmatically or in Appender Definition */ + public string Token + { + get { return logentriesAsync.getToken(); } + set { logentriesAsync.setToken(value); } + } + + /** HTTP PUT Flag */ + public bool HttpPut + { + get { return logentriesAsync.getUseHttpPut(); } + set { logentriesAsync.setUseHttpPut(value); } + } + + /** SSL/TLS parameter flag */ + public bool Ssl + { + get { return logentriesAsync.getUseSsl(); } + set { logentriesAsync.setUseSsl(value); } + } + + /** ACCOUNT_KEY parameter for HTTP PUT logging */ + public String Key + { + get { return logentriesAsync.getAccountKey(); } + set { logentriesAsync.setAccountKey(value); } + } + + /** LOCATION parameter for HTTP PUT logging */ + public String Location + { + get { return logentriesAsync.getLocation(); } + set { logentriesAsync.setLocation(value); } + } + + /* LogHostname - switch that defines whether add host name to the log message */ + public bool LogHostname + { + get { return logentriesAsync.getUseHostName(); } + set { logentriesAsync.setUseHostName(value); } + } + + /* HostName - user-defined host name. If empty the library will try to obtain it automatically */ + public String HostName + { + get { return logentriesAsync.getHostName(); } + set { logentriesAsync.setHostName(value); } + } + + /* User-defined log message ID */ + public String LogID + { + get { return logentriesAsync.getLogID(); } + set { logentriesAsync.setLogID(value); } + } + + public bool KeepConnection { get; set; } + + protected override void Write(LogEventInfo logEvent) + { + //Render message content + String renderedEvent = this.Layout.Render(logEvent); + + logentriesAsync.AddLine(renderedEvent); + } + + protected override void CloseTarget() + { + base.CloseTarget(); + + logentriesAsync.interruptWorker(); + } } + } - protected override void CloseTarget() + public static class LoggerExtension + { + public static string Metric(this Logger log) { - base.CloseTarget(); - - logentriesAsync.interruptWorker(); + string metric = SystemMetric.Metric(); + log.Info(metric); + return metric; } } } diff --git a/src/le_dotnet - Shortcut.lnk b/src/le_dotnet - Shortcut.lnk deleted file mode 100644 index 6cf0871..0000000 Binary files a/src/le_dotnet - Shortcut.lnk and /dev/null differ