Azure Data Explorer: A Comprehensive Guide to Real-Time Analytics
Introduction
Azure Data Explorer: A Comprehensive Guide to Real-Time Analytics
Introduction
In today’s data-driven world, the ability to analyze massive volumes of data in real-time is crucial. Azure Data Explorer (ADX), also known as Kusto, is Microsoft’s fast and highly scalable data exploration service designed for log and telemetry data analysis. Whether you’re monitoring applications, analyzing IoT data, or performing security analytics, ADX provides the performance and flexibility you need.
In this article, we’ll walk through setting up Azure Data Explorer, ingesting data, and running powerful queries to extract insights from your data.
What is Azure Data Explorer?
Azure Data Explorer is a fully managed, high-performance, big data analytics platform optimized for near real-time analysis of large volumes of data streaming from applications, websites, IoT devices, and more. It uses the Kusto Query Language (KQL), a powerful and intuitive query language similar to SQL.
Key Features
- Lightning-fast queries: Analyze petabytes of data in seconds
- Real-time ingestion: Stream data with minimal latency
- Rich analytics: Built-in machine learning, time series analysis, and geospatial functions
- Flexible data formats: Support for JSON, CSV, Parquet, and more
- Seamless integration: Works with Azure ecosystem and popular tools
Setting Up Azure Data Explorer
Prerequisites
- An active Azure subscription
- Azure CLI installed (optional but recommended)
- Basic understanding of cloud services
Step 1: Create an Azure Data Explorer Cluster
Via Azure Portal
- Navigate to the Azure Portal (portal.azure.com)
- Click “Create a resource” and search for “Azure Data Explorer”
- Click “Create” and fill in the required details:
- Subscription: Select your subscription
- Resource Group: Create new or use existing
- Cluster name: Choose a unique name (e.g.,
myadxcluster) - Region: Select your preferred region
- Compute specification: Start with Dev/Test for learning (2 instances, D11_v2)
- Review and create (this takes about 10–15 minutes)
Via Azure CLI
# Login to Azure
az login
# Create a resource group
az group create --name myResourceGroup --location eastus
# Create ADX cluster
az kusto cluster create \
--name myadxcluster \
--resource-group myResourceGroup \
--location eastus \
--sku name="Dev(No SLA)_Standard_D11_v2" tier="Basic" capacity=1
Step 2: Create a Database
Once your cluster is ready, create a database:
Via Azure Portal
- Navigate to your ADX cluster
- Click “Databases” in the left menu
- Click “+ Add database”
- Enter a database name (e.g.,
TestDatabase) - Set retention period (e.g., 365 days)
- Click “Create”
Via Azure CLI
az kusto database create \
--cluster-name myadxcluster \
--database-name TestDatabase \
--resource-group myResourceGroup \
--soft-delete-period P365D \
--hot-cache-period P31D
Creating Tables and Ingesting Data
Step 1: Access the Query Interface
Navigate to your cluster in the Azure Portal and click “Query” to open the web UI, or access it directly at [https://dataexplorer.azure.com/](https://dataexplorer.azure.com/)
Step 2: Create a Table
Let’s create a table to store application logs:
.create table ApplicationLogs (
Timestamp: datetime,
Level: string,
Message: string,
UserId: string,
RequestId: string,
Duration: long,
StatusCode: int,
Region: string
)
Step 3: Create a Mapping for JSON Ingestion
.create table ApplicationLogs ingestion json mapping 'ApplicationLogsMapping'
```json
[
{"column":"Timestamp", "path":"$.timestamp", "datatype":"datetime"},
{"column":"Level", "path":"$.level", "datatype":"string"},
{"column":"Message", "path":"$.message", "datatype":"string"},
{"column":"UserId", "path":"$.userId", "datatype":"string"},
{"column":"RequestId", "path":"$.requestId", "datatype":"string"},
{"column":"Duration", "path":"$.duration", "datatype":"long"},
{"column":"StatusCode", "path":"$.statusCode", "datatype":"int"},
{"column":"Region", "path":"$.region", "datatype":"string"}
]
### Step 4: Ingest Sample Data
#### Method 1: Inline Ingestion (for testing)
```kql
.ingest inline into table ApplicationLogs <|
2025-01-15T10:30:00Z,INFO,"User login successful",user123,req-001,145,200,US-East
2025-01-15T10:31:00Z,WARNING,"Slow database query",user456,req-002,3500,200,EU-West
2025-01-15T10:32:00Z,ERROR,"Failed to connect to external API",user789,req-003,5000,500,US-West
2025-01-15T10:33:00Z,INFO,"Data export completed",user123,req-004,890,200,US-East
Method 2: Ingest from Azure Blob Storage
.ingest into table ApplicationLogs
(
'https://mystorageaccount.blob.core.windows.net/logs/app-logs-2025-01.json?sas-token'
)
with (format='json', jsonMappingReference='ApplicationLogsMapping')
Method 3: Using Python SDK
from azure.kusto.data import KustoClient, KustoConnectionStringBuilder
from azure.kusto.ingest import QueuedIngestClient, IngestionProperties, DataFormat
# Connection string
cluster_uri = "https://myadxcluster.eastus.kusto.windows.net"
kcsb = KustoConnectionStringBuilder.with_aad_device_authentication(cluster_uri)
# Ingest client
ingest_client = QueuedIngestClient(kcsb)
# Ingestion properties
ingestion_props = IngestionProperties(
database="TestDatabase",
table="ApplicationLogs",
data_format=DataFormat.JSON,
ingestion_mapping_reference="ApplicationLogsMapping"
)
# Ingest from file
ingest_client.ingest_from_file("logs.json", ingestion_properties=ingestion_props)
Querying Data with KQL
Now comes the fun part — querying your data! KQL is incredibly powerful and expressive.
Basic Queries
View all data
ApplicationLogs
| take 10
Filter by log level
ApplicationLogs
| where Level == "ERROR"
| project Timestamp, Message, UserId, StatusCode
Time-based filtering
ApplicationLogs
| where Timestamp > ago(1h)
| where Level in ("ERROR", "WARNING")
| order by Timestamp desc
Aggregation and Analytics
Count logs by level
ApplicationLogs
| summarize Count = count() by Level
| order by Count desc
Average duration by region
ApplicationLogs
| summarize AvgDuration = avg(Duration), RequestCount = count() by Region
| order by AvgDuration desc
Time series analysis
ApplicationLogs
| where Timestamp > ago(24h)
| summarize ErrorCount = countif(Level == "ERROR") by bin(Timestamp, 1h)
| render timechart
Advanced Analytics
Percentile calculations
ApplicationLogs
| where Level == "INFO"
| summarize
P50 = percentile(Duration, 50),
P95 = percentile(Duration, 95),
P99 = percentile(Duration, 99)
by Region
Anomaly detection
ApplicationLogs
| where Timestamp > ago(7d)
| make-series RequestCount = count() default=0 on Timestamp step 1h
| extend Anomalies = series_decompose_anomalies(RequestCount, 1.5)
| render anomalychart with (anomalycolumns=Anomalies)
User behavior analysis
ApplicationLogs
| where Timestamp > ago(1d)
| summarize
TotalRequests = count(),
UniqueUsers = dcount(UserId),
AvgDuration = avg(Duration),
ErrorRate = 100.0 * countif(Level == "ERROR") / count()
by bin(Timestamp, 15m), Region
| order by Timestamp desc
Data Management and Optimization
Creating Update Policies
Update policies allow you to automatically transform and aggregate data during ingestion:
.create table ApplicationLogsSummary (
Hour: datetime,
Region: string,
TotalRequests: long,
ErrorCount: long,
AvgDuration: real
)
.alter table ApplicationLogsSummary policy update
@'[{
"IsEnabled": true,
"Source": "ApplicationLogs",
"Query": "ApplicationLogs | summarize TotalRequests=count(), ErrorCount=countif(Level=='ERROR'), AvgDuration=avg(Duration) by Hour=bin(Timestamp, 1h), Region",
"IsTransactional": false,
"PropagateIngestionProperties": false
}]'
Data Retention Policies
.alter table ApplicationLogs policy retention
```json
{
"SoftDeletePeriod": "365.00:00:00",
"Recoverability": "Enabled"
}
### Caching Policy
```kql
.alter table ApplicationLogs policy caching hot = 30d
Real-World Use Cases
Use Case 1: Application Performance Monitoring
// Identify slow API endpoints
ApplicationLogs
| where Timestamp > ago(1d)
| where Duration > 1000 // Requests taking more than 1 second
| summarize
SlowRequestCount = count(),
MaxDuration = max(Duration),
P95Duration = percentile(Duration, 95)
by Message
| order by SlowRequestCount desc
| take 10
Use Case 2: Security Monitoring
// Detect potential brute force attacks
ApplicationLogs
| where Level == "ERROR" and Message contains "login"
| summarize FailedAttempts = count() by UserId, bin(Timestamp, 5m)
| where FailedAttempts > 5
| order by FailedAttempts desc
Use Case 3: Regional Performance Comparison
ApplicationLogs
| where Timestamp > ago(7d)
| summarize
TotalRequests = count(),
ErrorRate = 100.0 * countif(StatusCode >= 400) / count(),
AvgDuration = avg(Duration)
by Region
| extend PerformanceScore = 100 - (ErrorRate + (AvgDuration / 100))
| order by PerformanceScore desc
Integration with Other Tools
Power BI Integration
Connect ADX to Power BI for rich visualizations:
- Open Power BI Desktop
- Get Data → More → Azure → Azure Data Explorer (Kusto)
- Enter your cluster URI and database
- Write KQL queries or import tables
Grafana Integration
Use the ADX plugin for Grafana to create monitoring dashboards:
# Install Grafana ADX plugin
grafana-cli plugins install grafana-azure-data-explorer-datasource
Azure Monitor Integration
Export Azure Monitor logs directly to ADX for long-term analysis and custom queries.
Best Practices
- Index your data properly: Use appropriate data types and consider partitioning for large tables
- Use materialized views: Pre-aggregate frequently queried data
- Leverage caching: Keep hot data in cache for faster queries
- Optimize queries: Use
whereclauses early, limit projections, and avoid unnecessary joins - Monitor costs: Use query metrics and set up alerts for cluster health
- Implement retention policies: Archive or delete old data to manage costs
- Use batch ingestion: For bulk data, batch ingestion is more efficient than individual records
Performance Tips
// Bad: Filtering after aggregation
ApplicationLogs
| summarize Count = count() by Region
| where Region == "US-East"
// Good: Filter before aggregation
ApplicationLogs
| where Region == "US-East"
| summarize Count = count()
// Bad: Using contains with wildcards
ApplicationLogs
| where Message contains "error"
// Better: Use has for token matching
ApplicationLogs
| where Message has "error"
Conclusion
Azure Data Explorer is a powerful platform for real-time analytics at scale. With its intuitive query language, fast performance, and seamless Azure integration, it’s an excellent choice for log analytics, IoT data processing, security monitoring, and much more.
The combination of flexible ingestion methods, rich analytical capabilities, and cost-effective scaling makes ADX suitable for organizations of all sizes. Whether you’re analyzing application logs, monitoring infrastructure, or building custom analytics solutions, ADX provides the tools and performance you need.
Start small with the Dev/Test tier, experiment with KQL, and gradually scale as your needs grow. The investment in learning ADX will pay dividends in your ability to extract insights from your data quickly and efficiently.
메타데이터
- post_id
- 802876d9cdaf
- slug
- azure-data-explorer-a-comprehensive-guide-to-real-time-analytics-802876d9cdaf
- url
- https://medium.com/@mohnish1997/azure-data-explorer-a-comprehensive-guide-to-real-time-analytics-802876d9cdaf
- canonical_url
- https://medium.com/@mohnish1997/azure-data-explorer-a-comprehensive-guide-to-real-time-analytics-802876d9cdaf
- author_url
- https://medium.com/@mohnish1997
- status
- ok
- fetched_at
- 2026-07-10 06:45:42