Can't get Log4Net to work in our WCF application [duplicate] - c#

This question already has answers here:
Log4Net in WCF not working
(6 answers)
Closed 9 years ago.
We are trying to use Log4Net to log from our IIS 6-deployed WCF Application. We are trying to log to a file, but can't seem to get the log files to be created, let alone see the logging output in them. The pertinent pieces of out web.config are:
<sectionGroup name="common">
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
</sectionGroup>
...
<common>
<logging>
<factoryAdapter type="Common.Logging.Simple.TraceLoggerFactoryAdapter, Common.Logging">
<arg key="level" value="INFO" />
<arg key="showLogName" value="true" />
<arg key="showDataTime" value="true" />
<arg key="dateTimeFormat" value="yyyy/MM/dd HH:mm:ss:fff" />
</factoryAdapter>
</logging>
</common>
<log4net>
<appender name="FileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="c:\logs\ApplicationInfoTest.log" />
<threshold value="INFO" />
<param name="AppendToFile" value="true" />
<param name="DatePattern" value="ddMMyyyy" />
<param name="MaxSizeRollBackups" value="10" />
<param name="MaximumFileSize" value="10MB" />
<param name="RollingStyle" value="Size" />
<param name="StaticLogFileName" value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="Header" value="\r\n\r\n---------------------------------------------\r\n" />
<param name="Footer" value="\r\n---------------------------------------------\r\n\r\n" />
<param name="ConversionPattern" value="%d [%t] %-5p - %m%n" />
</layout>
</appender>
<root>
<level value="INFO" />
<appender-ref ref="FileAppender" />
</root>
</log4net>
With this configuration we can see INFO level logging coming out of our application when using DebugView, but it is clear that this is from the
piece and not the
piece.
Is there something that we have failed to set up in web.config? Is it a permissions issue with the directory we have created for the logs to be written to?
Please point out our obvious mistake.

I have also had to add this line to the AssemblyInfo.cs file of my application in order to get log4net working.
// LOG 4 net config
[assembly:log4net.Config.XmlConfigurator(Watch=true)]

Use ProcessMonitor from SysInternals to find out where permissions are being refused
(Potentially you can determine the same info by attaching a debugger and trapping on exceptions, not in Just My Code)
Are you sure that the process under which the service is running has permissions on the folder you're trying to write to?

Try XmlConfigurator.Configure()

Do you have a configuration section configured for log4net? I didn't see that in your code snippet

I would first run the WCF service as a console application - this way you can specify the user account for the application to run as and see if the problem is with your config or with a permissions issue running the service through IIS.
If you are unsure of how to run the service as a console application take a look at http://www.jacopretorius.net/2009/08/running-windows-service-inside-console.html

Related

log4net not appending to azure blob

I want to append logs to azure blob storage. So i added nuget package called log4net.appender.azure.
Wrote following in app.config
<log4net>
<root>
<level value="ALL" />
<appender-ref ref="AzureBlobAppender" />
</root>
<appender name="AzureBlobAppender" type="log4net.Appender.AzureBlobAppender, log4net.Appender.Azure">
<param name="ContainerName" value="myConatiner"/>
<param name="DirectoryName" value="myFolder/logs.txt"/>
<param name="ConnectionString" value="DefaultEndpointsProtocol=https;AccountName=XXXX;AccountKey=Ngqa/KvLxL4zpxdPDv8Opm29JCOXTJuJsF8FrzFQZpWCOcoFm1EI+mvFu+7AJvaWEU3jDffYrf4rGOKPJu/ObA==;EndpointSuffix=core.windows.net" />
<param name="AsText" value="true" />
</appender>
this is how i defined connection string
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
then i wrote below in class file
log4net.ILog log =
log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
log.Info("I am being tested");
but when i run program i dont see anything logged in azure blob. What am i missing?
Looks to me like your configuration is wrong. According to the examples in the README...
<appender name="AzureBlobAppender" type="log4net.Appender.AzureBlobAppender, log4net.Appender.Azure">
<param name="ContainerName" value="testloggingblob"/>
<param name="DirectoryName" value="logs"/>
<!-- You can either specify a connection string or use the ConnectionStringName property instead -->
<param name="ConnectionString" value="UseDevelopmentStorage=true"/>
<!--<param name="ConnectionStringName" value="GlobalConfigurationString" />-->
<param name="AsText" value="true" />
</appender>
myContainer should be ContainerName
MyFolder should be DirectoryName
AzureBlobConnectionString should be ConnectionStringName
Try following steps and proceed to next only if previous one is fine.
You need to check if the Logger property in debugger mode and examine the ConfigurationMessages property to see if any errors are reported.
First try adding a file appender to see if log4net is working fine or not.
<appender name="fileAppender" type="log4net.Appender.RollingFileAppender">
<file value="log-file.txt" />
<appendToFile value="true" />
<maximumFileSize value="1000KB" />
<maxSizeRollBackups value="10" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %-5level %logger - %message%newline" />
</layout>
</appender>
With this, you can go to Kudo in Azure portal's webapp and see the physical file being written atleast.
Second, see if you are initializing the config properly with
log4net.Config.XmlConfigurator.Configure();
Third, check if the region of the storage account is the same as the web app or not.

How do I setup a FileAppender logger from log4net for a .NET Standard 2.0 class library?

