Capture of Web Application Logs with App Service Diagnostics Logging

Raja Rajan
5 min readMar 24, 2021

Think you are the lead web developer for an internet style site primarily based on azure net apps. The agency is rolling out a primary rebranding, and is the usage of this as an possibility to carry new purchasing, monitoring, and social media features to the corporation’s on line presence. The organisation has gained numerous prestigious and influential enterprise and client awards for the excessive well known of its present day online patron experience, so it’s miles critical that when the new apps pass stay, there aren’t any sudden performance or functionality issues. You have got an app in improvement and, all through this early level of the dev cycle, you need a easy and clean way to capture basic app logging output without the want for a specialized sdk, including azure application insights.
In this module, to document strains to your web apps, you’ll permit app logging. You may permit logging, reveal a live log stream, and retrieve logs from azure.

What are app logs?

App logs are the output of runtime trace statements in app code. For example, you would possibly want to test some logic in your code by including a hint to reveal whilst a specific characteristic is being processed, or you might most effective need to see a logged message while a specific degree of errors has happened. App logging is on the whole for apps in pre-production and for tough problems, because immoderate logs can convey a performance hit and quickly devour garage; for that reason, logging to the report gadget is robotically disabled after 12 hrs.

Install and Configure Azure Logging Package

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder
.UseStartup<Startup>()
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.AddConsole();
logging.AddAzureWebAppDiagnostics();
});
});

Enable logging using the Azure portal

Enable logging using the Azure CLI

The current version of Azure CLI does not enable you to manage app logging to blob storage. To enable app logging to the file system, run this command.

az webapp log config — application-logging true — level verbose — name <app-name> — resource-group <resource-group-name>

What logs can be streamed

The log streaming service provides a redirect from the record device logs, so you’ll see the equal information as is stored to those log files. So, if you allow verbose logging for ASP.NET Windows apps, as an instance, the stay log move will display all of your logged messages.

Creating webhook

POST https://graph.microsoft.com/v1.0/subscriptions
Content-type: application/json

{
"changeType": "created",
"notificationUrl": "https://url-to-your-api",
"resource": "me/mailFolders('Inbox')/messages",
"expirationDateTime":"2017-03-09T09:43:00.00Z",
"clientState": "subscription-identifier"
}

Notice the useful resource and changeType properties in the frame of the request. The useful resource property specifies the type of resource for that you are growing a new subscription. The changeType property specifies the type of occasions you want the subscription to run. In this example, the subscription will call my API whilst a brand new mail is obtained.

When you want to try this thru utility permission, you cannot use the resource URL that’s used above. With software permissions, you are not strolling inside the context of a user, so that you need to exchange the resource URL as follows inside the body:

{
"changeType": "created",
"notificationUrl": "https://url-to-your-api",
"resource": "Users/<user-id>/mailFolders('Inbox')/messages",
"clientState": "subscription-identifier"
}

Application monitoring with Terraform

Building the prerequisites

resource "azurerm_storage_account" "test_sa" {
name = "test_sa"
resource_group_name = "${var.rg_name}"
location = "${var.location}"
account_tier = "Standard"
account_replication_type = "LRS"
}

resource "azurerm_application_insights" "test_insight" {
name = "test_insight"
location = "${var.location}"
resource_group_name = "${var.rg_name}"
application_type = "Web"
}

resource "azurerm_log_analytics_workspace" "test_analytics" {
name = "test_analytics"
location = "${var.location}"
resource_group_name = "${var.rg_name}"
sku = "PerGB2018"
retention_in_days = "${var.retention_period}"
}

resource "azurerm_monitor_action_group" "test_ag" {
name = "${var.action_group_name}"
resource_group_name = "${var.rg_name}"
short_name = "action"

webhook_receiver {
name = "${var.webhook_name}"
service_uri = "${var.webhook_url}"
}
}

Azure VM Extension for more metrics

We increase our ‘azurerm_virtual_machine’ construct module in Terraform with the below, which configures Diagnostic Settings for the Azure VM.

resource "azurerm_virtual_machine_extension" "monitor-DependencyAgent-agent" {
count = "${var.do_bootstrap == true ? 1 : 0}"
name = "vmext-monitorDepAgent-${var.vm_hostname}"
location = "${var.location}"
resource_group_name = "${var.rg_name}"
virtual_machine_name = "${azurerm_virtual_machine.windows-vm.name}"
publisher = "Microsoft.Azure.Monitoring.DependencyAgent"
type = "DependencyAgentWindows"
type_handler_version = "9.5"
auto_upgrade_minor_version = true

settings = <<SETTINGS
{
"workspaceId": "${var.analytics_workspace_id}"
}
SETTINGS

protected_settings = <<PROTECTED_SETTINGS
{
"workspaceKey": "${var.analytics_workspace_key}"
}
PROTECTED_SETTINGS

tags = {
environment = "${var.environment}"
role = "${var.role}"
}
}

resource "azurerm_virtual_machine_extension" "monitor-agent" {
count = "${var.do_bootstrap == true ? 1 : 0}"
name = "vmext-monitorAgent-${var.vm_hostname}"
location = "${var.location}"
resource_group_name = "${var.rg_name}"
virtual_machine_name = "${azurerm_virtual_machine.windows-vm.name}"
publisher = "Microsoft.EnterpriseCloud.Monitoring"
type = "MicrosoftMonitoringAgent"
type_handler_version = "1.0"
auto_upgrade_minor_version = true

settings = <<SETTINGS
{
"workspaceId": "${var.analytics_workspace_id}"
}
SETTINGS

protected_settings = <<PROTECTED_SETTINGS
{
"workspaceKey": "${var.analytics_workspace_key}"
}
PROTECTED_SETTINGS

tags = {
environment = "${var.environment}"
role = "${var.role}"
}
}

Recipe Time

powershell_script 'Install Azure Insights' do
code <<-EOH
try {
Set-PSRepository -Name "PSGallery" -InstallationPolicy Trusted
Install-PackageProvider -Name NuGet -Force
Install-Module -Name PowerShellGet -Force
Update-Module -Name PowerShellGet
Install-WindowsFeature -Name Web-Server -IncludeAllSubFeature
Install-Module -Name Az.ApplicationMonitor -AcceptLicense -Force
Import-Module 'C:\\Program Files\\Microsoft Application Insights\\Status Monitor\\PowerShell\\Microsoft.Diagnostics.Agent.StatusMonitor.PowerShell.dll'
Start-ApplicationInsightsMonitoring -Name #{website} -InstrumentationKey #{insight_key}
} catch {
Write-Host $_.Exception.Message
Continue
}
EOH
end

Alerting

resource "azurerm_monitor_metric_alert" "storageAlert01" {
name = "storage-metricalert"
resource_group_name = "${var.rg_name}"
scopes = ["${var.alert_storage_id}"]
description = "Action will be triggered when Transactions count is greater than 50."

criteria {
metric_namespace = "Microsoft.Storage/storageAccounts"
metric_name = "Transactions"
aggregation = "Total"
operator = "GreaterThan"
threshold = "${var.storage_transaction_threshold}"

dimension {
name = "ApiName"
operator = "Include"
values = ["*"]
}
}

action {
action_group_id = "${var.alert_group_id}"
}
}

In this implementation, we have one not unusual ARM template with all the variables and we have exceptional ARM templates with unique parameters for distinct metrics.

--

--