Skip to content

Commit 8f1c6e1

Browse files
authored
[query/azlogs] add batch queries (Azure#23109)
* add batch * docs
1 parent 6c553d5 commit 8f1c6e1

File tree

12 files changed

+459
-51
lines changed

12 files changed

+459
-51
lines changed

sdk/monitor/query/azlogs/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
# Release History
22

3-
## 1.0.1 (Unreleased)
3+
## 1.1.0-beta.1 (Unreleased)
44

55
### Features Added
6+
* Added batch query functionality
67

78
### Breaking Changes
89

sdk/monitor/query/azlogs/assets.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
"AssetsRepo": "Azure/azure-sdk-assets",
33
"AssetsRepoPrefixPath": "go",
44
"TagPrefix": "go/monitor/query/azlogs",
5-
"Tag": "go/monitor/query/azlogs_139fabf226"
5+
"Tag": "go/monitor/query/azlogs_2bd6ffba1a"
66
}

sdk/monitor/query/azlogs/autorest.md

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,10 @@ directive:
2626
where: $["x-ms-paths"]
2727
transform: >
2828
delete $["/{resourceId}/query?disambiguation_dummy"];
29-
- from: swagger-document
30-
where: $["paths"]
31-
transform: >
32-
delete $["/$batch"];
3329
3430
# delete extra operations
3531
- remove-operation: Query_Get
3632
- remove-operation: Query_ResourceGet
37-
- remove-operation: Query_Batch
3833

3934
# delete metadata and batch models
4035
- remove-model: metadataResults
@@ -48,11 +43,6 @@ directive:
4843
- remove-model: metadataWorkspace
4944
- remove-model: metadataResource
5045
- remove-model: metadataPermissions
51-
- remove-model: batchRequest
52-
- remove-model: batchQueryRequest
53-
- remove-model: batchResponse
54-
- remove-model: batchQueryResponse
55-
- remove-model: batchQueryResults
5646

5747
# rename log operations to generate into a separate logs client
5848
- rename-operation:
@@ -61,6 +51,9 @@ directive:
6151
- rename-operation:
6252
from: Query_ResourceExecute
6353
to: Logs_QueryResource
54+
- rename-operation:
55+
from: Query_Batch
56+
to: Logs_QueryBatch
6457

6558
# rename Body.Workspaces to Body.AdditionalWorkspaces
6659
- from: swagger-document
@@ -69,13 +62,18 @@ directive:
6962

7063
# rename Render to Visualization
7164
- from: swagger-document
72-
where: $.definitions.queryResults.properties.render
65+
where: $.definitions..render
7366
transform: $["x-ms-client-name"] = "Visualization"
7467

7568
# rename LogsColumnType to ColumnType
7669
- from: swagger-document
7770
where: $.definitions.logsColumnType.x-ms-enum
7871
transform: $["name"] = "ColumnType"
72+
73+
# rename BatchQueryRequest.Workspace to BatchQueryRequest.WorkspaceID
74+
- from: swagger-document
75+
where: $.definitions.batchQueryRequest.properties.workspace
76+
transform: $["x-ms-client-name"] = "WorkspaceID"
7977

8078
# rename Prefer to Options
8179
- from: swagger-document

sdk/monitor/query/azlogs/client.go

Lines changed: 50 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sdk/monitor/query/azlogs/client_test.go

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,103 @@ func TestQueryResource_Advanced(t *testing.T) {
205205
testSerde(t, &res)
206206
}
207207

