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

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.

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.

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

Add application insights to stateless service fabric app

I'm trying to follow this documentation for starting to use application insights in a .net core application I deploy to service fabric.
My code is really simple
public FailedAuthorise(StatelessServiceContext context, IConfigManager config)
: base(context)
{
_worker = new Worker<PaymentFailedAuthorise>(config, FailedAuthoriseHandlerFactory.Create, "FailedAuthorise", "FailedAuthoriseError");
}
protected override async Task RunAsync(CancellationToken cancellationToken)
{
await _worker.RunAsync(cancellationToken);
}
Being the worker just a generic class that reads from some queues and processes the messages
But if I was to follow that document I would need to install some nuget packages (which actually are giving me problems to find and/or install, for instance no access to the using Microsoft.ApplicationInsights.ServiceFabric; or will need to change the instrumentation key on a configuration file modification on the pipeline) and start using "hosting" classes that I don't really need in my solution.
Is not a simple way of just adding application insights to what used to be a worker role in the cloud services with no need of the hosting bit?
Thanks,
You can just add this nuget package and create your own custom telemetry like this:
public class MyService
{
private readonly TelemetryClient telemetryClient;
public MyService()
{
telemetryClient = new TelemetryClient(configuration);
telemetryClient.Context.InstrumentationKey = "[Your Key Here]";
}
public FailedAuthorise(StatelessServiceContext context, IConfigManager config)
: base(context)
{
_worker = new Worker<PaymentFailedAuthorise>(config, FailedAuthoriseHandlerFactory.Create, "FailedAuthorise", "FailedAuthoriseError");
}
protected override async Task RunAsync(CancellationToken cancellationToken)
{
telemetryClient.TrackEvent("Worker started");
await _worker.RunAsync(cancellationToken);
}
}
There are several things you can track, like exceptions, traces, events, metrics and requests but if you are not using Asp.Net Core you will have to manually send those events as opposed to having some middleware sending the telemetry to App Insigths.
If your service calls other services you can add this package to automatically track communication to other services.

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":

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.

Resources