Log4net.Azure configuration - azure

Recently, we moved our solution (ASP.NET MVC4) to Windows Azure and so far, it is working
fine. Our only concern is that we are not able to locate our logs files no matter what
method we do implement:
Actually, our existing application uses log4net framework for Logging purpose.
Once we have moved our solution on Windows Azure, we still want to use log4net in
azure with minimal change in our existing code.
We have followed many blogs and tutorials in order to implement the following methods:
Synchronizing a log file to blob storage using Windows Azure Diagnostics module.
Using a custom log4net appender to write directly to table storage.
Logging to the Trace log and synchronizing to table storage.
Unfortunatly, none of the above has delivered the desired result. We are still not
able to get access to our logs. Is there any official source about how to use
Log4net with Windows Azure?
Step1: I imported Log4net.Azure as a reference to my MVC4 WebRole application
Step2: I added configuration lines in the On_Start method of WebRole class
public class WebRole : RoleEntryPoint
{
private static readonly ILog _logger = LogManager.GetLogger(typeof(WebRole));
public override void Run()
{
_logger.InfoFormat("{0}'s entry point called", typeof(WebRole).Name);
while (true)
{
Thread.Sleep(10000);
_logger.Debug("Working...");
}
}
public override bool OnStart()
{
BasicConfigurator.Configure(AzureAppender.New(conf =>
{
conf.Level = "Debug";
conf.ConfigureRepository((repo, mapper) =>
{
repo.Threshold = mapper("Debug"); // root
});
conf.ConfigureAzureDiagnostics(dmc =>
{
dmc.Logs.ScheduledTransferLogLevelFilter = LogLevel.Information;
});
}));
return base.OnStart();
}
Step3: I create an instance of ILog whenevr I need to log, here is an example:
public class TestController : ApiController
{
private static readonly ILog _logger = LogManager.GetLogger(typeof(WebRole));
[HttpGet]
public String Get()
{
_logger.InfoFormat("{0}'s entry point called", typeof(WebRole).Name);
_logger.Debug("<<<<<<<<<< WS just invoked >>>>>>>>>>>>...");
return "hello world logs on Azure :)";
}
}

You can use AdoNetAppender with Azure SQL database and config like this example: http://logging.apache.org/log4net/release/config-examples.html
Notice: create Log table using this statement:
CREATE TABLE [dbo].[Log](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Date] [datetime] NOT NULL,
[Thread] [varchar](255) NOT NULL,
[Level] [varchar](50) NOT NULL,
[Logger] [varchar](255) NOT NULL,
[Message] [varchar](4000) NOT NULL,
[Exception] [varchar](2000) NULL,
CONSTRAINT [PK_Log] PRIMARY KEY CLUSTERED (
[Id] ASC
))

Re: log4net.Azure
The logs won't be visible as the implementation uses the BufferingAppenderSkeleton base class which has a buffer size of 512 by default. You will have to make the application create 513 logs entries in ram before they are flushed. I did it this way to make it more performant.
You have 3 options to make it work per your expectations in an MVC/ASP.NET environment:
Change the buffer size in the config file
Call flush (but only in debug mode, this is a performance killer)
Call flush when your application shuts down so that it does an immediate write

If you are using a full IIS in your webrole (which is the default configuration), the website and the webrole run in seperate processes.
Because of this you'll have to setup the logging twice. Once in the OnStart() of your WebRole, and once in the Application_Start() of your Global.asax.

Related

How do I troubleshoot an exception in Startup class in Azure?

public class Startup
{
public IConfigurationRoot Configuration { get; }
public Startup(IHostingEnvironment env)
{
throw new Exception("boo");
}
}
Detailed error logging is enabled.
I don't use Application Insights and I don't want to.
The reply that will be marked as answer to this question will show:
The path and file name pattern of a log file that will contain the stack trace and also the text of the exception i.e. "boo".
or
A technique for displaying the error message on a page such as .UseDeveloperExceptionPage() (if you can show how to use .UseDeveloperExceptionPage() that would be great). I am in fact aware to not use .UseDeveloperExceptionPage() in prod.
Documentation states:
Only the hosting layer can handle exceptions that take place during app startup. Using the Web Host, you can configure how the host behaves in response to errors during startup with the captureStartupErrors and detailedErrors keys.
So you can configure your WebHost this way:
WebHost.CreateDefaultBuilder(args)
.CaptureStartupErrors(true)
.UseSetting(WebHostDefaults.DetailedErrorsKey, "true");

No job functions found in Azure Webjobs

Trying to get Azure Webjobs to react to incoming Service Bus event, Im running this by hitting F5. Im getting the error at startup.
No job functions found. Try making your job classes and methods
public. If you're using binding extensions (e.g. ServiceBus, Timers,
etc.) make sure you've called the registration method for the
extension(s) in your startup code (e.g. config.UseServiceBus(),
config.UseTimers(), etc.).
My functions-class look like this:
public class Functions
{
// This function will get triggered/executed when a new message is written
// on an Azure Queue called queue.
public static void ProcessQueueMessage([ServiceBusTrigger("test-from-dynamics-queue")] BrokeredMessage message, TextWriter log)
{
log.WriteLine(message);
}
}
I have every class and method set to public
I am calling config.UseServiceBus(); in my program.cs file
Im using Microsoft.Azure.WebJobs v 1.1.2
((Im not entirely sure I have written the correct AzureWebJobsDashboard- and AzureWebJobsStorage-connectionstrings, I took them from my only Azure storage-settings in Azure portal. If that might be the problem, where should I get them ))
According to your mentioned error, it seems that you miss parameter config for ininitializing JobHost. If it is that case, please use the following code.
JobHost host = new JobHost(config)
More detail info about how to use Azure Service Bus with the WebJobs SDK please refer to the document.The following is the sample code from document.
public class Program
{
public static void Main()
{
JobHostConfiguration config = new JobHostConfiguration();
config.UseServiceBus();
JobHost host = new JobHost(config);
host.RunAndBlock();
}
}

