I am in search of method or ways to log data into multiple tables using NLog. I have more than one log tables with different structures in my case. And, I would like to log two different datas in these two tables.
Please let me know if there is a way to configure NLog to handle two different tables while logging.
You need two database targets, one for each table.
e.g.
<targets>
<target name="table1" xsi:type="Database"
... />
<target name="table2" xsi:type="Database"
... />
</targets>
<rules>
<logger name="logger1" minlevel="Info" writeTo="table1" />
<logger name="logger2" minlevel="Info" writeTo="table2" />
</rules>
Related
NLog 4.6.6
I have tried everything to get a specific logger disabled and can't get it to work. I'm wondering if it's a bug in NLog. Based on documentation:
There is one more level, Off. Since it is the highest value and is not used for entries, it disables logging when used as the minimum log level.
and:
In case a rule is marked as final and contains any level-declaring attributes, the final attribute applies only to the specified levels.
So if I do the internet-recommended route (even this SO answer), it still gets logged.
<logger name="Example.*" minlevel="Off" final="true" />
<logger name="*" minlevel="Trace" writeTo="file" />
It is important for the answer to show the logger as disabled -- in order to short-circuit expensive debug code -- and not just dump it into the Null target.
A little farther down on the documentation linked in the question in the examples, there is this:
<logger name="Name.Space.*" minlevel="Debug" maxlevel="Error" final="true" />
<logger name="*" writeTo="f1" />
Configures to ignore messages from any class in the Name.Space
namespace with level between Debug and Error (which is Debug, Info,
Warn, Error). The first rule selects loggers, but since there is no
writeTo, these messages are not logged. And, since this rule contains
'final=true', the last rule does not apply to loggers matching the
first rule.
I tried the following and it worked:
<logger name="Example.*" minlevel="Trace" final="true" />
<logger name="*" minlevel="Trace" writeTo="file" />
The key was to just specify the lowest level (Trace) as minlevel, not Off. And that matches the rules of what the documentation says.
I'm guessing this has changed over the versions and hence the confusion.
I have two layouts in nlog.config. once is Default layout and other one is ErrorLayout in which have additional properties.
the problem is i want to add target and i want to use both layout for LogLevel.Error i have to use ErrorLayout and for the other levels i have to use DefaultLayout. i don't want to create two target because two targets creating two different file and store logs into it.
but i want to both layout into one target.
can I able to do that? How ?
can anyone help me to do this ?
Another option is you use two targets, targeting the same file. If you don't enable keepfileopen, then this is also a good solution.
For example:
<nlog>
<targets>
<target type="file" name="erp" layout="${message}" fileName="log-${shortdate}.log" />
<target type="file" name="erp-error" layout="${message} ${exception:format=tostring}" fileName="log-${shortdate}.log" />
</targets>
<rules>
<logger name="*" minLevel="Error" writeTo="erp-error" final="true" /> <!-- after match events won't be processed futher due to the final attribute -->
<logger name="*" minLevel="Debug" writeTo="erp" />
</rules>
</nlog>
Right now your DefaultLayout and ErrorLayout are quite simple, so you can just do this:
<nlog>
<variable name="DefaultLayout" value="${message}" />
<variable name="ErrorLayout" value="${message} ${exception:format=tostring}" />
<variable name="DynamicLayout= value="${when:when=level<=LogLevel.Info:inner=${DefaultLayout}:else=${ErrorLayout}}" />
<targets>
<target type="file" name="erp" layout="${DynamicLayout}" fileName="log-${shortdate}.log" />
</targets>
<rules>
<logger name="*" minLevel="Debug" writeTo="erp" />
</rules>
</nlog>
See also https://github.com/nlog/NLog/wiki/When-Layout-Renderer
Notice NLog might perform poorly if you include heavy layoutrenders in the ErrorLayout. Ex. like ${callsite}
I'd like to setup a way to easily include/exclude certain log messages from an all encompassing log file. Throughout my code I've logged messages based on a "Context" property, which I was then going to use in when conditions to include/exclude the message.
Here is my setup:
<logger writeTo=""
final="true">
<filters>
<when condition="equals('${event-properties:item=Context}', 'Database')"
action="Log"/>
</filters>
</logger>
<logger name="*"
minlevel="Trace"
writeTo="default"/>
My hope was that I could include/exclude any messages with Context='Database' in the first logger and then change the writeTo attribute to either include the message (i.e. writeTo="default") or exclude (i.e. writeTo="").
The issue seems to be that the first logger is including ALL messages and since final is set to true, no messages are allowed to follow through to the catch all logger? Only logs matching the condition in the logger one are written as expected, however ALL logs are being "finalized" by it.
Any ideas a to what is wrong with my configuration?
Maybe try this instead (Remove final="true" and instead use action="LogFinal")
<targets>
<target xsi:type="Null" name="BlackHole" />
</targets>
<rules>
<logger writeTo="BlackHole">
<filters>
<when condition="equals('${event-properties:item=Context}', 'Database')"
action="LogFinal"/>
</filters>
</logger>
</rules>
Looks like you have to specify an actual target to make the custom logger-filters work (Not dependent on LogLevel).
I have a logger that configured to multiple targets. Can I filter targets with some conditions?
<logger name="actionsLogger" minlevel="Info" writeTo="fileTarget,rmqTarget1,rmqTarget2" />
I need to always write actions to fileTarget and in some cases to rmqTarget1 and rmqTarget2. Maybe solution is to create multiple loggers with their own targets. But I can't change source code of the project and recompile.
Thanks for the reply. I have found the solution. FilteringWrapper - https://github.com/NLog/NLog/wiki/FilteringWrapper-target. It applies filter for target instead of filter for logger.
<target
xsi:type="FilteringWrapper"
condition="'${event-context:item=Status}'=='Success'"
name="rabbitMQFilteringTarget">
<target
xsi:type="RabbitMQ"
name="rabbitMQTarget"
...
</target>
</target>
Take a look at Conditions on the NLog wiki.
Conditions are filter expressions used with the when filter. They consist of one or more tests. They are used in the when filter to determine if an action will be taken.
You can do this with conditions:
<logger name="actionsLogger" minlevel="Info" writeTo="fileTarget" />
<logger name="actionsLogger" minlevel="Info" writeTo="rabbitMQTarget">
<filters defaultAction="Log">
<when condition="'${event-property:item=Status}'=='Success'" action="Ignore" />
</filters>
</logger>
I have an app where sometimes I'd like to log in Debug mode. Unfortunately i link with a third party lib that I can't rebuild. It was built to use log4net and on the Debug mode it is very verbose.
I don't want to get any notifications from that library. I do however want to get log notifications from all other code that wants to write.
Is there a way to exclude a namespace or library from logging when using either the SMTPAppender or RollingFile Appender writers?
You could use a filter, e.g.
<filter type="log4net.Filter.LoggerMatchFilter">
<!-- allows this sub-namespace to be logged... -->
<loggerToMatch value="Noisy.Namespace.But.Important" />
</filter>
<filter type="log4net.Filter.LoggerMatchFilter">
<!-- ...but not the rest of it -->
<loggerToMatch value="Noisy.Namespace" />
<acceptOnMatch value="false" />
</filter>
More details from this article.
Im imagine that you are using a configuration where you set only the root level of your logging infrastructure:
<root>
<level value="DEBUG" />
<appender-ref ref="A1" />
</root>
However it is possible to define other levels of logging using the logger names. If you or the third party app followed standard practices, your loggers are named after the class they live with its namespace, so you will have loggers called
MyApp.Main
MyApp.Business
MyApp.Business.Messages
ThirdParty.API
etc...
What you can do in this case is declare the logging at the namespace level you're interested in. For example to log only what lives under MyApp.Main add the following
<logger name="MyApp.Main">
<level value="DEBUG" />
<appender-ref ref="A1" />
</logger>
and remove any appender from the root level. Then you only log the loggers that live under the MyApp name. See the documentation for more info.
If you are unlucky and the loggers don't conform to this hierarchy, you can still filter them out by using a LoggerMatchFilter in your appender; this lets you either define what logger can pass, or what loggers cannot. There are lots of filters, feel free to explore them