Skip to content
Get Started for Free

Log Analytics

Azure Log Analytics workspaces are where Azure Monitor keeps log data: the resource logs that diagnostic settings send, the activity log, Application Insights telemetry, and the logs that services such as Container Apps write directly. You query a workspace with the Kusto Query Language (KQL). For more information, see Log Analytics workspace overview.

LocalStack for Azure emulates workspaces and their tables, and fills them with the logs your emulated resources produce when you configure them to send logs, as you would in Azure. You query the logs with the Azure CLI, the Azure Monitor Query SDK, or the Logs pages of the Azure Portal Emulator, and the KQL engine answers in the shapes Azure returns. The supported APIs are available on our API Coverage section, which provides information on the extent of Log Analytics’ integration with LocalStack.

This guide is designed for users new to Log Analytics and assumes basic knowledge of the Azure CLI and our lstk az proxy. It creates a workspace and a custom table, sends a storage account’s logs to the workspace, and queries them.

Launch LocalStack using your preferred method. For more information, see Introduction to LocalStack for Azure. Once the container is running, enable Azure CLI interception by running:

Terminal window
lstk az start-interception

This command points the az CLI away from the public Azure management REST API and toward the LocalStack for Azure emulator API. To revert this configuration, run:

Terminal window
lstk az stop-interception

This reconfigures the az CLI to send commands to the official Azure management REST API.

Create a resource group to hold all resources created in this guide:

Terminal window
az group create --name rg-laws-demo --location westeurope
Output
{
"id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-laws-demo",
"location": "westeurope",
...
"name": "rg-laws-demo",
"properties": {
"provisioningState": "Succeeded"
},
...
}

Create a workspace with a 30-day retention period, the default of --retention-time in the az monitor log-analytics workspace create reference:

Terminal window
az monitor log-analytics workspace create \
--name my-workspace \
--resource-group rg-laws-demo \
--location westeurope \
--retention-time 30
Output
{
...
"customerId": "5cb75716-b4fa-4944-aa74-f746e0520b60",
...
"location": "westeurope",
...
"name": "my-workspace",
"provisioningState": "Succeeded",
...
"retentionInDays": 30,
"sku": {
...
"name": "PerGB2018"
},
...
}

Diagnostic settings name a workspace by its resource ID, and the query API by its workspace ID, the customerId of the workspace. Read both into variables:

Terminal window
WORKSPACE_RESOURCE_ID=$(az monitor log-analytics workspace show \
--workspace-name my-workspace \
--resource-group rg-laws-demo \
--query id \
--output tsv)
WORKSPACE_ID=$(az monitor log-analytics workspace show \
--workspace-name my-workspace \
--resource-group rg-laws-demo \
--query customerId \
--output tsv)

Retrieve the primary and secondary shared keys of the workspace, which Container Apps environments and container groups use to write their logs to it:

Terminal window
az monitor log-analytics workspace get-shared-keys \
--workspace-name my-workspace \
--resource-group rg-laws-demo
Output
{
"primarySharedKey": "...",
"secondarySharedKey": "..."
}

Create a table for your own logs. The names of custom tables end in _CL:

Terminal window
az monitor log-analytics workspace table create \
--name AppEvents_CL \
--workspace-name my-workspace \
--resource-group rg-laws-demo \
--columns TimeGenerated=datetime Level=string Message=string \
--retention-time 30
Output
{
...
"name": "AppEvents_CL",
"plan": "Analytics",
"provisioningState": "Succeeded",
...
"retentionInDays": 30,
...
"totalRetentionInDays": 30,
...
}

Query the schema of the new table. Besides the columns you declared, it has the standard columns Azure adds:

Terminal window
az monitor log-analytics query \
--workspace "$WORKSPACE_ID" \
--analytics-query "AppEvents_CL | getschema | project ColumnName, ColumnType"
Output
[
{
"ColumnName": "TimeGenerated",
"ColumnType": "datetime",
"TableName": "PrimaryResult"
},
{
"ColumnName": "Level",
"ColumnType": "string",
"TableName": "PrimaryResult"
},
{
"ColumnName": "Message",
"ColumnType": "string",
"TableName": "PrimaryResult"
},
{
"ColumnName": "TenantId",
"ColumnType": "string",
"TableName": "PrimaryResult"
},
{
"ColumnName": "Type",
"ColumnType": "string",
"TableName": "PrimaryResult"
},
{
"ColumnName": "_ResourceId",
"ColumnType": "string",
"TableName": "PrimaryResult"
}
]

Send a storage account’s logs to the workspace

Section titled “Send a storage account’s logs to the workspace”

Create a storage account:

Terminal window
az storage account create \
--name stlawsdemo \
--resource-group rg-laws-demo \
--location westeurope \
--sku Standard_LRS
Output
{
...
"kind": "StorageV2",
...
"location": "westeurope",
...
"name": "stlawsdemo",
...
"provisioningState": "Succeeded",
...
"sku": {
"name": "Standard_LRS",
...
},
...
}

