How can I separate my normal
logging/auditing from my security logging/auditing? The Windows Event Log makes this distinction with Application Events and Security Events.
If I could create a custom LogLevel, e.g. LogLevel.AuditSuccess or LogLevel.AuditFailure, then I could set my config file rules to equal these and output those events. For example,
<logger name="*" levels="AuditSuccess,AuditFailure" writeTo="target1"/>
<logger name="*" levels="DEBUG,INFO" writeTo="target1"/>
Then I could just use 1 table, record the "Level" in a column, and be able to search and sort my data using this column info. (I don't think we can create a custom LogLevel.)
One workaround that I come up with is to use 2 loggers per class--with each logger being saved to a different target. However, this seems like overkill, especially if I need to add additional similar target types.
<logger name="myNamespace.*" levels="INFO,ERROR" writeTo="target1"/>
<logger name="mySecurityLogger" levels="INFO,ERROR" writeTo="target2"/>
public class MyClass {
private static Logger _logger = LogManager.GetCurrentClassLogger();
private statac Logger _loggerSecurity = LogManager.GetLogger("mySecurityLogger");
...
}
With this, I could create two database targets--each with a different table--and then create 1 rule for each destination target.
Any suggestions?
How do you use NLog for multiple projects in the same solution? If you want to log in other projects within the solution, just reference NLog. dll directly in each of the projects and use it. But now you only need to configure NLog in your main application.
NLog supports semantic/structured logging known from similar frameworks like Serilog and Microsoft. Extensions. Logging. With structured logging, you no longer log just simple text messages.
By default, the web. nlog file can be found at: C:\Program Files (x86)\Pleasant Solutions\Pleasant Password Server\www\web.
Targets - the destinations of a logevent, e.g. file, database, console. Layout - the layout e.g. json, csv, plain-text (default)
This might not be what you are after, but bear with me ...
You could wrap NLog such that you can log with your own "loggers". Have a look at Common.Logging for .NET or SLF for examples of how to wrap NLog (they are full logging abstractions, so they are more complex than what you are after, but you might pick up some good ideas). Also see here (probably should look here first if you think that you might be interested in simply wrapping or subclassing the NLog Logger) for examples of how to wrap (or subclass) NLog correctly (note that the key is to pass the type of your wrapped/subclassed logger to NLog's Log method).
So, you might have something like this (abbreviated):
//Wrapped logger that you could create once in a class and use to log both
//"normal" messages and "audit" messages. NLog log level is determined by the
//logger configuration for the class.
public class MyLogger
{
private Logger logger; //NLog logger
public MyLogger(string name)
{
logger = LogManager.GetLogger(name);
}
public void Info(string message)
{
if (!logger.IsInfoEnabled) return;
Write(LogLevel.Info, LogLevel.Info.ToString(), message);
}
public void AuditSuccess(string message)
{
if (!logger.IsInfoEnabled) return;
Write(LogLevel.Info, "AuditSuccess", message);
}
private void Write(LogLevel level, string customLevel, string message)
{
LogEventInfo le = new LogEventInfo(level, logger.Name, message);
le.Context["CustomLogLevel"] = customLevel;
logger.Log(typeof(MyLogger), le);
}
}
This will give you level-specific logging methods corresponding to your custom levels. It will also give you the ability to output a custom column containing your "custom level" (using the event-context layout renderer). It does not give you the ability to turn "AuditSuccess" level logging on or off. It must still be controlled by the built-in levels.
Alternatively, you could include two loggers in your wrapped class and use one for built-in levels and the other for custom levels. Your wrapper might look like this:
//Wrapped logger that you could create once in a class and use to log both "normal"
//and "audit" messages. NLog log level for each type of message is controllable
//separately since the logger wrapper actually wraps two logger.
public class MyLogger
{
private Logger logger; //NLog logger
private Logger auditLogger;
public MyLogger(string name)
{
logger = LogManager.GetLogger(name);
auditLogger = LogManager.GetLogger("AuditLogger");
}
public void Info(string message)
{
if (!logger.IsInfoEnabled) return;
Write(logger, LogLevel.Info, LogLevel.Info.ToString(), messsage);
}
public void AuditSuccess(string message)
{
if (!auditLogger.IsInfoEnabled) return;
Write(auditLogger, LogLevel.Info, "AuditSuccess", message);
}
private void Write(Logger log, LogLevel level, string customLevel, string message)
{
LogEventInfo le = new LogEventInfo(level, log.Name, message);
le.Context["CustomLogLevel"] = customLevel;
log.Log(typeof(MyLogger), le);
}
}
You still would have the same restrictions as listed above, but you could at least control "audit/security" logging separately from "normal" logging.
In either case, you can send the output from all loggers to the same database and just do your queries on your "custom level" column rather than the "level" column. Depending on how many security/auditing "categories" you have, you might even want to make a concrete hierarchy such that you can take advantage of the logger hierarchies in the NLog config file:
Security Security.Audit Security.Audit.Success Security.Audit.Failure Security.Login Security.Login.Success Security.Login.Failure Health Health.Heartbeat Health.Whatever
Then you could "turn on" Security or Security.Audit or ..Failure (not sure if that last one works or not).
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With