Using log4net in .net windows application - c#

We are using log4Net to log messages into files and database from our .Net 3.5 windows application.
The winforms application is deployed on to production environment and is up and running.
Before the deployment, the level node attribute value is set to "ALL".
<level value="ALL"/>
While the application is running, I need to change the level to say "ERROR" and save the xml.And then, the log4net should log only "error" type messages in the log.
How do i achieve this using log4net?
If not feasible,any other approach please?
Thanks.

By default, if you keep your log4net configuration in a separate file (as opposed to in the app.config file) you can update that file and the application will immediately change what level it logs information thanks to the XmlConfigurator in log4net.
If you'd like to update the logging level dynamically from within your application, there's a simple way of doing that thanks to the LINQ to XML capabilities from .Net 3.5+. I've written a blog post outlining how to do that here.

Using
[assembly:
log4net.Config.XmlConfigurator(Watch=true)]
may work, according to the documentation

In the application you would need to have a filewatcher on the config file, then re-run the log4net initialisation on change of config file.

Related

Do we really need ApplicationInsights.config file in C#.NET project?

To log a piece of information like errors, information, warnings and many more we used log4NET library and logging in a local file. But our new requirement, Along with file we need to log this information into Azure Application Insights.
We are working with .NET C# Library,
Is really required ApplicationInsights.config file with .NET C# Project? If not what is the best approach to solving this problem.
Is caching applicationInsights.config instrumentKey? if yes then what will be the solution?
Scenario 1: Tried without adding ApplicationInsights.config file
Output: Log4Net logs are not adding in Azure Application Insights
Scenario 2: Tried with adding ApplicationInsights.config file
Output: Log4Net logs are coming
Scenario 3: When I add Nuget API for ApplicationInsights.Log4NetAppender, It creates log4Net section and includes AIAppender. We have separate log4Net.config and it has only File Appender. We want to use only log4Net.config and remove log4net section from App.Config file.
Output: I removed log4Net section from App.Config and added it in log4Net.config and tested but logs are not adding in Application Insights.
Scenario 4: Implemented TelemetryClient through C# code with ApplicationInsights.config logs are coming in Application Insights
TelemetryClient telemetryClient = new TelemetryClient();
telemetryClient.InstrumentKey =<Your Instrument Key>;
// To test
telemetryClient.TrackTrace("Test through code");
The configuration of Application Insights can be done by any combination of config file and code: only the one, or the other, or both of them.
If you find an ApplicationInsights.config file in your project, it was most probably created by installing one of the Application Insights (AI) Nuget packages, but you can remove it and make the same configuration by code.
To allow the mix of configuration by config file and code, the AI clients and configuration classes have GetDefault() or Active static members that give access to an object which can be used globally. For example, you can see that the Log4Net appender TelemetryClient.cs
uses the active telemetry configuration:
public TelemetryClient() : this(TelemetryConfiguration.Active)
If you check the docs for TelemetryConfiguration.Active you'll see this:
Gets the active TelemetryConfiguration instance loaded from the ApplicationInsights.config file. If the configuration file does not exist, the active configuration instance is initialized with minimum defaults needed to send telemetry to Application Insights.
NOTE: Things are a bit different depending on the platform. For example in .NET Core is more advisable to use dependency injection. Have a look under at your case under Code-base monitoring.
For example, if you have a configuration file like this:
<ApplicationInsights xmlns="http://schemas.microsoft.com/ApplicationInsights/2013/Settings">
<InstrumentationKey>exxxxxxe-axxf-4xx6-bxx2-7xxxxxxxxxx3</InstrumentationKey>
this would take the instrumentation key from it:
_configuration = TelemetryConfiguration.CreateDefault();
If you remove the config file, this will not fail, but you'll need to do set the instrumentation key in code:
_configuration.InstrumentationKey = "exxxxxxe-axxf-4xx6-bxx2-7xxxxxxxxxx3";
If your config file include intializers, modules or whatever, you can also configure them by code. For example:
<TelemetryInitializers>
<Add Type="...MyInitializer, ..." />
</TelemetryInitializers>
can be setup in code like this:
_configuration.TelemetryInitializers.Add(new MyInitializer(...));

What is the correct way to modify dll.config of published project?

I published a .net core console application to my test server and scheduled it to run using task scheduler. I then wanted to turn on additional functionality using a switch from the app.config (that apparently turns into project.dll.config). The modifications did not take effect however. What is the correct way to modify my app.config file in this scenario? Do I need to republish? Maybe reschedule?
The Console Application will need to be restarted to pick up any change in its .config files.
Nope, you won't need to republish or recompile, unless you modify a ".cs" file. Just need to restart the app, like #Hayden said.

IIS Application name in NLog.config

