AzureMonitor: Correctly set resource parameter for Logs queries (#68133)
* Update to ensure the resources parameter is passed through for logs queries only * Use string slices for resources to ensure order remains the same * Fix lint * clarify test
This commit is contained in:
@@ -162,14 +162,20 @@ func (e *AzureLogAnalyticsDatasource) buildQueries(ctx context.Context, logger l
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
queryString = buildTracesQuery(operationId, queryJSONModel.AzureTraces.TraceTypes, queryJSONModel.AzureTraces.Filters, &resultFormat, resourcesMap)
|
queryResources := make([]string, 0)
|
||||||
|
for resource := range resourcesMap {
|
||||||
|
queryResources = append(queryResources, resource)
|
||||||
|
}
|
||||||
|
sort.Strings(queryResources)
|
||||||
|
|
||||||
|
queryString = buildTracesQuery(operationId, queryJSONModel.AzureTraces.TraceTypes, queryJSONModel.AzureTraces.Filters, &resultFormat, queryResources)
|
||||||
traceIdVariable := "${__data.fields.traceID}"
|
traceIdVariable := "${__data.fields.traceID}"
|
||||||
if operationId == "" {
|
if operationId == "" {
|
||||||
traceExploreQuery = buildTracesQuery(traceIdVariable, queryJSONModel.AzureTraces.TraceTypes, queryJSONModel.AzureTraces.Filters, &resultFormat, resourcesMap)
|
traceExploreQuery = buildTracesQuery(traceIdVariable, queryJSONModel.AzureTraces.TraceTypes, queryJSONModel.AzureTraces.Filters, &resultFormat, queryResources)
|
||||||
traceLogsExploreQuery = buildTracesLogsQuery(traceIdVariable, resourcesMap)
|
traceLogsExploreQuery = buildTracesLogsQuery(traceIdVariable, queryResources)
|
||||||
} else {
|
} else {
|
||||||
traceExploreQuery = queryString
|
traceExploreQuery = queryString
|
||||||
traceLogsExploreQuery = buildTracesLogsQuery(operationId, resourcesMap)
|
traceLogsExploreQuery = buildTracesLogsQuery(operationId, queryResources)
|
||||||
}
|
}
|
||||||
traceExploreQuery, err = macros.KqlInterpolate(logger, query, dsInfo, traceExploreQuery, "TimeGenerated")
|
traceExploreQuery, err = macros.KqlInterpolate(logger, query, dsInfo, traceExploreQuery, "TimeGenerated")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -353,7 +359,7 @@ func (e *AzureLogAnalyticsDatasource) executeQuery(ctx context.Context, logger l
|
|||||||
ResultFormat *dataquery.AzureMonitorQueryAzureLogAnalyticsResultFormat "json:\"resultFormat,omitempty\""
|
ResultFormat *dataquery.AzureMonitorQueryAzureLogAnalyticsResultFormat "json:\"resultFormat,omitempty\""
|
||||||
Workspace *string "json:\"workspace,omitempty\""
|
Workspace *string "json:\"workspace,omitempty\""
|
||||||
}{
|
}{
|
||||||
Resources: queryJSONModel.AzureTraces.Resources,
|
Resources: []string{queryJSONModel.AzureTraces.Resources[0]},
|
||||||
Query: &query.TraceLogsExploreQuery,
|
Query: &query.TraceLogsExploreQuery,
|
||||||
},
|
},
|
||||||
QueryType: &logsQueryType,
|
QueryType: &logsQueryType,
|
||||||
@@ -405,7 +411,7 @@ func (e *AzureLogAnalyticsDatasource) createRequest(ctx context.Context, logger
|
|||||||
"query": query.Query,
|
"query": query.Query,
|
||||||
"timespan": timespan,
|
"timespan": timespan,
|
||||||
}
|
}
|
||||||
if len(query.Resources) > 1 {
|
if len(query.Resources) > 1 && query.QueryType == string(dataquery.AzureQueryTypeAzureLogAnalytics) {
|
||||||
body["workspaces"] = query.Resources
|
body["workspaces"] = query.Resources
|
||||||
}
|
}
|
||||||
jsonValue, err := json.Marshal(body)
|
jsonValue, err := json.Marshal(body)
|
||||||
@@ -674,7 +680,7 @@ func encodeQuery(rawQuery string) (string, error) {
|
|||||||
return base64.StdEncoding.EncodeToString(b.Bytes()), nil
|
return base64.StdEncoding.EncodeToString(b.Bytes()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildTracesQuery(operationId string, traceTypes []string, filters []types.TracesFilters, resultFormat *string, resources map[string]bool) string {
|
func buildTracesQuery(operationId string, traceTypes []string, filters []types.TracesFilters, resultFormat *string, resources []string) string {
|
||||||
types := traceTypes
|
types := traceTypes
|
||||||
if len(types) == 0 {
|
if len(types) == 0 {
|
||||||
types = Tables
|
types = Tables
|
||||||
@@ -696,7 +702,7 @@ func buildTracesQuery(operationId string, traceTypes []string, filters []types.T
|
|||||||
resourcesQuery := strings.Join(filteredTypes, ",")
|
resourcesQuery := strings.Join(filteredTypes, ",")
|
||||||
if len(resources) > 0 {
|
if len(resources) > 0 {
|
||||||
intermediate := make([]string, 0)
|
intermediate := make([]string, 0)
|
||||||
for resource := range resources {
|
for _, resource := range resources {
|
||||||
resourceSplit := strings.SplitAfter(resource, "/")
|
resourceSplit := strings.SplitAfter(resource, "/")
|
||||||
resourceName := resourceSplit[len(resourceSplit)-1]
|
resourceName := resourceSplit[len(resourceSplit)-1]
|
||||||
for _, table := range filteredTypes {
|
for _, table := range filteredTypes {
|
||||||
@@ -768,13 +774,13 @@ func buildTracesQuery(operationId string, traceTypes []string, filters []types.T
|
|||||||
return baseQuery + whereClause + propertiesStaticQuery + errorProperty + propertiesQuery + filtersClause + projectClause
|
return baseQuery + whereClause + propertiesStaticQuery + errorProperty + propertiesQuery + filtersClause + projectClause
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildTracesLogsQuery(operationId string, resources map[string]bool) string {
|
func buildTracesLogsQuery(operationId string, resources []string) string {
|
||||||
types := Tables
|
types := Tables
|
||||||
sort.Strings(types)
|
sort.Strings(types)
|
||||||
selectors := "union " + strings.Join(types, ",\n") + "\n"
|
selectors := "union " + strings.Join(types, ",\n") + "\n"
|
||||||
if len(resources) > 0 {
|
if len(resources) > 0 {
|
||||||
intermediate := make([]string, 0)
|
intermediate := make([]string, 0)
|
||||||
for resource := range resources {
|
for _, resource := range resources {
|
||||||
resourceSplit := strings.SplitAfter(resource, "/")
|
resourceSplit := strings.SplitAfter(resource, "/")
|
||||||
resourceName := resourceSplit[len(resourceSplit)-1]
|
resourceName := resourceSplit[len(resourceSplit)-1]
|
||||||
for _, table := range types {
|
for _, table := range types {
|
||||||
|
|||||||
@@ -1223,6 +1223,7 @@ func TestLogAnalyticsCreateRequest(t *testing.T) {
|
|||||||
req, err := ds.createRequest(ctx, logger, url, &AzureLogAnalyticsQuery{
|
req, err := ds.createRequest(ctx, logger, url, &AzureLogAnalyticsQuery{
|
||||||
Resources: []string{"r1", "r2"},
|
Resources: []string{"r1", "r2"},
|
||||||
Query: "Perf",
|
Query: "Perf",
|
||||||
|
QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics),
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
expectedBody := `{"query":"Perf","timespan":"0001-01-01T00:00:00Z/0001-01-01T00:00:00Z","workspaces":["r1","r2"]}`
|
expectedBody := `{"query":"Perf","timespan":"0001-01-01T00:00:00Z/0001-01-01T00:00:00Z","workspaces":["r1","r2"]}`
|
||||||
@@ -1240,6 +1241,7 @@ func TestLogAnalyticsCreateRequest(t *testing.T) {
|
|||||||
req, err := ds.createRequest(ctx, logger, url, &AzureLogAnalyticsQuery{
|
req, err := ds.createRequest(ctx, logger, url, &AzureLogAnalyticsQuery{
|
||||||
Resources: []string{"r1", "r2"},
|
Resources: []string{"r1", "r2"},
|
||||||
Query: "Perf",
|
Query: "Perf",
|
||||||
|
QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics),
|
||||||
TimeRange: backend.TimeRange{
|
TimeRange: backend.TimeRange{
|
||||||
From: from,
|
From: from,
|
||||||
To: to,
|
To: to,
|
||||||
@@ -1253,6 +1255,27 @@ func TestLogAnalyticsCreateRequest(t *testing.T) {
|
|||||||
t.Errorf("Unexpected Body: %v", cmp.Diff(string(body), expectedBody))
|
t.Errorf("Unexpected Body: %v", cmp.Diff(string(body), expectedBody))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("does not pass multiple resources for traces queries", func(t *testing.T) {
|
||||||
|
ds := AzureLogAnalyticsDatasource{}
|
||||||
|
from := time.Now()
|
||||||
|
to := from.Add(3 * time.Hour)
|
||||||
|
req, err := ds.createRequest(ctx, logger, url, &AzureLogAnalyticsQuery{
|
||||||
|
Resources: []string{"r1", "r2"},
|
||||||
|
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||||
|
TimeRange: backend.TimeRange{
|
||||||
|
From: from,
|
||||||
|
To: to,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
expectedBody := fmt.Sprintf(`{"query":"","timespan":"%s/%s"}`, from.Format(time.RFC3339), to.Format(time.RFC3339))
|
||||||
|
body, err := io.ReadAll(req.Body)
|
||||||
|
require.NoError(t, err)
|
||||||
|
if !cmp.Equal(string(body), expectedBody) {
|
||||||
|
t.Errorf("Unexpected Body: %v", cmp.Diff(string(body), expectedBody))
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_executeQueryErrorWithDifferentLogAnalyticsCreds(t *testing.T) {
|
func Test_executeQueryErrorWithDifferentLogAnalyticsCreds(t *testing.T) {
|
||||||
|
|||||||
Reference in New Issue
Block a user