Semantic logging (SLAB) for MVC Azure Webapp

Am trying to implement SLAB for my Azure Web app (In Process) and my listner is Azure table Storage (table conection string) ,
the problem am facing is -“EventSource.IsEnabled() = always returns false”
(Am running the application from VS2013 with IIS express)
my code
————global.asax
var listener2 = new ObservableEventListener();
listener2.EnableEvents(SBEvents.Log, EventLevel.Verbose,Keywords.All);
listener2.LogToWindowsAzureTable(“sdf”, “DefaultEndpointsProtocol=https;AccountName=********;AccountKey=****************);
———-Event Source
Public class SBEvents :EventSource {
public class keywords{...}
public class Tasks {..}
private static readonly Lazy Instance = new Lazy(() => new SBEvents());
public static SBEvents Log { get { return Instance.Value; } }
[Event(102, Message = “Bike started with Bike ID :{0}”, Keywords = Keywords.Application, Level = EventLevel.Informational)]
public void BikeStarted(String BikeID){
if (this.IsEnabled()) //// = always returns false
this.WriteEvent(102,BikeID);
It looks like 'Azure Web Apps' cannot listen to ETW events.
https://azure.microsoft.com/en-in/documentation/articles/choose-web-site-cloud-service-vm/
Areas of diagnostics logging and tracing that aren't available to web applications on Azure are Windows ETW events, and common Windows event logs (e.g. System, Application and Security event logs). Since ETW trace information can potentially be viewable machine-wide (with the right ACLs), read and write access to ETW events are blocked. Developers might notice that API calls to read and write ETW events and common Windows event logs appear to work, but that is because WEb Apps is "faking" the calls so that they appear to succeed. In reality, the web app code has no access to this event data
Thanks

Changes to Azure ServiceConfiguration.Cloud.cscfg file

What are the sequence of events that occur when I make changes to the settings file (ServiceConfiguration.Cloud.cscfg) for an cloud deployed App? Will the worker roles restart so that the new changes are reflected? (Will the OnStop, OnStart, Run events be trigerred on changing the settings value?)
In my cloud service, I read the custom values from the configuration file in the Run() method of the WorkerRole and wondering if any change to ServiceConfiguration.Cloud.cscfg file for an app deployed in the cloud will re-trigger the OnStart and Run events?
Yes indeed, your instances will go through OnStop / (Reboot) / OnStart / Run after each configuration change. If you're storing the settings in your application in a static variable for example it might be a good thing to let this happen. This way, after the reboot your application will restart and it will get a chance to re-initialize all settings in the static variables.
Now on the other hand, if you want the instance to reboot you can handle this change yourself (maybe you cached the settings somewhere, or iniitalized a static object without those settings). You'll need to trigger the reboot by handling the RoleEnvironment.Changing event :
public override bool OnStart()
{
RoleEnvironment.Changing += RoleEnvironmentChanging;
return base.OnStart();
}
private void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e)
{
if ((e.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange)))
{
e.Cancel = true;
}
}

trace.writeline not working in azure Onstop method

I am wondering why the following azure workerrole does not show any diagnostic messages when the role is shutdown:
public class WorkerRole : RoleEntryPoint {
private bool running=true;
public override void Run() {
while (running)
{
Thread.Sleep(10000);
TTrace.WriteLine("working", "Information");
}
Trace.WriteLine("stopped", "Information");
}
public override bool OnStart()
{
Trace.WriteLine("starting", "Information");
return base.OnStart();
}
public override void OnStop() {
Trace.WriteLine("stopping", "Information");
running = false;
base.OnStop();
}
}
I can see the events 'starting' and 'working' in the diagnostic logs, but the Onstop method does not log anything. I was wondering if it's even called so I injected some code in the OnStop() method to write out some data. In fact the data was written as expected which proves that the method is called, it's just that I don't get any logs. Any ideas how to Trace my shutdown code?
My first and best guess is that the Diagnostics Agent does not have time to transfer the trace out to storage for you to see it. Traces are first logged locally on the VM, then the agent will transfer them off (OnDemand or Scheduled) depending on how you have configured it. Once the VM shuts down, the agent is gone too and cannot transfer it off.
Tracing in OnStop is not supported and if you manage to get it working via On-Demand Transfer (http://msdn.microsoft.com/en-us/library/windowsazure/gg433075.aspx ) it's likely to not work in the next release. Note, tracing in Web Role OnStart does not work either. See my blog post http://blogs.msdn.com/b/rickandy/archive/2012/12/21/optimal-azure-restarts.aspx to fix that. Also see my blog post for instructions on view real time OnStop trace data with DbgView.
The OnStop method should be used only to delay shutdown until you've cleaned up - so you shouldn't have much code in there to trace. Again, see my blog for details.

Resources