Log to datadog

This commit is contained in:
runebaas 2020-11-24 21:23:22 +01:00
parent 4c3b7044ce
commit b21d7bfab7
No known key found for this signature in database
GPG key ID: 2677AF508D0300D6
7 changed files with 119 additions and 75 deletions

View file

@ -23,11 +23,11 @@
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0-rc.1.*" /> <PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0-rc.1.*" />
<PackageReference Include="Microsoft.Extensions.Options" Version="5.0.0-rc.1.*" /> <PackageReference Include="Microsoft.Extensions.Options" Version="5.0.0-rc.1.*" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="NLog" Version="4.7.2" />
<PackageReference Include="NLog.Config" Version="4.7.2" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="5.0.0-rc1" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="5.0.0-rc1" />
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
<PackageReference Include="Serilog.Sinks.Datadog.Logs" Version="0.3.3" />
<PackageReference Include="SharpRaven" Version="2.4.0" /> <PackageReference Include="SharpRaven" Version="2.4.0" />
<PackageReference Include="SumoLogic.Logging.NLog" Version="1.0.1.3" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View file

@ -1,7 +1,8 @@
using System; using System;
using Geekbot.Core.Logger; using Geekbot.Core.Logger;
using Microsoft.Extensions.Logging;
using Npgsql.Logging; using Npgsql.Logging;
using LogLevel = NLog.LogLevel; using Serilog.Events;
namespace Geekbot.Core.Database.LoggingAdapter namespace Geekbot.Core.Database.LoggingAdapter
{ {
@ -21,7 +22,7 @@ namespace Geekbot.Core.Database.LoggingAdapter
public override bool IsEnabled(NpgsqlLogLevel level) public override bool IsEnabled(NpgsqlLogLevel level)
{ {
return (_runParameters.DbLogging && _geekbotLogger.GetNLogger().IsEnabled(ToGeekbotLogLevel(level))); return (_runParameters.DbLogging && _geekbotLogger.GetLogger().IsEnabled(ToGeekbotLogLevel(level)));
} }
public override void Log(NpgsqlLogLevel level, int connectorId, string msg, Exception exception = null) public override void Log(NpgsqlLogLevel level, int connectorId, string msg, Exception exception = null)
@ -51,16 +52,16 @@ namespace Geekbot.Core.Database.LoggingAdapter
} }
} }
private static LogLevel ToGeekbotLogLevel(NpgsqlLogLevel level) private static LogEventLevel ToGeekbotLogLevel(NpgsqlLogLevel level)
{ {
return level switch return level switch
{ {
NpgsqlLogLevel.Trace => LogLevel.Trace, NpgsqlLogLevel.Trace => LogEventLevel.Verbose,
NpgsqlLogLevel.Debug => LogLevel.Debug, NpgsqlLogLevel.Debug => LogEventLevel.Debug,
NpgsqlLogLevel.Info => LogLevel.Info, NpgsqlLogLevel.Info => LogEventLevel.Information,
NpgsqlLogLevel.Warn => LogLevel.Warn, NpgsqlLogLevel.Warn => LogEventLevel.Warning,
NpgsqlLogLevel.Error => LogLevel.Error, NpgsqlLogLevel.Error => LogEventLevel.Error,
NpgsqlLogLevel.Fatal => LogLevel.Fatal, NpgsqlLogLevel.Fatal => LogEventLevel.Fatal,
_ => throw new ArgumentOutOfRangeException(nameof(level)) _ => throw new ArgumentOutOfRangeException(nameof(level))
}; };
} }

View file

