Skip to content

Commit

Permalink
NLog ExceptionlessTarget: ApiKey and ServerUrl and Message and UserId…
Browse files Browse the repository at this point in the history
…entity with Layout support (#299)

* ExceptionlessTarget - ApiKey and ServerUrl and Message and and UserIdentity and ReferenceId with Layout support

* Resolved review comments from pull-request

* Added support for UserIdentityName + UserIdentityEmail

* Removed support for UserIdentityEmail
  • Loading branch information
snakefoot authored Apr 18, 2023
1 parent 7ed9cc3 commit b7cdc10
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
namespace Exceptionless.NLog {
public static class ExceptionlessClientExtensions {
public static EventBuilder CreateFromLogEvent(this ExceptionlessClient client, LogEventInfo ev) {
return CreateFromLogEvent(client, ev, ev.FormattedMessage);
}

public static EventBuilder CreateFromLogEvent(this ExceptionlessClient client, LogEventInfo ev, string formattedMessage) {
if (client == null)
throw new ArgumentNullException(nameof(client));

Expand All @@ -20,10 +24,10 @@ public static EventBuilder CreateFromLogEvent(this ExceptionlessClient client, L
builder.Target.Date = ev.TimeStamp;
builder.SetSource(ev.LoggerName);

if (ev.Properties.Count > 0) {
if (ev.HasProperties) {
foreach (var property in ev.Properties) {
string propertyKey = property.Key.ToString();
if (_ignoredEventProperties.Contains(propertyKey, StringComparer.OrdinalIgnoreCase))
if (_ignoredEventProperties.Contains(propertyKey))
continue;

if (propertyKey.Equals("@value", StringComparison.OrdinalIgnoreCase)) {
Expand Down Expand Up @@ -53,8 +57,8 @@ public static EventBuilder CreateFromLogEvent(this ExceptionlessClient client, L
builder.SetType(Event.KnownTypes.Error);
}

if (!String.IsNullOrWhiteSpace(ev.FormattedMessage))
builder.SetMessage(ev.FormattedMessage);
if (!String.IsNullOrWhiteSpace(formattedMessage))
builder.SetMessage(formattedMessage);

var tags = ev.GetTags();
if (tags != null)
Expand All @@ -70,10 +74,7 @@ public static void SubmitFromLogEvent(this ExceptionlessClient client, LogEventI
CreateFromLogEvent(client, ev).Submit();
}

private static readonly List<string> _ignoredEventProperties = new List<string> {
"CallerFilePath",
"CallerMemberName",
"CallerLineNumber",
private static readonly HashSet<string> _ignoredEventProperties = new HashSet<string>(StringComparer.OrdinalIgnoreCase) {
"Tags",
"ContextData"
};
Expand Down
31 changes: 22 additions & 9 deletions src/Platforms/Exceptionless.NLog/ExceptionlessTarget.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,39 @@
using System.Collections.Generic;
using NLog;
using NLog.Config;
using NLog.Layouts;
using NLog.Targets;

namespace Exceptionless.NLog {
[Target("Exceptionless")]
public class ExceptionlessTarget : TargetWithLayout {
private ExceptionlessClient _client = ExceptionlessClient.Default;

public string ApiKey { get; set; }
public string ServerUrl { get; set; }
public Layout ApiKey { get; set; }
public Layout ServerUrl { get; set; }
public Layout UserIdentity { get; set; }
public Layout UserIdentityName { get; set; }

[ArrayParameter(typeof(ExceptionlessField), "field")]
public IList<ExceptionlessField> Fields { get; set; }

public ExceptionlessTarget() {
Fields = new List<ExceptionlessField>();
Layout = "${message}";
}

protected override void InitializeTarget() {
base.InitializeTarget();

if (!String.IsNullOrEmpty(ApiKey) || !String.IsNullOrEmpty(ServerUrl))
var apiKey = RenderLogEvent(ApiKey, LogEventInfo.CreateNullEvent());
var serverUrl = RenderLogEvent(ServerUrl, LogEventInfo.CreateNullEvent());

if (!String.IsNullOrEmpty(apiKey) || !String.IsNullOrEmpty(serverUrl))
_client = new ExceptionlessClient(config => {
if (!String.IsNullOrEmpty(ApiKey) && ApiKey != "API_KEY_HERE")
config.ApiKey = ApiKey;
if (!String.IsNullOrEmpty(ServerUrl))
config.ServerUrl = ServerUrl;
if (!String.IsNullOrEmpty(apiKey) && apiKey != "API_KEY_HERE")
config.ApiKey = apiKey;
if (!String.IsNullOrEmpty(serverUrl))
config.ServerUrl = serverUrl;
config.UseInMemoryStorage();
});
}
Expand All @@ -40,9 +47,15 @@ protected override void Write(LogEventInfo logEvent) {
if (logEvent.Level < minLogLevel)
return;

var builder = _client.CreateFromLogEvent(logEvent);
var formattedMessage = RenderLogEvent(Layout, logEvent);
var builder = _client.CreateFromLogEvent(logEvent, formattedMessage);

var userIdentity = RenderLogEvent(UserIdentity, logEvent);
var userIdentityName = RenderLogEvent(UserIdentityName, logEvent);
builder.Target.SetUserIdentity(userIdentity, userIdentityName);

foreach (var field in Fields) {
var renderedField = field.Layout.Render(logEvent);
var renderedField = RenderLogEvent(field.Layout, logEvent);
if (!String.IsNullOrWhiteSpace(renderedField))
builder.AddObject(renderedField, field.Name);
}
Expand Down
8 changes: 4 additions & 4 deletions src/Platforms/Exceptionless.NLog/LogEventBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ public static LogEventBuilder MarkUnhandled(this LogEventBuilder builder, string
}

internal static HashSet<string> GetTags(this LogEventInfo ev) {
if (ev.Properties.ContainsKey(Tags) && ev.Properties[Tags] is HashSet<string>)
return (HashSet<string>)ev.Properties[Tags];
if (ev.HasProperties && ev.Properties.TryGetValue(Tags, out var tags))
return tags as HashSet<string>;

return null;
}
Expand All @@ -109,8 +109,8 @@ private static void AddTags(this LogEventInfo ev, params string[] tags) {
}

internal static IDictionary<string, object> GetContextData(this LogEventInfo ev) {
if (ev.Properties.ContainsKey(ContextData) && ev.Properties[ContextData] is IDictionary<string, object>)
return (IDictionary<string, object>)ev.Properties[ContextData];
if (ev.HasProperties && ev.Properties.TryGetValue(ContextData, out var contextData))
return contextData as IDictionary<string, object>;

return null;
}
Expand Down
11 changes: 5 additions & 6 deletions src/Platforms/Exceptionless.NLog/NLogExceptionlessLog.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using Exceptionless.Logging;
using NLog;
using NLog.Fluent;
using LogLevel = Exceptionless.Logging.LogLevel;

namespace Exceptionless.NLog {
Expand All @@ -19,35 +18,35 @@ public void Error(string message, string source = null, Exception exception = nu
if (LogLevel.Error < MinimumLogLevel)
return;

_logger.ForErrorEvent().Message(message).LoggerName(source).Exception(exception).Log();
_logger.ForErrorEvent().Message(message).LoggerName(source).Exception(exception).Log(typeof(NLogExceptionlessLog));
}

public void Info(string message, string source = null) {
if (LogLevel.Info < MinimumLogLevel)
return;

_logger.ForInfoEvent().Message(message).LoggerName(source).Log();
_logger.ForInfoEvent().Message(message).LoggerName(source).Log(typeof(NLogExceptionlessLog));
}

public void Debug(string message, string source = null) {
if (LogLevel.Debug < MinimumLogLevel)
return;

_logger.ForDebugEvent().Message(message).LoggerName(source).Log();
_logger.ForDebugEvent().Message(message).LoggerName(source).Log(typeof(NLogExceptionlessLog));
}

public void Warn(string message, string source = null) {
if (LogLevel.Warn < MinimumLogLevel)
return;

_logger.ForWarnEvent().Message(message).LoggerName(source).Log();
_logger.ForWarnEvent().Message(message).LoggerName(source).Log(typeof(NLogExceptionlessLog));
}

public void Trace(string message, string source = null) {
if (LogLevel.Trace < MinimumLogLevel)
return;

_logger.ForTraceEvent().Message(message).LoggerName(source).Log();
_logger.ForTraceEvent().Message(message).LoggerName(source).Log(typeof(NLogExceptionlessLog));
}

public void Flush() { }
Expand Down
5 changes: 2 additions & 3 deletions src/Platforms/Exceptionless.NLog/readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,10 @@ minimum log level that will be used until the client retrieves settings from the
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <targets async="true">
    <target xsi:type="Exceptionless, Exceptionless.NLog" name="exceptionless" apiKey="API_KEY_HERE">
    <target type="Exceptionless, Exceptionless.NLog" name="exceptionless" apiKey="API_KEY_HERE">
      <field name="host" layout="${machinename}" />
      <field name="identity" layout="${identity}" />
      <field name="windows-identity" layout="${windows-identity:userName=True:domain=False}" />
      <field name="process" layout="${processname}" />
      <field name="user" layout="${environment-user}" />
    </target>
  </targets>

Expand Down

0 comments on commit b7cdc10

Please sign in to comment.