I am integrating NLog logging in a WCF service hosted in IIS 7.5. Multiple instances (different versions) of the service are installed under the same site, so I would like the Application name to be part of the logging path.
I am aware of the NLog.Web extension and the ${iis-site-name} but since the site is common to all instances it is the application name below site level I would like to use in the log file path.
Each of the applications are installed from separate baseDirs but I would prefer to have logs in a folder structure away from the baseDir.
Any hints to getting the application name? When searching for answers most threads leads to HostingEnvironment.SiteName but I have not been able to find similar ways to get the application name.
Thanks in advance.
You can use the HostingEnvironment.ApplicationVirtualPath property and then hookup an NLog layout renderer.
This should work for NLog 4.4 and newer:
LayoutRenderer.Register("iis-application-name", (logEvent) => HostingEnvironment.ApplicationVirtualPath);
Then you can use ${iis-application-name} in your NLog config file.
Just remember to register the renderer before doing anything else, that is do it before you start loggin.

How to set up NLog configuration file load/reload when the app-config path is changed?

.Net applications are set up so that multiple instances of the same program will be (re)using the same application config (.exe.config - app.config in Visual Studio).
In our scenario we need to run each of the instances with their own .exe.config. This is not something that .Net is made to do "out of the box". However this nice little wrapper does the trick for us: https://stackoverflow.com/a/6151688/95008
This worked fine for us, until we realized that NLog does not seem to respect the app-config change. We are adding a config-section in the .exe.config for NLog which should make it possible each instance to log with different rules and targets to different locations.
But, it seems that NLog is not respecting the app-config changes. My guess is that it internally is not asking via the AppSettings API for its config-section, instead perhaps using code to manually look up the .exe.config and the config-section within it.
So, three alternatives it seems:
Look into NLog changing the code for this in a future release (given that this indeed is the issue). I will be posting an issue with the project for Update: Link to NLog issue.
Loading the configuration manually, either from the section of the .exe.config or from a specific nlog.config file (maybe given via a setting in the .exe.config). But, how do we do this effectively, so that any loggers created are based on the configs manually loaded?
Maybe there is another solution for this?
My guess is that it internally is not asking via the AppSettings API for its config-section, instead perhaps using code to manually look up the .exe.config and the config-section within it.
That's correct, as NLog is using the same code for the NLog's config, whether it's in web.config or in nlog.config
Reloading the config is easy in code, just do:
NLog.LogManager.Configuration = NLog.LogManager.Configuration.Reload();
and if there are loggers made before the config is reloaded,
NLog.LogManager.ReconfigExistingLoggers()

Updating config file and updating the values in application

I am currently updating a few settings in a rather large *.exe.config file via the *.exe executable by using XLinq to navigate the directories and read / write the values. The problem with updating this way is that changes only take effect after restarting the executable, but I would like the changes to take effect instantaneously. Is there a way to tell the executable to reload the *.exe.config file after I make the changes?
All help is appreciated and thanks in advance!
Exoskeleton for app.config
<configuration>
<system.serviceModel>
<!-- stuff... -->
<client>
<!-- this is the section I changed and want to have updated -->
</client>
</system.serviceModel>
</configuration>
EDIT: One of the reasons that I know so little on this subject is that I didn't create the app.config - it's auto-generated by somebody else's code. The reason that I have to change it and have the changes take effect in the application is that another part of the code (which I have no access to) calls on the config file to get its data, but if I don't reload the section then the old settings will be used, which won't work in this application.
EDIT2: If I can't change this dynamically, how do I change the code so that it can be done dynamically? Best answer gets the bounty...
var client =
System.ServiceModel.ChannelFactory<ISampleService>(
System.ServiceModel.Channels.Binding binding,
System.ServiceModel.EndpointAddress remoteAddress)
you can connect to a service also programmatically, and give the WCF directly the config needed.
with using this, you do not need the wcf config in the exe any more.
https://msdn.microsoft.com/en-us/library/ms576132.aspx
Settings with scope "User" can be easily stored and retrieved while the Application is running. If your settings are of scope "Application" I'm afraid you cannot modify and reload them without restarting your application. You'll need to roll your own configuration solution then.
There are 2 parts to making this work. 1) Updating the correct config file, and 2) forcing .net to reload the changes.
1) When a .net process starts, it will copy the existing .config to the vshost.exe.config file. If you update the original config file after the process has started, you will not see it in the vshost.config until you restart the process. So to make this work at runtime, you need to update the vshost.exe.config, not the exe.config file.
2) To force .net to reload the settings, you need to tell the configuration manager that the settings changed. You can do this with the ConfigurationManager.RefreshSection().
There is some more information and a couple code examples at: http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/3c365fdb-563e-4b0a-a4b4-df684c2dd908/
Basically, Microsoft designed it this way (having the configuration read at start up and not again), specifically to discourage you from trying this, because the *.config file live in the C:\Program Files folder, and that should not be writable by a non-Administrator.

Categories

Resources