@ -6,13 +6,13 @@ namespace Geekbot.Core.Logger
public class GeekbotLogger : IGeekbotLogger public class GeekbotLogger : IGeekbotLogger
{ {
private readonly bool _logAsJson; private readonly bool _logAsJson;
private readonly NLog.Logger _logger; private readonly Serilog.ILogger _logger;
private readonly JsonSerializerSettings _serializerSettings; private readonly JsonSerializerSettings _serializerSettings;
public GeekbotLogger(RunParameters runParameters) public GeekbotLogger(RunParameters runParameters)
{ {
_logAsJson = !string.IsNullOrEmpty(runParameters.SumologicEndpoint) || runParameters.LogJson; _logAsJson = !string.IsNullOrEmpty(runParameters.DatadogApiKey) || runParameters.LogJson;
_logger = LoggerFactory.CreateNLog(runParameters); _logger = LoggerFactory.CreateLogger(runParameters);
_serializerSettings = new JsonSerializerSettings _serializerSettings = new JsonSerializerSettings
{ {
ReferenceLoopHandling = ReferenceLoopHandling.Serialize, ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
@ -22,21 +22,21 @@ namespace Geekbot.Core.Logger
} }
public void Trace(LogSource source, string message, object extra = null) public void Trace(LogSource source, string message, object extra = null)
=> _logger.Trace(CreateLogString("Trace", source, message, null, extra)); => _logger.Verbose(CreateLogString("Trace", source, message, null, extra));
public void Debug(LogSource source, string message, object extra = null) public void Debug(LogSource source, string message, object extra = null)
=> _logger.Debug(CreateLogString("Debug", source, message, null, extra)); => _logger.Debug(CreateLogString("Debug", source, message, null, extra));
public void Information(LogSource source, string message, object extra = null) public void Information(LogSource source, string message, object extra = null)
=> _logger.Info(CreateLogString("Information", source, message, null, extra)); => _logger.Information(CreateLogString("Information", source, message, null, extra));
public void Warning(LogSource source, string message, Exception stackTrace = null, object extra = null) public void Warning(LogSource source, string message, Exception stackTrace = null, object extra = null)
=> _logger.Warn(CreateLogString("Warning", source, message, stackTrace, extra)); => _logger.Warning(CreateLogString("Warning", source, message, stackTrace, extra));
public void Error(LogSource source, string message, Exception stackTrace, object extra = null) public void Error(LogSource source, string message, Exception stackTrace, object extra = null)
=> _logger.Error(stackTrace, CreateLogString("Error", source, message, stackTrace, extra)); => _logger.Error(stackTrace, CreateLogString("Error", source, message, stackTrace, extra));
public NLog.Logger GetNLogger() => _logger; public Serilog.ILogger GetLogger() => _logger;
public bool LogAsJson() => _logAsJson; public bool LogAsJson() => _logAsJson;

View file

@ -9,7 +9,7 @@ namespace Geekbot.Core.Logger
void Information(LogSource source, string message, object extra = null); void Information(LogSource source, string message, object extra = null);
void Warning(LogSource source, string message, Exception stackTrace = null, object extra = null); void Warning(LogSource source, string message, Exception stackTrace = null, object extra = null);
void Error(LogSource source, string message, Exception stackTrace, object extra = null); void Error(LogSource source, string message, Exception stackTrace, object extra = null);
NLog.Logger GetNLogger(); Serilog.ILogger GetLogger();
bool LogAsJson(); bool LogAsJson();
} }
} }

View file

@ -1,64 +1,104 @@
using System; using System;
using System.Text; using Serilog;
using NLog; using Serilog.Events;
using NLog.Config; using Serilog.Sinks.Datadog.Logs;
using NLog.Targets;
using SumoLogic.Logging.NLog;
namespace Geekbot.Core.Logger namespace Geekbot.Core.Logger
{ {
public class LoggerFactory public class LoggerFactory
{ {
public static NLog.Logger CreateNLog(RunParameters runParameters) public static ILogger CreateLogger(RunParameters runParameters)
{ {
var config = new LoggingConfiguration(); var logger = new LoggerConfiguration();
var minLevel = runParameters.Verbose ? LogLevel.Trace : LogLevel.Info; var minLevel = runParameters.Verbose ? LogEventLevel.Verbose : LogEventLevel.Information;
if (!string.IsNullOrEmpty(runParameters.DatadogApiKey))
if (!string.IsNullOrEmpty(runParameters.SumologicEndpoint))
{ {
Console.WriteLine("Logging Geekbot Logs to Sumologic"); // 2nd error logger
config.LoggingRules.Add( var errorLogger = new LoggerConfiguration().WriteTo.Console().CreateLogger();
new LoggingRule("*", minLevel, LogLevel.Fatal, errorLogger.Information("Enabling Datadog Logger");
new SumoLogicTarget()
{ logger.WriteTo.DatadogLogs(
Url = runParameters.SumologicEndpoint, apiKey: runParameters.DatadogApiKey,
SourceName = "GeekbotLogger", source: "GeekbotLogger",
Layout = "${message}", service: "Geekbot",
UseConsoleLog = false, host: Environment.MachineName,
OptimizeBufferReuse = true, configuration: new DatadogConfiguration()
Name = "Geekbot" {
}) Url = "https://http-intake.logs.datadoghq.eu",
Port = 443,
UseSSL = true,
UseTCP = false
},
logLevel: minLevel,
exceptionHandler: exception =>
{
var cannotSendLogEventException = exception as CannotSendLogEventException;
errorLogger.Error(cannotSendLogEventException, "Datadog Error");
}
); );
} }
else if (runParameters.LogJson) else if (runParameters.LogJson)
{ {
config.LoggingRules.Add( logger.WriteTo.Console(restrictedToMinimumLevel: minLevel, outputTemplate: "{Message:lj}{NewLine}");
new LoggingRule("*", minLevel, LogLevel.Fatal,
new ConsoleTarget
{
Name = "Console",
Encoding = Encoding.UTF8,
Layout = "${message}"
}
)
);
} }
else else
{ {
config.LoggingRules.Add( logger.WriteTo.Console(restrictedToMinimumLevel: minLevel);
new LoggingRule("*", minLevel, LogLevel.Fatal,
new ColoredConsoleTarget
{
Name = "Console",
Encoding = Encoding.UTF8,
Layout = "[${longdate} ${level:format=FirstCharacter}] ${message} ${exception:format=toString}"
}
)
);
} }
var loggerConfig = new LogFactory {Configuration = config}; return logger.CreateLogger();
return loggerConfig.GetCurrentClassLogger();
} }
// public static NLog.Logger CreateNLog(RunParameters runParameters)
// {
// var config = new LoggingConfiguration();
// var minLevel = runParameters.Verbose ? LogLevel.Trace : LogLevel.Info;
//
// if (!string.IsNullOrEmpty(runParameters.SumologicEndpoint))
// {
// Console.WriteLine("Logging Geekbot Logs to Sumologic");
// config.LoggingRules.Add(
// new LoggingRule("*", minLevel, LogLevel.Fatal,
// new SumoLogicTarget()
// {
// Url = runParameters.SumologicEndpoint,
// SourceName = "GeekbotLogger",
// Layout = "${message}",
// UseConsoleLog = false,
// OptimizeBufferReuse = true,
// Name = "Geekbot"
// })
// );
// }
// else if (runParameters.LogJson)
// {
// config.LoggingRules.Add(
// new LoggingRule("*", minLevel, LogLevel.Fatal,
// new ConsoleTarget
// {
// Name = "Console",
// Encoding = Encoding.UTF8,
// Layout = "${message}"
// }
// )
// );
// }
// else
// {
// config.LoggingRules.Add(
// new LoggingRule("*", minLevel, LogLevel.Fatal,
// new ColoredConsoleTarget
// {
// Name = "Console",
// Encoding = Encoding.UTF8,
// Layout = "[${longdate} ${level:format=FirstCharacter}] ${message} ${exception:format=toString}"
// }
// )
// );
// }
//
// var loggerConfig = new LogFactory {Configuration = config};
// return loggerConfig.GetCurrentClassLogger();
// }
} }
} }

