Skip to content

Commit 9da1214

Browse files
[monitor] query resource (Azure#20570)
* added queryresource * update autorest version * update autorest.md * test * test example * documentation Co-authored-by: Charles Lowell <10964656+chlowell@users.noreply.github.com> --------- Co-authored-by: Charles Lowell <10964656+chlowell@users.noreply.github.com>
1 parent 367524c commit 9da1214

16 files changed

+283
-115
lines changed

eng/config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
},
8484
{
8585
"Name": "monitor/azquery",
86-
"CoverageGoal": 0.80
86+
"CoverageGoal": 0.85
8787
},
8888
{
8989
"Name": "resourcemanager",

sdk/monitor/azquery/CHANGELOG.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
# Release History
22

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

55
### Features Added
6-
7-
### Breaking Changes
8-
9-
### Bugs Fixed
6+
* Added the `LogsClient.QueryResource` method which allow users to query Azure resources directly without a Log Analytics workspace
107

118
### Other Changes
9+
* Updated dependencies and documentation
1210

1311
## 1.0.0 (2023-02-08)
1412

sdk/monitor/azquery/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ The Azure Monitor Query client module is used to execute read-only queries again
1313

1414
* Go, version 1.18 or higher - [Install Go](https://go.dev/doc/install)
1515
* Azure subscription - [Create a free account][azure_sub]
16-
* To query logs, an Azure Log Analytics workspace ID - Create an [Azure Log Analytics workspace][log_analytics_workspace_create]
17-
* To query metrics, the Resource URI of an Azure resource (Storage Account, Key Vault, CosmosDB, etc.) that you plan to monitor
16+
* To query some logs, an Azure Log Analytics workspace ID - Create an [Azure Log Analytics workspace][log_analytics_workspace_create]
17+
* To query metrics and some logs, the Resource URI of an Azure resource (Storage Account, Key Vault, CosmosDB, etc.) that you plan to monitor
1818

1919
### Install the packages
2020

@@ -100,7 +100,7 @@ To do the same with `QueryBatch`, set the values in the `BatchQueryRequest.Heade
100100

101101
Get started with our [examples][azquery_pkg_go_samples].
102102

103-
* For the majority of log queries, use the `LogsClient.QueryWorkspace` method. Only use the `LogsClient.QueryBatch` method in advanced scenerios.
103+
* For the majority of log queries, use the `LogsClient.QueryWorkspace` or the `LogsClient.QueryResource` method. Only use the `LogsClient.QueryBatch` method in advanced scenerios.
104104

105105
* Use `MetricsClient.QueryResource` for metric queries.
106106

sdk/monitor/azquery/TROUBLESHOOTING.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,15 +85,17 @@ The error message in `innererror` may include the location where the Kusto query
8585

8686
### Troubleshooting empty log query results
8787

88-
If your Kusto query returns empty no logs, please validate the following:
88+
If your Kusto query returns empty with no logs, please validate the following:
8989

90-
- You have the right workspace ID
90+
- You have the right workspace ID or resource ID
9191
- You are setting the correct time interval for the query. Try lengthening the time interval for your query to see if that
9292
returns any results.
9393
- If your Kusto query also has a time interval, the query is evaluated for the intersection of the time interval in the
9494
query string and the time interval set in the `Body.Timespan` field of the request query. The intersection of
9595
these time intervals may not have any logs. To avoid any confusion, it's recommended to remove any time interval in
9696
the Kusto query string and use `Body.Timespan` explicitly.
97+
- Your workspace or resource actually has logs to query. Sometimes, especially with newly created resources,
98+
there are no logs yet to query.
9799

98100
### Troubleshooting server timeouts when executing logs query request
99101

sdk/monitor/azquery/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/azquery",
5-
"Tag": "go/monitor/azquery_123118d585"
5+
"Tag": "go/monitor/azquery_4e1ec7fc44"
66
}

sdk/monitor/azquery/autorest.md

Lines changed: 40 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ clear-output-folder: false
99
export-clients: true
1010
go: true
1111
input-file:
12-
- https://github.com/Azure/azure-rest-api-specs/blob/dba6ed1f03bda88ac6884c0a883246446cc72495/specification/operationalinsights/data-plane/Microsoft.OperationalInsights/preview/2021-05-19_Preview/OperationalInsights.json
12+
- https://github.com/Azure/azure-rest-api-specs/blob/605407bc0c1a133018285f550d01175469cb3c3a/specification/operationalinsights/data-plane/Microsoft.OperationalInsights/stable/2022-10-27/OperationalInsights.json
1313
- https://github.com/Azure/azure-rest-api-specs/blob/dba6ed1f03bda88ac6884c0a883246446cc72495/specification/monitor/resource-manager/Microsoft.Insights/stable/2018-01-01/metricDefinitions_API.json
1414
- https://github.com/Azure/azure-rest-api-specs/blob/dba6ed1f03bda88ac6884c0a883246446cc72495/specification/monitor/resource-manager/Microsoft.Insights/stable/2018-01-01/metrics_API.json
1515
- https://github.com/Azure/azure-rest-api-specs/blob/dba6ed1f03bda88ac6884c0a883246446cc72495/specification/monitor/resource-manager/Microsoft.Insights/preview/2017-12-01-preview/metricNamespaces_API.json
@@ -19,20 +19,27 @@ openapi-type: "data-plane"
1919
output-folder: ../azquery
2020
override-client-name: LogsClient
2121
security: "AADToken"
22-
use: "@autorest/go@4.0.0-preview.44"
22+
use: "@autorest/go@4.0.0-preview.46"
2323
version: "^3.0.0"
2424

2525
directive:
26-
# delete metadata endpoint
26+
# delete extra endpoints
2727
- from: swagger-document
2828
where: $["paths"]
2929
transform: >
3030
delete $["/workspaces/{workspaceId}/metadata"];
31+
- from: swagger-document
32+
where: $["x-ms-paths"]
33+
transform: >
34+
delete $["/{resourceId}/query?disambiguation_dummy"];
3135
32-
# delete metadata operations
36+
# delete extra operations
3337
- remove-operation: Metadata_Post
3438
- remove-operation: Metadata_Get
3539
- remove-operation: Query_Get
40+
- remove-operation: Query_ResourceGet
41+
- remove-operation: Query_ResourceExecuteXms
42+
- remove-operation: Query_ResourceGetXms
3643

3744
# delete metadata models
3845
- remove-model: metadataResults
@@ -47,20 +54,19 @@ directive:
4754
- remove-model: metadataResource
4855
- remove-model: metadataPermissions
4956

50-
# rename log queries
57+
# rename operations to generate into metrics and logs clients
5158
- rename-operation:
5259
from: Query_Execute
5360
to: Logs_QueryWorkspace
5461
- rename-operation:
5562
from: Query_Batch
5663
to: Logs_QueryBatch
57-
58-
# rename metric list to QueryResource
64+
- rename-operation:
65+
from: Query_ResourceExecute
66+
to: Logs_QueryResource
5967
- rename-operation:
6068
from: Metrics_List
6169
to: Metrics_QueryResource
62-
63-
# rename ListMetricDefinitions and ListMetricNamespaces to generate in metrics_client.go
6470
- rename-operation:
6571
from: MetricDefinitions_List
6672
to: Metrics_ListDefinitions
@@ -123,7 +129,7 @@ directive:
123129
transform: return $.replace(/Options \*string/g, "Options *LogsQueryOptions");
124130
- from: logs_client.go
125131
where: $
126-
transform: return $.replace(/\*options\.Options/, "options.Options.preferHeader()");
132+
transform: return $.replace(/\*options\.Options/g, "options.Options.preferHeader()");
127133

128134
# add default values for batch request path and method attributes
129135
- from: swagger-document
@@ -132,6 +138,18 @@ directive:
132138
- from: swagger-document
133139
where: $.definitions.batchQueryRequest.properties.method
134140
transform: $["x-ms-client-default"] = "POST"
141+
- from: swagger-document
142+
where: $.definitions.batchQueryRequest.properties.path.x-ms-enum
143+
transform: $["modelAsString"] = true
144+
- from: swagger-document
145+
where: $.definitions.batchQueryRequest.properties.path.x-ms-enum
146+
transform: $["name"] = "BatchQueryRequestPath"
147+
- from: swagger-document
148+
where: $.definitions.batchQueryRequest.properties.method.x-ms-enum
149+
transform: $["modelAsString"] = true
150+
- from: swagger-document
151+
where: $.definitions.batchQueryRequest.properties.method.x-ms-enum
152+
transform: $["name"] = "BatchQueryRequestMethod"
135153

136154
# add descriptions for models and constants that don't have them
137155
- from: swagger-document
@@ -179,38 +197,22 @@ directive:
179197
# delete unused error models
180198
- from: models.go
181199
where: $
182-
transform: return $.replace(/(?:\/\/.*\s)+type (?:ErrorResponse|ErrorResponseAutoGenerated).+\{(?:\s.+\s)+\}\s/g, "");
183-
- from: models_serde.go
184-
where: $
185-
transform: return $.replace(/(?:\/\/.*\s)+func \(\w \*?(?:ErrorResponse|ErrorResponseAutoGenerated)\).*\{\s(?:.+\s)+\}\s/g, "");
186-
- from: models.go
187-
where: $
188-
transform: return $.replace(/(?:\/\/.*\s)+type (?:ErrorInfo|ErrorDetail).+\{(?:\s.+\s)+\}\s/g, "");
200+
transform: return $.replace(/(?:\/\/.*\s)+type (?:ErrorResponse|ErrorResponseAutoGenerated|ErrorInfo|ErrorDetail).+\{(?:\s.+\s)+\}\s/g, "");
189201
- from: models_serde.go
190202
where: $
191-
transform: return $.replace(/(?:\/\/.*\s)+func \(\w \*?(?:ErrorInfo|ErrorDetail)\).*\{\s(?:.+\s)+\}\s/g, "");
192-
193-
# delete generated constructor and client
194-
- from: logs_client.go
195-
where: $
196-
transform: return $.replace(/(?:\/\/.*\s)+func NewLogsClient.+\{\s(?:.+\s)+\}\s/, "");
197-
- from: logs_client.go
198-
where: $
199-
transform: return $.replace(/(?:\/\/.*\s)+type LogsClient struct.+\{\s(?:.+\s)+\}\s/, "");
200-
- from: metrics_client.go
201-
where: $
202-
transform: return $.replace(/(?:\/\/.*\s)+func NewMetricsClient.+\{\s(?:.+\s)+\}\s/, "");
203-
- from: metrics_client.go
204-
where: $
205-
transform: return $.replace(/(?:\/\/.*\s)+type MetricsClient.+\{\s(?:.+\s)+\}\s/, "");
203+
transform: return $.replace(/(?:\/\/.*\s)+func \(\w \*?(?:ErrorResponse|ErrorResponseAutoGenerated|ErrorInfo|ErrorDetail)\).*\{\s(?:.+\s)+\}\s/g, "");
206204

207205
# point the clients to the correct host url
208-
- from: logs_client.go
206+
- from:
207+
- logs_client.go
208+
- metrics_client.go
209209
where: $
210210
transform: return $.replace(/host/g, "client.host");
211-
- from: metrics_client.go
211+
- from:
212+
- logs_client.go
213+
- metrics_client.go
212214
where: $
213-
transform: return $.replace(/host/g, "client.host");
215+
transform: return $.replace(/internal \*azcore.Client/g, "host string\n internal *azcore.Client");
214216

215217
# delete generated host url
216218
- from: constants.go
@@ -220,15 +222,15 @@ directive:
220222
# change Table.Rows from type [][]interface{} to type []Row
221223
- from: models.go
222224
where: $
223-
transform: return $.replace(/Rows \[\]\[\]interface{}/, "Rows []Row");
225+
transform: return $.replace(/Rows \[\]\[\]any/, "Rows []Row");
224226

225227
# change render and statistics type to []byte
226228
- from: models.go
227229
where: $
228-
transform: return $.replace(/Statistics interface{}/g, "Statistics []byte");
230+
transform: return $.replace(/Statistics any/g, "Statistics []byte");
229231
- from: models.go
230232
where: $
231-
transform: return $.replace(/Visualization interface{}/g, "Visualization []byte");
233+
transform: return $.replace(/Visualization any/g, "Visualization []byte");
232234
- from: models_serde.go
233235
where: $
234236
transform: return

sdk/monitor/azquery/custom_client.go

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,6 @@ type LogsClientOptions struct {
3232
azcore.ClientOptions
3333
}
3434

35-
// LogsClient contains the methods for the LogsClient group.
36-
// Don't use this type directly, use NewLogsClient() instead.
37-
type LogsClient struct {
38-
host string
39-
pl runtime.Pipeline
40-
}
41-
42-
// MetricsClient contains the methods for the Metrics group.
43-
// Don't use this type directly, use NewMetricsClient() instead.
44-
type MetricsClient struct {
45-
host string
46-
pl runtime.Pipeline
47-
}
48-
4935
// NewLogsClient creates a client that accesses Azure Monitor logs data.
5036
func NewLogsClient(credential azcore.TokenCredential, options *LogsClientOptions) (*LogsClient, error) {
5137
if options == nil {
@@ -60,8 +46,11 @@ func NewLogsClient(credential azcore.TokenCredential, options *LogsClientOptions
6046
}
6147

6248
authPolicy := runtime.NewBearerTokenPolicy(credential, []string{c.Audience + "/.default"}, nil)
63-
pl := runtime.NewPipeline(moduleName, version, runtime.PipelineOptions{PerRetry: []policy.Policy{authPolicy}}, &options.ClientOptions)
64-
return &LogsClient{host: c.Endpoint, pl: pl}, nil
49+
azcoreClient, err := azcore.NewClient("azquery.LogsClient", version, runtime.PipelineOptions{PerRetry: []policy.Policy{authPolicy}}, &options.ClientOptions)
50+
if err != nil {
51+
return nil, err
52+
}
53+
return &LogsClient{host: c.Endpoint, internal: azcoreClient}, nil
6554
}
6655

6756
// NewMetricsClient creates a client that accesses Azure Monitor metrics data.
@@ -78,8 +67,11 @@ func NewMetricsClient(credential azcore.TokenCredential, options *MetricsClientO
7867
}
7968

8069
authPolicy := runtime.NewBearerTokenPolicy(credential, []string{c.Audience + "/.default"}, nil)
81-
pl := runtime.NewPipeline(moduleName, version, runtime.PipelineOptions{PerRetry: []policy.Policy{authPolicy}}, &options.ClientOptions)
82-
return &MetricsClient{host: c.Endpoint, pl: pl}, nil
70+
azcoreClient, err := azcore.NewClient("azquery.MetricsClient", version, runtime.PipelineOptions{PerRetry: []policy.Policy{authPolicy}}, &options.ClientOptions)
71+
if err != nil {
72+
return nil, err
73+
}
74+
return &MetricsClient{host: c.Endpoint, internal: azcoreClient}, nil
8375
}
8476

8577
// ErrorInfo - The code and message for an error.

sdk/monitor/azquery/example_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ func ExampleLogsClient_QueryWorkspace() {
6262
// 1. If not already made, create a Log Analytics workspace (https://learn.microsoft.com/azure/azure-monitor/logs/quick-create-workspace).
6363
// 2. Navigate to your workspace's page in the Azure portal.
6464
// 3. From the **Overview** blade, copy the value of the ***Workspace ID*** property.
65+
6566
workspaceID := "g4d1e129-fb1e-4b0a-b234-250abc987ea65" // example Azure Log Analytics Workspace ID
6667

6768
res, err := logsClient.QueryWorkspace(
@@ -150,6 +151,40 @@ func ExampleLogsClient_QueryWorkspace_second() {
150151

151152
}
152153

154+
func ExampleLogsClient_QueryResource() {
155+
// Instead of requiring a Log Analytics workspace,
156+
// QueryResource allows users to query logs directly from an Azure resource through a resource ID.
157+
158+
// To find the resource ID:
159+
// 1. Navigate to your resource's page in the Azure portal.
160+
// 2. From the **Overview** blade, select the **JSON View** link.
161+
// 3. In the resulting JSON, copy the value of the `id` property.
162+
163+
resourceID := "/subscriptions/fajfkx93-c1d8-40ad-9cce-e49c10ca8qe6/resourceGroups/testgroup/providers/Microsoft.Storage/storageAccounts/mystorageacount" // example resource ID
164+
165+
res, err := logsClient.QueryResource(
166+
context.TODO(),
167+
resourceID,
168+
azquery.Body{
169+
Query: to.Ptr("StorageBlobLogs | where TimeGenerated > ago(3d)"), // example Kusto query
170+
Timespan: to.Ptr(azquery.NewTimeInterval(time.Date(2022, 12, 25, 0, 0, 0, 0, time.UTC), time.Date(2022, 12, 25, 12, 0, 0, 0, time.UTC))),
171+
},
172+
nil)
173+
if err != nil {
174+
//TODO: handle error
175+
}
176+
if res.Error != nil {
177+
//TODO: handle partial error
178+
}
179+
180+
// Print Rows
181+
for _, table := range res.Tables {
182+
for _, row := range table.Rows {
183+
fmt.Println(row)
184+
}
185+
}
186+
}
187+
153188
func ExampleLogsClient_QueryBatch() {
154189
// `QueryBatch` is an advanced method allowing users to execute multiple log queries in a single request.
155190
// For help formatting a `BatchRequest`, please use the method `NewBatchQueryRequest`.

0 commit comments

Comments
 (0)