elmah in azure webjobs - azure

does anyone know how to setup elmah in an azure webjob ? The help section in the official website says it requires a few lines of code so this is what I have
static void Main()
{
AppDomain.CurrentDomain.UnhandledException += Log;
...
}
private static void Log(object sender, UnhandledExceptionEventArgs e)
{
var exception = e.ExceptionObject as Exception;
if (exception != null)
{
var logger = ElmahioAPI.Create("API_KEY");
logger.Messages.Error(new Guid("LOG_ID"), exception, "An error message");
}
}
I have an api_key and a log_id but nothing is being logged. I have elmah setup in a web app and I have to enter details in the web.config, this works perfectly (logging to sql server). The official help makes no reference to any settings in an app.config so how on earth does it know where to log the information ? Also they seem to have changed it so that you can read the logs from their website but how is this even setup ? Its very confusing, can anyone help ?

I have elmah setup in a web app and I have to enter details in the web.config, this works perfectly (logging to sql server).
It seems that you have confused EMLAH and elmah.io. Here are ELMAh and elmah.io differences.
ELMAH:
Errors can be logged to a variety of destinations through ELMAH’s plugin model called error logs. Plugins for XML, SQL Server, MySQL, Elasticsearch and many more exists.
elmah.io:
elmah.io is a cloud-based error management system originally developed on top of ELMAH.
As you have said, you have an API_KEY and LOG_ID, then you could use the following code to write log in emlah.io dashboard.
[ElmahIoExceptionFilter("API_KEY", "LOG_ID")]
public class Functions
{
// This function will get triggered/executed when a new message is written
// on an Azure Queue called queue.
public static void Trigger([TimerTrigger("0 */1 * * * *")]TimerInfo myTimer, TextWriter log)
{
throw new ApplicationException("Error from webjob");
}
}
The log screen shot are as below:
For same demo about Elmah.Io, you could refer to this github.

Related

How can I add tracing / logging messages for a Blazor Server Side App on Azure? (Preferred with App Service Logs)

