2 instance of Log4Net in same process parallel logging issue - multithreading

I've read this question: log4net-and-logging-from-parallel-instances
I have written a DLL that uses log4net for logging.
I have a process that uses my DLL with 2 instances (same process)
The first instance of the class has access to the log. the second instance doesn't log at all.
I can't use the processID in the file name - as it works only with 2 different instance of the app, not from the same app.
how can I make all calls to log from both instance to write to the log file ?
(I get the logger using Ilog log = LogManager.GetLogger("ClassName") )
and in the Ctor I read the configuration file...
The only solution I thought is to get the log from the external app in the ctor but I don't want to external app to do anything with my own logging.

The problem was using the configurator at the constructor.
You can't call the configurator more than once.

Related

how to use structured logging in Azure Functions

I am using the relatively new ILogger (vs. TraceWriter) option in Azure functions and trying to understand how logs are captured.
Here's my function:
public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]HttpRequestMessage req, ILogger log)
{
log.LogTrace("Function 1 {level}", "trace");
log.LogWarning("Function 1 {level}", "warning");
log.LogError("Function 1 {level}", "error");
return req.CreateResponse(HttpStatusCode.OK, "Success!!!!");
}
When I look at the server logs, the LogFiles directory has a hierarchy.
The yellow highlighted file includes my log statements:
2017-08-19T13:58:31.814 Function started (Id=d40f2ca6-4cb6-4fbe-a05f-006ae3273562)
2017-08-19T13:58:33.045 Function 1 trace
2017-08-19T13:58:33.045 Function 1 warning
2017-08-19T13:58:33.045 Function 1 error
2017-08-19T13:58:33.075 Function completed (Success, Id=d40f2ca6-4cb6-4fbe-a05f-006ae3273562, Duration=1259ms)
The structured directory contains nothing here, but it seems to have various "codeddiagnostic" log statements in my real function applications directory.
What should I expect here? Ultimately, I would like to have a single sink for logging from all of my application components and take advantage of structured logging across the board.
The best way to collect structured logging from Azure Functions is to use Application Insights. One you defined that your Logger is based on ILogger, you can define a Template that specifies the properties you want to log. Then on Application Insights traces, using the Application Insights Query Language (aka Kusto) you can access the values of each of these properties with the name customDimensions.prop__{name}.
You can find a sample of how to do this with Azure Functions v2 on this post https://platform.deloitte.com.au/articles/correlated-structured-logging-on-azure-functions
Just FYI: Azure Functions running in isolated mode (.NET5 and .NET6) don't support structured logging using the ILogger from DI or provided in the FunctionContext. As of November 2021, there is an open bug about it: https://github.com/Azure/azure-functions-dotnet-worker/issues/423
As I understand it, the bug happens because all ILogger calls goes through the GRPC connection between the host and the isolated function, and in that process the message gets formatted instead of sending the original format and arguments. The Azure Insights connection that would record the structured log runs on the host and only receives the final message.
I plan on investigating some king of workaround, playing with direct access to Azure Insights inside the isolated process. If it works, I'll post the workaround in a comment at the bug linked above.
I had the same question. The log file logger doesn't really respect structured logging, but if you use AppInsights for Azure Functions it will in fact add custom properties for your structured logging
I had a conversation going about it here
https://github.com/Azure/azure-webjobs-sdk-script/issues/1675

Pre azure start up

We are sending all trace logs to our NLog logger. (with a trace listener)
Nlog is configured to work with DryIoC.
Locally this works perfect, however, in Azure (web app), the first trace message is logged, before we could create our DryIoc container. Even a PreAppStartMethodAttribute does not help, as the trace log has occurred even before the PreAppStartMethodAttribute.
Is there a way to do some initialization tasks before azure logs it's first trace message?
I found a work-around by using an async wrapper that prevents NLog from flushing the data until the container/configuration has been initiliazed.

AccessViolationException thrown when running Azure web role under the Azure emulator

