How do I enable logging in RhinoETL process? - log4net

I have nearly completed my first ETL process that uses Rhino ETL, and I've been able to figure out the way to use the API by referring to the tests.
Great. I have data moving through the pipeline and being written to the db.
However I can't seem to figure out how to enable logging.
the log4net assemblies are there, the log4net object is being created
the WithLoggingMixin class seems to be doing its thing (although I must admit I'm a bit fuzzy on exactly what that is)
in the log4net.config file I have a follingFileAppender set up, and it contains the following:
But no log file is created. When I make a call to Debug() in my code it doesn't do anything because log.IsDebugEnabled is false.
What am I missing?

In Rhino Etl 1.2.3, I was able to get logging to the console by adding the following to items the configuration section of the program's app.config file:
<configSections>
<sectionGroup name="common">
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
</sectionGroup>
</configSections>
<common>
<logging>
<factoryAdapter type="Common.Logging.Simple.ConsoleOutLoggerFactoryAdapter, Common.Logging">
<arg key="level" value="DEBUG" />
<arg key="showLogName" value="true" />
<arg key="showDataTime" value="true" />
<arg key="dateTimeFormat" value="yyyy/MM/dd HH:mm:ss:fff" />
</factoryAdapter>
</logging>
</common>
To log to destinations other than the console, the Common.Logging documentation has information on how to wire up log4net.

Okay. I dug through the [log4net documentation][1] and figured out a way to do it.
First of all I moved the log4net config into the App.config file (in a log4net section) and then executed
log4net.Config.XmlConfigurator.Configure();
during initialization. Now it works.
[1]: http://logging.apache.org/log4net/release/manual/configuration.html#.config Files "Apache log4net documentation"

Related

Nlog - Can I set an action when nlog is done writing to a file?

My current .net core nlog WebAPI config. I'm using:
<targets async="true">
Asynchronous target wrapper allows the logger code to execute more
quickly, by queueing messages and processing them in a separate
thread.
https://github.com/nlog/NLog/wiki/AsyncWrapper-target#async-attribute-and-asyncwrapper
<targets async="true">
<target name="jsonfile" xsi:type="File" fileName="/MyAPI${date:format=yyyy-MM-dd HH-mm-ss}.json" >
<layout xsi:type="JsonLayout">
<attribute name="Date" layout="${date:format=O}" />
</layout>
</target>
</targets>
This creates files every second:
MyAPI_2022-12-08 23-06-28.json
How how can I let nlog do something (f.ex. change the name or move it to another folder) when nlog is done writing to the file? I have a system (Splunk Universal Forwarder) that picks up the logs and I don't want it to pick up the file while it's being written to.
Thanks! :-)

NLog Archive configuration

In some of my programs I have a 30 day rotation as expected with multiple entries from several months, but only 30 log files. In other programs, I have only one day's worth of log files, but still only 30 log files total. What I want to have is just the log file entries from the last 30 days with 30 log files. I guess I don't know what I am missing.
Yesterday one of my log files was overwritten when the program started back up so I lost the data that would tell me what happened. Then my second question is, does archiving just remove the files that don't fit the pattern or does it actually take the log files and put them somewhere? What really is archiving? Here is my nlog.config:
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!--
See https://github.com/nlog/nlog/wiki/Configuration-file
for information on customizing logging rules and outputs.
-->
<variable name="LogDir" value="${specialfolder:folder=MyDocuments}/MyApp/Log"/>
<variable name="LogDay" value="${date:format=dd}"/>
<targets async="true">
<!-- add your targets here -->
<target name="LogTarget1"
xsi:type="File"
fileName="${LogDay}.log"
encoding="utf-8"
maxArchiveFiles="30"
archiveNumbering="Sequence"
archiveAboveSize="52428800"
archiveFileName="${LogDay}.{#######}.log"
layout="${date:format=MM/dd/yyyy HH\:mm\:ss}|${level:uppercase=true}|${message}" />
</targets>
<rules>
<!-- add your logging rules here -->
<logger name="*" minlevel="Trace" writeTo="LogTarget1" />
</rules>
</nlog>
This is a shortcoming of NLog which isn't documented well.
When files should be deleted (e.g. max archives files) then the log files and archive files can't be in the same folder.
So one fix for this config would be to change the archifeFilePath to
archiveFileName="archive/${LogDay}.{#######}.log"
See also this issue on GitHub