I have a Blazor Server Side App that runs on Azure. I want to add tracing / logging messages (_logger.LogInformation()). I would prefer to use Azue App Service Logs. But, I am open to other options.
I was able to get tracing / logging messages working with an API written in .Net Core that runs on Azure. These logs are written to Azure App Service Logs. Their type are Application.
For my Blazor App, I followed the same steps setting up tracing / logging as I did with my API. However, when I check the log files in Cloud Explorer no Application folder, under the LogFiles folder is created.
I made sure I turned Azure App Service Logs and set the correct Level. See below.
My Program.cs uses the default setting. Which I read should automatically set up logging. (It did from my API) See below.
Below is the example of the code I added to do the tracing / logging.
public class VpbDelegateAdminService : IVpbDelegateAdminService
{
private readonly HttpClient _httpClient;
private readonly IJsonSerializerWrapper _jsonSerializerWrapper;
private readonly TokenProvider _tokenProvider;
private readonly ILogger<VpbDelegateAdminService> _logger;
public VpbDelegateAdminService(HttpClient httpClient, IJsonSerializerWrapper jsonSerializerWrapper, TokenProvider tokenProvider, ILogger<VpbDelegateAdminService> logger)
{
_httpClient = httpClient;
_jsonSerializerWrapper = jsonSerializerWrapper;
_tokenProvider = tokenProvider;
_logger = logger;
}
public async Task<VpbDelegateListVm> GetVpbDelegatesAsync(int pageNo, string searchText)
{
_logger.LogInformation($"Argument(s)- pageNo: {pageNo}, searchText: {searchText ?? "null"}");
As I mentioned above, I would prefer to use Azure App Service Logs. But, if that is not possible with Blazor or if someone has had success with other options to use with Blazor, I am interested to hearing about them.
Thanks for your help.
I figured it out myself.
I was able to get Logging / Tracing working with my Blazor server side app using App Service Logs by following the steps here: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-3.1 Related to steps for: AzureAppServices
Steps: (Note: There steps are only for filesystem / filestream. I didn't set up blob):
1. Update appsetting with:
"AzureAppServicesFile": {
"IncludeScopes": true,
"LogLevel": {
"Default": "Warning"
}
}
2. Install nuget packages for Microsoft.Extensions.Logging.AzureAppServices
3. Update the Program.cs with the following code:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging => logging.AddAzureWebAppDiagnostics())
.ConfigureServices(serviceCollection => serviceCollection
.Configure<AzureFileLoggerOptions>(options =>
{
options.FileName = "diagnostics-";
options.FileSizeLimit = 50 * 1024;
options.RetainedFileCountLimit = 5;
}))
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
4. Turned on App Service Log for Application Logging (Filesystem)
5. Set the Level to Information
And my logs / tracing (see below) started showing up in Cloud Explorer
_logger.LogInformation($"Argument(s)- pageNo: {pageNo}, searchText: {searchText ?? "null"}");
I hope these steps help someone else.
I would recommend using Application Insights, for .NET based apps it provides an excellent way for you to do complete APM. If you want to use with ILogger then please take a look here. If you want to get started without ILogger then take a look here.

No logs when exception is thrown in bot

We have an ASP.Net Core v4 bot that we deployed to Azure. It works fine when using the testing feature in Azure. Then we deployed to MS Teams. It works find except every message is followed with another message saying "Sorry, it looks like something went wrong." That message is usually sent when an exception is thrown. I tried to go to Azure to see the logs, but it's not logging anything.
We do have logger.LogError($"Exception caught : {exception.Message}"); in in our code, and I would think that it would log it somewhere when in production. So I turned on Application Insights for the bot, but it's not logging any exceptions. I tried streaming the logs from the web server, but it doesn't log anything when an exception is thrown.
I tried watching the application logs from the "Application logs" and "Web server logs"
Here is the code that handles errors:
public AdapterWithErrorHandler(IConfiguration configuration, ILogger<BotFrameworkHttpAdapter> logger, ConversationState conversationState = null)
: base(configuration, logger)
{
OnTurnError = async (turnContext, exception) =>
{
// Log any leaked exception from the application.
logger.LogError($"Exception caught : {exception.Message}");
// Send a catch-all apology to the user.
var errorMessage = MessageFactory.Text(ErrorMsgText, ErrorMsgText, InputHints.ExpectingInput);
await turnContext.SendActivityAsync(errorMessage);
if (conversationState != null)
{
try
{
// Delete the conversationState for the current conversation to prevent the
// bot from getting stuck in a error-loop caused by being in a bad state.
// ConversationState should be thought of as similar to "cookie-state" in a Web pages.
await conversationState.DeleteAsync(turnContext);
}
catch (Exception e)
{
logger.LogError($"Exception caught on attempting to Delete ConversationState : {e.Message}");
}
}
};
}
And here is the log settings for the app service for our bot:
#JohnGardner is correct. Botframework catches all errors, so you wouldn't may not see them in the typical Azure App Service logging.
#VinodkumarG is also correct that you can see the errors generated by logger.LogError($"Exception caught : {exception.Message}"); in
Bot Management >> Build >>Open online code editor >> Output window
or
https://<yourEndpoint>.scm.azurewebsites.net/dev/wwwroot/:vs.output
You actually should be able to see this in Log Stream > Application Logs
I added this to my bot:
In testing:
In Output:
In Log Stream > Application Logs:
Our current recommended approach is to use Application Insights. You can use Sample 21.Corebot-App-Insights as a guide. The primary modifications are how it adds App Insights in its Startup.cs:
Full
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.ApplicationInsights;
using Microsoft.Bot.Builder.Integration.ApplicationInsights.Core;
using Microsoft.Bot.Builder.Integration.AspNet.Core;
using Microsoft.Bot.Connector.Authentication;
using Microsoft.BotBuilderSamples.Bots;
using Microsoft.BotBuilderSamples.Dialogs;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.BotBuilderSamples
{
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
// Create the credential provider to be used with the Bot Framework Adapter.
services.AddSingleton<ICredentialProvider, ConfigurationCredentialProvider>();
// Add Application Insights services into service collection
services.AddApplicationInsightsTelemetry();
// Create the telemetry client.
services.AddSingleton<IBotTelemetryClient, BotTelemetryClient>();
// Add ASP middleware to store the http body mapped with bot activity key in the httpcontext.items. This will be picked by the TelemetryBotIdInitializer
services.AddTransient<TelemetrySaveBodyASPMiddleware>();
// Add telemetry initializer that will set the correlation context for all telemetry items.
services.AddSingleton<ITelemetryInitializer, OperationCorrelationTelemetryInitializer>();
// Add telemetry initializer that sets the user ID and session ID (in addition to other bot-specific properties such as activity ID)
services.AddSingleton<ITelemetryInitializer, TelemetryBotIdInitializer>();
// Create the telemetry middleware to track conversation events
services.AddSingleton<IMiddleware, TelemetryLoggerMiddleware>();
// Create the Bot Framework Adapter with error handling enabled.
services.AddSingleton<IBotFrameworkHttpAdapter, AdapterWithErrorHandler>();
// Create the storage we'll be using for User and Conversation state. (Memory is great for testing purposes.)
services.AddSingleton<IStorage, MemoryStorage>();
// Create the User state. (Used in this bot's Dialog implementation.)
services.AddSingleton<UserState>();
// Create the Conversation state. (Used by the Dialog system itself.)
services.AddSingleton<ConversationState>();
// The Dialog that will be run by the bot.
services.AddSingleton<MainDialog>();
// Create the bot as a transient. In this case the ASP Controller is expecting an IBot.
services.AddTransient<IBot, DialogAndWelcomeBot<MainDialog>>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseDefaultFiles();
app.UseStaticFiles();
//app.UseHttpsRedirection();
app.UseBotApplicationInsights();
app.UseMvc();
}
}
}
Diff vs CoreBot
You may also find this blog post useful: Bot Analytics: Behind the Scenes

