A container-first application designed for querying Azure Log Analytics workspaces, constructing KQL queries, and analyzing log telemetry with interactive GUI controls.
AI-Powered KQL Assistant (
Ask AI):- Click Ask AI in the top navigation bar to open the AI Assistant modal.
- Describe what logs you want to investigate in plain English (e.g., "Find all HTTP 500 errors from Application Gateway in the last 24 hours").
- Integrates with Azure OpenAI (
gpt-4o) to automatically generate optimized KQL queries with step-by-step technical explanations. - Generates KQL code that automatically populates into the editor for instant 1-click execution.
Query Row Limit Selector (
Max Rows):- Select query maximum row limits (
100,500,1000,2500,5000,10000,50000rows) directly from the query toolbar before running queries. - Default value set to
1000rows to optimize performance and backend memory usage while preventing browser DOM overload.
- Select query maximum row limits (
Alphabetically Sorted Log Presets Library:
- Interactive ⚡ Log Presets dropdown menu and Quick Switch chips, automatically sorted in strict alphabetical order by name:
- AFD Access Log (
AzureDiagnosticsFrontDoorAccessLog) - AFD Firewall Log (
AzureDiagnosticsFrontDoorWebApplicationFirewallLog) - App Gateway Log (
AzureDiagnosticsApplicationGatewayAccessLog) - App Service HTTP Logs (
AppServiceHTTPLogs) - Automation Job Logs (
AzureDiagnosticsMICROSOFT.AUTOMATION JobLogs) - Azure Firewall Application Log (
AzureDiagnosticsAZFWApplicationRule) - Azure Firewall Network Log (
AzureDiagnosticsNetworkRule) - Email Delivery Status (
ACSEmailStatusUpdateOperational) - Key Vault Audit Log (
AzureDiagnosticsMICROSOFT.KEYVAULT AuditEvent) - Kube Events (
KubeEvents) - Log Usage by DataType (
Usagebillable volume summary by DataType per day) - Network Security Group Logs (
AzureDiagnosticsNetworkSecurity withResourceGroup&Resourcedynamic filters) - SMS Incoming Operations (
ACSSMSIncomingOperationswithOperationName&PhoneNumberdynamic filters) - Storage Blob Log (
StorageBlobLogs) - Storage Fileshare Log (
StorageFileLogs) - WVD Connections (
WVDConnectionsAzure Virtual Desktop telemetry)
- AFD Access Log (
- Interactive ⚡ Log Presets dropdown menu and Quick Switch chips, automatically sorted in strict alphabetical order by name:
Interactive Dynamic Filters & KQL Preview:
- Dynamic filter dropdowns populated via live distinct value queries from Azure Log Analytics.
- Smart query stripping engine (
fetchDynamicFilters) that strips post-aggregation operations (summarize,order by,project,render) when fetching distinct filter values to ensure 100% dropdown population. - GUI condition controls with real-time
⚡ KQL Previewbar. - Multiple condition operators supported:
==,!=,contains,!contains, andbetween(e.g.,between (400 .. 599)).
Isolated Table Body Scrollbar & Column Tools:
- Vertical scrollbar is strictly contained within the table body scroll area (
.table-body-wrap) below column headers, preventing scrollbar overlap on Column Names. - Direct click-hold drag header reordering to customize column sequence.
- Synchronized horizontal scrollbar across header and body tables.
- Multi-operator primary result filtering (
==,!=,contains,!contains) with visual active filter pills. - Page size customization (
50,100,200,500,1000rows per page), dynamic pagination, type-aware sorting (numeric, ISO timestamp, string), CSV export, and Local/UTC timezone toggles.
- Vertical scrollbar is strictly contained within the table body scroll area (
Summarized Result Output & KQL Group By Breakdown:
- Analytical summary table displaying distinct value frequency counts (
Count) and percentage share (% Share) with progress indicators. - KQL Multi-Column Grouping (
| summarize count() by ...): Select multiple columns (e.g.,requestUri_sandclientIP_s) to execute AND tuple grouping, displaying exact combination counts for each URI per Client IP. - Cascading Filter Dropdown: 2-level menu allowing multi-column checking and specific sub-value selection per column.
- Interactive Column Header Sorting: Click any header (
Column Name,Distinct Output Value,Count,% Share, or dynamic column headers) to sort rows in Ascending (↑) or Descending (↓) order. - Dynamic View Scope Toggle: Switch between summarizing over active primary filtered results (
Filtered) or the total dataset (All Rows).
- Analytical summary table displaying distinct value frequency counts (
Multi-Tab Query Workspace (
Multi Tab):- Open, switch between, and manage multiple query tabs (
Query 1,Query 2, etc.) simultaneously. - Each tab maintains an isolated, independent state including KQL editor query text, active preset, filter conditions, project columns, dynamic filters, workspace ID, timespan, max rows, and query result tables.
- Changing workspace ID on a tab resets all query data for that specific tab cleanly, keeping other open tabs untouched.
- Open, switch between, and manage multiple query tabs (
KQL Code Intellisense & Command Suggestions (
Command Suggestions):- Live autocompletion and KQL command suggestions directly within the KQL Code Editor.
- Autocompletes KQL keywords (
where,project,summarize,extend,order by,count(),ago(),contains,between,by,take,limit, etc.) and column field names as you type. - Press
Tab,Enter, or click a suggestion chip to insert commands instantly into the editor.
Real-Time KQL Syntax Error Notifications (
Syntax Error Notifications):- Real-time syntax validation engine (
validateKql) analyzing KQL queries as you type. - Detects missing/unmatched parentheses, brackets, invalid or misspelled operators, and unclosed quotes.
- Displays header warning badges (e.g.
⚠️ 1 Syntax Error/⚠️ N Syntax Errors) and red glowing alert borders (rgba(244, 63, 94, 0.5)) detailing exact line numbers and syntax diagnostic explanations.
- Real-time syntax validation engine (
Secure Azure AD Auth & Workspace Discovery:
- Secure Azure AD authentication (MSAL SPA) with dynamic Azure Resource Graph workspace discovery and Service Principal (SPN) / Managed Identity support.
The application features an integrated AI Assistant powered by Azure OpenAI to help users construct complex KQL queries effortlessly:
Natural Language to KQL Translation:
- Click the Ask AI button at the top right of the navigation bar.
- Enter natural language questions or prompt requests such as:
- "Find all blocked traffic from Azure Firewall for client IP 10.0.0.45"
- "Summarize top 10 request URIs with high latency on Application Gateway"
- "List failed authentication attempts in Key Vault during the last 7 days"
Automated KQL Editor Population:
- The AI Assistant generates valid KQL queries formatted specifically for Azure Log Analytics schemas.
- The generated KQL query can be copied or loaded directly into the KQL Code Editor with a single click (
Apply Query).
Backend Azure OpenAI Configuration:
- Enabled by configuring
AZURE_OPENAI_ENDPOINT,AZURE_OPENAI_API_KEY, andAZURE_OPENAI_DEPLOYMENT(e.g.,gpt-4o) in.envor Kubernetes secret manifests.
- Enabled by configuring
The application includes a dedicated Summarized Telemetry panel located below the primary result table:
Multi-Column KQL Grouping:
- Selecting 1 column displays frequency breakdown for that field.
- Selecting 2 or more columns performs multi-column tuple grouping (
| summarize count() by col1, col2), rendering separate columns for each field and computing exact occurrence counts.
Sub-Value Filtering & View Scope:
- Check specific sub-values per column to refine summary telemetry.
- Toggle between Filtered (evaluates active primary table filters) and All Rows (evaluates raw query output).
Column Header Sorting:
- Click any table header to toggle Ascending (
↑) or Descending (↓) sort order.
- Click any table header to toggle Ascending (
- Frontend: React 19, TypeScript, Vite, Lucide Icons,
@azure/msal-react,@azure/msal-browser. - Backend: Node.js 22, Express, TypeScript, Zod,
@azure/monitor-query-logs,@azure/identity, OpenAI SDK (azure-openai), Helmet, Express-Rate-Limit. - Packaging & Monorepo: Managed via npm workspaces (
client/andserver/).
- Communication between the client and server occurs via a secure REST API over HTTP/HTTPS using JSON payloads.
- Development Mode: Vite dev server (
http://localhost:5173) proxies/api/*requests to the Express backend (http://localhost:8080). - Production Mode: The Express server directly serves both
/api/*endpoints and the compiled single-page static React build (client/dist).
- User Authentication: Frontend integrates
@azure/msal-reactfor Single Sign-On (SSO) using Microsoft Entra ID (Azure AD). Users sign in using OAuth 2.0 Authorization Code Flow with PKCE. - Dynamic Workspace Discovery: Client uses the user's OAuth access token to query Azure Resource Graph (
microsoft.operationalinsights/workspaces) and fetch all Log Analytics Workspaces the user has permissions to view. - Log Analytics Execution: Backend queries Log Analytics using
@azure/monitor-query-logsauthenticated via@azure/identityusingDefaultAzureCredential, Service Principal (AZURE_CLIENT_SECRET), or container Managed Identity.
Grant the application identity access to the Log Analytics workspace (e.g., Log Analytics Reader role).
Configurable via environment variables or Kubernetes secrets:
- Service Principal (SPN):
AZURE_TENANT_ID,AZURE_CLIENT_ID,AZURE_CLIENT_SECRET - Azure OpenAI Integration:
AZURE_OPENAI_ENDPOINT,AZURE_OPENAI_API_KEY,AZURE_OPENAI_DEPLOYMENT
The application supports Single Sign-On (SSO) using Microsoft Entra ID (Azure AD) via MSAL (@azure/msal-react). Follow these steps to configure authentication and restrict access to authorized Azure AD Security Groups.
- Navigate to Azure Portal > Microsoft Entra ID > App Registrations > New Registration.
- Enter Name:
Azure Log Analytics KQL Explorer. - Supported account types: Accounts in this organizational directory only (Single tenant).
- Platform Configuration:
- Platform type: Single-page application (SPA).
- Redirect URIs:
http://localhost:5173,http://localhost:8080, or your production deployment URL.
- Click Register and copy your Application (client) ID and Directory (tenant) ID.
Set the following variables in your root .env file or Kubernetes aks/secret.yaml:
# Enable Azure AD Login screen (set to "false" to bypass login screen during local testing)VITE_REQUIRE_AZURE_AD_AUTH=true# Azure AD App Registration (SPA) DetailsVITE_AZURE_CLIENT_ID="00000000-0000-0000-0000-000000000000"VITE_AZURE_TENANT_ID="00000000-0000-0000-0000-000000000000"# Restrict login access to specific Azure AD Security Groups (comma-separated Group Object IDs or Names)VITE_ALLOWED_AZURE_AD_GROUPS="SecOps-Admins,99887766-5544-3322-1100-a1b2c3d4e5f6"Note: If
VITE_ALLOWED_AZURE_AD_GROUPSis left empty (""), all authenticated users within your Azure AD tenant will be granted access to the query workspace.
To enforce group-based authorization (VITE_ALLOWED_AZURE_AD_GROUPS), your Azure AD App Registration must emit user group claims in the MSAL ID Token:
- Option A (Token Configuration GUI):
- In your Azure AD App Registration, go to Token configuration > Add groups claim.
- Select Security groups (or All groups) under ID, then click Add.
- Option B (App Manifest):
- In your Azure AD App Registration, select Manifest.
- Locate
"groupMembershipClaims"and set its value to"SecurityGroup":"groupMembershipClaims": "SecurityGroup"
- Save the manifest. When users authenticate, MSAL receives their group memberships in ID token claims. If a user is not a member of any group listed in
VITE_ALLOWED_AZURE_AD_GROUPS, the application presents an Access Denied authorization screen detailing authorized groups and troubleshooting steps.
npm run install:all
npm run devTo run a production build locally:
npm run productionCopy aks/deploy-config.example.json to aks/deploy-config.json and configure your Azure Subscription, Resource Group, Cluster Name, and ACR Registry:
{
"SubscriptionId": "00000000-0000-0000-0000-000000000000",
"ResourceGroup": "rg-loganalytics-prod",
"ClusterName": "aks-cluster-prod",
"AcrName": "myacrregistry",
"ImageName": "loganalytics-app",
"ImageTag": "latest"
}Run the master deployment script from the project root:
.\scripts\deploy-prod.ps1The script builds the Docker image, pushes it to ACR, prompts for user confirmation (Y/N), connects to AKS, and applies Kubernetes manifests (aks/secret.yaml, aks/deployment.yaml, aks/istio-ingress.yaml).
