Can you set a property value within the log4net config? - log4net

I'm working on a C# application that will have quite a few log files. These log files will be created in the same file path, and this file path will be determined at configuration time.
Is there a way I could specify this log files basepath in a single location the log4net configuration e.g. in a property?
I'd, of course, be referencing this basepath in the file param of each logfile appender?
One option I've considered is setting this path in the app.config/web.config, which the application will transfer into a log4net global context property. However, that would mean making sure that all loggers are created AFTER this property is set.
Any comments on the preferred, or the fallback method are welcome.
cheers!

You can implement a log4net custom pattern converter to return the basepath for logfiles. This is explained here: https://stackoverflow.com/a/4389828/910348.
The difference for your scenario is that your converter can simply read the basepath from your app.config/web.config.
Cheers!

Related

Cannot change zookeeper log filename

Zookeeper is creating the logs with a name zookeeper-root-hostname.out but this is my log4j.properties:
zookeeper.root.logger=INFO, CONSOLE
zookeeper.console.threshold=INFO
zookeeper.log.dir=.
zookeeper.log.file=zookeeper.log
zookeeper.log.threshold=INFO
zookeeper.log.maxfilesize=256MB
zookeeper.log.maxbackupindex=20
zookeeper.tracelog.dir=${zookeeper.log.dir}
zookeeper.tracelog.file=zookeeper_trace.log
log4j.rootLogger=${zookeeper.root.logger}
#
# console
# Add "console" to rootlogger above if you want to use this
#
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=${zookeeper.console.threshold}
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} [myid:%X{myid}] - %-5p [%t:%C{1}#%L] - %m%n
#
# Add ROLLINGFILE to rootLogger to get log file output
#
log4j.appender.ROLLINGFILE=org.apache.log4j.RollingFileAppender
log4j.appender.ROLLINGFILE.Threshold=${zookeeper.log.threshold}
log4j.appender.ROLLINGFILE.File=${zookeeper.log.dir}/${zookeeper.log.file}
log4j.appender.ROLLINGFILE.MaxFileSize=${zookeeper.log.maxfilesize}
log4j.appender.ROLLINGFILE.MaxBackupIndex=${zookeeper.log.maxbackupindex}
log4j.appender.ROLLINGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.ROLLINGFILE.layout.ConversionPattern=%d{ISO8601} [myid:%X{myid}] - %-5p [%t:%C{1}#%L] - %m%n
If a change the property zookeeper.log.file=zookeeper.log the file is created with the same name, How can I change the filename of the log?
Update
I found that the file zkServer.sh set the variable ZOO_LOG_FILE and overrides the value that is define in the log4j.properties:
ZOO_LOG_FILE=zookeeper-$USER-server-$HOSTNAME.log
I can modify this file but Is it ok to change that manually?
In typical Java application fashion the logging situation with Zookeeper is incredibly complicated, custom, and poorly documented. The official Administrators manual logging section is a tiny paragraph with about zero information, but suggests you can rely on your existing knowledge of the third party library log4j configured to proxy through the other third party library SLF4J. This actually wouldn't be too bad since that complicated arrangement is common as many popular open source projects ignore the built-in logging framework that ships will Java, but later you'll discover using the log4j.properties file in the conf directory actually doesn't work as expected because custom properties are used in the provided start up script (zkServer.sh) that override many things.
In order to set the file name note the file conf/log4j.properties contains the following variable assignment that is overridden by the start up script (zkServer.sh):
zookeeper.log.file=zookeeper.log
Either set the environment variables externally, modify the start up script or update the log4j.properties to not use the variable:
#log4j.appender.ROLLINGFILE.File=${zookeeper.log.dir}/${zookeeper.log.file}
log4j.appender.ROLLINGFILE.File=/the/actual/path/goes/here.log
You may also want to enable the ROLLINGFILE like so:
#log4j.rootLogger=${zookeeper.root.logger}
log4j.rootLogger=INFO,ROLLINGFILE
After searching I found this link but I didn't found how to change the variable for the log, I noticed that inside the file zkServer.sh is defined the name of the file, so I needed to change this variable:
_ZOO_DAEMON_OUT="$ZOO_LOG_DIR/zookeeper-$USER-server-$HOSTNAME.out"
I don't know if it's ok to change that variable but now is working as expected.

how to switch log4net multiple log files using C# code?

I'm using log4net, I would like to have 2 logs,
- BasketballCustomer.log, for all Customers that plays Basketball;
- ChessCustomer.log, for all Customers that plays Chess.
, while for each customer, whether he/she plays Basketball or Chess, is only known until runtime.
I would like to have each log configured separately, about log file name, size, number, log level, etc.
Also, I'd prefer such set up done by C# code, not config file.
How could I do that?
I tried search on net, there are some articles but none meet exactly my requirements
- Log4Net and multiple log files talked about multiple log files but it does not toggle during runtime;
- Configure Log4net to write to multiple files is similiar but it's done in config file....
Please kindly suggest, many thanks!
You can do this by using an environment variable in the log4net.config and then set the value of the environment variable through the C# code
So somewhere in your C# class, do something like:
Environment.SetEnvironmentVariable("log_file_name", "MyLogFileName");
And then in the log4net.config that is used, specify the value to the name of the environment variable. The syntax would be something like this:
<param name="File" value="${log_file_name}".log/>

Can we change the settings of the Windows applications app.config?

I have two app.config's in my application where i have written two connectionstrings in one config file and another two in other config file .Now in .cs file i have written this
string Connect = ConfigurationManager.ConnectionStrings["con1"].ConnectionString.ToString();
string Connect = ConfigurationManager.ConnectionStrings["con3"].ConnectionString.ToString();
Now first line gives the connectionstring from app.config.But for the second line am getting an error that "object reference not set to an instance"
Can any one tell me how to use the connection from different app.config's
Per Microsoft's documentation for the ConfigurationManager class, the ConnectionStrings property operates on the current application's default configuration file.
I believe that what you probably want to do is use the OpenExeConfiguration method to read the second app.config file then use the returned Configuration class instead of the static ConfigurationManager.

log4 net Dynamic file name assigning

I want to know how to dynamically assign file name using Log4net .My application is such that 10 different files should be dynamically created based on user input ,and later based on the name the corresponding file name needs to be picked up and information written to it
For example in my application based on my buisness requirement for every xml file a corresponding log file with the same name as xml file should be created .Later whenever I do any modification to the xml file an entry needs to be in the corresponding log file
Please help . I having trouble to get control of the appropriate log to write it
Have not done this, but there are probably a number of ways of doing this, so this may not be the best way, but it should work
public OpenLogFile(string fileName)
{
log4net.Layout.ILayout layout = new log4net.Layout.PatternLayout("%d [%t]%-5p : - %m%n");;
log4net.Appender.FileAppender appender = new log4net.Appender.FileAppender(layout , filename);
appender.Threshold = log4net.Core.Level.Info;
log4net.Config.BasicConfigurator.Configure(appender);
}
Then just call OpenLogfile when you need to switch files.
You might need to tweak the layout or appender type.
A big disadvantage of this method is you losing the xml configuration and the ability to change settings at runtime. So a better way might be to configure your appender in the xml file to use a property
eg
file type="log4net.Util.PatternString" value="Logfiles\Log_For_%property{MyLogFileName}"
Then in your code you could change the property
log4net.GlobalContext.Properties["MyLogFileName"] = ...;
The tricky bit is to get log4net to reload itself. I haven't read the documentation of this, so I don't know if there is a way of forcing a reload. It might work if you just call log4net.Config.XmlConfigurator.ConfigureAndWatch again. Otherwise it should work if you opened the xml file and saved it again (without needing to change anything)
Hope this helps.

log4j, fileappender and tomcat6 logs question

I have seen many questions about the above topics but none that address this.
I am trying to use log4j to log to a custom file in $CATALINA_BASE/logs/ directory.
I configured the log4j.xml file and copied it into the $CATALINA_BASE/lib/ directory.
I use the following lines to create the logger -
PatternLayout layout = new PatternLayout();
FileAppender appender= new FileAppender("filename.txt");
This is where my problem is. How do I make the FileAppender take the file name I configured in the log4j.xml?
I was hoping it will automatically pick that up, but there is no consructor for FileAppender that will not take a filename.
Do I have to read the log4j.xml to get the name of the file? If so why in the world do I need to set that property in the xml at all?
Any help would be greatly appreciated.
Thanks,
- Vas
Hmm... why are you creating a FileAppender in code? Just create a logger using LoggerFactory specifying the string (usually in com.xxx.yyy format that you configured in the log4j XML/properties file) and start logging. Make sure the logger is configured to use the FileAppender implementation (Daily or RollingFile) in the config file and you are all set to go.

Resources