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

Make the query batch a simpler model #21009

Merged
merged 3 commits into from
May 11, 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
4 changes: 2 additions & 2 deletions sdk/monitor/Azure.Monitor.Query/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,11 @@ string workspaceId = "<workspace_id>";

// Query TOP 10 resource groups by event count
// And total event count
LogsBatchQuery batch = client.CreateBatchQuery();
LogsBatchQuery batch = new LogsBatchQuery();
string countQueryId = batch.AddQuery(workspaceId, "AzureActivity | count", TimeSpan.FromDays(1));
string topQueryId = batch.AddQuery(workspaceId, "AzureActivity | summarize Count = count() by ResourceGroup | top 10 by Count", TimeSpan.FromDays(1));

Response<LogsBatchQueryResult> response = await batch.SubmitAsync();
Response<LogsBatchQueryResult> response = await client.QueryBatchAsync(batch);

var count = response.Value.GetResult<int>(countQueryId).Single();
var topEntries = response.Value.GetResult<MyLogEntryModel>(topQueryId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,19 @@ namespace Azure.Monitor.Query
}
public partial class LogsBatchQuery
{
protected LogsBatchQuery() { }
public LogsBatchQuery() { }
public virtual string AddQuery(string workspaceId, string query, Azure.Monitor.Query.DateTimeRange timeRange, Azure.Monitor.Query.LogsQueryOptions options = null) { throw null; }
public virtual Azure.Response<Azure.Monitor.Query.Models.LogsBatchQueryResult> Submit(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual System.Threading.Tasks.Task<Azure.Response<Azure.Monitor.Query.Models.LogsBatchQueryResult>> SubmitAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
}
public partial class LogsClient
{
protected LogsClient() { }
public LogsClient(Azure.Core.TokenCredential credential) { }
public LogsClient(Azure.Core.TokenCredential credential, Azure.Monitor.Query.LogsClientOptions options) { }
public virtual Azure.Monitor.Query.LogsBatchQuery CreateBatchQuery() { throw null; }
public virtual Azure.Response<Azure.Monitor.Query.Models.LogsQueryResult> Query(string workspaceId, string query, Azure.Monitor.Query.DateTimeRange timeRange, Azure.Monitor.Query.LogsQueryOptions options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual System.Threading.Tasks.Task<Azure.Response<Azure.Monitor.Query.Models.LogsQueryResult>> QueryAsync(string workspaceId, string query, Azure.Monitor.Query.DateTimeRange timeRange, Azure.Monitor.Query.LogsQueryOptions options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual System.Threading.Tasks.Task<Azure.Response<System.Collections.Generic.IReadOnlyList<T>>> QueryAsync<T>(string workspaceId, string query, Azure.Monitor.Query.DateTimeRange timeRange, Azure.Monitor.Query.LogsQueryOptions options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual Azure.Response<Azure.Monitor.Query.Models.LogsBatchQueryResult> QueryBatch(Azure.Monitor.Query.LogsBatchQuery batch, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual System.Threading.Tasks.Task<Azure.Response<Azure.Monitor.Query.Models.LogsBatchQueryResult>> QueryBatchAsync(Azure.Monitor.Query.LogsBatchQuery batch, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public virtual Azure.Response<System.Collections.Generic.IReadOnlyList<T>> Query<T>(string workspaceId, string query, Azure.Monitor.Query.DateTimeRange timeRange, Azure.Monitor.Query.LogsQueryOptions options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
}
public partial class LogsClientOptions : Azure.Core.ClientOptions
Expand Down
48 changes: 44 additions & 4 deletions sdk/monitor/Azure.Monitor.Query/src/LogsClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,14 +135,54 @@ public virtual async Task<Response<LogsQueryResult>> QueryAsync(string workspace
}

/// <summary>
/// Creates an instance of <see cref="LogsBatchQuery"/> that allows executing multiple queries at once.
/// Submits the batch query.
/// </summary>
/// <returns>The <see cref="LogsBatchQuery"/> instance that allows building a list of queries and submitting them.</returns>
public virtual LogsBatchQuery CreateBatchQuery()
/// <param name="batch">The batch of queries to send.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to use.</param>
/// <returns>The <see cref="LogsBatchQueryResult"/> containing the query identifier that has to be passed into <see cref="LogsBatchQueryResult.GetResult"/> to get the result.</returns>
public virtual Response<LogsBatchQueryResult> QueryBatch(LogsBatchQuery batch, CancellationToken cancellationToken = default)
{
return new LogsBatchQuery(_clientDiagnostics, _queryClient, _rowBinder);
Argument.AssertNotNull(batch, nameof(batch));

using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(LogsClient)}.{nameof(QueryBatch)}");
scope.Start();
try
{
var response = _queryClient.Batch(batch.Batch, cancellationToken);
response.Value.RowBinder = _rowBinder;
return response;
}
catch (Exception e)
{
scope.Failed(e);
throw;
}
}

/// <summary>
/// Submits the batch query.
/// </summary>
/// <param name="batch">The batch of queries to send.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to use.</param>
/// <returns>The <see cref="LogsBatchQueryResult"/> that allows retrieving query results.</returns>
public virtual async Task<Response<LogsBatchQueryResult>> QueryBatchAsync(LogsBatchQuery batch, CancellationToken cancellationToken = default)
{
Argument.AssertNotNull(batch, nameof(batch));

using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(LogsClient)}.{nameof(QueryBatch)}");
scope.Start();
try
{
var response = await _queryClient.BatchAsync(batch.Batch, cancellationToken).ConfigureAwait(false);
response.Value.RowBinder = _rowBinder;
return response;
}
catch (Exception e)
{
scope.Failed(e);
throw;
}
}
internal static QueryBody CreateQueryBody(string query, DateTimeRange timeRange, LogsQueryOptions options, out string prefer)
{
var queryBody = new QueryBody(query);
Expand Down
66 changes: 6 additions & 60 deletions sdk/monitor/Azure.Monitor.Query/src/Models/LogsBatchQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,19 @@ namespace Azure.Monitor.Query
/// </summary>
public class LogsBatchQuery
{
private readonly ClientDiagnostics _clientDiagnostics;
private readonly QueryRestClient _restClient;
private readonly RowBinder _rowBinder;
private readonly BatchRequest _batch;
internal BatchRequest Batch { get; }
private int _counter;

internal LogsBatchQuery(ClientDiagnostics clientDiagnostics, QueryRestClient restClient, RowBinder rowBinder)
{
_clientDiagnostics = clientDiagnostics;
_restClient = restClient;
_rowBinder = rowBinder;
_batch = new BatchRequest();
}

/// <summary>
/// Initializes a new instance of <see cref="LogsBatchQuery"/> for mocking.
/// Initializes a new instance of <see cref="LogsBatchQuery"/>.
/// </summary>
protected LogsBatchQuery()
public LogsBatchQuery()
{
Batch = new BatchRequest();
}

/// <summary>
/// Adds the specified query to the batch. Results can be retrieved after the query is submitted via the <see cref="SubmitAsync"/> call.
/// Adds the specified query to the batch. Results can be retrieved after the query is submitted via the <see cref="LogsClient.QueryBatchAsync"/> call.
/// </summary>
/// <param name="workspaceId">The workspace to include in the query.</param>
/// <param name="query">The query text to execute.</param>
Expand All @@ -58,52 +48,8 @@ public virtual string AddQuery(string workspaceId, string query, DateTimeRange t
{
logQueryRequest.Headers.Add("prefer", prefer);
}
_batch.Requests.Add(logQueryRequest);
Batch.Requests.Add(logQueryRequest);
return id;
}

/// <summary>
/// Submits the batch.
/// </summary>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to use.</param>
/// <returns>The <see cref="LogsBatchQueryResult"/> containing the query identifier that has to be passed into <see cref="LogsBatchQueryResult.GetResult"/> to get the result.</returns>
public virtual Response<LogsBatchQueryResult> Submit(CancellationToken cancellationToken = default)
{
using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(LogsBatchQuery)}.{nameof(Submit)}");
scope.Start();
try
{
var response = _restClient.Batch(_batch, cancellationToken);
response.Value.RowBinder = _rowBinder;
return response;
}
catch (Exception e)
{
scope.Failed(e);
throw;
}
}

/// <summary>
/// Submits the batch.
/// </summary>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to use.</param>
/// <returns>The <see cref="LogsBatchQueryResult"/> that allows retrieving query results.</returns>
public virtual async Task<Response<LogsBatchQueryResult>> SubmitAsync(CancellationToken cancellationToken = default)
{
using DiagnosticScope scope = _clientDiagnostics.CreateScope($"{nameof(LogsBatchQuery)}.{nameof(Submit)}");
scope.Start();
try
{
var response = await _restClient.BatchAsync(_batch, cancellationToken).ConfigureAwait(false);
response.Value.RowBinder = _rowBinder;
return response;
}
catch (Exception e)
{
scope.Failed(e);
throw;
}
}
}
}
4 changes: 2 additions & 2 deletions sdk/monitor/Azure.Monitor.Query/tests/LogsClientSamples.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,11 @@ public async Task BatchQuery()

// Query TOP 10 resource groups by event count
// And total event count
LogsBatchQuery batch = client.CreateBatchQuery();
LogsBatchQuery batch = new LogsBatchQuery();
string countQueryId = batch.AddQuery(workspaceId, "AzureActivity | count", TimeSpan.FromDays(1));
string topQueryId = batch.AddQuery(workspaceId, "AzureActivity | summarize Count = count() by ResourceGroup | top 10 by Count", TimeSpan.FromDays(1));

Response<LogsBatchQueryResult> response = await batch.SubmitAsync();
Response<LogsBatchQueryResult> response = await client.QueryBatchAsync(batch);

var count = response.Value.GetResult<int>(countQueryId).Single();
var topEntries = response.Value.GetResult<MyLogEntryModel>(topQueryId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,10 @@ public async Task CanQueryIntoIDictionary()
public async Task CanQueryBatch()
{
var client = CreateClient();
LogsBatchQuery batch = InstrumentClient(client.CreateBatchQuery());
LogsBatchQuery batch = new LogsBatchQuery();
string id1 = batch.AddQuery(TestEnvironment.WorkspaceId, "Heartbeat", _logsTestData.DataTimeRange);
string id2 = batch.AddQuery(TestEnvironment.WorkspaceId, "Heartbeat", _logsTestData.DataTimeRange);
Response<LogsBatchQueryResult> response = await batch.SubmitAsync();
Response<LogsBatchQueryResult> response = await client.QueryBatchAsync(batch);

var result1 = response.Value.GetResult(id1);
var result2 = response.Value.GetResult(id2);
Expand Down Expand Up @@ -380,10 +380,10 @@ public async Task CanQueryBatchWithTimespan()
timespan = timespan.Add(TimeSpan.FromDays(1));

var client = CreateClient();
LogsBatchQuery batch = InstrumentClient(client.CreateBatchQuery());
LogsBatchQuery batch = new LogsBatchQuery();
string id1 = batch.AddQuery(TestEnvironment.WorkspaceId, $"{_logsTestData.TableAName} | project {LogsTestData.TimeGeneratedColumnName}", _logsTestData.DataTimeRange);
string id2 = batch.AddQuery(TestEnvironment.WorkspaceId, $"{_logsTestData.TableAName} | project {LogsTestData.TimeGeneratedColumnName}", timespan);
Response<LogsBatchQueryResult> response = await batch.SubmitAsync();
Response<LogsBatchQueryResult> response = await client.QueryBatchAsync(batch);

var result1 = response.Value.GetResult<DateTimeOffset>(id1);
var result2 = response.Value.GetResult<DateTimeOffset>(id2);
Expand All @@ -410,9 +410,9 @@ public async Task ThrowsExceptionWhenQueryFailsBatch()
{
var client = CreateClient();

LogsBatchQuery batch = InstrumentClient(client.CreateBatchQuery());
LogsBatchQuery batch = new LogsBatchQuery();
var queryId = batch.AddQuery(TestEnvironment.WorkspaceId, "this won't work", _logsTestData.DataTimeRange);
var batchResult = await batch.SubmitAsync();
var batchResult = await client.QueryBatchAsync(batch);

var exception = Assert.Throws<RequestFailedException>(() => batchResult.Value.GetResult(queryId));

Expand All @@ -425,9 +425,9 @@ public async Task ThrowsExceptionWhenBatchQueryNotFound()
{
var client = CreateClient();

LogsBatchQuery batch = InstrumentClient(client.CreateBatchQuery());
LogsBatchQuery batch = new LogsBatchQuery();
batch.AddQuery(TestEnvironment.WorkspaceId, _logsTestData.TableAName, _logsTestData.DataTimeRange);
var batchResult = await batch.SubmitAsync();
var batchResult = await client.QueryBatchAsync(batch);

var exception = Assert.Throws<ArgumentException>(() => batchResult.Value.GetResult("12345"));

Expand Down Expand Up @@ -464,12 +464,12 @@ public async Task CanQueryWithStatisticsBatch(bool include)
{
var client = CreateClient();

LogsBatchQuery batch = InstrumentClient(client.CreateBatchQuery());
LogsBatchQuery batch = new LogsBatchQuery();
var queryId = batch.AddQuery(TestEnvironment.WorkspaceId, _logsTestData.TableAName, _logsTestData.DataTimeRange, options: new LogsQueryOptions()
{
IncludeStatistics = include
});
var batchResult = await batch.SubmitAsync();
var batchResult = await client.QueryBatchAsync(batch);
var result = batchResult.Value.GetResult(queryId);

if (include)
Expand Down