Log4net does not write the log in the log file - asp.net

I have created a simple scenario using Log4net, but it seems that my log appenders do not work because the messages are not added to the log file.
I added the following to the web.config file:
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" requirePermission="false"/>
</configSections>
<log4net>
<appender name="LogFileAppender" type="log4net.Appender.FileAppender">
<file value="D:\MyData\Desktop\LogFile.txt" />
<appendToFile value="true" />
<encoding value="utf-8" />
<layout type="log4net.Layout.SimpleLayout" />
</appender>
<root>
<level value="INFO" />
<appender-ref ref="LogFileAppender" />
</root>
</log4net>
Within the global ASAX file I have added:
ILog logger = LogManager.GetLogger(typeof(MvcApplication));
And within the Application_Start method:
logger.Info("Starting the application...");
Why the test log "Starting the application..." is not being added to the log file?

Do you call
log4net.Config.XmlConfigurator.Configure();
somewhere to make log4net read your configuration? E.g. in Global.asax:
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
// Initialize log4net.
log4net.Config.XmlConfigurator.Configure();
}

Use this FAQ page: Apache log4net Frequently Asked Questions
About 3/4 of the way down it tells you how to enable log4net debugging by using application tracing. This will tell you where your issue is.
The basics are:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="log4net.Internal.Debug" value="true"/>
</appSettings>
</configuration>
And you see the trace in the standard output

As #AndreasPaulsson suggested, we need to configure it. I am doing the configuration in AssemblyInfo file. I specify the configuration file name here.
// Log4Net Configuration.
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]

Also, Make sure the "Copy always" option is selected for [log4net].config

Make sure the process (account) that the site is running under has privileges to write to the output directory.
In IIS 7 and above this is configured on the application pool and is normally the AppPool Identity, which will not normally have permission to write to all directories.
Check your event logs (application and security) to see if any exceptions were thrown.

Insert:
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
at the end of AssemblyInfo.cs file

In my case I had to give the IIS_IUSRS Read\write permission to the log file.

For me I moved the location of the logfiles and it was only when I changed the name of the file to something else it started again.
It seems if there is a logfile with the same name already existing, nothing happens.
Afterwards I rename the old file and changed the log filename in the config back again to what it was.

In my case, log4net wasn't logging properly due to having a space in my project name. Drove me nuts why the same code worked just fine in a different project, but didn't in the new one. Spaces. A simple space.
So, beware spaces in project names. I've learned my lesson.

Make sure the following line code should be there in AssemblyInfo.cs file.
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Web.config", Watch = true)]
and also check for this line in Application_start() method.
log4net.Config.XmlConfigurator.Configure();

For me I had to move Logger to a Nuget Package. Below code need to be added in NuGet package project.
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config")]
See https://gurunadhduvvuru.wordpress.com/2020/04/30/log4net-issues-when-moved-it-to-a-nuget-package/ for more details.

Your config file seems correct. Then, you have to register your Log4net config file to application. So you can use below code:
var logRepo = LogManager.GetRepository(Assembly.GetEntryAssembly());
XmlConfigurator.Configure(logRepo, new FileInfo("log4net.config"));
After registering process, you can call below definition to call logger:
private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
log.Error("Sample log");

There are a few ways to use log4net.
I found it is useful while I was searching for a solution. The solution is described here: https://www.hemelix.com/log4net/

Related

maxRequestLength+maxAllowedContentLength+HTTPS not working