How do I setup a File Appender logger from log4net for a class library using .NET Standard 2.0? I don't have an AssemblyInfo.cs. I think I have a fundamental misunderstanding that's leading to my confusion with this, so this may be a simple answer, but I just started a class library that I want to be accessible to as many projects as possible in our solutions and have internal logging from the get-go.
Any and all suggestions/help is much appreciated.
There is nothing special about the AssemblyInfo.cs file. The attribute to configure log4net can be put in any file in the assembly.
That being said I would recommend against using log4net directly and instead use a ILogger from the NuGet package Microsoft.Extensions.Logging.Abstractions. This allows the consumer of your library use any logging system they want instead of being tied to only using log4net.
Not sure if I understood what you need/want but this is an idea of how the config file should look like
<log4net>
<root>
<level value="INFO" />
<appender-ref ref="LogFileAppender" />
</root>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="test.txt" />
<param name="AppendToFile" value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="5MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%date [%thread] %-5level %logger [%M %C] - %message%newline" />
</layout>
</log4net>
If i'm not mistaken, you don't need to add anything to your assemblyinfo (if you dont have one) but you need to add something like this on the startup
log4net.Config.XmlConfigurator.Configure();
(in my case webapi so I add it to my startup.cs)
I hope this helps!

Using registry values in log4net configuration

Is it possible to put a registry value in the log4net filename in the configuration file?
for example, something like this:
<log4net>
<appender name="MainLog" type="log4net.Appender.RollingFileAppender">
<param name="Encoding" value="Unicode" />
<param name="File" value="Logs\{Some-Registry-Value}\myLog.log" />
<param name="AppendToFile" value="false" />
<maximumFileSize value="50MB" />
<maxSizeRollBackups value="20" />
<rollingStyle value="Size"/>
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%t] %logger - %m%n%exception" />
</layout>
</appender>
You can use a custom property in your xml so your line would look like:
<param name="File" value="Logs\%property{RegLogPath}\myLog.log" />
Then in code, before configuring log4net:
log4net.GlobalContext.Properties["RegLogPath"] = logsFolder;
The accepted answer doesn't work for me - instead it creates the log files in a directory that is literally named "%property{RegLogPath}"!
Maybe this syntax is not quite right?
EDIT:
As noted here: log4net %property does not work
...it appears the parameter 'type="log4net.Util.PatternString"' (but not the '.\' before '%property') is needed in the config file.
With this change, it works.

GetAppenders() returns empty list in log4net

I have the following method that fetches the name of the log file in log4net:
private string GetLogFile()
{
var repo = LogManager.GetRepository();
var fileAppender = repo.GetAppenders()
.OfType<FileAppender>().Single(fa => fa.Name == "LogFileAppender");
var logFile = fileAppender != null ? fileAppender.File : string.Empty;
return logFile;
}
This code works fine when I have this code running in a Windows service. But I was given the task to move logging to the main web app. So I referenced log4net in the web app, moved over the config settings, etc. But now when I run the same code the call to GetAppenders() returns an empty list.
Here is the config I have:
<log4net>
<appender name="LogFileAppender" type="log4net.Appender.FileAppender">
<param name="File" value="\\MYSERVER\Temp\MYFiles\Log\Log.txt" />
<param name="AppendToFile" value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c %m%n" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="LogFileAppender" />
</root>
</log4net>
Is there an extra step in the web app version that I need to do?
It turned out to be something missing in the Global.asax.cs file in the Application_Start method. I needed to add the following line:
log4net.Config.XmlConfigurator.Configure();
You are required to also call out the additional config sections at the top of the file, as such:
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
<sectionGroup name="common">
<section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
</sectionGroup>
</configSections>
As well as the addition of the following above your log4net element:
<common>
<logging>
<factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4net">
<arg key="configType" value="INLINE" />
</factoryAdapter>
</logging>
</common>
This makes the assumption that you're using Common.Logging and that you are not using a standalone config file (meaning the configuration is within the web.config).

How to include log4net for a class library?

I want to implement logging function into a class library, which is itself referenced in a webservice. I tried to add app.config and did everything needed, but it seems that when an exception is thrown, log4net simply does nothing.
my app.config
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="D:\\mylogfile.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="5" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<filter type="log4net.Filter.StringMatchFilter">
<stringToMatch value="test" />
</filter>
<filter type="log4net.Filter.StringMatchFilter">
<stringToMatch value="error" />
</filter>
<filter type="log4net.Filter.DenyAllFilter" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %level %logger - %message%newline%exception" />
</layout>
</appender>
<root>
<level value="INFO"/>
<appender-ref ref="RollingFileAppender"/>
<appender-ref ref="ConsoleAppender" />
</root>
</log4net>
in AssemblyInfo.cs:
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "app.config")]
in LogManager.cs:
private static readonly ILog Log = log4net.LogManager.GetLogger
(MethodBase.GetCurrentMethod().DeclaringType);
public static void WriteLog(Exception ex)
{
Log.Error(ex);
}
Can you please tell me what's wrong? How can I get log4net working for my class library?
Thank you
At runtime, config file is always used from host application, unless declared explicitly. Here in case, web.config is being used not app.cofig. Rather mention some other custom config file name and ensure that file is copied in virtual directory of web service. Also as chibacity said, ensure permission on log file. Better keep it in app_data folder for web service host.
You could use some kind of injection, either you build a simple one like:
public interface ILogger
{
void LogInfo(string message);
.
.
.
}
And then you just inject something that matches that interface, like a wrapper for log4net or such.
But, I think the most correct thing is to not log in the class library. Why I think so is because the library itself is not the application, your web service is so your web service should decide what to log. If you want to log exceptions just don't catch them in the class library and let your web service handle the logging. This will also make it easier to centralize the logging.
Please see my answer to the following question:
Use log4net in SDK
It has a log configuration routine that will construct a complete path to a log4net config file. As you are in a webservice it my not be looking where you expect for "app.config".
Also make sure that you have permission to write to "D:\mylogfile.txt" from your webservice.

Categories