Is there a way to exclude a project from being logged?

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

log4net creates 2 log files instead of expected one, when log4net is configure both in mine and 3rd party dll

I have 2 projects in my solution, both of class library type.
Actions: Project which contains actions, written using White (UI automation framework over MS UI Automation)
Tests: Project with test fixtures and test methods, using MbUnit
I decided to add logging using log4net for both projects. The log4net configuration I'm using is below:
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file type="log4net.Util.PatternString"
value="c:/AutomationLog/Automation_%date{dd.MM.yy_HH.mm.ss}.log" />
<appendToFile value="false" />
<rollingStyle value="Once" />
<maxSizeRollBackups value="-1" />
<maximumFileSize value="10MB" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level %date{HH:mm:ss,fff} %logger - %message%newline" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="RollingLogFileAppender" />
</root>
<logger name="root">
<level value="OFF" />
</logger>
</log4net>
I would like that one file is created each run (one per fixture suite run). But two files are created:
Automation_27.01.13_07.33.53.log
Automation_27.01.13_07.33.53.log.1
After investigation I found that log is spitted into 2nd file each time in the same place -- when actions contain types from White is called. Looks like it happens due to White also uses log4net internally.
So, I guess, situation is like this:
I have a class which initializes log4net
I start the fixtures suite
In the tests project there is a class which runs 1st, which contains Log.Info("...")
log file is created
text is appended until..
1st action which references White's types is run from tests project
At this stage a new file is created
I guess it happens because of inside White Dlls there is another call to initialize log4net, it is hard coded inside
Any idea how to prevent log splitting without modifying the code of White (3rd party dlls)?
I have solved the problem by just renaming the config file, white looks for log4net.config name. But I still haven't got the answer - is it possible how to force log4net to be initialized just once, and skip future attempts.

Log4Net composite RollingFileAppender with static file extension

Does the current version of Log4net have a way to create a RollingFileAppender with composite rolling style where the rolled files always preserves the given extension (.log in my case)?
Example of the format I would like:
MyLog.log
MyLog.2011-04-10.1.log
MyLog.2011-04-10.2.log
MyLog.2011-04-10.3.log
I found this post which says that there is a "PreserveLogFileNameExtension" property, but that it's not included in the official binaries. Is this still the case?
If so: Can anyone explain why this property is still not an offical part of Log4Net? I am a bit sceptical to use a custom build, but maybe I should not be?
I am also curious to know why the default functionality does not preserve the file extension. I do not see why it would gain the user that all the log files have different extensions.
Edit: Got it working by doing this:
1: Downloading and building the log4net source code
2: Applying these patches: https://issues.apache.org/jira/browse/LOG4NET-64
3: Setting PreserveLogFileNameExtension to "true" in the config.
Have you tried these parameters?
<file value="log-files\MyLog" />
<appendToFile value="true" />
<rollingStyle value="Date" />
<datePattern value="yyyy-MM-dd'.log'" />
<param name="StaticLogFileName" value="false" />
It will preserve the extension, but will give you a date in every filename like this.
MyLog2011-05-16.log
MyLog2011-05-17.log
MyLog2011-05-18.log
MyLog2011-05-19.log
Maybe it is possible to combine this with the size rolling?
The situation is unchanged. There is no newer release of log4net. It is quite unclear to me when (if) there will be a new release...
I think you do not need to worry to much about using a custom build. Test your software, if it works it is good enough.
EDIT: There is a new release that should include LOG4NET-64. Of course you can still stick to your custom build.
I'm using this configuration:
<file value="" />
<appendToFile value="true" />
<rollingStyle value="Date" />
<datePattern value="yyyyMMdd'.log'" />
<staticLogFileName value="false" />
To get filenames like:
20111101.log
20111102.log
20111103.log

Resources