I have made a service that i host on an azure webapp. This will be used to upload files. IIS has a built in security feature that limits the file upload size.
To work around this i have put the following in my web.config
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="80000000" />
</requestFiltering>
</security>
</system.webServer>
...
<system.web>
<httpRuntime maxRequestLength="80000" targetFramework="4.5.2" executionTimeout="9000" />
</system.web>
This is however not working for me. As soon as i upload a large file (50mb for example) it hits me with a 404. When i upload a smaller file (10mb) it works fine. The service is a soap and is called over https. The call does not time out, the exception occurs within 5 seks of the call being made, my guess is it uploads 30mb and then it thinks it is under attack and aborts.
Am i missing something here?
You can go to folder:
%windir%\system32\inetsrv\
run command:
appcmd set config -section:requestFiltering -requestLimits.maxAllowedContentLength:80000000
or if you only want to set it for your app, run this:
appcmd set config "Default Web Site/" -section:requestFiltering -requestLimits.maxAllowedContentLength:80000000
also you need to update overrideModeDefault to 'Allow' in web.config:
<section name="requestFiltering" overrideModeDefault="Allow" />
Then you can have your web.config updated with appcmd.exe
Hope this article and this article will help you.
About how to use appcmd.exe, you can see https://technet.microsoft.com/en-us/library/cc772200%28v=ws.10%29.aspx
After that deploy your project to azure webapp and try again.
I did that configuration, but i fixed my problem putting on my ControllerBase something like:
protected override void OnResultExecuting(ResultExecutingContext filterContext)
{
base.OnResultExecuting(filterContext);
if(filterContext.Result.GetType().Name == "JsonResult")
filterContext.Result.GetType().GetProperty("MaxJsonLength").SetValue(filterContext.Result, int.MaxValue);
}
For classic ASP users also check this settings in addition to the web.config settigns:
IIS > CLick on Website > ASP > Limit Properties > Maximum request entity body limit
In my case, the problem was because the configuration of httpProtocol in the web.config file had the 'allowKeepAlive' in false.
<httpProtocol allowKeepAlive="false">
I deleted the allowKeepAlive="false" (making it uses the default value of true) and all worked with big files (configuring the 'maxrequestlength' and 'maxallowedcontentlength')

How to properly reference an external web.config file?

I have my main web.config file and another one like:
web.config
web.logging.config
The web.logging.config has:
<configuration>
<configSection>
<section name="log4net" ... />
</configSection>
<log4net> ....</lognet>
</configuration>
I just want to confirm, if I don't somehow reference this web.logging.config file from my web.config file, it will not automatically pick it up will it?
How would I reference this file then?
If you are looking anything specific to log4net, that is possible to have log4net configuration file as a separate file.
[assembly: log4net.Config.XmlConfigurator(ConfigFile ="MyLog4Net.config", Watch = true)]

Adding custom section to web.config in ASP.NET 4

I've spent half of a day trying to understand why the following fails.
I can add section anywhere but never got it working like that ():
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<mysection />
<system.web>
<compilation debug="false" batch="false" targetFramework="4.0" />
</system.web>
<system.webServer>
<handlers>
</handlers>
</system.webServer>
</configuration>
I think the error related to .NET 4, because when you put section without pre-configuration in applicationHost.config it shows error with gray border saying that config is incorrect. That is what I expect. Then I add section definition and everything seems to work I can edit config from console - this means it is parsed correctly now.
But when I try to reach Application, it gives:
Parser Error Message: Unrecognized configuration section mysection
with a piece of config on yellow background.
Or do I need to write a module to consume that settings ? At the moment I do not have any, just a text in config.
following links will help you understand for this.
http://www.codeproject.com/Articles/32628/ASP-NET-Custom-Web-Configuration-Section
https://web.archive.org/web/20211020133931/https://www.4guysfromrolla.com/articles/032807-1.aspx
Regards,
Old topic but these links are very helpfull:
http://www.iis.net/learn/develop/extending-iis-configuration/configuration-extensibility
http://www.iis.net/learn/develop/extending-iis-configuration/extending-iis-schema-and-accessing-the-custom-sections-using-mwa
Edit (05/25/2016) :
The Details of how to store custom information in applicationHost.config file ... I hope this helps !
Note : These settings wont be visible on IIS Manager. There is a way to do that but thats beyond the scope of this response.
Requirement:
Need to extend the system.applicationHost/sites section of applicationHost.config file to allow a siteowner attribute at the site level. (IIS Does not allow us to do this by default). Nor can you manually edit the applicationHost.config file and add custom tags/attributes.
Steps:
Create a custom schema ( xml ) file under %windir%\system32\inetsrv\config\schema\ . File name: siteExtension_schema.xml
Include the custom elements that you want to eventually save in the applicationHost.config in that xml and save it with a appropriate name. The crucial thing to keep in mind is the sectionSchema tag.So when extending the schema of an existing section, simply create a element and set the name attribute to be the same as an existing section. In the schema file (see below), we have defined a with a name of "system.applicationHost/sites" - this is the same as the sectionSchema name in the default IIS_Schema.xml file in the Schema directory. So in essence you are instructing IIS to add these
<!-- Contents of %windir%\system32\inetsrv\config\schema\siteExtension_schema.xml -->
<configSchema>
<sectionSchema name="system.applicationHost/sites">
<collection addElement="site">
<attribute name="owner" type="string" />
<attribute name="ownerEmail" type="string" />
</collection>
</sectionSchema>
</configSchema>
Test the modifications by adding values for the "owner" and "ownerEmail" attributes that we included in step 2 above and then check the configuration file (applicationHost.config) to see the changes. Simply run the following command (must be elevated as Administrator) from the command line (uses appcmd ) to do so:
C:\> %windir%\system32\inetsrv\appcmd set site "Default Web Site" /owner:"John Contoso" /ownerEmail:"john#contoso.com"
To see if the configuration was applied, run the following command and check the output:
C:\> %windir%\system32\inetsrv\appcmd list site "Default Web Site" /config
<system.applicationHost>
<sites>
...
<site name="Default Web Site" id="1" siteOwner="John Contoso" siteOwnerEmail="john#contoso.com">
...
...
</site>
</sites>
</system.applicationHost>
To Read and Write your settings programmatically thru C# :
//this Will work with the ServerManager.OpenRemote("MyRemoteHostname") method also
using(var mgr = new ServerManager())
{
//Read
Console.WriteLine(mgr.Sites["Default Web Site"].Attributes["owner"].Value ); //Prints "John Contoso"
//Write
mgr.Sites["Default Web Site"].Attributes["owner"].Value = "New Owner";// Sets new value
mgr.CommitChanges(); // commits the changes to applicationHost.Config
}

