No logs when exception is thrown in bot - azure

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

Related

Finding "Application Stop Events" in Azure Application insights

I have a web application that sometimes undergoes "Platform (Infrastructure Upgrade)" events.
The only way that I can detect these is by going to the Azure portal and drilling down
Diagnose and Solve Problems > Web App Restarted
and looking for errors such as below
My question really, is can I use Application Insights to query Azure to find out when these events happen?
Seems like a simple thing to do, but can't figure it out to do it.
can I use Application Insights to query Azure to find out when these events happen?
No, but your application is maybe able to log an event upon start or close? For example, in a .Net Core app you can listen to stop/start events like this:
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public static void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime hostApplicationLifetime, TelemetryClient telemetryClient)
{
hostApplicationLifetime.ApplicationStarted.Register(() => { telemetryClient.TrackEvent("App Started"); });
hostApplicationLifetime.ApplicationStopping.Register(() => { telemetryClient.TrackEvent("App Stopping"); });
hostApplicationLifetime.ApplicationStopped.Register(() => {
telemetryClient.TrackEvent("App Stopped");
telemetryClient.Flush();
Thread.Sleep(TimeSpan.FromSeconds(5));
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
}
It uses the IHostApplicationLifetime interface to get notified of application lifetime events.

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.

elmah in azure webjobs

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.

.NET Core 2.0 HttpClient Singleton throwing 502

I have a web application acting as a gateway to a variety of internal services. These services are consumed by using a single instance of HttpClient, instantiated at startup (i.e. Startup.cs)
After a certain period of time, something is causing our HttpClient to stop hitting our APIs and immediately fail with HTTP 502 errors for every call using that client. (Note that I can still hit our APIs using other means, such as Postman)
Also be aware that this is all deployed to a variety of AppServices in Azure.
Any ideas as to what could corrupt HttpClient in this manner?
Thanks,
-Tim
This error is usually given when you are behind a proxy server.
If you are using a proxy you will probably have to authenticate the http client again.
Another possibility is to generate the Singleton instance again when it gives an error, for Example Singleton.killInstance(); If your implementation is like this:
public class Singleton
{
private static Singleton instance;
private Singleton() {}
public static Singleton instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
public static void Singleton killInstance()
{
instance == null
}
}
Whatever the error might be, your httpclient request is causing your web server to crash. In order to investigate it, you need to go to to the Event Viewer of your AppService.
Here are the steps to launch the event viewer:
Go to Kudu management site of your website (ie https://{sitename}.scm.azurewebsites.net
Open menu item: Tools => Support
Choose relevant Azure AD Directory of your website
Click on Analyze => Event Viewer.
Check the error messages

My custom Windows Service is not writing to my custom Event Log

I have written a custom Windows Service that writes data to a custom Event Log (in the Windows Event Viewer).
For dev'ing the biz logic that the service uses, I created a Windows Form which simulates the Start/Stop methods of the Windows Service.
When executing the biz logic via the Windows Forms, info is successfully written to my custom Event Log. However, when I run the same biz logic from the custom Windows Service, information is failing to be written to the Event Log.
To be clear, I have written a library (.dll) that does all the work that I want my custom service to do - including the create/write to the custom Event Log. My Form application references this library as does my Windows Service.
Thinking the problem is a security issue, I manually set the custom Windows Service to "Log on" as "Administrator", but the service still did not write to the Event Log.
I'm stuck on how to even troubleshoot this problem since I can't debug and step into the code when I run the service (if there is a way to debug a service, please share).
Do you have any ideas as to what could be causing my service to fail to write to the event log?
I use it like this. There can be some typos. Writed it on my phone browser...
public class MyClass
{
private EventLog eventLog = new EventLog();
public void MyClass()
{
if (!System.Diagnostics.EventLog.SourceExists("MyLogSource"))
System.Diagnostics.EventLog.CreateEventSource("MyLogSource", "MyLogSource_Log");
eventLog.Source = "MyLogSource";
eventLog.Log = "MyLogSource_Log";
}
private void MyLogWrite()
{
eventLog.WriteEntry(ex.ToString(), EventLogEntryType.Error);
}
}
To debug a running service you need to attach to the process. See here for the steps.
You could also add parameter checking to the Main entry point and have a combination service and console app which would start based on some flag. See this SO post for a good example but here's a snippet:
using System;
using System.ServiceProcess;
namespace WindowsService1
{
static class Program
{
static void Main(string[] args)
{
if (args == null)
{
Console.WriteLine("Starting service...");
ServiceBase.Run(new ServiceBase[] { new Service1() });
}
else
{
Console.WriteLine("Hi, not from service: " + args[0]);
}
}
}
}
The above starts the app in console mode if there any parameters exist and in service mode if there are no parameters. Of course it can be much fancier but that's the gist of the switch.
I discovered why my service wasn't writing to the Event Log.
The problem had nothing to do with any part of the code/security/etc that was attempting to write to the EL. The problem was that my service wasn't successfully collecting the information that is written to the EL - therefore, the service wasn't even attempting to write the log.
Now that I fixed the code that collects the data, data is successfully writing to the event log.
I'm open to having this question closed since the question was amiss to the real problem.

Resources