Using log4net in a complex software - log4net

I'm using log4net logging in my software that consists of several applications.
I want to have one common library for this.
I created a library and put it in the conficuration file. In AssemblyInfo.cs placed attribute:
log4net.Config.XmlConfigurator(ConfigFile = #"c:\logging.xml", Watch = true)
It work for windows service, but in dosn't work for asp.net application.
It work in asp.net if delete attribute from common library and put in into global.asax. However, this leads to that section of the log4net configuration must be made in the windows service.
There is also a business process which causes our library through the
remouting. I want the logging was carried out there too.
Is there way around this?

In my opinion the library should not define where the configuration file is found. Maybe a better idea would be to have a helper method that allows you to configure log4net quickly; that method would take an optional parameter for the config file path and would try to load the configuration file from the specified path first and if that does not work fallback to some maybe the current folder, the application folder or even the web / app.config.
If you insist that it must be an absolute path then you need to give the IIS Application Pool user read access to this file. This way the configuration by attribute should work for services and ASP.Net applications. I do not understand what you mean by "remounting".

Related

Why disable/remove IIS modules when using ASP.NET Core?

Microsoft's ASP.NET Core documentation (https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/iis/modules?view=aspnetcore-2.1#disabling-iis-modules) says
If an IIS module is configured at the server level that must be disabled for an app, an addition to the app's web.config file can disable the module.
but it doesn't explain when/why one would have to disable or remove such a module. Are there specific reasons? Is it recommended to disable any module that doesn't function along with ASP.NET Core?
The whole guiding design philosophy of ASP.NET Core is streamlining your app. ASP.NET Core removes library dependencies that aren't actually used from your build. The whole middleware pipeline exists so that you can include only what you need, etc. This is just one more of thing along those lines.
IIS loads a default set of modules. If you don't actually need those modules for your app, then it's just cruft that adds extra processing to each request. Hence, remove the modules you don't need/aren't utilizing. The goal is to get from request to response in the fewest steps possible, and IIS modules are simply one more of those steps the request has to pass through. That's fine if you need it, but if you don't, you're wasting cycles, resources and time.

Load Log4net custom appender from a library outside the application folder

I have a C# custom appender library which needs to be used by several applications in different solutions which run in the same server. I have an addon installer solution that creates all the folders and stuffs which includes the custom appender library, which the other projects needs to use. Instead of adding this library into all the application's directory, I just want to let the each application's App.Config to point to this single custom appender library.
I have built a custom appender call MyCustomAppender in a library call MyCustomLibrary.dll.
Here is the xml code of one of the App.Configs:
<appender name="MyCustomAppender" type="MyCustomerLibrary.MyCustomAppender, C:\Users\Admin\Libraries\MyCustomLibrary">
It is not possible for me to put the path of the library because Log4net doesn't work this way. Is there a walk around for each application to point to C:\Users\Admin\Libraries\MyCustomLibrary.dll? to use the MyCustomAppender? The other applications needs to have 0 code changes, only their App.Config can be modified due the the reason this process needs to have minimal changes.
You can add the dll to the GAC on the machine your application is runnen. This will allow all programs to find the dll. BTW, coping the dll into the bin directory of the application will not change the code of the application.

How to take binding information from outside App.config in C# console application?

I have an App.config fiel in which i defined some binding information.
I want this information in some external file so that user can change it whenever required.
Anyone have an idea about how to implement it?
Thanks in advance
Assuming we're talking about assembly binding redirects...
The runtime is going to use your App.exe.config file to locate the binding redirects. I don't believe you can do anything about this in a normal managed application because the runtime is already initialized by the time you can run any code.
If you had an unmanaged "shim" (an exe in C++ for example) that used the CLR hosting API's, you can tell it the name of a config file to use when you set up the AppDomain. But I don't believe you can make your binding redirects separate from the main application config.
Your only other option would be to handle the AppDomain.AssemblyResolve event to handle binding failures. But this is potentially expensive as the runtime will exhaust all of its options for probing the assembly before raising this event.

log4j multiple configuration files

I have couple of projects embedded in a web app as jars. Each project has a log4j.properties file. When the web app is deloyed, which configuration file gets used and how to override the configurations in log4j.xml in a jar file. The jars are not web projects. They are more like service layer code. What is the order in which the log4j.properties file is loaded in the below scenario
Web-project
classes
log4j.properties
ProjectB.jar
com
log4j.properties
ProjectC.jar
com
log4j.properties and so on.
If your jars are separate web applications, each web application should use the one it first finds on the classpath (WEB-INF/classes).
You can pass a -Dlog4j.configuration=path_to_file setting to e.g. the tomcat startup to make sure that it uses the one you intend it to use.
However, this would then to my understanding and knowledge be the one that tomcat will use for every webapp that is deployed.
Question here is how you deploy your apps. Either all web applications in one tomcat in which case you probably want each web application to use a different log4.properties (or log4j.xml) or in the case where you specify one to tomcat, it should use the one you specify.
What it boils down to as far as i know: Either the first one found on classpath (remember: each web-app has it's own classpath) or the one you specify via the -D setting.
Just found this reference which i think nicely summarizes the main concepts of logging in tomcat and webapps deployed in tomcat: http://wiki.apache.org/tomcat/FAQ/Logging
If you need even more control over the log4j logging, you can resort to coding the log4j configuration in java. However, this would mean that you have to modify the source code and add code into it, which relates to infrastructure and relates deployment details to your application (not so nice).
If you set additivity to false in common packages at ProjectA, ProjectB and WebProject your log will not duplicate.
log4j.additivity.[logged package] = false
For example:
log4j.properies -> Project A, Project B
log4j.additivity.org.spring.framework = false
All org.spring.framework log will come from WebProject ignoring ProjectA and ProjectB.

deploying global.asax to sharepoint 2010 in an enterprise environment to enable unity DI container

Working on a SharePoint project I'm trying to use Unity as a dependency injection container.
My first idea to get this container running is using the global.asax as described in the best practices by P&P:
http://webclientguidance.codeplex.com/releases/view/17134#DownloadId=43305
In these best practices they tell you to manually edit the global.asax file to make it inherit SPUnityHttpApplication.
<%# Application Language="C#" Inherits="Unity.SharePoint.SPUnityHttpApplication" %>
Manually editing this file is not an option in enterprise environments since we have multiple environments (DTAP) and all of them have multiple frontend servers that would need manual steps.
I can't find any way to deploy a global.asax file by using a feature or wsp or anything because the global.asax is located in the web application root and sharepoint deploys other files to the /14 hive folder so you can't acces the web application root directory.
Alternatives i've looked into is the SharePointServiceLocator. this build in functionality does almost what i want. but it can only resolve classes that have a default constructor. this way i can't chain resolve all my implementations by using constructor injection. I found a post how to change the service locator to make use of unity but this doesn't seem to work properly if you read the comments.
My problem can be fixed by fixing 1 of these 2 main problems:
Don't arrange unity in the global.asax, but then where and how?
Deploy the global.asax in sharepoint? possible?
The global.asax doesn't seem to be the best solution to do this because of the deployment issues described in the question.
A viable solution is implementing this in a httpmodule
The init method can be used to wire everything up since this is called when the sharepoint application starts.
the httpmodule can be added in the web.config by a feature receiver
This way there is no need to do tricks with the global.asax that is located in a directory you can't deploy to with a feature and you have all the functionality and correct time to instantiate the DI container.
It may not be ideal, but you could look at using a feature receiver and write code to edit the existing files directly.

Resources