Nlog: Custom print layout for LogEventInfo

Created on 16 Feb 2017  路  6Comments  路  Source: NLog/NLog

Type: Feature request
NLog version: 4.4.2
Platform: .NET 4.5, others

Why do we need it?
Use case: all log messages should go to File/Console, only specific log messages should go to EventViewer.
When I log to EventViewer I want to specify Category and EventId. The only way to do it (to the best of my knowledge) is using LogEventInfo. Because I don't use LogEventInfo to create all log statements, my logs don't look consistently in the file/console:

2017-02-16 18:16:27.3777 ERROR TestApp.Program.Main Thread#9 Just a simple message
2017-02-16 18:16:27.3777 ERROR TestApp.Program.Main Thread#9 Log Event: Logger='TestApp.Program' Level=Error Message='Just a simple message logged with LogEventInfo' SequenceID=2

I understand the reason why LogEventInfo is logged with all this information, but in my situation I don't need Level and Logger name to appear twice, as well as words 'Log Event', 'Message' and even SequenceID. I only use LogEventInfo because of Category and EventId and it would be cool to make all log statements to look consistently in file/console.

Any thoughts?

Target layout looks like this:
layout="${longdate:universalTime=true} ${uppercase:${level}} ${callsite} Thread#${threadid} ${message}"

Thank you!

question

Most helpful comment

ow I see the problem.

There is a Logger.Log(LogEventInfo), but there is not a Logger.Error(LogEventInfo). The latter would be strange, as the loglevel is in the LogEventInfo (and which one should have preference?)

But there is a Logger.Error(object), which is doing obvious ;) as toString. So that explains the Log Event: Logger='TestApp.Program' Level=Error Message='Just a simple message logged with LogEventInfo' SequenceID=2

PS you could also use the fluent interfac, if you like:

```c#
using NLog.Fluent;

...

logger.Error()
.Message("test")
.Property("EventId", 29)
.Property("Category",40)
.Write(); //don't forget .Write()
```

All 6 comments

Could you please post some examples of calling the logger?

The one I used to generate statements from above looks like this:

var log = LogManager.GetCurrentClassLogger();
log.Error("Just a simple message");
var theEvent = new LogEventInfo(LogLevel.Error, log.Name, "Just a simple message logged with LogEventInfo");
theEvent.Properties["EventId"] = 29;
theEvent.Properties["Category"] = 40;
log.Error(theEvent);

However after your request to post the calling code I found, that if I change the last line to:

log.Log(theEvent);

then it will generate the following output:

2017-02-16 19:47:12.4398 ERROR TestApp.Program.Main Thread#9 Just a simple message
2017-02-16 19:47:12.4710 ERROR TestApp.Program.Main Thread#9 Just a simple message logged with LogEventInfo

which is basically exactly what I need. So this feature request can be closed.
Just because of curiosity, can you please clarify what is the reason to print LogEventInfo differently in case of log.Log and log.Error(Debug/Info/etc). Or where can I read more about this? Thanks.

is this NLog 4.5 beta? Which version exact?

Sorry for confusion. It is actually everywhere. The latest release (4.4.2) has it as well as the latest master.

ow I see the problem.

There is a Logger.Log(LogEventInfo), but there is not a Logger.Error(LogEventInfo). The latter would be strange, as the loglevel is in the LogEventInfo (and which one should have preference?)

But there is a Logger.Error(object), which is doing obvious ;) as toString. So that explains the Log Event: Logger='TestApp.Program' Level=Error Message='Just a simple message logged with LogEventInfo' SequenceID=2

PS you could also use the fluent interfac, if you like:

```c#
using NLog.Fluent;

...

logger.Error()
.Message("test")
.Property("EventId", 29)
.Property("Category",40)
.Write(); //don't forget .Write()
```

Ok, thanks for clarifications. It does make sense. Yes, that's true: Logger.Error(LogEventInfo) would be weird. It goes to Log.Error(T value). Intuitively I would expect from such call something like overriding the loglevel from the LogEventInfo.
The existing behavior is a bit non-intuitive... Ideally it will be worthwhile to add some kind of check at compile, something like code contract (but it requires project settings change) with the message "hey, you really want to use Logger.Log". Or may be we can just add a detailed example of EventLog usage to Tutorial...

I think this issue can be closed. Thank you.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sszost picture sszost  路  3Comments

Jerefeny picture Jerefeny  路  3Comments

imanushin picture imanushin  路  3Comments

Sam13 picture Sam13  路  3Comments

JustArchi picture JustArchi  路  3Comments