View file

@ -74,12 +74,15 @@ namespace Geekbot.Core
* Intergrations * * Intergrations *
************************************/ ************************************/
[Option("sumologic", HelpText = "Sumologic endpoint for logging (default: null) (env: SUMOLOGIC)")] // [Option("sumologic", HelpText = "Sumologic endpoint for logging (default: null) (env: SUMOLOGIC)")]
public string SumologicEndpoint { get; set; } = ParamFallback("SUMOLOGIC"); // public string SumologicEndpoint { get; set; } = ParamFallback("SUMOLOGIC");
[Option("sentry", HelpText = "Sentry endpoint for error reporting (default: null) (env: SENTRY)")] [Option("sentry", HelpText = "Sentry endpoint for error reporting (default: null) (env: SENTRY)")]
public string SentryEndpoint { get; set; } = ParamFallback("SENTRY"); public string SentryEndpoint { get; set; } = ParamFallback("SENTRY");
[Option("datadog-api-key", HelpText = "Datadog API Key (default: null) (env: DATADOG_API_KEY)")]
public string DatadogApiKey { get; set; } = ParamFallback("DATADOG_API_KEY");
/************************************ /************************************
* Helper Functions * * Helper Functions *
************************************/ ************************************/

View file

@ -1,6 +1,7 @@
using System; using System;
using Geekbot.Core.Logger; using Geekbot.Core.Logger;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Serilog.Events;
namespace Geekbot.Web.Logging namespace Geekbot.Web.Logging
{ {
@ -45,7 +46,7 @@ namespace Geekbot.Web.Logging
public bool IsEnabled(LogLevel logLevel) public bool IsEnabled(LogLevel logLevel)
{ {
return !_geekbotLogger.LogAsJson() && _geekbotLogger.GetNLogger().IsEnabled(ToGeekbotLogLevel(logLevel)); return !_geekbotLogger.LogAsJson() && _geekbotLogger.GetLogger().IsEnabled(ToGeekbotLogLevel(logLevel));
} }
public IDisposable BeginScope<TState>(TState state) public IDisposable BeginScope<TState>(TState state)
@ -53,17 +54,16 @@ namespace Geekbot.Web.Logging
return null; return null;
} }
private static NLog.LogLevel ToGeekbotLogLevel(LogLevel level) private static LogEventLevel ToGeekbotLogLevel(LogLevel level)
{ {
return level switch return level switch
{ {
LogLevel.Trace => NLog.LogLevel.Trace, LogLevel.Trace => LogEventLevel.Verbose,
LogLevel.Debug => NLog.LogLevel.Debug, LogLevel.Debug => LogEventLevel.Debug,
LogLevel.Information => NLog.LogLevel.Info, LogLevel.Information => LogEventLevel.Information,
LogLevel.Warning => NLog.LogLevel.Warn, LogLevel.Warning => LogEventLevel.Warning,
LogLevel.Error => NLog.LogLevel.Error, LogLevel.Error => LogEventLevel.Error,
LogLevel.Critical => NLog.LogLevel.Fatal, LogLevel.Critical => LogEventLevel.Fatal,
LogLevel.None => NLog.LogLevel.Off,
_ => throw new ArgumentOutOfRangeException(nameof(level)) _ => throw new ArgumentOutOfRangeException(nameof(level))
}; };
} }