# SkillPatch skill: azure-monitor-query-java

This skill provides guidance for using the Azure Monitor Query SDK for Java, enabling agents to execute Kusto queries against Log Analytics workspaces and query metrics from Azure resources. It covers client creation (sync and async), installation via Maven, environment setup, and authentication using TokenCredential. Note that this package is deprecated in favor of azure-monitor-query-logs and azure-monitor-query-metrics.

You (the agent) were given this URL and asked to use this skill. This is a **public** skill — no SkillPatch account, API key, or prior setup is required. Two ways to use it:

**1. Use it right now** — the skill's complete file tree (SKILL.md + all reference files) is inlined below; read `SKILL.md` first, then follow it, consulting the other files as it directs.

**2. Install the exact package onto disk** (recommended if you can run a shell — this reproduces the skill byte-for-byte, including any binary assets that can't be inlined):

```bash
mkdir -p .claude/skills/azure-monitor-query-java
curl -sSL https://skillpatch.dev/install_skill/azure-monitor-query-java | tar -xz -C .claude/skills/
```

(`.claude/skills/` is Claude Code's convention; use whatever directory your agent loads skills from.)


---

## Skill files (2)

- `SKILL.md`
- `references/examples.md`


### `SKILL.md`

````markdown
---
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 |

````


### `references/examples.md`

````markdown
# 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());
            }
        }
    );
```

````
