Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NLog - how can I encrypt the logged stacktrace in the database

I am using the latest version of NLog ( from nuget ) and I configure it programmatically. Currently it saves in my database but I would like it to encrypt my stacktrace parameter.

Is there any way that NLog does this automatically? Given that I have a simple function to encrypt the stacktrace is there an easy way to apply it?

like image 879
Thanos Papathanasiou Avatar asked Oct 25 '11 10:10

Thanos Papathanasiou


2 Answers

I would suggest writing a LayoutRendererWrapper. A LayoutRendererWrapper allows you to "wrap" a LayoutRenderer so that you can apply processing to the output. In the case of encrypting the stack trace, you can configure NLog to add the StackTrace to the output, but you can wrap the StackTrace layout renderer so that you can apply your encryption.

You see examples of LayuoutRendererWrappers in NLog's source code repository.

Actually, the general nature of the LayoutRendererWrapper means that you can write an encrypting wrapper and apply it to any LayoutRenderer. So, you could, for example, encrypt the stack trace and the message, but leave the rest of the fields as clear text.

Here is an example (untested) of how you might write an encrypting LayoutRendererWrapper:

namespace NLog.LayoutRenderers.Wrappers
{
  using System.ComponentModel;
  using System.Globalization;
  using NLog.Config;

  [LayoutRenderer("Encrypt")]
  [AmbientProperty("Encrypt")]
  [ThreadAgnostic]
  public sealed class EncryptLayoutRendererWrapper : WrapperLayoutRendererBase    
  {
    public EncryptLayoutRendererWrapper()
    {
      this.Culture = CultureInfo.InvariantCulture;
      this.Encrypt = true;
    }

    [DefaultValue(true)]
    public bool Encrypt { get; set; }

    public CultureInfo Culture { get; set; }

    protected override string Transform(string text)
    {
      return this.Encrypt ? Encrypt(text) : text;
    }

    protected string Encrypt(string text)
    {
      //Encrypt your text here.
    }
  }
}

I think it would be configured like this in the NLog.config file:

${longdate} | ${logger} | ${level} | ${encrypt:${stacktrace}} | ${message}

I'm not sure how you would configure it programmatically as I don't normally use programmatic configuration.

like image 104
wageoghe Avatar answered Nov 01 '22 01:11

wageoghe


Assuming that you have an extension method called Encrypt that you can call on a String object,

I see two solutions:

  • Either you call your encrypt function when logging in your code:

 

logger.Trace("Sample trace message".Encrypt());

 

  • Or you can create new methods to log events and call them instead of the basic NLog.Log() methods:

 

class Log {

    public static void TraceEncrypt(Logger logger, String message) {
        LogEncrypt(logger, LogLevel.Trace, message);
    }

    public static void DebugEncrypt(Logger logger, String message) {
        LogEncrypt(logger, LogLevel.Debug, message);
    }

    public static void InfoEncrypt(Logger logger, String message) {
        LogEncrypt(logger, LogLevel.Info, message);
    }

    public static void WarnEncrypt(Logger logger, String message) {
        LogEncrypt(logger, LogLevel.Warn, message);
    }

    public static void ErrorEncrypt(Logger logger, String message) {
        LogEncrypt(logger, LogLevel.Error, message);
    }

    public static void FatalEncrypt(Logger logger, String message) {
        LogEncrypt(logger, LogLevel.Fatal, message);
    }

    public static void LogEncrypt(Logger logger, LogLevel logLevel, String message) {
        // Prepare log event
        LogEventInfo logEvent = new LogEventInfo(logLevel, logger.Name, message.Encrypt());
        // Log data
        logger.Log(logEvent);
    }
}
like image 43
Otiel Avatar answered Oct 31 '22 23:10

Otiel