1
votes

I have a strange situation:

I have configured custom log4net Appender to write to Azure Table storage. I have WorkerRole and WebRole. Both roles use osFamily="3" (Windows Server 2012), I use .NET 4.5 in both and use ASP.NET MVC4 for the WebRole. Everything is configured and works fine locally - both the worker and the web role are logging correctly. However, when I deploy to Azure, only Worker role logs successfully, webrole does not produce any logs (any!), while it should.

I have configured log4net on the WebRole to debug and emit log4net debugging data into the Trace to check for some issues, but it sends no errors/warnings. Nor it sends logging messages.

Here is the log produced by log4net debugging (stripped sensitive data):

log4net: log4net assembly [log4net, Version=1.2.11.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a]. Loaded from [D:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\59a01799\5b6b1a2\assembly\dl3\8d97587f\b9d49402_c202ce01\log4net.dll]. (.NET Runtime [4.0.30319.18010] on Microsoft Windows NT 6.2.9200.0) log4net: defaultRepositoryType [log4net.Repository.Hierarchy.Hierarchy] log4net: Creating repository for assembly [_my_referenced_assembly_, Version=1.3.0.20282, Culture=neutral, PublicKeyToken=null] log4net: Assembly [_my_referenced_assembly_, Version=1.3.0.20282, Culture=neutral, PublicKeyToken=null] Loaded From [D:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\59a01799\5b6b1a2\assembly\dl3\8cc98c20\594c5b41_6f07ce01_my_referenced_assembly_.dll] log4net: Assembly [_my_referenced_assembly_, Version=1.3.0.20282, Culture=neutral, PublicKeyToken=null] does not have a RepositoryAttribute specified. log4net: Assembly [_my_referenced_assembly_, Version=1.3.0.20282, Culture=neutral, PublicKeyToken=null] using repository [log4net-default-repository] and repository type [log4net.Repository.Hierarchy.Hierarchy] log4net: Creating repository [log4net-default-repository] using type [log4net.Repository.Hierarchy.Hierarchy] Loaded "Microsoft.WindowsAzure.ServiceRuntime, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Getting "_some_setting_1_" from ServiceRuntime: PASS (_my_value1_). Getting "_some_setting_2_" from ServiceRuntime: PASS (_my_value2_). Getting "_some_setting_3_" from ServiceRuntime: PASS (_my_value3_). Getting "Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString" from ServiceRuntime: PASS (_my_conn_string_). Getting "_some_setting_4_" from ServiceRuntime: PASS (_my_value4_). log4net: Creating repository for assembly [_my_WEB_assembly_, Version=1.3.0.20283, Culture=neutral, PublicKeyToken=null] log4net: Assembly [_my_WEB_assembly_, Version=1.3.0.20283, Culture=neutral, PublicKeyToken=null] Loaded From [D:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\59a01799\5b6b1a2\assembly\dl3\f695181f\98c73242_6f07ce01_my_WEB_assembly_.dll] log4net: Assembly [_my_WEB_assembly_, Version=1.3.0.20283, Culture=neutral, PublicKeyToken=null] does not have a RepositoryAttribute specified. log4net: Assembly [_my_WEB_assembly_, Version=1.3.0.20283, Culture=neutral, PublicKeyToken=null] using repository [log4net-default-repository] and repository type [log4net.Repository.Hierarchy.Hierarchy] log4net: repository [log4net-default-repository] already exists, using repository type [log4net.Repository.Hierarchy.Hierarchy] Getting "acs:idps" from ServiceRuntime: FAIL. Getting "acs:idps" from ConfigurationManager: PASS ([my_value]).

Here is sample of both my app.config (for worker) and web.config (for web role) files (I also set this into WaIISHost.config just in case, but the result is still the same - totally muted WebRole):

<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
    ...
  </configSections>
 ...
  <log4net>
    <appender name="AzureTableStoreAppender" type="_MyAssembly_.Logging.AzureTableStorageAppender, MyAssembly">
    </appender>
    <root>
      <level value="ALL" />
      <appender-ref ref="AzureTableStoreAppender" />
    </root>
  </log4net>
</configuration>

I configure log4net via the assembly level attribute. Thus in Worker role assembly I have:

[assembly: log4net.Config.XmlConfigurator(Watch = true)]

And in web role I have:

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Web.config", Watch = true)]

As I said, everything works fine and writes table entities fine when run locally. My Local Environemtn is Windows 8 Pro, running the web roles in IIS Server (not IIS Express), which is IIS8. I also tried marking the WebRole executionContext to elevated but still nothing happens. It is like a black hole for log4net.

My custom appender is defined in a separate Assembly, .net Framework 4.5 (full), of type Class Library which is referenced in both Web and Worker projects. As already said - locally everything works fine. The assembly that defines my custom appender is definitely loaded, because it also contains business logic of my web app, which works deployed in Azure as well.

UPDATE

Interesting discovery. When I use Debug build configuration everything works everywhere (azure web role also). But when I use Release configuration (which is default for packaging and production code) I can't seem to be able to make log4net working anywhere. Meaning that I can't make Log4Net running even locally with Release config. No exceptions are being raised, no errors being logged. As strange as it can be...

2

2 Answers

1
votes

It turns out the Release build is causing issues. According to the log4net's FAQ section, configuring log4net via assembly level attribute may behave different in DEBUG and RELEASE configurations.

In my setup I was using a static readonly property (of a base controller) initialized upon declaration. This seemed to bug the logger configuration. I moved my Logger instance to an instance property of my Web Application type and changed my controller property to just return Application's property. Now everything is working fine in all build configurations.

0
votes

Regarding Azure, I have run into the same problem. I encountered that when in Release configuration nothing is being logged, even if locally both Debug and Release work fine. My problem was not a configuration of log4net but rather its initialization.

I had it that way:

private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

so then I replaced it with following line and it helped:

private readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(WorkerRole));