added loggly integration

This commit is contained in:
kay.one 2013-05-23 20:23:59 -07:00
parent 0e7ca07e02
commit 3010ed6073
7 changed files with 211 additions and 1 deletions

View File

@ -0,0 +1,89 @@
using System;
using System.Text;
using System.Threading;
namespace NzbDrone.Common
{
public static class HashUtil
{
//This should never be changed. very bad things will happen!
private static readonly DateTime Epoch = new DateTime(2010, 1, 1);
private static readonly object _lock = new object();
public static string CalculateCrc(string input)
{
uint mCrc = 0xffffffff;
byte[] bytes = Encoding.UTF8.GetBytes(input);
foreach (byte myByte in bytes)
{
mCrc ^= ((uint)(myByte) << 24);
for (var i = 0; i < 8; i++)
{
if ((Convert.ToUInt32(mCrc) & 0x80000000) == 0x80000000)
{
mCrc = (mCrc << 1) ^ 0x04C11DB7;
}
else
{
mCrc <<= 1;
}
}
}
return String.Format("{0:x8}", mCrc);
}
public static string GenerateUserId()
{
return GenerateId("u");
}
public static string GenerateAppId()
{
return GenerateId("a");
}
public static string GenerateApiToken()
{
return Guid.NewGuid().ToString().Replace("-", "");
}
public static string GenerateSecurityToken(int length)
{
var byteSize = (length / 4) * 3;
var linkBytes = new byte[byteSize];
var rngCrypto = new System.Security.Cryptography.RNGCryptoServiceProvider();
rngCrypto.GetBytes(linkBytes);
var base64String = Convert.ToBase64String(linkBytes);
return base64String;
}
private static string GenerateId(string prefix)
{
lock (_lock)
{
Thread.Sleep(1);
var tick = (DateTime.Now - Epoch).Ticks;
return prefix + "." + ToBase(tick);
}
}
private static string ToBase(long input)
{
const string BASE_CHARS = "0123456789abcdefghijklmnopqrstuvwxyz";
int targetBase = BASE_CHARS.Length;
var result = new StringBuilder();
do
{
result.Append(BASE_CHARS[(int)(input % targetBase)]);
input /= targetBase;
} while (input > 0);
return result.ToString();
}
}
}

View File

@ -0,0 +1,40 @@
using System;
using NLog;
using NzbDrone.Common.Serializer;
namespace NzbDrone.Common.Instrumentation
{
public static class LogEventExtensions
{
public static string GetHash(this LogEventInfo logEvent)
{
var stackString = Json.Serialize(logEvent.StackTrace);
var hashSeed = String.Concat(logEvent.LoggerName, logEvent.Exception.GetType().ToString(), stackString, logEvent.Level);
return HashUtil.CalculateCrc(hashSeed);
}
public static string GetFormattedMessage(this LogEventInfo logEvent)
{
var message = logEvent.FormattedMessage;
if (logEvent.Exception != null)
{
if (logEvent.Exception != null)
{
if (String.IsNullOrWhiteSpace(message))
{
message = logEvent.Exception.Message;
}
else
{
message += ": " + logEvent.Exception.Message;
}
}
}
return message;
}
}
}

View File