Azure Monitor... or is it Log Analytics? Or Application Insights? Or Operational Insights? Or

Here's my scenario.
Application:
Created an asp.net core app
Grab an ILogger<T> logger;
logger.LogInformation(new EventId(123456, "HelloEvent"), "Hello there");
Infrastructure:
Deploy service fabric (via ARM template)
Deploy app to service fabric
Me:
Click around hopelessly looking for "Hello there" in my HelloEvent
So...
The BIG question: What are all the pieces of log collection/processing offered by Microsoft Azure, and how do they fit together?
Application Insights... Looks cool. I added .UseApplicationInsights() in my builder and .AddApplicationInsightsTelemetry(..) into my Startup.
And I get beautiful logs... ...about service fabric events, dependencies like http calls, etc. But I can't find my "Hello there" HelloEvent.
Where do I get it?
...
Moving onwards, I looked into logs, monitoring, etc, with Azure.
I find "Log Analytics", which looks cool. Apparently Application Insights uses it. But I already have Application Insights. Does that mean I have Log Analytics? Or do I create my own Log Analytics workspace. If so, do my logs go to two places? Do I connect Application Insights to it somehow?
The ARM template for that actually is from 2015 for something called OperationalInsights. Although there's a 2017 version in examples, but not in the reference documentation.
So Operational Insights? Apparently that's from some Microsoft Operations Management Suite / OMS. Which was MMS before...?
And the more recent docs all talk about "Azure Monitor". But that's not even something I can deploy in Azure. Is it just a concept?
…
All I want to do is collect logs somewhere and then have cool stuff to search & visualize them :)
...and I still haven't found my "HelloEvent"
Can anyone shed light on either my simple "Where's my HelloEvent" or speak to the bigger picture question "What are the pieces and how do they all fit together"?
Regarding the "Where's my HelloEvent" with application insights:
Please make sure in Startup.cs -> Configure method, you specify the loglevel to information, like below:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
// other code
//specify the LogLevel to Information, the default is warning
loggerFactory.AddApplicationInsights(app.ApplicationServices,LogLevel.Information);
}
(Update)and if you want to include event id in the logs, Simply setup ApplicationInsightsLoggerOptions instance in Startup.ConfigureServices method.
services
.AddOptions<ApplicationInsightsLoggerOptions>()
.Configure(o => o.IncludeEventId = true);
My test code as below:
public class HomeController : Controller
{
ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
_logger.LogInformation(new EventId(123456, "HelloEvent"), "Hello there");
return View();
}
// other code
}
And in the azure portal, I can see "hello there":