208+
func TestQueryBatch_QuerySuccess(t *testing.T) {
209+
client := startTest(t)
210+
query1, query2 := query, query+" | take 2"
211+
timespan := azlogs.NewTimeInterval(time.Date(2022, 3, 2, 0, 0, 0, 0, time.UTC), time.Date(2022, 3, 3, 0, 0, 0, 0, time.UTC))
212+
213+
batchRequest := azlogs.BatchRequest{[]azlogs.BatchQueryRequest{
214+
{Body: &azlogs.QueryBody{Query: to.Ptr(query1), Timespan: to.Ptr(timespan)}, ID: to.Ptr("1"), WorkspaceID: to.Ptr(workspaceID)},
215+
{Body: &azlogs.QueryBody{Query: to.Ptr(query2), Timespan: to.Ptr(timespan)}, ID: to.Ptr("2"), WorkspaceID: to.Ptr(workspaceID)},
216+
}}
217+
testSerde(t, &batchRequest)
218+
219+
res, err := client.QueryBatch(context.Background(), batchRequest, nil)
220+
require.NoError(t, err)
221+
require.Len(t, res.Responses, 2)
222+
for _, resp := range res.Responses {
223+
require.Nil(t, resp.Body.Error)
224+
require.NotNil(t, resp.Body.Tables)
225+
if *resp.ID == "1" && len(resp.Body.Tables[0].Rows) != 100 {
226+
t.Fatal("expected 100 rows from batch request 1")
227+
}
228+
if *resp.ID == "2" && len(resp.Body.Tables[0].Rows) != 2 {
229+
t.Fatal("expected 2 rows from batch request 2")
230+
}
231+
}
232+
testSerde(t, &res)
233+
}
234+
235+
func TestQueryBatch_BasicQueryFailure(t *testing.T) {
236+
client := startTest(t)
237+
238+
batchRequest := azlogs.BatchRequest{[]azlogs.BatchQueryRequest{
239+
{Body: &azlogs.QueryBody{Query: to.Ptr(query)}, ID: to.Ptr("1"), WorkspaceID: to.Ptr(workspaceID)},
240+
{Body: &azlogs.QueryBody{Query: to.Ptr(query)}, ID: to.Ptr("1"), WorkspaceID: to.Ptr(workspaceID)},
241+
}}
242+
testSerde(t, &batchRequest)
243+
244+
res, err := client.QueryBatch(context.Background(), batchRequest, nil)
245+
require.Error(t, err)
246+
require.Nil(t, res.Responses)
247+
248+
var httpErr *azcore.ResponseError
249+
require.ErrorAs(t, err, &httpErr)
250+
require.Equal(t, httpErr.ErrorCode, "BadArgumentError")
251+
require.Equal(t, httpErr.StatusCode, 400)
252+
}
253+
254+
func TestQueryBatch_AdvancedQuerySuccess(t *testing.T) {
255+
client := startTest(t)
256+
timespan := azlogs.NewTimeInterval(time.Date(2022, 12, 25, 0, 0, 0, 0, time.UTC), time.Date(2022, 12, 25, 12, 0, 0, 0, time.UTC))
257+
batchPrefer1 := "wait=600,include-statistics=true,include-render=true"
258+
headers1 := map[string]*string{"prefer": &batchPrefer1}
259+
batchPrefer2 := "wait=180,include-statistics=true,include-render=true"
260+
headers2 := map[string]*string{"prefer": &batchPrefer2}
261+
262+
batchRequestAdvanced := azlogs.BatchRequest{[]azlogs.BatchQueryRequest{
263+
{Body: &azlogs.QueryBody{Query: to.Ptr(query), Timespan: to.Ptr(timespan)}, ID: to.Ptr("1"), WorkspaceID: to.Ptr(workspaceID2), Headers: headers1},
264+
{Body: &azlogs.QueryBody{Query: to.Ptr(query), Timespan: to.Ptr(timespan)}, ID: to.Ptr("2"), WorkspaceID: to.Ptr(workspaceID2), Headers: headers2},
265+
}}
266+
testSerde(t, &batchRequestAdvanced)
267+
268+
res, err := client.QueryBatch(context.Background(), batchRequestAdvanced, nil)
269+
require.NoError(t, err)
270+
require.Len(t, res.Responses, 2)
271+
for _, resp := range res.Responses {
272+
require.Nil(t, resp.Body.Error)
273+
require.NotNil(t, resp.Body.Tables)
274+
require.NotNil(t, resp.Body.Visualization)
275+
require.NotNil(t, resp.Body.Statistics)
276+
require.Len(t, resp.Body.Tables[0].Rows, 100)
277+
}
278+
testSerde(t, &res)
279+
}
280+
281+
func TestQueryBatch_PartialError(t *testing.T) {
282+
client := startTest(t)
283+
284+
batchRequest := azlogs.BatchRequest{[]azlogs.BatchQueryRequest{
285+
{Body: &azlogs.QueryBody{Query: to.Ptr("not a valid query")}, ID: to.Ptr("1"), WorkspaceID: to.Ptr(workspaceID)},
286+
{Body: &azlogs.QueryBody{Query: to.Ptr(query)}, ID: to.Ptr("2"), WorkspaceID: to.Ptr(workspaceID)},
287+
}}
288+
289+
res, err := client.QueryBatch(context.Background(), batchRequest, nil)
290+
require.NoError(t, err)
291+
require.Len(t, res.Responses, 2)
292+
for _, resp := range res.Responses {
293+
if *resp.ID == "1" {
294+
require.NotNil(t, resp.Body.Error)
295+
require.Equal(t, resp.Body.Error.Code, "BadArgumentError")
296+
require.Contains(t, resp.Body.Error.Error(), "BadArgumentError")
297+
}
298+
if *resp.ID == "2" {
299+
require.Nil(t, resp.Body.Error)
300+
require.Len(t, resp.Body.Tables[0].Rows, 100)
301+
}
302+
}
303+
}
304+
208305
func TestTimeInterval(t *testing.T) {
209306
timespan := azlogs.NewTimeInterval(time.Date(2022, 3, 2, 1, 2, 3, 0, time.UTC), time.Date(2022, 3, 3, 0, 0, 0, 0, time.UTC))
210307
require.Equal(t, timespan, azlogs.TimeInterval("2022-03-02T01:02:03Z/2022-03-03T00:00:00Z"))

sdk/monitor/query/azlogs/examples_test.go

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,12 @@ import (
1313
"github.com/Azure/azure-sdk-for-go/sdk/monitor/query/azlogs"
1414
)
1515

16-
var client azlogs.Client
16+
var (
17+
client azlogs.Client
18+
kustoQuery1 string
19+
kustoQuery2 string
20+
kustoQuery3 string
21+
)
1722

1823
type queryResult struct {
1924
Bool bool
@@ -164,3 +169,31 @@ func ExampleClient_QueryResource() {
164169
}
165170
}
166171
}
172+
173+
func ExampleClient_QueryBatch() {
174+
// `QueryBatch` is an advanced method allowing users to execute multiple log queries in a single request.
175+
176+
workspaceID := "g4d1e129-fb1e-4b0a-b234-250abc987ea65" // example Azure Log Analytics Workspace ID
177+
timespan := azlogs.NewTimeInterval(time.Date(2022, 12, 25, 0, 0, 0, 0, time.UTC), time.Date(2022, 12, 25, 12, 0, 0, 0, time.UTC))
178+
179+
batchRequest := azlogs.BatchRequest{[]azlogs.BatchQueryRequest{
180+
{Body: &azlogs.QueryBody{Query: to.Ptr(kustoQuery1), Timespan: to.Ptr(timespan)}, ID: to.Ptr("1"), WorkspaceID: to.Ptr(workspaceID)},
181+
{Body: &azlogs.QueryBody{Query: to.Ptr(kustoQuery2), Timespan: to.Ptr(timespan)}, ID: to.Ptr("2"), WorkspaceID: to.Ptr(workspaceID)},
182+
{Body: &azlogs.QueryBody{Query: to.Ptr(kustoQuery3), Timespan: to.Ptr(timespan)}, ID: to.Ptr("3"), WorkspaceID: to.Ptr(workspaceID)},
183+
}}
184+
185+
res, err := client.QueryBatch(context.TODO(), batchRequest, nil)
186+
if err != nil {
187+
//TODO: handle error
188+
}
189+
190+
// `QueryBatch` can return results in any order, usually by time it takes each individual query to complete.
191+
// Use the `ID` field to identify the correct response.
192+
responses := res.Responses
193+
fmt.Println("ID's of successful responses:")
194+
for _, response := range responses {
195+
if response.Body.Error == nil {
196+
fmt.Println(*response.ID)
197+
}
198+
}
199+
}

sdk/monitor/query/azlogs/models.go

Lines changed: 59 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)