Send the write operations of its Blob service to the workspace with a diagnostic setting:

Terminal window
STORAGE_ACCOUNT_ID=$(az storage account show \
--name stlawsdemo \
--resource-group rg-laws-demo \
--query id \
--output tsv)
az monitor diagnostic-settings create \
--name send-to-workspace \
--resource "$STORAGE_ACCOUNT_ID/blobServices/default" \
--workspace "$WORKSPACE_RESOURCE_ID" \
--logs '[{"category":"StorageWrite","enabled":true}]'
Output
{
...
"logs": [
{
"category": "StorageWrite",
"enabled": true,
"retentionPolicy": {
"days": 0,
"enabled": false
}
}
],
...
"name": "send-to-workspace",
...
"workspaceId": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-laws-demo/providers/Microsoft.OperationalInsights/workspaces/my-workspace"
}

Create a blob container. The request is a write, so the diagnostic setting sends its record to the workspace:

Terminal window
az storage container create \
--name logs-demo \
--account-name stlawsdemo \
--auth-mode key
Output
{
"created": true
}

Query the StorageBlobLogs table for the request:

Terminal window
az monitor log-analytics query \
--workspace "$WORKSPACE_ID" \
--analytics-query "StorageBlobLogs | where OperationName == 'CreateContainer' | project OperationName, StatusCode, AuthenticationType"
Output
[
{
"AuthenticationType": "AccountKey",
"OperationName": "CreateContainer",
"StatusCode": "201",
"TableName": "PrimaryResult"
}
]

Delete the workspace:

Terminal window
az monitor log-analytics workspace delete \
--workspace-name my-workspace \
--resource-group rg-laws-demo \
--yes

Then list the workspaces in the resource group to confirm it’s gone:

Terminal window
az monitor log-analytics workspace list \
--resource-group rg-laws-demo
Output
[]

Delete the resource group, which deletes the storage account and its diagnostic setting too:

Terminal window
az group delete --name rg-laws-demo --yes
  • Workspace lifecycle: Create, read, list, update, and delete workspaces, with their shared keys, retention, and SKU, and list the workspaces you deleted.
  • Built-in tables: A new workspace lists the built-in tables Azure creates for it, with their schemas.
  • Custom tables: Create, update, and delete custom tables (_CL) with the Tables API, set a table’s retention, total retention, and plan, and add custom columns (_CF) to built-in tables.
  • KQL queries: The query API answers queries on a workspace, on a single resource’s records, and in batches, and its metadata lists the workspace’s tables with their columns. The query hosts are api.loganalytics.io and api.loganalytics.azure.com. See Kusto Query Language (KQL).
  • Logs from what your resources do: Records come from the requests the emulator serves, the messages it carries, the statements its database engines run, and the output of the containers it starts. A record reaches a workspace only when a diagnostic setting or a service’s own log setting sends it there, as in Azure.
  • Diagnostic settings: A diagnostic setting sends a resource’s logs to AzureDiagnostics or to the category’s resource-specific table, as each resource type does in Azure, and its platform metrics to AzureMetrics. See the categories the emulator produces.
  • Activity log export: A subscription’s diagnostic setting exports its activity log to the AzureActivity table.
  • Services’ own log settings: Container Apps environments with the log-analytics destination, container groups with diagnostics.logAnalytics, the Application Insights components linked to the workspace, and AKS clusters with the monitoring add-on write their tables.
Environment variable Default Description
LS_AZURE_LOG_ANALYTICS_DELIVERY 1 Whether the emulator collects its services’ resource logs and platform metrics for the diagnostic settings that ask for them. Set it to 0 to turn the collection off.
LS_AZURE_LOG_ANALYTICS_MAX_ROWS_PER_TABLE 100000 The most rows a table of a workspace keeps. Past it, the oldest rows go first.
  • Logs live in memory: A workspace keeps its records in memory, each table up to LS_AZURE_LOG_ANALYTICS_MAX_ROWS_PER_TABLE rows, and the records are gone when the emulator stops.
  • No ingestion APIs: The Logs Ingestion API and the legacy HTTP Data Collector API aren’t emulated, so a custom table you create receives no rows from your own code.
  • Some categories stay empty: The emulator accepts every diagnostic log category of a resource type, but produces only the categories whose activity it sees. See Log categories.
  • No ingestion latency: Records arrive within seconds of the operation that produces them, where Azure can take up to 90 minutes for a new diagnostic setting.
  • Other workspace features: Saved searches, query packs, linked services and storage accounts, data export rules, clusters, summary rules, search jobs, and Microsoft Sentinel aren’t emulated.

The following samples demonstrate how to use Azure Log Analytics with LocalStack for Azure:

23 of 87 operations implemented

Operation ▲Implemented ▼
Page 1 of 0
Was this page helpful?