ServiceStack v4 : Configuring ELMAH with NLOG?

Hi am using ServiceStack V4 . Here i tried to configure Elmah with NLog using the below statement in the AppHost construtor.
LogManager.LogFactory = new ElmahLogFactory(new NLogFactory(), new HttpApplication());
Configured Elmah to log exceptions to XML files(In web.config file).
Whenever i get an exception in the service i can see the exception in the log file(As configured for NLog) but not in XML files(For elmah).
But if i add the below statements i can see the exception logged to XML files(As configured for elmah).
ServiceExceptionHandlers.Add((httpReq, request, exception) =>
{
HttpContext context = HttpContext.Current;
ErrorLog.GetDefault(context).Log(new Error(exception, context));
return DtoUtils.CreateErrorResponse(request, exception);
});
But the below link says we no need to add ServiceExceptionHandlers
How do we integrate elmah logging in servicestack
Can anyone please help me out in explaining where i am wrong.
This section on configuring Elmah and the Logging.Elmah UseCase for a working example of ServiceStack and Elmah configured together.
The ElmahLogFactory should be configured in your Global.asax before initializing the ServiceStack AppHost, e.g:
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
var debugMessagesLog = new ConsoleLogFactory();
LogManager.LogFactory = new ElmahLogFactory(debugMessagesLog, this);
new AppHost().Init();
}
}
The constructor accepts an alternate logger to use for your Debug/Info messages as well as the instance of the HttpApplication you wish to log to which on AppStartUp is the Global instance itself, that is accessible at runtime at HttpContext.Current.ApplicationInstance.

Force Application Start on Azure Web Role

I have a web role on azure and I would like to force a Application_Start without waiting for the first request.
I managed to set the "Start Automatically" property to true on my site
AutoStart a WCF on Azure WebRole
But the Application_Start is not called until the first request comes.
I don't know exactly if I am missing something important here. The server is a W2008 R2 and the IIS version is 7.5
Thanks!
SOLUTION
I put the solution code here. I hope will help someone. I just added a WebRole.cs and just put that code to perform a ping every 30 seconds. Please netice I'm browsing Service.svc because this is my endpoint, your endpoint could be another one. Notice I'm asking for "Endpoint1". If you have more than one endpoints, you should review that line.
public class WebRole : RoleEntryPoint
{
public override void Run()
{
var localuri = new Uri( string.Format( "http://{0}/Service.svc", RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["Endpoint1"].IPEndpoint ) );
while (true)
{
try
{
var request = (HttpWebRequest)WebRequest.Create(localuri);
request.Method = "GET";
var response = request.GetResponse();
}
catch { }
System.Threading.Thread.Sleep(30000);
}
}
public override bool OnStart()
{
return base.OnStart();
}
}
The IIS will only start when the first request arrives. The workaround is to send an HTTP request to the same VM from within OnStart or your RoleEntryPoint descendant - that's easy using WebRequest or equivalent class.
Jordi, I've recently experienced the same issue.
Based on my test Application_Start() is called ONLY when the 1st request ISS for the WebApp. (if you try to start VS in Debug without it open any page (see options in proj/debug), you will see that Application_Start() won't be called also if you don't run the WebApp in Azure)
I suppose that you need doing somethings when the WebRole start, well put your code in the WebRole.cs ;)
Here you can override OnStart() and OnStop() and put your code that wiil be execuded when the WebRole will start.
I've used this way to run a BakgroundWorker that do some scheduled tasks, independently from IIS.
I hope this help.
Davide.
Note:
1 - if you dont'have a WebRole.cs create it in the root of project and write inside:
public class WebRole : RoleEntryPoint
{
public override bool OnStart()
{
...your code...
return base.OnStart();
}
}
2 - If you need to debug the code mind that you need to run VS in debug with the Azure project that refer to WebApp as a "Run Project", otherwise the WebRole will not be called
You could try putting some code in your WebRole.cs to request some URLs from your website. I've tried that, and it seems to work somewhat. But it's a pain to debug, so I never got it really nailed down.
Another option would be to use IIS Application Initialization. You can't use it on IIS 7.5, but you can get IIS 8 if you upgrade your roles to Windows 2012 (set osFamily="3" in your .cscfg).

Resources