I am getting a System.AccessViolationException thrown during the execution of an Azure Web Role (run on the Azure emulator, this has not been uploaded to Azure yet) when a call is made to an overridden method of an object when a local int variable is passed as one of the method parameters. The exception message is "Attempted to read or write protected memory. This is often an indication that other memory is corrupt".
The code where the exception is thrown is part of a local library that has been used for several years on live systems (not Azure) with no issues. The part that errors is as follows:
foreach (XmlDataComponent item in this.items)
{
int index = 0;
XmlNode node = item.ToXml(dataSet, xmlDocument, this, index); // Exception thrown when this call is made
...
}
The XmlDataComponent is a base class, when the code runs item is one of its derived classes. The ToXml() method is overridden in the derived classes. The exception is thrown as soon as the call is made to ToXml().
The problem is the index parameter. If I swap this to use an explicit value instead of the local variable, e.g.
item.ToXml(dataSet, xmlDocument, this, 0)
there are no errors.
Similarly, if I cast the item to its actual type e.g.
((XmlDataItem)item).ToXml(dataSet, xmlDocument, this, index))
and mark the ToXml() method in the XmlDataItem class as new instead of override there are no errors.
I have also tried calling the library from a console application rather than a web role with exactly the same data (i.e. everything the same other than running under a web role). Again, this caused no problems.
It appears that when run under the Azure emulator, accessing a local variable as a parameter to an overridden method is an issue!!!
I'm hoping this is only an issue when run under the emulator, however we still need a fix otherwise dev is more difficult.
Any suggestions or advise would be much appreciated.

Getting Azure Logs from role process

I've configured the Azure Diagnostics so that the logs get uploaded to a storage table. I'm using Trace.TraceXxx from my code and all works well.
Now I'm trying to add tracing from the Role OnStart() and OnStop() methods. I know that the tracing works as I see the lines in the Debug window when running in the emulator. But from the cloud deployment, it seems that these trace lines never get uploaded to the table. My guess is that it is somewhat related to TraceSources, as the only trace lines I've in the table come from the w3wp.exe source... Any hint ?
Thanks
Like you said you can add the trace listener using the WaIISHost.exe.config, but besides that you can also add the trace listener in code (you'll need a reference to Microsoft.WindowsAzure.Diagnostics.dll):
public class WebRole : RoleEntryPoint
{
public override void Run()
{
var listener = new Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener();
Trace.Listeners.Add(listener);
...
}
}
Another way of setting up diagnostics is through the configuration file. If you created a VS solution recently, it will automatically create the diagnostics plug-in and configuration for the trace listener. With the config file (diagnostics.wadcfg) there is no code that needs to be written for the different data sources. Here is a link where you can get started and a sample file:
http://msdn.microsoft.com/en-us/library/gg604918.aspx
You cannot include custom performance counters right now and you need to make sure that you don’t try to allocate more than 4GB of buffer to anything (you can leave at 0), or it tends to fail.
Note, the time interval format (e.g PT1M). That is a serialization format, so PTXM is X minutes, while PTXS is X in seconds. You need to mark this as content and copy always in Visual Studio (place at root of project) so it gets packaged.
And here is a link to the three ways to setup diagnostics
http://msdn.microsoft.com/en-us/library/windowsazure/hh411541.aspx
Ranjith
http://www.opstera.com

log4j with liferay and tomcat

I have a Liferay setup on the Tomcat6. I used Log4j initially for portlets/webapps by adding log4j.properties file in the classes folder and log4j.jar file in the web-inf/lib.
Now we have few quartz jobs which are available in the tomcat/lib folder and I want to enable log4j logging for these jobs as well.
For these quartz jobs I have copied same log4j.properties file in the tomcat/lib.
With the new configuration I keep getting the following error:
Could not instantiate appender named "JOBS"
A "org.apache.log4j.RollingFileAppender" is not assignable a "org.apache.log4j.Appender" variable.
The class "org.apache.log4j.Appender" was loaded by ...
How to remove this error?
Is there any way I can keep a single log4j.properties file which can be used by both shared/lib as well as portlet/webapps.
According to this post the problem is that you have configured your log4j twice.
My solution would be that you create the logger instance like this
private static Logger logger = Logger.getLogger(FooBar.class.getName());
and not to have log4j.properties under any lib or class folder but having it under a folder named resources.
AFAIK this should be a place where the both parts of your application may have access to.
Known issue in Liferay: http://issues.liferay.com/browse/LPS-9376
In my case, the problem occurred once I started to use ServiceBuilder services, and added Log4J Logger to one of my ...LocalServiceImpl classes.
Once I removed Log4J logging from there everything got back to norm - exception disappeared.
(I made service methods throw exceptions, and was catching them in a code not related to ServiceBuilder read/generated classes, but it could also be done by changing Log4J logger calls to Liferay's LogUtil calls).

Resources