azure-monitor-query-java
Azure Monitor Query SDK for Java. Execute Kusto queries against Log Analytics workspaces and query metrics from Azure resources. Triggers: "LogsQueryClient java", "MetricsQueryClient java", "kusto query java", "log analytics java", "azure monitor query java". Note: This package i
Install
npx skills add https://github.com/microsoft/skills/tree/main/.github/plugins/azure-sdk-java/skills/azure-monitor-query-java
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install microsoft-skills@llmmart
git clone https://github.com/microsoft/skills.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole microsoft/skills collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Azure Monitor Query SDK for Java
DEPRECATION NOTICE: This package is deprecated in favor of:
azure-monitor-query-logs— For Log Analytics queriesazure-monitor-query-metrics— For metrics queriesSee migration guides: Logs Migration | Metrics Migration
Client library for querying Azure Monitor Logs and Metrics.
Installation
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-monitor-query</artifactId>
<version>1.5.9</version>
</dependency>
Or use Azure SDK BOM:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-sdk-bom</artifactId>
<version>{bom_version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-monitor-query</artifactId>
</dependency>
</dependencies>
Prerequisites
- Log Analytics workspace (for logs queries)
- Azure resource (for metrics queries)
- TokenCredential with appropriate permissions
Environment Variables
LOG_ANALYTICS_WORKSPACE_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx # Required for Log Analytics workspace queries
AZURE_RESOURCE_ID=/subscriptions/{sub}/resourceGroups/{rg}/providers/{provider}/{resource} # Required for metrics queries against a resource
AZURE_TOKEN_CREDENTIALS=prod # Required only if DefaultAzureCredential is used in production
Client Creation
LogsQueryClient (Sync)
import com.azure.core.credential.TokenCredential;
import com.azure.identity.AzureIdentityEnvVars;
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.ManagedIdentityCredentialBuilder;
import com.azure.monitor.query.LogsQueryClient;
import com.azure.monitor.query.LogsQueryClientBuilder;
// Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential>
TokenCredential credential = new DefaultAzureCredentialBuilder()
.requireEnvVars(AzureIdentityEnvVars.AZURE_TOKEN_CREDENTIALS)
.build();
// Or use a specific credential directly in production:
// See https://learn.microsoft.com/java/api/overview/azure/identity-readme?view=azure-java-stable#credential-classes
// TokenCredential credential = new ManagedIdentityCredentialBuilder().build();
LogsQueryClient logsClient = new LogsQueryClientBuilder()
.credential(credential)
.buildClient();
LogsQueryAsyncClient
import com.azure.monitor.query.LogsQueryAsyncClient;
LogsQueryAsyncClient logsAsyncClient = new LogsQueryClientBuilder()
.credential(credential)
.buildAsyncClient();
MetricsQueryClient (Sync)
import com.azure.monitor.query.MetricsQueryClient;
import com.azure.monitor.query.MetricsQueryClientBuilder;
MetricsQueryClient metricsClient = new MetricsQueryClientBuilder()
.credential(credential)
.buildClient();
MetricsQueryAsyncClient
import com.azure.monitor.query.MetricsQueryAsyncClient;
MetricsQueryAsyncClient metricsAsyncClient = new MetricsQueryClientBuilder()
.credential(credential)
.buildAsyncClient();
Sovereign Cloud Configuration
// Azure China Cloud - Logs
LogsQueryClient logsClient = new LogsQueryClientBuilder()
.credential(credential)
.endpoint("https://api.loganalytics.azure.cn/v1")
.buildClient();
// Azure China Cloud - Metrics
MetricsQueryClient metricsClient = new MetricsQueryClientBuilder()
.credential(credential)
.endpoint("https://management.chinacloudapi.cn")
.buildClient();
Key Concepts
| Concept | Description |
|---|---|
| Logs | Log and performance data from Azure resources via Kusto Query Language |
| Metrics | Numeric time-series data collected at regular intervals |
| Workspace ID | Log Analytics workspace identifier |
| Resource ID | Azure resource URI for metrics queries |
| QueryTimeInterval | Time range for the query |
Logs Query Operations
Basic Query
import com.azure.monitor.query.models.LogsQueryResult;
import com.azure.monitor.query.models.LogsTableRow;
import com.azure.monitor.query.models.QueryTimeInterval;
import java.time.Duration;
LogsQueryResult result = logsClient.queryWorkspace(
"{workspace-id}",
"AzureActivity | summarize count() by ResourceGroup | top 10 by count_",
new QueryTimeInterval(Duration.ofDays(7))
);
for (LogsTableRow row : result.getTable().getRows()) {
System.out.println(row.getColumnValue("ResourceGroup") + ": " + row.getColumnValue("count_"));
}
Query by Resource ID
LogsQueryResult result = logsClient.queryResource(
"{resource-id}",
"AzureMetrics | where TimeGenerated > ago(1h)",
new QueryTimeInterval(Duration.ofDays(1))
);
for (LogsTableRow row : result.getTable().getRows()) {
System.out.println(row.getColumnValue("MetricName") + " " + row.getColumnValue("Average"));
}
Map Results to Custom Model
// Define model class
public class ActivityLog {
private String resourceGroup;
private String operationName;
public String getResourceGroup() { return resourceGroup; }
public String getOperationName() { return operationName; }
}
// Query with model mapping
List<ActivityLog> logs = logsClient.queryWorkspace(
"{workspace-id}",
"AzureActivity | project ResourceGroup, OperationName | take 100",
new QueryTimeInterval(Duration.ofDays(2)),
ActivityLog.class
);
for (ActivityLog log : logs) {
System.out.println(log.getOperationName() + " - " + log.getResourceGroup());
}
Batch Query
import com.azure.monitor.query.models.LogsBatchQuery;
import com.azure.monitor.query.models.LogsBatchQueryResult;
import com.azure.monitor.query.models.LogsBatchQueryResultCollection;
import com.azure.core.util.Context;
LogsBatchQuery batchQuery = new LogsBatchQuery();
String q1 = batchQuery.addWorkspaceQuery("{workspace-id}", "AzureActivity | count", new QueryTimeInterval(Duration.ofDays(1)));
String q2 = batchQuery.addWorkspaceQuery("{workspace-id}", "Heartbeat | count", new QueryTimeInterval(Duration.ofDays(1)));
String q3 = batchQuery.addWorkspaceQuery("{workspace-id}", "Perf | count", new QueryTimeInterval(Duration.ofDays(1)));
LogsBatchQueryResultCollection results = logsClient
.queryBatchWithResponse(batchQuery, Context.NONE)
.getValue();
LogsBatchQueryResult result1 = results.getResult(q1);
LogsBatchQueryResult result2 = results.getResult(q2);
LogsBatchQueryResult result3 = results.getResult(q3);
// Check for failures
if (result3.getQueryResultStatus() == LogsQueryResultStatus.FAILURE) {
System.err.println("Query failed: " + result3.getError().getMessage());
}
Query with Options
import com.azure.monitor.query.models.LogsQueryOptions;
import com.azure.core.http.rest.Response;
LogsQueryOptions options = new LogsQueryOptions()
.setServerTimeout(Duration.ofMinutes(10))
.setIncludeStatistics(true)
.setIncludeVisualization(true);
Response<LogsQueryResult> response = logsClient.queryWorkspaceWithResponse(
"{workspace-id}",
"AzureActivity | summarize count() by bin(TimeGenerated, 1h)",
new QueryTimeInterval(Duration.ofDays(7)),
options,
Context.NONE
);
LogsQueryResult result = response.getValue();
// Access statistics
BinaryData statistics = result.getStatistics();
// Access visualization data
BinaryData visualization = result.getVisualization();
Query Multiple Workspaces
import java.util.Arrays;
LogsQueryOptions options = new LogsQueryOptions()
.setAdditionalWorkspaces(Arrays.asList("{workspace-id-2}", "{workspace-id-3}"));
Response<LogsQueryResult> response = logsClient.queryWorkspaceWithResponse(
"{workspace-id-1}",
"AzureActivity | summarize count() by TenantId",
new QueryTimeInterval(Duration.ofDays(1)),
options,
Context.NONE
);
Metrics Query Operations
Basic Metrics Query
import com.azure.monitor.query.models.MetricsQueryResult;
import com.azure.monitor.query.models.MetricResult;
import com.azure.monitor.query.models.TimeSeriesElement;
import com.azure.monitor.query.models.MetricValue;
import java.util.Arrays;
MetricsQueryResult result = metricsClient.queryResource(
"{resource-uri}",
Arrays.asList("SuccessfulCalls", "TotalCalls")
);
for (MetricResult metric : result.getMetrics()) {
System.out.println("Metric: " + metric.getMetricName());
for (TimeSeriesElement ts : metric.getTimeSeries()) {
System.out.println(" Dimensions: " + ts.getMetadata());
for (MetricValue value : ts.getValues()) {
System.out.println(" " + value.getTimeStamp() + ": " + value.getTotal());
}
}
}
Metrics with Aggregations
import com.azure.monitor.query.models.MetricsQueryOptions;
import com.azure.monitor.query.models.AggregationType;
Response<MetricsQueryResult> response = metricsClient.queryResourceWithResponse(
"{resource-id}",
Arrays.asList("SuccessfulCalls", "TotalCalls"),
new MetricsQueryOptions()
.setGranularity(Duration.ofHours(1))
.setAggregations(Arrays.asList(AggregationType.AVERAGE, AggregationType.COUNT)),
Context.NONE
);
MetricsQueryResult result = response.getValue();
Query Multiple Resources (MetricsClient)
import com.azure.monitor.query.MetricsClient;
import com.azure.monitor.query.MetricsClientBuilder;
import com.azure.monitor.query.models.MetricsQueryResourcesResult;
MetricsClient metricsClient = new MetricsClientBuilder()
.credential(new DefaultAzureCredentialBuilder().build())
.endpoint("{endpoint}")
.buildClient();
MetricsQueryResourcesResult result = metricsClient.queryResources(
Arrays.asList("{resourceId1}", "{resourceId2}"),
Arrays.asList("{metric1}", "{metric2}"),
"{metricNamespace}"
);
for (MetricsQueryResult queryResult : result.getMetricsQueryResults()) {
for (MetricResult metric : queryResult.getMetrics()) {
System.out.println(metric.getMetricName());
metric.getTimeSeries().stream()
.flatMap(ts -> ts.getValues().stream())
.forEach(mv -> System.out.println(
mv.getTimeStamp() + " Count=" + mv.getCount() + " Avg=" + mv.getAverage()));
}
}
Response Structure
Logs Response Hierarchy
LogsQueryResult
├── statistics (BinaryData)
├── visualization (BinaryData)
├── error
└── tables (List<LogsTable>)
├── name
├── columns (List<LogsTableColumn>)
│ ├── name
│ └── type
└── rows (List<LogsTableRow>)
├── rowIndex
└── rowCells (List<LogsTableCell>)
Metrics Response Hierarchy
MetricsQueryResult
├── granularity
├── timeInterval
├── namespace
├── resourceRegion
└── metrics (List<MetricResult>)
├── id, name, type, unit
└── timeSeries (List<TimeSeriesElement>)
├── metadata (dimensions)
└── values (List<MetricValue>)
├── timeStamp
├── count, average, total
├── maximum, minimum
Error Handling
import com.azure.core.exception.HttpResponseException;
import com.azure.monitor.query.models.LogsQueryResultStatus;
try {
LogsQueryResult result = logsClient.queryWorkspace(workspaceId, query, timeInterval);
// Check partial failure
if (result.getStatus() == LogsQueryResultStatus.PARTIAL_FAILURE) {
System.err.println("Partial failure: " + result.getError().getMessage());
}
} catch (HttpResponseException e) {
System.err.println("Query failed: " + e.getMessage());
System.err.println("Status: " + e.getResponse().getStatusCode());
}
Best Practices
- Use batch queries — Combine multiple queries into a single request
- Set appropriate timeouts — Long queries may need extended server timeout
- Limit result size — Use
toportakein Kusto queries - Use projections — Select only needed columns with
project - Check query status — Handle PARTIAL_FAILURE results gracefully
- Cache results — Metrics don't change frequently; cache when appropriate
- Migrate to new packages — Plan migration to
azure-monitor-query-logsandazure-monitor-query-metrics
Reference Links
Files (skills)
-
references
-
examples.md 11.3 KB
# Azure Monitor Query SDK for Java - Examples Comprehensive code examples for the Azure Monitor Query SDK for Java. ## Table of Contents - [Maven Dependency](#maven-dependency) - [Client Creation](#client-creation) - [Querying Log Analytics](#querying-log-analytics) - [Querying Metrics](#querying-metrics) - [Batch Queries](#batch-queries) - [Handling Query Results](#handling-query-results) - [Time Ranges](#time-ranges) - [Async Client Patterns](#async-client-patterns) - [Error Handling](#error-handling) ## Maven Dependency ```xml <!-- Using Azure SDK BOM (recommended) --> <dependencyManagement> <dependencies> <dependency> <groupId>com.azure</groupId> <artifactId>azure-sdk-bom</artifactId> <version>{bom_version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>com.azure</groupId> <artifactId>azure-monitor-query</artifactId> </dependency> <dependency> <groupId>com.azure</groupId> <artifactId>azure-identity</artifactId> </dependency> </dependencies> <!-- Or direct dependencies --> <dependency> <groupId>com.azure</groupId> <artifactId>azure-monitor-query</artifactId> <version>1.5.9</version> </dependency> ``` ## Client Creation ### LogsQueryClient ```java import com.azure.identity.DefaultAzureCredentialBuilder; import com.azure.monitor.query.LogsQueryClient; import com.azure.monitor.query.LogsQueryClientBuilder; LogsQueryClient logsQueryClient = new LogsQueryClientBuilder() .credential(new DefaultAzureCredentialBuilder().build()) .buildClient(); ``` ### MetricsQueryClient ```java import com.azure.monitor.query.MetricsQueryClient; import com.azure.monitor.query.MetricsQueryClientBuilder; MetricsQueryClient metricsQueryClient = new MetricsQueryClientBuilder() .credential(new DefaultAzureCredentialBuilder().build()) .buildClient(); ``` ### For Sovereign Clouds ```java LogsQueryClient logsQueryClient = new LogsQueryClientBuilder() .credential(new DefaultAzureCredentialBuilder().build()) .endpoint("https://api.loganalytics.azure.cn/v1") .buildClient(); ``` ## Querying Log Analytics ### Query Workspace ```java import com.azure.monitor.query.models.LogsQueryResult; import com.azure.monitor.query.models.LogsTableRow; import com.azure.monitor.query.models.QueryTimeInterval; import java.time.Duration; LogsQueryResult result = logsQueryClient.queryWorkspace( "{workspace-id}", "AzureActivity | top 10 by TimeGenerated", new QueryTimeInterval(Duration.ofDays(2)) ); for (LogsTableRow row : result.getTable().getRows()) { System.out.println( row.getColumnValue("OperationName") + " " + row.getColumnValue("ResourceGroup") ); } ``` ### Query by Resource ID ```java LogsQueryResult result = logsQueryClient.queryResource( "{resource-id}", // Full Azure resource ID "AzureActivity | top 10 by TimeGenerated", new QueryTimeInterval(Duration.ofDays(2)) ); ``` ### Query with Options ```java import com.azure.monitor.query.models.LogsQueryOptions; LogsQueryResult result = logsQueryClient.queryWorkspace( "{workspace-id}", "AzureActivity | top 10 by TimeGenerated", new QueryTimeInterval(Duration.ofDays(2)), new LogsQueryOptions() .setServerTimeout(Duration.ofMinutes(2)) .setIncludeStatistics(true) .setIncludeVisualization(true) ); ``` ## Querying Metrics ### Basic Metrics Query ```java import com.azure.monitor.query.models.MetricResult; import com.azure.monitor.query.models.MetricValue; import com.azure.monitor.query.models.MetricsQueryResult; import com.azure.monitor.query.models.TimeSeriesElement; import java.util.Arrays; MetricsQueryResult result = metricsQueryClient.queryResource( "{resource-uri}", Arrays.asList("SuccessfulCalls", "TotalCalls") ); for (MetricResult metric : result.getMetrics()) { System.out.println("Metric: " + metric.getMetricName()); for (TimeSeriesElement ts : metric.getTimeSeries()) { System.out.println("Dimensions: " + ts.getMetadata()); for (MetricValue value : ts.getValues()) { System.out.println(value.getTimeStamp() + ": " + value.getTotal()); } } } ``` ### With Aggregations and Granularity ```java import com.azure.core.http.rest.Response; import com.azure.core.util.Context; import com.azure.monitor.query.models.AggregationType; import com.azure.monitor.query.models.MetricsQueryOptions; Response<MetricsQueryResult> response = metricsQueryClient.queryResourceWithResponse( "{resource-id}", Arrays.asList("SuccessfulCalls", "TotalCalls"), new MetricsQueryOptions() .setGranularity(Duration.ofHours(1)) .setAggregations(Arrays.asList( AggregationType.AVERAGE, AggregationType.COUNT )), Context.NONE ); MetricsQueryResult result = response.getValue(); ``` ## Batch Queries ```java import com.azure.monitor.query.models.LogsBatchQuery; import com.azure.monitor.query.models.LogsBatchQueryResult; import com.azure.monitor.query.models.LogsBatchQueryResultCollection; import com.azure.monitor.query.models.LogsQueryResultStatus; LogsBatchQuery batchQuery = new LogsBatchQuery(); String q1 = batchQuery.addWorkspaceQuery("{workspace-id}", "{query-1}", new QueryTimeInterval(Duration.ofDays(2))); String q2 = batchQuery.addWorkspaceQuery("{workspace-id}", "{query-2}", new QueryTimeInterval(Duration.ofDays(30))); String q3 = batchQuery.addWorkspaceQuery("{workspace-id}", "{query-3}", new QueryTimeInterval(Duration.ofDays(10))); LogsBatchQueryResultCollection results = logsQueryClient .queryBatchWithResponse(batchQuery, Context.NONE).getValue(); // Process query 1 - iterate rows LogsBatchQueryResult result1 = results.getResult(q1); for (LogsTableRow row : result1.getTable().getRows()) { System.out.println(row.getColumnValue("OperationName")); } // Process query 2 - map to model List<CustomModel> models = results.getResult(q2, CustomModel.class); // Check query 3 for failures LogsBatchQueryResult result3 = results.getResult(q3); if (result3.getQueryResultStatus() == LogsQueryResultStatus.FAILURE) { System.out.println("Error: " + result3.getError().getMessage()); } ``` ## Handling Query Results ### Response Structure ``` LogsQueryResult ├── statistics ├── visualization ├── error └── tables (List<LogsTable>) └── LogsTable ├── name ├── columns (List<LogsTableColumn>) │ ├── name │ └── type └── rows (List<LogsTableRow>) └── LogsTableRow └── getColumnValue(name) ``` ### Iterate Tables and Rows ```java import com.azure.monitor.query.models.LogsTable; import com.azure.monitor.query.models.LogsTableColumn; import com.azure.monitor.query.models.LogsTableRow; LogsQueryResult result = logsQueryClient.queryWorkspace(...); LogsTable table = result.getTable(); // Print columns System.out.println("Columns:"); for (LogsTableColumn col : table.getColumns()) { System.out.println(" " + col.getName() + " (" + col.getType() + ")"); } // Print rows System.out.println("Rows:"); for (LogsTableRow row : table.getRows()) { Object operationName = row.getColumnValue("OperationName"); Object resourceGroup = row.getColumnValue("ResourceGroup"); System.out.println(operationName + " - " + resourceGroup); } ``` ### Map to Custom Model ```java // Define model public class CustomLogModel { private String resourceGroup; private String operationName; public String getResourceGroup() { return resourceGroup; } public String getOperationName() { return operationName; } } // Query and map List<CustomLogModel> models = logsQueryClient.queryWorkspace( "{workspace-id}", "{kusto-query}", new QueryTimeInterval(Duration.ofDays(2)), CustomLogModel.class ); for (CustomLogModel model : models) { System.out.println(model.getOperationName()); } ``` ## Time Ranges ### Using Duration ```java QueryTimeInterval last2Days = new QueryTimeInterval(Duration.ofDays(2)); QueryTimeInterval last1Hour = new QueryTimeInterval(Duration.ofHours(1)); QueryTimeInterval last30Min = new QueryTimeInterval(Duration.ofMinutes(30)); ``` ### Predefined Constants ```java QueryTimeInterval lastHour = QueryTimeInterval.LAST_1_HOUR; QueryTimeInterval last7Days = QueryTimeInterval.LAST_7_DAYS; ``` ### Absolute Time Range ```java import java.time.OffsetDateTime; OffsetDateTime start = OffsetDateTime.now().minusDays(7); OffsetDateTime end = OffsetDateTime.now(); QueryTimeInterval absolute = new QueryTimeInterval(start, end); ``` ## Async Client Patterns ### Create Async Clients ```java import com.azure.monitor.query.LogsQueryAsyncClient; import com.azure.monitor.query.MetricsQueryAsyncClient; LogsQueryAsyncClient asyncLogsClient = new LogsQueryClientBuilder() .credential(new DefaultAzureCredentialBuilder().build()) .buildAsyncClient(); MetricsQueryAsyncClient asyncMetricsClient = new MetricsQueryClientBuilder() .credential(new DefaultAzureCredentialBuilder().build()) .buildAsyncClient(); ``` ### Async Logs Query ```java asyncLogsClient.queryWorkspace( "{workspace-id}", "AzureActivity | top 10 by TimeGenerated", new QueryTimeInterval(Duration.ofDays(2)) ) .subscribe( result -> { for (LogsTableRow row : result.getTable().getRows()) { System.out.println(row.getColumnValue("OperationName")); } }, error -> System.err.println("Error: " + error.getMessage()) ); ``` ### Async Metrics Query ```java asyncMetricsClient.queryResource( "{resource-id}", Arrays.asList("SuccessfulCalls") ) .subscribe( result -> { for (MetricResult metric : result.getMetrics()) { System.out.println("Metric: " + metric.getMetricName()); } }, error -> System.err.println("Error: " + error.getMessage()) ); ``` ## Error Handling ### Sync Error Handling ```java import com.azure.core.exception.HttpResponseException; import com.azure.monitor.query.models.LogsQueryResultStatus; try { LogsQueryResult result = logsQueryClient.queryWorkspace(...); // Check for partial errors if (result.getQueryResultStatus() == LogsQueryResultStatus.PARTIAL_FAILURE) { System.out.println("Warning: " + result.getError().getMessage()); } } catch (HttpResponseException e) { System.err.println("HTTP error: " + e.getResponse().getStatusCode()); System.err.println("Message: " + e.getMessage()); } catch (Exception e) { System.err.println("Error: " + e.getMessage()); } ``` ### Async Error Handling ```java asyncLogsClient.queryWorkspace(...) .subscribe( result -> { if (result.getQueryResultStatus() == LogsQueryResultStatus.FAILURE) { System.err.println("Query failed: " + result.getError().getMessage()); } else { // Process results } }, error -> { if (error instanceof HttpResponseException) { HttpResponseException httpError = (HttpResponseException) error; System.err.println("HTTP: " + httpError.getResponse().getStatusCode()); } else { System.err.println("Error: " + error.getMessage()); } } ); ```
-
-
SKILL.md 13.6 KB
--- name: azure-monitor-query-java description: | Azure Monitor Query SDK for Java. Execute Kusto queries against Log Analytics workspaces and query metrics from Azure resources. Triggers: "LogsQueryClient java", "MetricsQueryClient java", "kusto query java", "log analytics java", "azure monitor query java". Note: This package is deprecated. Migrate to azure-monitor-query-logs and azure-monitor-query-metrics. license: MIT metadata: author: Microsoft version: "1.0.0" package: com.azure:azure-monitor-query --- # Azure Monitor Query SDK for Java > **DEPRECATION NOTICE**: This package is deprecated in favor of: > - `azure-monitor-query-logs` — For Log Analytics queries > - `azure-monitor-query-metrics` — For metrics queries > > See migration guides: [Logs Migration](https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/monitor/azure-monitor-query-logs/migration-guide.md) | [Metrics Migration](https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/monitor/azure-monitor-query-metrics/migration-guide.md) Client library for querying Azure Monitor Logs and Metrics. ## Installation ```xml <dependency> <groupId>com.azure</groupId> <artifactId>azure-monitor-query</artifactId> <version>1.5.9</version> </dependency> ``` Or use Azure SDK BOM: ```xml <dependencyManagement> <dependencies> <dependency> <groupId>com.azure</groupId> <artifactId>azure-sdk-bom</artifactId> <version>{bom_version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>com.azure</groupId> <artifactId>azure-monitor-query</artifactId> </dependency> </dependencies> ``` ## Prerequisites - Log Analytics workspace (for logs queries) - Azure resource (for metrics queries) - TokenCredential with appropriate permissions ## Environment Variables ```bash LOG_ANALYTICS_WORKSPACE_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx # Required for Log Analytics workspace queries AZURE_RESOURCE_ID=/subscriptions/{sub}/resourceGroups/{rg}/providers/{provider}/{resource} # Required for metrics queries against a resource AZURE_TOKEN_CREDENTIALS=prod # Required only if DefaultAzureCredential is used in production ``` ## Client Creation ### LogsQueryClient (Sync) ```java import com.azure.core.credential.TokenCredential; import com.azure.identity.AzureIdentityEnvVars; import com.azure.identity.DefaultAzureCredentialBuilder; import com.azure.identity.ManagedIdentityCredentialBuilder; import com.azure.monitor.query.LogsQueryClient; import com.azure.monitor.query.LogsQueryClientBuilder; // Local dev: DefaultAzureCredential. Production: set AZURE_TOKEN_CREDENTIALS=prod or AZURE_TOKEN_CREDENTIALS=<specific_credential> TokenCredential credential = new DefaultAzureCredentialBuilder() .requireEnvVars(AzureIdentityEnvVars.AZURE_TOKEN_CREDENTIALS) .build(); // Or use a specific credential directly in production: // See https://learn.microsoft.com/java/api/overview/azure/identity-readme?view=azure-java-stable#credential-classes // TokenCredential credential = new ManagedIdentityCredentialBuilder().build(); LogsQueryClient logsClient = new LogsQueryClientBuilder() .credential(credential) .buildClient(); ``` ### LogsQueryAsyncClient ```java import com.azure.monitor.query.LogsQueryAsyncClient; LogsQueryAsyncClient logsAsyncClient = new LogsQueryClientBuilder() .credential(credential) .buildAsyncClient(); ``` ### MetricsQueryClient (Sync) ```java import com.azure.monitor.query.MetricsQueryClient; import com.azure.monitor.query.MetricsQueryClientBuilder; MetricsQueryClient metricsClient = new MetricsQueryClientBuilder() .credential(credential) .buildClient(); ``` ### MetricsQueryAsyncClient ```java import com.azure.monitor.query.MetricsQueryAsyncClient; MetricsQueryAsyncClient metricsAsyncClient = new MetricsQueryClientBuilder() .credential(credential) .buildAsyncClient(); ``` ### Sovereign Cloud Configuration ```java // Azure China Cloud - Logs LogsQueryClient logsClient = new LogsQueryClientBuilder() .credential(credential) .endpoint("https://api.loganalytics.azure.cn/v1") .buildClient(); // Azure China Cloud - Metrics MetricsQueryClient metricsClient = new MetricsQueryClientBuilder() .credential(credential) .endpoint("https://management.chinacloudapi.cn") .buildClient(); ``` ## Key Concepts | Concept | Description | |---------|-------------| | Logs | Log and performance data from Azure resources via Kusto Query Language | | Metrics | Numeric time-series data collected at regular intervals | | Workspace ID | Log Analytics workspace identifier | | Resource ID | Azure resource URI for metrics queries | | QueryTimeInterval | Time range for the query | ## Logs Query Operations ### Basic Query ```java import com.azure.monitor.query.models.LogsQueryResult; import com.azure.monitor.query.models.LogsTableRow; import com.azure.monitor.query.models.QueryTimeInterval; import java.time.Duration; LogsQueryResult result = logsClient.queryWorkspace( "{workspace-id}", "AzureActivity | summarize count() by ResourceGroup | top 10 by count_", new QueryTimeInterval(Duration.ofDays(7)) ); for (LogsTableRow row : result.getTable().getRows()) { System.out.println(row.getColumnValue("ResourceGroup") + ": " + row.getColumnValue("count_")); } ``` ### Query by Resource ID ```java LogsQueryResult result = logsClient.queryResource( "{resource-id}", "AzureMetrics | where TimeGenerated > ago(1h)", new QueryTimeInterval(Duration.ofDays(1)) ); for (LogsTableRow row : result.getTable().getRows()) { System.out.println(row.getColumnValue("MetricName") + " " + row.getColumnValue("Average")); } ``` ### Map Results to Custom Model ```java // Define model class public class ActivityLog { private String resourceGroup; private String operationName; public String getResourceGroup() { return resourceGroup; } public String getOperationName() { return operationName; } } // Query with model mapping List<ActivityLog> logs = logsClient.queryWorkspace( "{workspace-id}", "AzureActivity | project ResourceGroup, OperationName | take 100", new QueryTimeInterval(Duration.ofDays(2)), ActivityLog.class ); for (ActivityLog log : logs) { System.out.println(log.getOperationName() + " - " + log.getResourceGroup()); } ``` ### Batch Query ```java import com.azure.monitor.query.models.LogsBatchQuery; import com.azure.monitor.query.models.LogsBatchQueryResult; import com.azure.monitor.query.models.LogsBatchQueryResultCollection; import com.azure.core.util.Context; LogsBatchQuery batchQuery = new LogsBatchQuery(); String q1 = batchQuery.addWorkspaceQuery("{workspace-id}", "AzureActivity | count", new QueryTimeInterval(Duration.ofDays(1))); String q2 = batchQuery.addWorkspaceQuery("{workspace-id}", "Heartbeat | count", new QueryTimeInterval(Duration.ofDays(1))); String q3 = batchQuery.addWorkspaceQuery("{workspace-id}", "Perf | count", new QueryTimeInterval(Duration.ofDays(1))); LogsBatchQueryResultCollection results = logsClient .queryBatchWithResponse(batchQuery, Context.NONE) .getValue(); LogsBatchQueryResult result1 = results.getResult(q1); LogsBatchQueryResult result2 = results.getResult(q2); LogsBatchQueryResult result3 = results.getResult(q3); // Check for failures if (result3.getQueryResultStatus() == LogsQueryResultStatus.FAILURE) { System.err.println("Query failed: " + result3.getError().getMessage()); } ``` ### Query with Options ```java import com.azure.monitor.query.models.LogsQueryOptions; import com.azure.core.http.rest.Response; LogsQueryOptions options = new LogsQueryOptions() .setServerTimeout(Duration.ofMinutes(10)) .setIncludeStatistics(true) .setIncludeVisualization(true); Response<LogsQueryResult> response = logsClient.queryWorkspaceWithResponse( "{workspace-id}", "AzureActivity | summarize count() by bin(TimeGenerated, 1h)", new QueryTimeInterval(Duration.ofDays(7)), options, Context.NONE ); LogsQueryResult result = response.getValue(); // Access statistics BinaryData statistics = result.getStatistics(); // Access visualization data BinaryData visualization = result.getVisualization(); ``` ### Query Multiple Workspaces ```java import java.util.Arrays; LogsQueryOptions options = new LogsQueryOptions() .setAdditionalWorkspaces(Arrays.asList("{workspace-id-2}", "{workspace-id-3}")); Response<LogsQueryResult> response = logsClient.queryWorkspaceWithResponse( "{workspace-id-1}", "AzureActivity | summarize count() by TenantId", new QueryTimeInterval(Duration.ofDays(1)), options, Context.NONE ); ``` ## Metrics Query Operations ### Basic Metrics Query ```java import com.azure.monitor.query.models.MetricsQueryResult; import com.azure.monitor.query.models.MetricResult; import com.azure.monitor.query.models.TimeSeriesElement; import com.azure.monitor.query.models.MetricValue; import java.util.Arrays; MetricsQueryResult result = metricsClient.queryResource( "{resource-uri}", Arrays.asList("SuccessfulCalls", "TotalCalls") ); for (MetricResult metric : result.getMetrics()) { System.out.println("Metric: " + metric.getMetricName()); for (TimeSeriesElement ts : metric.getTimeSeries()) { System.out.println(" Dimensions: " + ts.getMetadata()); for (MetricValue value : ts.getValues()) { System.out.println(" " + value.getTimeStamp() + ": " + value.getTotal()); } } } ``` ### Metrics with Aggregations ```java import com.azure.monitor.query.models.MetricsQueryOptions; import com.azure.monitor.query.models.AggregationType; Response<MetricsQueryResult> response = metricsClient.queryResourceWithResponse( "{resource-id}", Arrays.asList("SuccessfulCalls", "TotalCalls"), new MetricsQueryOptions() .setGranularity(Duration.ofHours(1)) .setAggregations(Arrays.asList(AggregationType.AVERAGE, AggregationType.COUNT)), Context.NONE ); MetricsQueryResult result = response.getValue(); ``` ### Query Multiple Resources (MetricsClient) ```java import com.azure.monitor.query.MetricsClient; import com.azure.monitor.query.MetricsClientBuilder; import com.azure.monitor.query.models.MetricsQueryResourcesResult; MetricsClient metricsClient = new MetricsClientBuilder() .credential(new DefaultAzureCredentialBuilder().build()) .endpoint("{endpoint}") .buildClient(); MetricsQueryResourcesResult result = metricsClient.queryResources( Arrays.asList("{resourceId1}", "{resourceId2}"), Arrays.asList("{metric1}", "{metric2}"), "{metricNamespace}" ); for (MetricsQueryResult queryResult : result.getMetricsQueryResults()) { for (MetricResult metric : queryResult.getMetrics()) { System.out.println(metric.getMetricName()); metric.getTimeSeries().stream() .flatMap(ts -> ts.getValues().stream()) .forEach(mv -> System.out.println( mv.getTimeStamp() + " Count=" + mv.getCount() + " Avg=" + mv.getAverage())); } } ``` ## Response Structure ### Logs Response Hierarchy ``` LogsQueryResult ├── statistics (BinaryData) ├── visualization (BinaryData) ├── error └── tables (List<LogsTable>) ├── name ├── columns (List<LogsTableColumn>) │ ├── name │ └── type └── rows (List<LogsTableRow>) ├── rowIndex └── rowCells (List<LogsTableCell>) ``` ### Metrics Response Hierarchy ``` MetricsQueryResult ├── granularity ├── timeInterval ├── namespace ├── resourceRegion └── metrics (List<MetricResult>) ├── id, name, type, unit └── timeSeries (List<TimeSeriesElement>) ├── metadata (dimensions) └── values (List<MetricValue>) ├── timeStamp ├── count, average, total ├── maximum, minimum ``` ## Error Handling ```java import com.azure.core.exception.HttpResponseException; import com.azure.monitor.query.models.LogsQueryResultStatus; try { LogsQueryResult result = logsClient.queryWorkspace(workspaceId, query, timeInterval); // Check partial failure if (result.getStatus() == LogsQueryResultStatus.PARTIAL_FAILURE) { System.err.println("Partial failure: " + result.getError().getMessage()); } } catch (HttpResponseException e) { System.err.println("Query failed: " + e.getMessage()); System.err.println("Status: " + e.getResponse().getStatusCode()); } ``` ## Best Practices 1. **Use batch queries** — Combine multiple queries into a single request 2. **Set appropriate timeouts** — Long queries may need extended server timeout 3. **Limit result size** — Use `top` or `take` in Kusto queries 4. **Use projections** — Select only needed columns with `project` 5. **Check query status** — Handle PARTIAL_FAILURE results gracefully 6. **Cache results** — Metrics don't change frequently; cache when appropriate 7. **Migrate to new packages** — Plan migration to `azure-monitor-query-logs` and `azure-monitor-query-metrics` ## Reference Links | Resource | URL | |----------|-----| | Maven Package | https://central.sonatype.com/artifact/com.azure/azure-monitor-query | | GitHub | https://github.com/Azure/azure-sdk-for-java/tree/main/sdk/monitor/azure-monitor-query | | API Reference | https://learn.microsoft.com/java/api/com.azure.monitor.query | | Kusto Query Language | https://learn.microsoft.com/azure/data-explorer/kusto/query/ | | Log Analytics Limits | https://learn.microsoft.com/azure/azure-monitor/service-limits#la-query-api | | Troubleshooting | https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/monitor/azure-monitor-query/TROUBLESHOOTING.md |
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.