Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support getting rows as objects and map errors #21997

Merged
merged 2 commits into from
Jun 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 122 additions & 2 deletions sdk/monitor/azure-monitor-query/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,127 @@ LogsAsyncClient logsAsyncClient = new LogsClientBuilder()
+ "; value = " + logsTableCell.getValueAsString()));
}
}
}

```
### Get logs for a query and read the response as a model type

```java

LogsQueryResult queryResults = logsClient
.queryLogs("d2d0e126-fa1e-4b0a-b647-250cdd471e68", "AppRequests", null);

// Sample to use a model type to read the results
for (LogsTable table : queryResults.getLogsTables()) {
for (LogsTableRow row : table.getTableRows()) {
srnagar marked this conversation as resolved.
Show resolved Hide resolved
CustomModel model = row.getRowAsObject(CustomModel.class);
System.out.println("Time generated " + model.getTimeGenerated() + "; success = " + model.getSuccess() +
"; operation name = " + model.getOperationName());
}
}


public class CustomModel {
private OffsetDateTime timeGenerated;
private String tenantId;
private String id;
private String source;
private Boolean success;
private Double durationMs;
private Object properties;
private Object measurements;
private String operationName;
private String operationId;
private Object operationLinks;


public OffsetDateTime getTimeGenerated() {
return timeGenerated;
}

public void setTimeGenerated(OffsetDateTime timeGenerated) {
this.timeGenerated = timeGenerated;
}

public String getTenantId() {
return tenantId;
}

public void setTenantId(String tenantId) {
this.tenantId = tenantId;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getSource() {
return source;
}

public void setSource(String source) {
this.source = source;
}

public Boolean getSuccess() {
return success;
}

public void setSuccess(Boolean success) {
this.success = success;
}

public Double getDurationMs() {
return durationMs;
}

public void setDurationMs(Double durationMs) {
this.durationMs = durationMs;
}

public Object getProperties() {
return properties;
}

public void setProperties(Object properties) {
this.properties = properties;
}

public Object getMeasurements() {
return measurements;
}

public void setMeasurements(Object measurements) {
this.measurements = measurements;
}

public String getOperationName() {
return operationName;
}

public void setOperationName(String operationName) {
this.operationName = operationName;
}

public String getOperationId() {
return operationId;
}

public void setOperationId(String operationId) {
this.operationId = operationId;
}

public Object getOperationLinks() {
return operationLinks;
}

public void setOperationLinks(Object operationLinks) {
this.operationLinks = operationLinks;
}
}
```

### Get logs for a batch of queries
Expand Down Expand Up @@ -272,7 +392,7 @@ client library to use the Netty HTTP client. Configuring or changing the HTTP cl

All client libraries, by default, use the Tomcat-native Boring SSL library to enable native-level performance for SSL
operations. The Boring SSL library is an uber jar containing native libraries for Linux / macOS / Windows, and provides
better performance compared to the default SSL implementation within the JDK. For more information, including how to
better performance compared to the default SSL com.azure.monitor.collect.metrics.implementation within the JDK. For more information, including how to
reduce the dependency size, refer to the [performance tuning][performance_tuning] section of the wiki.

## Next steps
Expand Down
6 changes: 6 additions & 0 deletions sdk/monitor/azure-monitor-query/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@
<version>1.6.2</version> <!-- {x-version-update;com.azure:azure-core-test;dependency} -->
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-core-serializer-json-jackson</artifactId>
<version>1.2.3</version> <!-- {x-version-update;com.azure:azure-core-serializer-json-jackson;dependency} -->
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.azure.monitor.query.log.implementation.models.BatchRequest;
import com.azure.monitor.query.log.implementation.models.BatchResponse;
import com.azure.monitor.query.log.implementation.models.ErrorInfo;
import com.azure.monitor.query.log.implementation.models.ErrorResponseException;
import com.azure.monitor.query.log.implementation.models.LogQueryRequest;
import com.azure.monitor.query.log.implementation.models.LogQueryResponse;
import com.azure.monitor.query.log.implementation.models.LogQueryResult;
Expand All @@ -22,7 +23,9 @@
import com.azure.monitor.query.models.LogsQueryBatch;
import com.azure.monitor.query.models.LogsQueryBatchResult;
import com.azure.monitor.query.models.LogsQueryBatchResultCollection;
import com.azure.monitor.query.models.LogsQueryError;
import com.azure.monitor.query.models.LogsQueryErrorDetails;
import com.azure.monitor.query.models.LogsQueryException;
import com.azure.monitor.query.models.LogsQueryOptions;
import com.azure.monitor.query.models.LogsQueryResult;
import com.azure.monitor.query.models.LogsTable;
Expand All @@ -33,6 +36,7 @@
import reactor.core.publisher.Mono;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
Expand Down Expand Up @@ -128,6 +132,14 @@ Mono<Response<LogsQueryBatchResultCollection>> queryLogsBatchWithResponse(LogsQu
batchRequest.setRequests(requests);

return innerClient.getQueries().batchWithResponseAsync(batchRequest, context)
.onErrorMap(ex -> {
if (ex instanceof ErrorResponseException) {
ErrorResponseException error = (ErrorResponseException) ex;
ErrorInfo errorInfo = error.getValue().getError();
return new LogsQueryException(error.getResponse(), mapLogsQueryError(errorInfo));
}
return ex;
})
.map(this::convertToLogQueryBatchResult);
}

Expand All @@ -139,17 +151,39 @@ private Response<LogsQueryBatchResultCollection> convertToLogQueryBatchResult(Re
for (LogQueryResponse singleQueryResponse : batchResponse.getResponses()) {
LogsQueryBatchResult logsQueryBatchResult = new LogsQueryBatchResult(singleQueryResponse.getId(),
singleQueryResponse.getStatus(), getLogsQueryResult(singleQueryResponse.getBody()),
mapLogsQueryBatchError(singleQueryResponse.getBody().getError()));
mapLogsQueryError(singleQueryResponse.getBody().getError()));
batchResults.add(logsQueryBatchResult);
}
batchResults.sort(Comparator.comparingInt(o -> Integer.parseInt(o.getId())));
return new SimpleResponse<>(response.getRequest(), response.getStatusCode(), response.getHeaders(), logsQueryBatchResultCollection);
}

private LogsQueryErrorDetails mapLogsQueryBatchError(ErrorInfo errors) {
private LogsQueryErrorDetails mapLogsQueryError(ErrorInfo errors) {
if (errors != null) {
return new LogsQueryErrorDetails(errors.getMessage(), errors.getCode(),
errors.getDetails().get(0).getTarget());
List<LogsQueryError> errorDetails = Collections.emptyList();
if (errors.getDetails() != null) {
errorDetails = errors.getDetails()
.stream()
.map(errorDetail -> new LogsQueryError(errorDetail.getCode(),
errorDetail.getMessage(),
errorDetail.getTarget(),
errorDetail.getValue(),
errorDetail.getResources(),
errorDetail.getAdditionalProperties()))
.collect(Collectors.toList());
}

ErrorInfo innerError = errors.getInnererror();
ErrorInfo currentError = errors.getInnererror();
while (currentError != null) {
innerError = errors.getInnererror();
currentError = errors.getInnererror();
}
String code = errors.getCode();
if (!errors.getCode().equals(innerError.getCode())) {
code = innerError.getCode();
}
return new LogsQueryErrorDetails(errors.getMessage(), code, errorDetails);
}
return null;
}
Expand Down Expand Up @@ -186,6 +220,14 @@ Mono<Response<LogsQueryResult>> queryLogsWithResponse(LogsQueryOptions options,
queryBody,
preferHeader,
context)
.onErrorMap(ex -> {
if (ex instanceof ErrorResponseException) {
ErrorResponseException error = (ErrorResponseException) ex;
ErrorInfo errorInfo = error.getValue().getError();
return new LogsQueryException(error.getResponse(), mapLogsQueryError(errorInfo));
}
return ex;
})
.map(this::convertToLogQueryResult);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.monitor.query.models;

import java.util.List;

/**
* Error details of a failed log query.
*/

public final class LogsQueryError {
/*
* The error's code.
*/
private final String code;

/*
* A human readable error message.
*/
private final String message;

/*
* Indicates which property in the request is responsible for the error.
*/
private final String target;

/*
* Indicates which value in 'target' is responsible for the error.
*/
private final String value;

/*
* Indicates resources which were responsible for the error.
*/
private final List<String> resources;

/*
* Additional properties that can be provided on the error details object
*/
private final Object additionalProperties;

/**
* Creates an instance of ErrorDetail class.
* @param code the code value to set.
* @param message the message value to set.
* @param target indicates which property in the request is responsible for the error.
* @param value indicates which value in 'target' is responsible for the error.
* @param resources indicates resources which were responsible for the error.
* @param additionalProperties additional properties that can be provided on the error details object
*/
public LogsQueryError(
String code,
String message,
String target,
String value,
List<String> resources,
Object additionalProperties) {
this.code = code;
this.message = message;
this.target = target;
this.value = value;
this.resources = resources;
this.additionalProperties = additionalProperties;
}

/**
* Get the code property: The error's code.
* @return the code value.
*/
public String getCode() {
return this.code;
}

/**
* Get the message property: A human readable error message.
* @return the message value.
*/
public String getMessage() {
return this.message;
}

/**
* Get the target property: Indicates which property in the request is responsible for the error.
* @return the target value.
*/
public String getTarget() {
return this.target;
}

/**
* Get the value property: Indicates which value in 'target' is responsible for the error.
* @return the value value.
*/
public String getValue() {
return this.value;
}

/**
* Get the resources property: Indicates resources which were responsible for the error.
* @return the resources value.
*/
public List<String> getResources() {
return this.resources;
}

/**
* Get the additionalProperties property: Additional properties that can be provided on the error details object.
* @return the additionalProperties value.
*/
public Object getAdditionalProperties() {
return this.additionalProperties;
}
}
Loading