@ -0,0 +1,70 @@
using System.Collections.Generic;
using NLog;
using NLog.Config;
using NLog.Layouts;
using NLog.Targets;
using NzbDrone.Common.Serializer;
using Logger = Loggly.Logger;
namespace NzbDrone.Common.Instrumentation
{
public class LogglyTarget : TargetWithLayout
{
private readonly IEnvironmentProvider _environmentProvider;
private Logger _logger;
public void Register(LogLevel minLevel)
{
Layout = new SimpleLayout("${callsite:className=false:fileName=false:includeSourcePath=false:methodName=true}");
var rule = new LoggingRule("*", minLevel, this);
LogManager.Configuration.AddTarget("LogglyLogger", this);
LogManager.Configuration.LoggingRules.Add(rule);
LogManager.ConfigurationReloaded += (sender, args) => Register(minLevel);
LogManager.ReconfigExistingLoggers();
}
public LogglyTarget(IEnvironmentProvider environmentProvider)
{
_environmentProvider = environmentProvider;
}
protected override void InitializeTarget()
{
string apiKey = string.Empty;
if (EnvironmentProvider.IsProduction)
{
apiKey = "4c4ecb69-d1b9-4e2a-b54b-b0c4cc143a95";
}
else
{
apiKey = "d344a321-b107-45c4-a548-77138f446510";
}
_logger = new Logger(apiKey);
}
protected override void Write(NLog.LogEventInfo logEvent)
{
var dictionary = new Dictionary<string, object>();
if (logEvent.Exception != null)
{
dictionary.Add("ex", logEvent.Exception.ToString());
dictionary.Add("extyp", logEvent.Exception.GetType().Name);
dictionary.Add("hash", logEvent.GetHash());
}
dictionary.Add("logger", logEvent.LoggerName);
dictionary.Add("method", Layout.Render(logEvent));
dictionary.Add("level", logEvent.Level.Name);
dictionary.Add("message", logEvent.GetFormattedMessage());
dictionary.Add("ver", _environmentProvider.Version.ToString());
_logger.Log(Json.Serialize(dictionary));
}
}
}

View File

@ -58,6 +58,10 @@
<Reference Include="Ionic.Zip">
<HintPath>..\packages\DotNetZip.1.9.1.8\lib\net20\Ionic.Zip.dll</HintPath>
</Reference>
<Reference Include="Loggly, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\loggly-csharp.2.2\lib\Loggly.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@ -101,8 +105,11 @@
<Compile Include="EnsureThat\Resources\ExceptionMessages.Designer.cs" />
<Compile Include="EnsureThat\StringExtensions.cs" />
<Compile Include="EnsureThat\TypeParam.cs" />
<Compile Include="HashUtil.cs" />
<Compile Include="Instrumentation\ApplicationLogLayoutRenderer.cs" />
<Compile Include="Instrumentation\DirSeparatorLayoutRenderer.cs" />
<Compile Include="Instrumentation\LogEventExtensions.cs" />
<Compile Include="Instrumentation\LogglyTarget.cs" />
<Compile Include="Instrumentation\UpdateLogLayoutRenderer.cs" />
<Compile Include="Serializer\Json.cs" />
<Compile Include="Messaging\CommandCompletedEvent.cs" />

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="DotNetZip" version="1.9.1.8" targetFramework="net40" />
<package id="loggly-csharp" version="2.2" targetFramework="net40" />
<package id="Newtonsoft.Json" version="5.0.3" targetFramework="net35" />
<package id="NLog" version="2.0.1.2" targetFramework="net40" />
</packages>

View File

@ -56,7 +56,6 @@ namespace NzbDrone.Core.Datastore
connectionBuilder.CacheSize = (int)-10.Megabytes();
connectionBuilder.DateTimeKind = DateTimeKind.Utc;
connectionBuilder.JournalMode = SQLiteJournalModeEnum.Wal;
connectionBuilder.Pooling = true;
return connectionBuilder.ConnectionString;
}

View File

@ -2,6 +2,8 @@
using System.Diagnostics;
using System.Reflection;
using NLog;
using NzbDrone.Common;
using NzbDrone.Common.Instrumentation;
namespace NzbDrone
{
@ -14,6 +16,8 @@ namespace NzbDrone
{
try
{
new LogglyTarget(new EnvironmentProvider()).Register(LogLevel.Warn);
logger.Info("Starting NzbDrone Console. Version {0}", Assembly.GetExecutingAssembly().GetName().Version);
AppDomain.CurrentDomain.UnhandledException += ((s, e) => AppDomainException(e.ExceptionObject as Exception));