using web.config variables within web.config

I would like to have a variable defined in my web.config that I can use in multiple places within my web.config file (and other config files). It's probably easier to explain by example ...
web.config
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="AuthServiceEndPoint" value="any_old_name_i_like"/>
</appSettings>
<system.web>
...
<system.serviceModel>
<client>
<endpoint
address="net.tcp://localhost/AuthService"
binding="netTcpBinding"
contract="MyServices.Contracts.IAuthService"
name="#{AppSettings.AuthServiceEndPoint}"
bindingConfiguration="netTcpBindingConfig"
/>
</client>
</system.serviceModel>
</configuration>
windsor.config
<?xml version="1.0" encoding="utf-8" ?>
<castle>
<components>
...
<component
id="AuthProvider"
service="MyServices.Client.IAuthProvider, MyServices.Client"
type="MyServices.Client.AuthProvider, MyServices.Client"
lifestyle="transient">
<parameters>
<endpoint>#{AppSettings.AuthServiceEndPoint}</endpoint>
</parameters>
</component>
</components>
</castle>
Is this possible?
Edit (a bit more information)
I already have the ability to access the AppSettings from my windsor.config file (which is actually processed by castle windsor and a custom XmlInterpreter.
The real question is can I do this in my web.config?
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="AuthServiceEndPoint" value="any_old_name_i_like"/>
</appSettings>
<system.web>
...
<system.serviceModel>
<client>
<endpoint
address="net.tcp://localhost/AuthService"
binding="netTcpBinding"
contract="MyServices.Contracts.IAuthService"
name="#{AppSettings.AuthServiceEndPoint}"
bindingConfiguration="netTcpBindingConfig"
/>
</client>
</system.serviceModel>
</configuration>
ie - access variable in my <appSettings> from other parts of my web.config file.
Off the top of my head, I wonder if you might be able to do this with T4? I'm thinking that perhaps you could define a template which parses Web-Template.config and outputs Web.config? Of course, this only works for a single file.
You can use NAnt or MSBuild for this. You do need separate configuration files for both, but when you build your project they can automatically do transformations on your Web.config and other configuration files.
Not that I can think of. You could do your configuration in C# in global.asax.cs instead of the xml file.
Alternatively, have your web.config edited by your build process to replace all these values. FinalBuilder has a neato "Edit XML File" action that uses XPath quite well to do this, and FinalBuilder does have variables. Problem solved. This is how I do my builds at work.
Here I go answering my own question again :-S
I solved this by writing a NetTcpServiceLocator ...
public interface INetTcpServiceLocator
{
EndpointAddress GetAddress(Type serviceType);
}
... along with a custom config section handler which also implements the above interface and reads in the following config section ...
<services>
<service contract="My.Services.TestService.Contracts.ITestService" address="net.tcp://localhost/TestService" />
</services>
Then I created a proxy for each service ...
public class TestServiceProxy : ITestService
{
public SomeInformation GetSomeInformation(SomeParams #params)
{
using (var factory = new NetTcpServiceFactory<ITestService>())
{
var service = factory.Service;
return service.GetSomeInformation(#params);
}
}
}
My Controller has a dependency on a Service, which has a dependancy on ITestService. All this is glued together with Castle Windsor and by using property dependency injection.
So, my controller calls it's Service, which in turn calls the ITestService (in this case a proxy, which gets it's endpoint from the custom section handler).
The custom section handler (which is also the INetTcpServiceLocator) has a windsor lifestyle of "perWebRequest", so it gets called by the framework and web.config is read into an array in memory. When the service proxy is called, it then just pulls the relevant endpoint based on the contract type.
It's all driven by the type of the contract, so there is no need to have any variables in web.config anymore.
I've gone for a code based solution, as I don't use a build process locally, only when I submit my code to subversion does the build process kick in on our build server.

Combres' route (combres.axd) doesn't work

I have followed the article http://www.codeproject.com/KB/aspnet/combres2.aspx.
When I run my site I cannot get the combres.axd to work ? I know that the combres is running since an incorrect file in my xml will cause an error. I am running an ASP.NET 4.0 web forms site on vista.
My Combres XML settings are.
resourceSets url="~/combres.axd" defaultDuration="30" defaultVersion="auto" defaultDebugEnabled="auto"
I have checked the web.config for all correct values. The reference has been added from the merge directory and the global ASX file has the following.
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.AddCombresRoute("Combres");
}
I also checked the value is created in the html source.
href="/combres.axd/siteCss/309885723"
src="/combres.axd/siteJs/408582048"
I do not get an error or anything to help me track down the reason it will not work or what I may have missed. Any suggestions would be great.
I had the same problem when trying to get it to work for the first time.
Make sure that the Combres route is added before the call to ignore the route {resource}.axd.
Correct:
RouteTable.Routes.AddCombresRoute("Combres");
RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
Incorrect:
RouteTable.Routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
RouteTable.Routes.AddCombresRoute("Combres");
First, i'd suggest to hook a log4net to the combres logger in your web.config (don't forget to setup the configsection for log4net)
<log4net>
<logger name="Combres">
<level value="ALL"/>
<appender-ref ref="LogCombres" />
</logger>
<appender name="LogCombres" type="log4net.Appender.RollingFileAppender">
<file value="Combres.log.txt"/>
<appendToFile value="true"/>
<maximumFileSize value="5000KB"/>
<maxSizeRollBackups value="2"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%d [%t] %-5p %c - %m%n"/>
</layout>
</appender>
</log4net>
And in your global.asax launch the configuration
log4net.Config.XmlConfigurator.Configure()
You should have a detailed log of what's happening. If what's wrong doesn't pop out, don't hesitate to come back with some log output
For some reason the only way we could fix showing css in debug=false mode is by adding combres.axd to the anonymous access in web.config
<location path="combres.axd">
<system.web>
<authorization>
<allow users="*" />
</authorization>
</system.web>
</location>
What is your modules setting in web.config? Check for the runAllManagedModulesForAllRequests attribute.
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
With a legacy WebForms app, I found I did not have that setting and once I put it in, the combres.axd route worked.
More on my question too
These are the changes i did in the project and it stated to run properly.
In the Global.asax file add these lines
using Combres;
In the application_start method
protected void Application_Start()
{
RouteTable.Routes.AddCombresRoute("Combres");//Add this line
RegisterRoutes(RouteTable.Routes);
}
Comment out the line in Combres.cs file.
This happened to me too but the problem was from Yahoo.Yui.Compressor they changed one property signature in their new version 1.6*.
So to fix it i just down the Yahoo.Yui.Compressor to version 1.5.
And i'm happy now :)

Resources