NLog's behavior can be configured both via configuration files and programmatically.
It seems like when I set up programmatic rules, any configuration file present is still processed, so both mechanisms are in play at the same time. Is this accurate?
Is it possible to set up NLog to use only programmatic rules and prevent it from reading any config files?
To expand on Sergey's answer, suppose you have a LogFactory:
var factory = new LogFactory()
When this is created, it tries to read configuration data from a configuration file. You can adjust, or supplement, this configuration
factory.Configuration.LoggingRules.Add( ... )
However you can also just replace the configuration with your own:
factory.Configuration = new LoggingConfiguration();
In this case, any configuration that got loaded is discarded and now you are proceeding with just the rules that you create in code.
LoggingConfiguration config = new LoggingConfiguration(); //Create configuration object in code
Logger Log = LogManager.GetCurrentClassLogger(); //Load configuration from xml file
if you use one of these methods, respectively, and it will work
more info: https://github.com/nlog/nlog/wiki
Related
Is there a way to restart the log files using the configured parameters in the config file as if the application was relaunching?
I have file appenders that put the date in the file name, and on certain events I want to close that log and start a new one with the current date/time.
It looks like there is a reset function in the appender class that should do the job, but it is inaccessable.
If found a post that manually sets a new filename and calls the ActivateOptions() function to create a new file, but I don't want to manually set the file name. I want it autogenerated with the pattern that is in the config file.
Any ideas would be appreciated!
Thanks,
John Vickers
I'm developing a windows desktop application with C# .NET4.0 VS2010 on Windows 8.1. I've a range of settings that I store using the .NET settings mechanism. These have user scope so, when set within the application they are written to Users\username\AppData\Local\companyname\App.exe_URL_randomstuff\versionno\user.config.
These settings include some user registration information that I need to keep hidden. My research suggests that I should be able to encrypt settings using an RsaProtectedConfigurationProvider but all the examples I've found for this relate to encrypting app.config rather than user.config (e.g. http://msdn.microsoft.com/en-us/library/system.configuration.rsaprotectedconfigurationprovider.aspx).
My question therefore is can user.config be encrypted and if so how? I note that when I instance a System.Configuration.Configuration object I can set the ConfigurationUserLevel to PerUserRoamingAndLocal. When I examine the object via the debugger it seems to be refering to the correct user.config file but when I go on to instance a ConfigurationSection to protect it returns null. The code looks like this:
System.Configuration.Configuration config =
ConfigurationManager.OpenExeConfiguration(
ConfigurationUserLevel.PerUserRoamingAndLocal);
ConfigurationSection connStrings = config.AppSettings;
connStrings.SectionInformation.ProtectSection(provider);
I'm thinking that config.AppSettings is probably not correct but I'm not sure what to replace it with.
Any advice greatly appreciated.
Got it working now. I was correct to be using ConfigurationUserLevel.PerUserRoamingAndLocal to access my user.config file. The problem was with config.AppSettings. I was on the right track replacing this with config.GetSection("Progname.Properties.Settings") but I got the naming wrong. The working code now is as follows:
System.Configuration.Configuration config =
ConfigurationManager.OpenExeConfiguration(
ConfigurationUserLevel.PerUserRoamingAndLocal);
ConfigurationSection connStrings = config.GetSection("userSettings/Progname.Properties.Settings");
connStrings.SectionInformation.ProtectSection(provider);
"Progname" is whatever your assembly is called. Thanks to #neoistheone and #hatchet for your input.
I'm setting up a dll to be used as a third party dll for a different application. I want this dll to have it's own logging so the external application doesn't have to deal with setting up anything (I don't believe they use the same logging as we do). I've read that may not be the best solution but it's the task I've been given. We want to use log4net with this. I've looked at a few of the other questions on here and they mention that it is configurable via code, however, the main issue I'm having is that there is no clear cut entry point into our code to configure log4net. I'm curious if I should just abandon having the dll configure itself and have a method that is called by the secondary application that configures the dll's logging or if there is a better way to go about this. Any input would be much appreciated
You can configure log4net programmatically. Perhaps add this code to the constructor of your DLL.
if (!log4net.LogManager.GetRepository().Configured)
{
// my DLL is referenced by web service applications to log SOAP requests before
// execution is passed to the web method itself, so I load the log4net.config
// file that resides in the web application root folder
var configFileDirectory = (new DirectoryInfo(TraceExtension.AssemblyDirectory)).Parent; // not the bin folder but up one level
var configFile = new FileInfo(configFileDirectory.FullName + "\\log4net.config");
if (!configFile.Exists)
{
throw new FileLoadException(String.Format("The configuration file {0} does not exist", configFile));
}
log4net.Config.XmlConfigurator.Configure(configFile);
}
I'm writing a game server in C# and would like to reload or refresh settings from a config file while the server is running.
Ideally I would like to save the settings in an XML file, have the ability to edit
the file while the game server is running and then send the server the command to reload
the settings from the file.
I know I can use a database to do this as well, but the game server is fairly small and I think it would be more practical to just save settings in a flat-file. I will have file-level access to the machine the server will run on.
What should I use?
Use http://msdn.microsoft.com/en-us/library/system.configuration.configurationmanager.aspx
Use a Custom Configuration Section, hookup the sections from the app.config to external config file(s) by setting the location attrib of the section. All xml loading and serialization is done by those custom classes
Code provided by CarelZA:
First of all, ConfigurationManager caches the application's configuration by config section, and you can call ConfigurationManager.RefreshSection() to invalidate the cache for a specific section.
In app.config I added:
<configSections>
<section name="gameSettings"
type="System.Configuration.NameValueSectionHandler,system , Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, Custom=null"/>
</configSections>
<gameSettings configSource="game.config"/>
I created a file called "game.config" and set "Copy to Output Directory" to "Copy always".
In game.config:
<gameSettings>
<add key="SettingName" value="SettingValue" />
</gameSettings>
Then in code, in order to access any setting:
settings = (NameValueCollection) ConfigurationManager.GetSection("gameSettings");
return settings["SettingName"];
And to reload the game config at any time when the reload command is sent to the server:
ConfigurationManager.RefreshSection("gameSettings");
As per request posting my comment as an answer:
You can set it up so the server auto-loads the file settings with FileSystemWatcher. If you use a custom Settings class, you can simply lock the class, reload it from a file and unlock it (if you are using multiple threads).
Reading/writing from/to file or serialization is so trivial in .NET that that is probably not what you need help with and there are many options how to do it.
Sounds like a job for XML Serialization! Instead of manually parsing and editing XML, you can easily achieve this same effect by creating a settings object, serializing it to XML, and de/serializing it when you need to make modifications. This way, you could hot swap configuration files.
using System.Xml.Serialization;
For instance, you could have the object
public class Settings
{
public string SomeProperty {get; set;}
public string SomeProperty2 {get; set;}
}
Save it to your disk as,
var settings = new Settings {SomeProperty="Hello", SomeProperty2="Joe"};
var fs = new FileStream("settings.xml");
var xs = new XmlSerializer(settings.GetType());
xs.Serialize(fs,settings);
Read it back in as,
var fs = new FileStream("settings.xml");
var settings = (Settings)fs.Deserialize(fs);
Check out the MemoryCache in System.Runtime.Caching (.NET 4.0). You could write yourself a simple class which performs the following steps:
Load the XML file
Parse its contents into whatever representation you want them in
Store the output in the cache with a HostFileChangeMonitor watching it - this will cause it to be removed from the cache automatically when the file is changed
Before performing any of the above, you'd check the cache to see if a previously-cached copy of the settings exists and only proceed if it doesn't.
The advantage of rolling your own approach like this is that you do not trigger restarts of the application as is the case with AppSettings stored in your web.config or app.config files. (It should be said that this is not the only way of achieving this)
simple question how do i change the connection string of the nhibernate at runtime ?
<property name="connection.connection_string" >value</property>
nevermind i got it.
Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
var root = XElement.Load(configuration.FilePath);
root.Elements().Where(m => m.Name.LocalName == "hibernate-configuration").First().Elements().First().Elements().Where(m => m.FirstAttribute.Value == "connection.connection_string").First().Value = cs;
root.Save(configuration.FilePath);
Tinkering with your app.config on the fly is a bit horrible.
I'd suggest not storing your connection string amongst the other nhibernate settings. Keep your various connection strings elsewhere (e.g. in appSettings), then set the appropriate connection string directly against your NH Configuration:
var configuration = new Configuration();
configuration.SetProperty("connection.connection_string", "...connection string...");
configuration.Configure();
Just make sure that the connection.connection_string setting is not specified in your config file, as configuration.SetProperty will only work correctly if the setting is not there already.
When you need to switch connections based on some conditions (such as having one website with live and demo mode, each with different connection string) then it´s probably best to implement a class inherited from DriverConnectionProvider and set this class as value of the connection.provider configuration property in your config file.
See http://jasondentler.com/blog/2009/11/authentication-impersonation-and-dynamic-nhibernate-connection-strings/
I would personally go with Enterprise Library and its Data Access Application Block to provide the NHibernate sessions APIs with proper named connectiong strings when instantiating a session API.
The DAAB has the feature to instantiate a DbConnection based on the configuration file. So you could possibly use several connection strings definition, and tell DAAB what connection to use, then pass it to your NHibernate session so that you may work with NHibernate against multiple datastores at once.
Using this approach will avoid you messing with the configuration file on runtime, and even allows you to create your own connections instance without having them defined in the configuration file at once.