From 49e6bf26b34f61e2658a25cccedeab28aa523490 Mon Sep 17 00:00:00 2001 From: Andreas Christou Date: Fri, 10 May 2024 17:11:54 +0100 Subject: [PATCH] AzureMonitor: Refactor Log Analytics backend (#87429) * Remove unneeded error check * Refactor to reduce cyclomatic complexity * Add util function for parsing resultformat * Make use of util * Remove unneeded types * Move types to their own file * Move getApiUrl to utils * Move traces functions to separate file - Add separate helper for building trace string queries * Add helper for determining resources * Add test for RetrieveResources * Don't append twice * Refactor tests --- .../azure-log-analytics-datasource.go | 410 +---- .../azure-log-analytics-datasource_test.go | 1358 ++--------------- pkg/tsdb/azuremonitor/loganalytics/traces.go | 255 ++++ .../azuremonitor/loganalytics/traces_test.go | 1160 ++++++++++++++ pkg/tsdb/azuremonitor/loganalytics/types.go | 75 + pkg/tsdb/azuremonitor/loganalytics/utils.go | 57 + .../azuremonitor/loganalytics/utils_test.go | 101 ++ pkg/tsdb/azuremonitor/types/types.go | 6 - 8 files changed, 1824 insertions(+), 1598 deletions(-) create mode 100644 pkg/tsdb/azuremonitor/loganalytics/traces.go create mode 100644 pkg/tsdb/azuremonitor/loganalytics/traces_test.go create mode 100644 pkg/tsdb/azuremonitor/loganalytics/types.go create mode 100644 pkg/tsdb/azuremonitor/loganalytics/utils_test.go diff --git a/pkg/tsdb/azuremonitor/loganalytics/azure-log-analytics-datasource.go b/pkg/tsdb/azuremonitor/loganalytics/azure-log-analytics-datasource.go index cdfdc6a147d..09ee29e1c1d 100644 --- a/pkg/tsdb/azuremonitor/loganalytics/azure-log-analytics-datasource.go +++ b/pkg/tsdb/azuremonitor/loganalytics/azure-log-analytics-datasource.go @@ -12,48 +12,20 @@ import ( "net/url" "path" "regexp" - "sort" "strings" "time" "github.com/grafana/grafana-plugin-sdk-go/backend" - "github.com/grafana/grafana-plugin-sdk-go/backend/log" "github.com/grafana/grafana-plugin-sdk-go/backend/tracing" "github.com/grafana/grafana-plugin-sdk-go/data" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" - "k8s.io/utils/strings/slices" "github.com/grafana/grafana/pkg/tsdb/azuremonitor/kinds/dataquery" "github.com/grafana/grafana/pkg/tsdb/azuremonitor/macros" "github.com/grafana/grafana/pkg/tsdb/azuremonitor/types" ) -// AzureLogAnalyticsDatasource calls the Azure Log Analytics API's -type AzureLogAnalyticsDatasource struct { - Proxy types.ServiceProxy - Logger log.Logger -} - -// AzureLogAnalyticsQuery is the query request that is built from the saved values for -// from the UI -type AzureLogAnalyticsQuery struct { - RefID string - ResultFormat dataquery.ResultFormat - URL string - TraceExploreQuery string - TraceParentExploreQuery string - TraceLogsExploreQuery string - JSON json.RawMessage - TimeRange backend.TimeRange - Query string - Resources []string - QueryType dataquery.AzureQueryType - AppInsightsQuery bool - DashboardTime bool - TimeColumn string -} - func (e *AzureLogAnalyticsDatasource) ResourceRequest(rw http.ResponseWriter, req *http.Request, cli *http.Client) (http.ResponseWriter, error) { return e.Proxy.Do(rw, req, cli) } @@ -81,18 +53,59 @@ func (e *AzureLogAnalyticsDatasource) ExecuteTimeSeriesQuery(ctx context.Context return result, nil } -func getApiURL(resourceOrWorkspace string, isAppInsightsQuery bool) string { - matchesResourceURI, _ := regexp.MatchString("^/subscriptions/", resourceOrWorkspace) - - if matchesResourceURI { - if isAppInsightsQuery { - componentName := resourceOrWorkspace[strings.LastIndex(resourceOrWorkspace, "/")+1:] - return fmt.Sprintf("v1/apps/%s/query", componentName) - } - return fmt.Sprintf("v1%s/query", resourceOrWorkspace) - } else { - return fmt.Sprintf("v1/workspaces/%s/query", resourceOrWorkspace) +func buildLogAnalyticsQuery(query backend.DataQuery, dsInfo types.DatasourceInfo, appInsightsRegExp *regexp.Regexp) (*AzureLogAnalyticsQuery, error) { + queryJSONModel := types.LogJSONQuery{} + err := json.Unmarshal(query.JSON, &queryJSONModel) + if err != nil { + return nil, fmt.Errorf("failed to decode the Azure Log Analytics query object from JSON: %w", err) } + var queryString string + appInsightsQuery := false + dashboardTime := false + timeColumn := "" + azureLogAnalyticsTarget := queryJSONModel.AzureLogAnalytics + + resultFormat := ParseResultFormat(azureLogAnalyticsTarget.ResultFormat, dataquery.AzureQueryTypeAzureLogAnalytics) + + resources, resourceOrWorkspace := retrieveResources(azureLogAnalyticsTarget) + appInsightsQuery = appInsightsRegExp.Match([]byte(resourceOrWorkspace)) + + if azureLogAnalyticsTarget.Query != nil { + queryString = *azureLogAnalyticsTarget.Query + } + + if azureLogAnalyticsTarget.DashboardTime != nil { + dashboardTime = *azureLogAnalyticsTarget.DashboardTime + if dashboardTime { + if azureLogAnalyticsTarget.TimeColumn != nil { + timeColumn = *azureLogAnalyticsTarget.TimeColumn + } else { + // Final fallback to TimeGenerated if no column is provided + timeColumn = "TimeGenerated" + } + } + } + + apiURL := getApiURL(resourceOrWorkspace, appInsightsQuery) + + rawQuery, err := macros.KqlInterpolate(query, dsInfo, queryString, "TimeGenerated") + if err != nil { + return nil, err + } + + return &AzureLogAnalyticsQuery{ + RefID: query.RefID, + ResultFormat: resultFormat, + URL: apiURL, + JSON: query.JSON, + TimeRange: query.TimeRange, + Query: rawQuery, + Resources: resources, + QueryType: dataquery.AzureQueryType(query.QueryType), + AppInsightsQuery: appInsightsQuery, + DashboardTime: dashboardTime, + TimeColumn: timeColumn, + }, nil } func (e *AzureLogAnalyticsDatasource) buildQueries(ctx context.Context, queries []backend.DataQuery, dsInfo types.DatasourceInfo) ([]*AzureLogAnalyticsQuery, error) { @@ -103,161 +116,21 @@ func (e *AzureLogAnalyticsDatasource) buildQueries(ctx context.Context, queries } for _, query := range queries { - resources := []string{} - var resourceOrWorkspace string - var queryString string - var resultFormat dataquery.ResultFormat - appInsightsQuery := false - traceExploreQuery := "" - traceParentExploreQuery := "" - traceLogsExploreQuery := "" - dashboardTime := false - timeColumn := "" if query.QueryType == string(dataquery.AzureQueryTypeAzureLogAnalytics) { - queryJSONModel := types.LogJSONQuery{} - err := json.Unmarshal(query.JSON, &queryJSONModel) + azureLogAnalyticsQuery, err := buildLogAnalyticsQuery(query, dsInfo, appInsightsRegExp) if err != nil { - return nil, fmt.Errorf("failed to decode the Azure Log Analytics query object from JSON: %w", err) - } - - azureLogAnalyticsTarget := queryJSONModel.AzureLogAnalytics - - if azureLogAnalyticsTarget.ResultFormat != nil { - resultFormat = *azureLogAnalyticsTarget.ResultFormat - } - if resultFormat == "" { - resultFormat = types.TimeSeries - } - - // Legacy queries only specify a Workspace GUID, which we need to use the old workspace-centric - // API URL for, and newer queries specifying a resource URI should use resource-centric API. - // However, legacy workspace queries using a `workspaces()` template variable will be resolved - // to a resource URI, so they should use the new resource-centric. - if len(azureLogAnalyticsTarget.Resources) > 0 { - resources = azureLogAnalyticsTarget.Resources - resourceOrWorkspace = azureLogAnalyticsTarget.Resources[0] - appInsightsQuery = appInsightsRegExp.Match([]byte(resourceOrWorkspace)) - } else if azureLogAnalyticsTarget.Resource != nil && *azureLogAnalyticsTarget.Resource != "" { - resources = []string{*azureLogAnalyticsTarget.Resource} - resourceOrWorkspace = *azureLogAnalyticsTarget.Resource - } else if azureLogAnalyticsTarget.Workspace != nil { - resourceOrWorkspace = *azureLogAnalyticsTarget.Workspace - } - - if azureLogAnalyticsTarget.Query != nil { - queryString = *azureLogAnalyticsTarget.Query - } - - if azureLogAnalyticsTarget.DashboardTime != nil { - dashboardTime = *azureLogAnalyticsTarget.DashboardTime - if dashboardTime { - if azureLogAnalyticsTarget.TimeColumn != nil { - timeColumn = *azureLogAnalyticsTarget.TimeColumn - } else { - // Final fallback to TimeGenerated if no column is provided - timeColumn = "TimeGenerated" - } - } + return nil, fmt.Errorf("failed to build azure log analytics query: %w", err) } + azureLogAnalyticsQueries = append(azureLogAnalyticsQueries, azureLogAnalyticsQuery) } if query.QueryType == string(dataquery.AzureQueryTypeAzureTraces) { - queryJSONModel := types.TracesJSONQuery{} - err := json.Unmarshal(query.JSON, &queryJSONModel) + azureAppInsightsQuery, err := buildAppInsightsQuery(ctx, query, dsInfo, appInsightsRegExp) if err != nil { - return nil, fmt.Errorf("failed to decode the Azure Traces query object from JSON: %w", err) + return nil, fmt.Errorf("failed to build azure application insights query: %w", err) } - - azureTracesTarget := queryJSONModel.AzureTraces - - if azureTracesTarget.ResultFormat == nil { - resultFormat = types.Table - } else { - resultFormat = *azureTracesTarget.ResultFormat - if resultFormat == "" { - resultFormat = types.Table - } - } - - resources = azureTracesTarget.Resources - resourceOrWorkspace = azureTracesTarget.Resources[0] - appInsightsQuery = appInsightsRegExp.Match([]byte(resourceOrWorkspace)) - resourcesMap := make(map[string]bool, 0) - if len(resources) > 1 { - for _, resource := range resources { - resourcesMap[strings.ToLower(resource)] = true - } - // Remove the base resource as that's where the query is run anyway - delete(resourcesMap, strings.ToLower(resourceOrWorkspace)) - } - - operationId := "" - if queryJSONModel.AzureTraces.OperationId != nil && *queryJSONModel.AzureTraces.OperationId != "" { - operationId = *queryJSONModel.AzureTraces.OperationId - resourcesMap, err = getCorrelationWorkspaces(ctx, resourceOrWorkspace, resourcesMap, dsInfo, operationId) - if err != nil { - return nil, fmt.Errorf("failed to retrieve correlation resources for operation ID - %s: %s", operationId, err) - } - } - - queryResources := make([]string, 0) - for resource := range resourcesMap { - queryResources = append(queryResources, resource) - } - sort.Strings(queryResources) - - queryString = buildTracesQuery(operationId, nil, queryJSONModel.AzureTraces.TraceTypes, queryJSONModel.AzureTraces.Filters, &resultFormat, queryResources) - traceIdVariable := "${__data.fields.traceID}" - parentSpanIdVariable := "${__data.fields.parentSpanID}" - if operationId == "" { - traceExploreQuery = buildTracesQuery(traceIdVariable, nil, queryJSONModel.AzureTraces.TraceTypes, queryJSONModel.AzureTraces.Filters, &resultFormat, queryResources) - traceParentExploreQuery = buildTracesQuery(traceIdVariable, &parentSpanIdVariable, queryJSONModel.AzureTraces.TraceTypes, queryJSONModel.AzureTraces.Filters, &resultFormat, queryResources) - traceLogsExploreQuery = buildTracesLogsQuery(traceIdVariable, queryResources) - } else { - traceExploreQuery = queryString - traceParentExploreQuery = buildTracesQuery(operationId, &parentSpanIdVariable, queryJSONModel.AzureTraces.TraceTypes, queryJSONModel.AzureTraces.Filters, &resultFormat, queryResources) - traceLogsExploreQuery = buildTracesLogsQuery(operationId, queryResources) - } - traceExploreQuery, err = macros.KqlInterpolate(query, dsInfo, traceExploreQuery, "TimeGenerated") - if err != nil { - return nil, fmt.Errorf("failed to create traces explore query: %s", err) - } - traceParentExploreQuery, err = macros.KqlInterpolate(query, dsInfo, traceParentExploreQuery, "TimeGenerated") - if err != nil { - return nil, fmt.Errorf("failed to create parent span traces explore query: %s", err) - } - traceLogsExploreQuery, err = macros.KqlInterpolate(query, dsInfo, traceLogsExploreQuery, "TimeGenerated") - if err != nil { - return nil, fmt.Errorf("failed to create traces logs explore query: %s", err) - } - - dashboardTime = true - timeColumn = "timestamp" + azureLogAnalyticsQueries = append(azureLogAnalyticsQueries, azureAppInsightsQuery) } - - apiURL := getApiURL(resourceOrWorkspace, appInsightsQuery) - - rawQuery, err := macros.KqlInterpolate(query, dsInfo, queryString, "TimeGenerated") - if err != nil { - return nil, err - } - - azureLogAnalyticsQueries = append(azureLogAnalyticsQueries, &AzureLogAnalyticsQuery{ - RefID: query.RefID, - ResultFormat: resultFormat, - URL: apiURL, - JSON: query.JSON, - TimeRange: query.TimeRange, - Query: rawQuery, - Resources: resources, - QueryType: dataquery.AzureQueryType(query.QueryType), - TraceExploreQuery: traceExploreQuery, - TraceParentExploreQuery: traceParentExploreQuery, - TraceLogsExploreQuery: traceLogsExploreQuery, - AppInsightsQuery: appInsightsQuery, - DashboardTime: dashboardTime, - TimeColumn: timeColumn, - }) } return azureLogAnalyticsQueries, nil @@ -347,7 +220,7 @@ func (e *AzureLogAnalyticsDatasource) executeQuery(ctx context.Context, query *A } } - if query.ResultFormat == types.TimeSeries { + if query.ResultFormat == dataquery.ResultFormatTimeSeries { tsSchema := frame.TimeSeriesSchema() if tsSchema.Type == data.TimeSeriesTypeLong { wideFrame, err := data.LongToWide(frame, nil) @@ -527,12 +400,7 @@ func getQueryUrl(query string, resources []string, azurePortalUrl string, timeRa return "", fmt.Errorf("failed to encode the query: %s", err) } - portalUrl := azurePortalUrl - if err != nil { - return "", fmt.Errorf("failed to parse base portal URL: %s", err) - } - - portalUrl += "/#blade/Microsoft_OperationsManagementSuite_Workspace/AnalyticsBlade/initiator/AnalyticsShareLinkToQuery/isQueryEditorVisible/true/scope/" + portalUrl := azurePortalUrl + "/#blade/Microsoft_OperationsManagementSuite_Workspace/AnalyticsBlade/initiator/AnalyticsShareLinkToQuery/isQueryEditorVisible/true/scope/" resourcesJson := AzureLogAnalyticsURLResources{ Resources: make([]AzureLogAnalyticsURLResource, 0), } @@ -660,46 +528,6 @@ func getCorrelationWorkspaces(ctx context.Context, baseResource string, resource return resourcesMap, nil } -// Error definition has been inferred from real data and other model definitions like -// https://github.com/Azure/azure-sdk-for-go/blob/3640559afddbad452d265b54fb1c20b30be0b062/services/preview/virtualmachineimagebuilder/mgmt/2019-05-01-preview/virtualmachineimagebuilder/models.go -type AzureLogAnalyticsAPIError struct { - Details *[]AzureLogAnalyticsAPIErrorBase `json:"details,omitempty"` - Code *string `json:"code,omitempty"` - Message *string `json:"message,omitempty"` -} - -type AzureLogAnalyticsAPIErrorBase struct { - Code *string `json:"code,omitempty"` - Message *string `json:"message,omitempty"` - Innererror *AzureLogAnalyticsInnerError `json:"innererror,omitempty"` -} - -type AzureLogAnalyticsInnerError struct { - Code *string `json:"code,omitempty"` - Message *string `json:"message,omitempty"` - Severity *int `json:"severity,omitempty"` - SeverityName *string `json:"severityName,omitempty"` -} - -// AzureLogAnalyticsResponse is the json response object from the Azure Log Analytics API. -type AzureLogAnalyticsResponse struct { - Tables []types.AzureResponseTable `json:"tables"` - Error *AzureLogAnalyticsAPIError `json:"error,omitempty"` -} - -type AzureCorrelationAPIResponse struct { - ID string `json:"id"` - Name string `json:"name"` - Type string `json:"type"` - Properties AzureCorrelationAPIResponseProperties `json:"properties"` - Error *AzureLogAnalyticsAPIError `json:"error,omitempty"` -} - -type AzureCorrelationAPIResponseProperties struct { - Resources []string `json:"resources"` - NextLink *string `json:"nextLink,omitempty"` -} - // GetPrimaryResultTable returns the first table in the response named "PrimaryResult", or an // error if there is no table by that name. func (ar *AzureLogAnalyticsResponse) GetPrimaryResultTable() (*types.AzureResponseTable, error) { @@ -757,121 +585,3 @@ func encodeQuery(rawQuery string) (string, error) { return base64.StdEncoding.EncodeToString(b.Bytes()), nil } - -func buildTracesQuery(operationId string, parentSpanID *string, traceTypes []string, filters []dataquery.AzureTracesFilter, resultFormat *dataquery.ResultFormat, resources []string) string { - types := traceTypes - if len(types) == 0 { - types = Tables - } - - filteredTypes := make([]string, 0) - // If the result format is set to trace then we filter out all events that are of the type traces as they don't make sense when visualised as a span - if resultFormat != nil && *resultFormat == dataquery.ResultFormatTrace { - filteredTypes = slices.Filter(filteredTypes, types, func(s string) bool { return s != "traces" }) - } else { - filteredTypes = types - } - sort.Strings(filteredTypes) - - if len(filteredTypes) == 0 { - return "" - } - - resourcesQuery := strings.Join(filteredTypes, ",") - if len(resources) > 0 { - intermediate := make([]string, 0) - for _, resource := range resources { - for _, table := range filteredTypes { - intermediate = append(intermediate, fmt.Sprintf("app('%s').%s", resource, table)) - } - } - resourcesQuery += "," + strings.Join(intermediate, ",") - } - - tagsMap := make(map[string]bool) - var tags []string - for _, t := range filteredTypes { - tableTags := getTagsForTable(t) - for _, i := range tableTags { - if tagsMap[i] { - continue - } - if i == "cloud_RoleInstance" || i == "cloud_RoleName" || i == "customDimensions" || i == "customMeasurements" { - continue - } - tags = append(tags, i) - tagsMap[i] = true - } - } - sort.Strings(tags) - - whereClause := "" - - if operationId != "" { - whereClause = fmt.Sprintf("| where (operation_Id != '' and operation_Id == '%s') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == '%s')", operationId, operationId) - } - - parentWhereClause := "" - if parentSpanID != nil && *parentSpanID != "" { - parentWhereClause = fmt.Sprintf("| where (operation_ParentId != '' and operation_ParentId == '%s')", *parentSpanID) - } - - filtersClause := "" - - if len(filters) > 0 { - for _, filter := range filters { - if len(filter.Filters) == 0 { - continue - } - operation := "in" - if filter.Operation == "ne" { - operation = "!in" - } - filterValues := []string{} - for _, val := range filter.Filters { - filterValues = append(filterValues, fmt.Sprintf(`"%s"`, val)) - } - filtersClause += fmt.Sprintf("| where %s %s (%s)", filter.Property, operation, strings.Join(filterValues, ",")) - } - } - - propertiesFunc := "bag_merge(customDimensions, customMeasurements)" - if len(tags) > 0 { - propertiesFunc = fmt.Sprintf("bag_merge(bag_pack_columns(%s), customDimensions, customMeasurements)", strings.Join(tags, ",")) - } - - errorProperty := `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` - - baseQuery := fmt.Sprintf(`set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true %s`, resourcesQuery) - propertiesStaticQuery := `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` - propertiesQuery := fmt.Sprintf(`| extend tags = %s`, propertiesFunc) - projectClause := `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc` - return baseQuery + whereClause + parentWhereClause + propertiesStaticQuery + errorProperty + propertiesQuery + filtersClause + projectClause -} - -func buildTracesLogsQuery(operationId string, resources []string) string { - types := Tables - sort.Strings(types) - selectors := "union " + strings.Join(types, ",\n") + "\n" - if len(resources) > 0 { - intermediate := make([]string, 0) - for _, resource := range resources { - for _, table := range types { - intermediate = append(intermediate, fmt.Sprintf("app('%s').%s", resource, table)) - } - } - sort.Strings(intermediate) - types = intermediate - selectors = strings.Join(append([]string{"union *"}, types...), ",\n") + "\n" - } - - query := selectors - query += fmt.Sprintf(`| where operation_Id == "%s"`, operationId) - return query -} diff --git a/pkg/tsdb/azuremonitor/loganalytics/azure-log-analytics-datasource_test.go b/pkg/tsdb/azuremonitor/loganalytics/azure-log-analytics-datasource_test.go index 56e56a545bb..adaa1e840d9 100644 --- a/pkg/tsdb/azuremonitor/loganalytics/azure-log-analytics-datasource_test.go +++ b/pkg/tsdb/azuremonitor/loganalytics/azure-log-analytics-datasource_test.go @@ -7,6 +7,7 @@ import ( "io" "net/http" "net/http/httptest" + "regexp" "strings" "testing" "time" @@ -20,11 +21,9 @@ import ( "github.com/grafana/grafana/pkg/tsdb/azuremonitor/types" ) -func TestBuildingAzureLogAnalyticsQueries(t *testing.T) { - datasource := &AzureLogAnalyticsDatasource{} +func TestBuildLogAnalyticsQuery(t *testing.T) { fromStart := time.Date(2018, 3, 15, 13, 0, 0, 0, time.UTC).In(time.Local) timeRange := backend.TimeRange{From: fromStart, To: fromStart.Add(34 * time.Minute)} - ctx := context.Background() svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -89,17 +88,21 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) { }, } + appInsightsRegExp, err := regexp.Compile("providers/Microsoft.Insights/components") + if err != nil { + t.Error("failed to compile reg: %w", err) + } + tests := []struct { - name string - queryModel []backend.DataQuery - azureLogAnalyticsQueries []*AzureLogAnalyticsQuery - Err require.ErrorAssertionFunc + name string + queryModel backend.DataQuery + azureLogAnalyticsQuery AzureLogAnalyticsQuery + Err require.ErrorAssertionFunc }{ { name: "Query with macros should be interpolated", - queryModel: []backend.DataQuery{ - { - JSON: []byte(fmt.Sprintf(`{ + queryModel: backend.DataQuery{ + JSON: []byte(fmt.Sprintf(`{ "queryType": "Azure Log Analytics", "azureLogAnalytics": { "resource": "/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace", @@ -107,18 +110,16 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) { "resultFormat": "%s", "dashboardTime": false } - }`, types.TimeSeries)), - RefID: "A", - TimeRange: timeRange, - QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics), - }, + }`, dataquery.ResultFormatTimeSeries)), + RefID: "A", + TimeRange: timeRange, + QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics), }, - azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{ - { - RefID: "A", - ResultFormat: types.TimeSeries, - URL: "v1/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace/query", - JSON: []byte(fmt.Sprintf(`{ + azureLogAnalyticsQuery: AzureLogAnalyticsQuery{ + RefID: "A", + ResultFormat: dataquery.ResultFormatTimeSeries, + URL: "v1/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace/query", + JSON: []byte(fmt.Sprintf(`{ "queryType": "Azure Log Analytics", "azureLogAnalytics": { "resource": "/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace", @@ -126,98 +127,88 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) { "resultFormat": "%s", "dashboardTime": false } - }`, types.TimeSeries)), - Query: "Perf | where ['TimeGenerated'] >= datetime('2018-03-15T13:00:00Z') and ['TimeGenerated'] <= datetime('2018-03-15T13:34:00Z') | where ['Computer'] in ('comp1','comp2') | summarize avg(CounterValue) by bin(TimeGenerated, 34000ms), Computer", - Resources: []string{"/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace"}, - TimeRange: timeRange, - QueryType: dataquery.AzureQueryTypeAzureLogAnalytics, - AppInsightsQuery: false, - DashboardTime: false, - }, + }`, dataquery.ResultFormatTimeSeries)), + Query: "Perf | where ['TimeGenerated'] >= datetime('2018-03-15T13:00:00Z') and ['TimeGenerated'] <= datetime('2018-03-15T13:34:00Z') | where ['Computer'] in ('comp1','comp2') | summarize avg(CounterValue) by bin(TimeGenerated, 34000ms), Computer", + Resources: []string{"/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace"}, + TimeRange: timeRange, + QueryType: dataquery.AzureQueryTypeAzureLogAnalytics, + AppInsightsQuery: false, + DashboardTime: false, }, Err: require.NoError, }, { name: "Legacy queries with a workspace GUID should use workspace-centric url", - queryModel: []backend.DataQuery{ - { - JSON: []byte(fmt.Sprintf(`{ + queryModel: backend.DataQuery{ + JSON: []byte(fmt.Sprintf(`{ "queryType": "Azure Log Analytics", "azureLogAnalytics": { "workspace": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", "query": "Perf", "resultFormat": "%s" } - }`, types.TimeSeries)), - RefID: "A", - QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics), - }, + }`, dataquery.ResultFormatTimeSeries)), + RefID: "A", + QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics), }, - azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{ - { - RefID: "A", - ResultFormat: types.TimeSeries, - URL: "v1/workspaces/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/query", - JSON: []byte(fmt.Sprintf(`{ + azureLogAnalyticsQuery: AzureLogAnalyticsQuery{ + RefID: "A", + ResultFormat: dataquery.ResultFormatTimeSeries, + URL: "v1/workspaces/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/query", + JSON: []byte(fmt.Sprintf(`{ "queryType": "Azure Log Analytics", "azureLogAnalytics": { "workspace": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", "query": "Perf", "resultFormat": "%s" } - }`, types.TimeSeries)), - Query: "Perf", - Resources: []string{}, - QueryType: dataquery.AzureQueryTypeAzureLogAnalytics, - AppInsightsQuery: false, - DashboardTime: false, - }, + }`, dataquery.ResultFormatTimeSeries)), + Query: "Perf", + Resources: []string{}, + QueryType: dataquery.AzureQueryTypeAzureLogAnalytics, + AppInsightsQuery: false, + DashboardTime: false, }, Err: require.NoError, }, { name: "Legacy workspace queries with a resource URI (from a template variable) should use resource-centric url", - queryModel: []backend.DataQuery{ - { - JSON: []byte(fmt.Sprintf(`{ + queryModel: backend.DataQuery{ + JSON: []byte(fmt.Sprintf(`{ "queryType": "Azure Log Analytics", "azureLogAnalytics": { "workspace": "/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace", "query": "Perf", "resultFormat": "%s" } - }`, types.TimeSeries)), - RefID: "A", - QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics), - }, + }`, dataquery.ResultFormatTimeSeries)), + RefID: "A", + QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics), }, - azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{ - { - RefID: "A", - ResultFormat: types.TimeSeries, - URL: "v1/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace/query", - JSON: []byte(fmt.Sprintf(`{ + azureLogAnalyticsQuery: AzureLogAnalyticsQuery{ + RefID: "A", + ResultFormat: dataquery.ResultFormatTimeSeries, + URL: "v1/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace/query", + JSON: []byte(fmt.Sprintf(`{ "queryType": "Azure Log Analytics", "azureLogAnalytics": { "workspace": "/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace", "query": "Perf", "resultFormat": "%s" } - }`, types.TimeSeries)), - Query: "Perf", - Resources: []string{}, - QueryType: dataquery.AzureQueryTypeAzureLogAnalytics, - AppInsightsQuery: false, - DashboardTime: false, - }, + }`, dataquery.ResultFormatTimeSeries)), + Query: "Perf", + Resources: []string{}, + QueryType: dataquery.AzureQueryTypeAzureLogAnalytics, + AppInsightsQuery: false, + DashboardTime: false, }, Err: require.NoError, }, { name: "Queries with multiple resources", - queryModel: []backend.DataQuery{ - { - JSON: []byte(fmt.Sprintf(`{ + queryModel: backend.DataQuery{ + JSON: []byte(fmt.Sprintf(`{ "queryType": "Azure Log Analytics", "azureLogAnalytics": { "resource": "/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace", @@ -225,17 +216,15 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) { "resultFormat": "%s", "dashboardTime": false } - }`, types.TimeSeries)), - RefID: "A", - QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics), - }, + }`, dataquery.ResultFormatTimeSeries)), + RefID: "A", + QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics), }, - azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{ - { - RefID: "A", - ResultFormat: types.TimeSeries, - URL: "v1/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace/query", - JSON: []byte(fmt.Sprintf(`{ + azureLogAnalyticsQuery: AzureLogAnalyticsQuery{ + RefID: "A", + ResultFormat: dataquery.ResultFormatTimeSeries, + URL: "v1/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace/query", + JSON: []byte(fmt.Sprintf(`{ "queryType": "Azure Log Analytics", "azureLogAnalytics": { "resource": "/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace", @@ -243,21 +232,19 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) { "resultFormat": "%s", "dashboardTime": false } - }`, types.TimeSeries)), - Query: "Perf", - Resources: []string{"/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace"}, - QueryType: dataquery.AzureQueryTypeAzureLogAnalytics, - AppInsightsQuery: false, - DashboardTime: false, - }, + }`, dataquery.ResultFormatTimeSeries)), + Query: "Perf", + Resources: []string{"/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace"}, + QueryType: dataquery.AzureQueryTypeAzureLogAnalytics, + AppInsightsQuery: false, + DashboardTime: false, }, Err: require.NoError, }, { name: "Query with multiple resources", - queryModel: []backend.DataQuery{ - { - JSON: []byte(fmt.Sprintf(`{ + queryModel: backend.DataQuery{ + JSON: []byte(fmt.Sprintf(`{ "queryType": "Azure Log Analytics", "azureLogAnalytics": { "resources": ["/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace", "/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace2"], @@ -265,18 +252,16 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) { "resultFormat": "%s", "dashboardTime": false } - }`, types.TimeSeries)), - RefID: "A", - TimeRange: timeRange, - QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics), - }, + }`, dataquery.ResultFormatTimeSeries)), + RefID: "A", + TimeRange: timeRange, + QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics), }, - azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{ - { - RefID: "A", - ResultFormat: types.TimeSeries, - URL: "v1/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace/query", - JSON: []byte(fmt.Sprintf(`{ + azureLogAnalyticsQuery: AzureLogAnalyticsQuery{ + RefID: "A", + ResultFormat: dataquery.ResultFormatTimeSeries, + URL: "v1/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace/query", + JSON: []byte(fmt.Sprintf(`{ "queryType": "Azure Log Analytics", "azureLogAnalytics": { "resources": ["/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace", "/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace2"], @@ -284,22 +269,20 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) { "resultFormat": "%s", "dashboardTime": false } - }`, types.TimeSeries)), - Query: "Perf", - Resources: []string{"/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace", "/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace2"}, - TimeRange: timeRange, - QueryType: dataquery.AzureQueryTypeAzureLogAnalytics, - AppInsightsQuery: false, - DashboardTime: false, - }, + }`, dataquery.ResultFormatTimeSeries)), + Query: "Perf", + Resources: []string{"/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace", "/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace2"}, + TimeRange: timeRange, + QueryType: dataquery.AzureQueryTypeAzureLogAnalytics, + AppInsightsQuery: false, + DashboardTime: false, }, Err: require.NoError, }, { name: "Query that uses dashboard time", - queryModel: []backend.DataQuery{ - { - JSON: []byte(fmt.Sprintf(`{ + queryModel: backend.DataQuery{ + JSON: []byte(fmt.Sprintf(`{ "queryType": "Azure Log Analytics", "azureLogAnalytics": { "resources": ["/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace"], @@ -308,18 +291,16 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) { "dashboardTime": true, "timeColumn": "TimeGenerated" } - }`, types.TimeSeries)), - RefID: "A", - TimeRange: timeRange, - QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics), - }, + }`, dataquery.ResultFormatTimeSeries)), + RefID: "A", + TimeRange: timeRange, + QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics), }, - azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{ - { - RefID: "A", - ResultFormat: types.TimeSeries, - URL: "v1/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace/query", - JSON: []byte(fmt.Sprintf(`{ + azureLogAnalyticsQuery: AzureLogAnalyticsQuery{ + RefID: "A", + ResultFormat: dataquery.ResultFormatTimeSeries, + URL: "v1/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace/query", + JSON: []byte(fmt.Sprintf(`{ "queryType": "Azure Log Analytics", "azureLogAnalytics": { "resources": ["/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace"], @@ -328,1121 +309,14 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) { "dashboardTime": true, "timeColumn": "TimeGenerated" } - }`, types.TimeSeries)), - Query: "Perf", - Resources: []string{"/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace"}, - TimeRange: timeRange, - QueryType: dataquery.AzureQueryTypeAzureLogAnalytics, - AppInsightsQuery: false, - DashboardTime: true, - TimeColumn: "TimeGenerated", - }, - }, - Err: require.NoError, - }, - - { - name: "trace query", - queryModel: []backend.DataQuery{ - { - JSON: []byte(fmt.Sprintf(`{ - "queryType": "Azure Traces", - "azureTraces": { - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], - "resultFormat": "%s", - "traceTypes": ["trace"], - "operationId": "test-op-id" - } - }`, dataquery.ResultFormatTable)), - RefID: "A", - TimeRange: timeRange, - QueryType: string(dataquery.AzureQueryTypeAzureTraces), - }, - }, - azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{ - { - RefID: "A", - ResultFormat: dataquery.ResultFormatTable, - URL: "v1/apps/r1/query", - JSON: []byte(fmt.Sprintf(`{ - "queryType": "Azure Traces", - "azureTraces": { - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], - "resultFormat": "%s", - "traceTypes": ["trace"], - "operationId": "test-op-id" - } - }`, dataquery.ResultFormatTable)), - Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true trace` + - `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"}, - TimeRange: timeRange, - QueryType: dataquery.AzureQueryTypeAzureTraces, - TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true trace` + - `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - TraceParentExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true trace` + - `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + - `| where (operation_ParentId != '' and operation_ParentId == '${__data.fields.parentSpanID}')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - TraceLogsExploreQuery: "union availabilityResults,\n" + "customEvents,\n" + "dependencies,\n" + "exceptions,\n" + "pageViews,\n" + "requests,\n" + "traces\n" + - "| where operation_Id == \"test-op-id\"", - AppInsightsQuery: true, - DashboardTime: true, - TimeColumn: "timestamp", - }, - }, - Err: require.NoError, - }, - { - name: "trace query with no result format set", - queryModel: []backend.DataQuery{ - { - JSON: []byte(`{ - "queryType": "Azure Traces", - "azureTraces": { - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], - "traceTypes": ["trace"], - "operationId": "test-op-id" - } - }`), - RefID: "A", - TimeRange: timeRange, - QueryType: string(dataquery.AzureQueryTypeAzureTraces), - }, - }, - azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{ - { - RefID: "A", - ResultFormat: dataquery.ResultFormatTable, - URL: "v1/apps/r1/query", - JSON: []byte(`{ - "queryType": "Azure Traces", - "azureTraces": { - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], - "traceTypes": ["trace"], - "operationId": "test-op-id" - } - }`), - Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true trace` + - `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"}, - TimeRange: timeRange, - QueryType: dataquery.AzureQueryTypeAzureTraces, - TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true trace` + - `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - TraceParentExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true trace` + - `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + - `| where (operation_ParentId != '' and operation_ParentId == '${__data.fields.parentSpanID}')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - TraceLogsExploreQuery: "union availabilityResults,\n" + "customEvents,\n" + "dependencies,\n" + "exceptions,\n" + "pageViews,\n" + "requests,\n" + "traces\n" + - "| where operation_Id == \"test-op-id\"", - AppInsightsQuery: true, - DashboardTime: true, - TimeColumn: "timestamp", - }, - }, - Err: require.NoError, - }, - { - name: "trace query with no operation ID", - queryModel: []backend.DataQuery{ - { - JSON: []byte(fmt.Sprintf(`{ - "queryType": "Azure Traces", - "azureTraces": { - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], - "resultFormat": "%s" - } - }`, dataquery.ResultFormatTable)), - RefID: "A", - TimeRange: timeRange, - QueryType: string(dataquery.AzureQueryTypeAzureTraces), - }, - }, - azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{ - { - RefID: "A", - ResultFormat: dataquery.ResultFormatTable, - URL: "v1/apps/r1/query", - JSON: []byte(fmt.Sprintf(`{ - "queryType": "Azure Traces", - "azureTraces": { - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], - "resultFormat": "%s" - } - }`, dataquery.ResultFormatTable)), - Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"}, - TimeRange: timeRange, - QueryType: dataquery.AzureQueryTypeAzureTraces, - TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + - `| where (operation_Id != '' and operation_Id == '${__data.fields.traceID}') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == '${__data.fields.traceID}')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - TraceParentExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + - `| where (operation_Id != '' and operation_Id == '${__data.fields.traceID}') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == '${__data.fields.traceID}')` + - `| where (operation_ParentId != '' and operation_ParentId == '${__data.fields.parentSpanID}')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - TraceLogsExploreQuery: "union availabilityResults,\n" + "customEvents,\n" + "dependencies,\n" + "exceptions,\n" + "pageViews,\n" + "requests,\n" + "traces\n" + - "| where operation_Id == \"${__data.fields.traceID}\"", - AppInsightsQuery: true, - DashboardTime: true, - TimeColumn: "timestamp", - }, - }, - Err: require.NoError, - }, - { - name: "trace query with no types", - queryModel: []backend.DataQuery{ - { - JSON: []byte(fmt.Sprintf(`{ - "queryType": "Azure Traces", - "azureTraces": { - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], - "resultFormat": "%s", - "operationId": "test-op-id" - } - }`, dataquery.ResultFormatTable)), - RefID: "A", - TimeRange: timeRange, - QueryType: string(dataquery.AzureQueryTypeAzureTraces), - }, - }, - azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{ - { - RefID: "A", - ResultFormat: dataquery.ResultFormatTable, - URL: "v1/apps/r1/query", - JSON: []byte(fmt.Sprintf(`{ - "queryType": "Azure Traces", - "azureTraces": { - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], - "resultFormat": "%s", - "operationId": "test-op-id" - } - }`, dataquery.ResultFormatTable)), - Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + - `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"}, - TimeRange: timeRange, - QueryType: dataquery.AzureQueryTypeAzureTraces, - TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + - `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - TraceParentExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + - `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + - `| where (operation_ParentId != '' and operation_ParentId == '${__data.fields.parentSpanID}')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - TraceLogsExploreQuery: "union availabilityResults,\n" + "customEvents,\n" + "dependencies,\n" + "exceptions,\n" + "pageViews,\n" + "requests,\n" + "traces\n" + - "| where operation_Id == \"test-op-id\"", - AppInsightsQuery: true, - DashboardTime: true, - TimeColumn: "timestamp", - }, - }, - Err: require.NoError, - }, - { - name: "trace query with eq filter", - queryModel: []backend.DataQuery{ - { - JSON: []byte(fmt.Sprintf(`{ - "queryType": "Azure Traces", - "azureTraces": { - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], - "resultFormat": "%s", - "operationId": "test-op-id", - "filters": [{"filters": ["test-app-id"], "property": "appId", "operation": "eq"}] - } - }`, dataquery.ResultFormatTable)), - RefID: "A", - TimeRange: timeRange, - QueryType: string(dataquery.AzureQueryTypeAzureTraces), - }, - }, - azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{ - { - RefID: "A", - ResultFormat: dataquery.ResultFormatTable, - URL: "v1/apps/r1/query", - JSON: []byte(fmt.Sprintf(`{ - "queryType": "Azure Traces", - "azureTraces": { - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], - "resultFormat": "%s", - "operationId": "test-op-id", - "filters": [{"filters": ["test-app-id"], "property": "appId", "operation": "eq"}] - } - }`, dataquery.ResultFormatTable)), - Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + - `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| where appId in ("test-app-id")` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"}, - TimeRange: timeRange, - QueryType: dataquery.AzureQueryTypeAzureTraces, - TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + - `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| where appId in ("test-app-id")` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - TraceParentExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + - `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + - `| where (operation_ParentId != '' and operation_ParentId == '${__data.fields.parentSpanID}')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| where appId in ("test-app-id")` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - TraceLogsExploreQuery: "union availabilityResults,\n" + "customEvents,\n" + "dependencies,\n" + "exceptions,\n" + "pageViews,\n" + "requests,\n" + "traces\n" + - "| where operation_Id == \"test-op-id\"", - AppInsightsQuery: true, - DashboardTime: true, - TimeColumn: "timestamp", - }, - }, - Err: require.NoError, - }, - { - name: "trace query with ne filter", - queryModel: []backend.DataQuery{ - { - JSON: []byte(fmt.Sprintf(`{ - "queryType": "Azure Traces", - "azureTraces": { - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], - "resultFormat": "%s", - "operationId": "test-op-id", - "filters": [{"filters": ["test-app-id"], "property": "appId", "operation": "ne"}] - } - }`, dataquery.ResultFormatTable)), - RefID: "A", - TimeRange: timeRange, - QueryType: string(dataquery.AzureQueryTypeAzureTraces), - }, - }, - azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{ - { - RefID: "A", - ResultFormat: dataquery.ResultFormatTable, - URL: "v1/apps/r1/query", - JSON: []byte(fmt.Sprintf(`{ - "queryType": "Azure Traces", - "azureTraces": { - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], - "resultFormat": "%s", - "operationId": "test-op-id", - "filters": [{"filters": ["test-app-id"], "property": "appId", "operation": "ne"}] - } - }`, dataquery.ResultFormatTable)), - Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + - `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| where appId !in ("test-app-id")` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"}, - TimeRange: timeRange, - QueryType: dataquery.AzureQueryTypeAzureTraces, - TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + - `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| where appId !in ("test-app-id")` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - TraceParentExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + - `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + - `| where (operation_ParentId != '' and operation_ParentId == '${__data.fields.parentSpanID}')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| where appId !in ("test-app-id")` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - TraceLogsExploreQuery: "union availabilityResults,\n" + "customEvents,\n" + "dependencies,\n" + "exceptions,\n" + "pageViews,\n" + "requests,\n" + "traces\n" + - "| where operation_Id == \"test-op-id\"", - AppInsightsQuery: true, - DashboardTime: true, - TimeColumn: "timestamp", - }, - }, - Err: require.NoError, - }, - { - name: "trace query with multiple filters", - queryModel: []backend.DataQuery{ - { - JSON: []byte(fmt.Sprintf(`{ - "queryType": "Azure Traces", - "azureTraces": { - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], - "resultFormat": "%s", - "operationId": "test-op-id", - "filters": [{"filters": ["test-app-id"], "property": "appId", "operation": "ne"},{"filters": ["test-client-id"], "property": "clientId", "operation": "eq"}] - } - }`, dataquery.ResultFormatTable)), - RefID: "A", - TimeRange: timeRange, - QueryType: string(dataquery.AzureQueryTypeAzureTraces), - }, - }, - azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{ - { - RefID: "A", - ResultFormat: dataquery.ResultFormatTable, - URL: "v1/apps/r1/query", - JSON: []byte(fmt.Sprintf(`{ - "queryType": "Azure Traces", - "azureTraces": { - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], - "resultFormat": "%s", - "operationId": "test-op-id", - "filters": [{"filters": ["test-app-id"], "property": "appId", "operation": "ne"},{"filters": ["test-client-id"], "property": "clientId", "operation": "eq"}] - } - }`, dataquery.ResultFormatTable)), - Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + - `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| where appId !in ("test-app-id")| where clientId in ("test-client-id")` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"}, - TimeRange: timeRange, - QueryType: dataquery.AzureQueryTypeAzureTraces, - TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + - `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| where appId !in ("test-app-id")| where clientId in ("test-client-id")` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - TraceParentExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + - `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + - `| where (operation_ParentId != '' and operation_ParentId == '${__data.fields.parentSpanID}')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| where appId !in ("test-app-id")| where clientId in ("test-client-id")` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - TraceLogsExploreQuery: "union availabilityResults,\n" + "customEvents,\n" + "dependencies,\n" + "exceptions,\n" + "pageViews,\n" + "requests,\n" + "traces\n" + - "| where operation_Id == \"test-op-id\"", - AppInsightsQuery: true, - DashboardTime: true, - TimeColumn: "timestamp", - }, - }, - Err: require.NoError, - }, - { - name: "trace query with trace result format", - queryModel: []backend.DataQuery{ - { - JSON: []byte(fmt.Sprintf(`{ - "queryType": "Azure Traces", - "azureTraces": { - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], - "resultFormat": "%s" - } - }`, dataquery.ResultFormatTrace)), - RefID: "A", - TimeRange: timeRange, - QueryType: string(dataquery.AzureQueryTypeAzureTraces), - }, - }, - azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{ - { - RefID: "A", - ResultFormat: dataquery.ResultFormatTrace, - URL: "v1/apps/r1/query", - JSON: []byte(fmt.Sprintf(`{ - "queryType": "Azure Traces", - "azureTraces": { - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], - "resultFormat": "%s" - } - }`, dataquery.ResultFormatTrace)), - Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"}, - TimeRange: timeRange, - QueryType: dataquery.AzureQueryTypeAzureTraces, - TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests` + - `| where (operation_Id != '' and operation_Id == '${__data.fields.traceID}') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == '${__data.fields.traceID}')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - TraceParentExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests` + - `| where (operation_Id != '' and operation_Id == '${__data.fields.traceID}') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == '${__data.fields.traceID}')` + - `| where (operation_ParentId != '' and operation_ParentId == '${__data.fields.parentSpanID}')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - TraceLogsExploreQuery: "union availabilityResults,\n" + "customEvents,\n" + "dependencies,\n" + "exceptions,\n" + "pageViews,\n" + "requests,\n" + "traces\n" + - "| where operation_Id == \"${__data.fields.traceID}\"", - AppInsightsQuery: true, - DashboardTime: true, - TimeColumn: "timestamp", - }, - }, - Err: require.NoError, - }, - { - name: "trace query with trace result format and operation ID", - queryModel: []backend.DataQuery{ - { - JSON: []byte(fmt.Sprintf(`{ - "queryType": "Azure Traces", - "azureTraces": { - "operationId": "test-op-id", - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], - "resultFormat": "%s" - } - }`, dataquery.ResultFormatTrace)), - RefID: "A", - TimeRange: timeRange, - QueryType: string(dataquery.AzureQueryTypeAzureTraces), - }, - }, - azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{ - { - RefID: "A", - ResultFormat: dataquery.ResultFormatTrace, - URL: "v1/apps/r1/query", - JSON: []byte(fmt.Sprintf(`{ - "queryType": "Azure Traces", - "azureTraces": { - "operationId": "test-op-id", - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], - "resultFormat": "%s" - } - }`, dataquery.ResultFormatTrace)), - Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests` + - `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"}, - TimeRange: timeRange, - QueryType: dataquery.AzureQueryTypeAzureTraces, - TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests` + - `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - TraceParentExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests` + - `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + - `| where (operation_ParentId != '' and operation_ParentId == '${__data.fields.parentSpanID}')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName` + - `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - TraceLogsExploreQuery: "union availabilityResults,\n" + "customEvents,\n" + "dependencies,\n" + "exceptions,\n" + "pageViews,\n" + "requests,\n" + "traces\n" + - "| where operation_Id == \"test-op-id\"", - AppInsightsQuery: true, - DashboardTime: true, - TimeColumn: "timestamp", - }, - }, - Err: require.NoError, - }, - { - name: "trace query with trace result format and only trace type", - queryModel: []backend.DataQuery{ - { - JSON: []byte(fmt.Sprintf(`{ - "queryType": "Azure Traces", - "azureTraces": { - "operationId": "test-op-id", - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], - "resultFormat": "%s", - "traceTypes": ["traces"] - } - }`, dataquery.ResultFormatTrace)), - RefID: "A", - TimeRange: timeRange, - QueryType: string(dataquery.AzureQueryTypeAzureTraces), - }, - }, - azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{ - { - RefID: "A", - ResultFormat: dataquery.ResultFormatTrace, - URL: "v1/apps/r1/query", - JSON: []byte(fmt.Sprintf(`{ - "queryType": "Azure Traces", - "azureTraces": { - "operationId": "test-op-id", - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], - "resultFormat": "%s", - "traceTypes": ["traces"] - } - }`, dataquery.ResultFormatTrace)), - Query: "", - Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"}, - TimeRange: timeRange, - QueryType: dataquery.AzureQueryTypeAzureTraces, - TraceExploreQuery: "", - TraceParentExploreQuery: "", - TraceLogsExploreQuery: "union availabilityResults,\n" + "customEvents,\n" + "dependencies,\n" + "exceptions,\n" + "pageViews,\n" + "requests,\n" + "traces\n" + - "| where operation_Id == \"test-op-id\"", - AppInsightsQuery: true, - DashboardTime: true, - TimeColumn: "timestamp", - }, - }, - Err: require.NoError, - }, - { - name: "trace query with operation ID and correlated workspaces", - queryModel: []backend.DataQuery{ - { - JSON: []byte(fmt.Sprintf(`{ - "queryType": "Azure Traces", - "azureTraces": { - "operationId": "op-id-multi", - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], - "resultFormat": "%s" - } - }`, dataquery.ResultFormatTrace)), - RefID: "A", - TimeRange: timeRange, - QueryType: string(dataquery.AzureQueryTypeAzureTraces), - }, - }, - azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{ - { - RefID: "A", - ResultFormat: dataquery.ResultFormatTrace, - URL: "v1/apps/r1/query", - JSON: []byte(fmt.Sprintf(`{ - "queryType": "Azure Traces", - "azureTraces": { - "operationId": "op-id-multi", - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], - "resultFormat": "%s" - } - }`, dataquery.ResultFormatTrace)), - Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests` + - `| where (operation_Id != '' and operation_Id == 'op-id-multi') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'op-id-multi')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"}, - TimeRange: timeRange, - QueryType: dataquery.AzureQueryTypeAzureTraces, - TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests` + - `| where (operation_Id != '' and operation_Id == 'op-id-multi') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'op-id-multi')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - TraceParentExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests` + - `| where (operation_Id != '' and operation_Id == 'op-id-multi') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'op-id-multi')` + - `| where (operation_ParentId != '' and operation_ParentId == '${__data.fields.parentSpanID}')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - TraceLogsExploreQuery: "union *,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').traces\n" + - "| where operation_Id == \"op-id-multi\"", - AppInsightsQuery: true, - DashboardTime: true, - TimeColumn: "timestamp", - }, - }, - Err: require.NoError, - }, - { - name: "trace query with multiple resources", - queryModel: []backend.DataQuery{ - { - JSON: []byte(fmt.Sprintf(`{ - "queryType": "Azure Traces", - "azureTraces": { - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1", "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r2"], - "resultFormat": "%s" - } - }`, dataquery.ResultFormatTrace)), - RefID: "A", - TimeRange: timeRange, - QueryType: string(dataquery.AzureQueryTypeAzureTraces), - }, - }, - azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{ - { - RefID: "A", - ResultFormat: dataquery.ResultFormatTrace, - URL: "v1/apps/r1/query", - JSON: []byte(fmt.Sprintf(`{ - "queryType": "Azure Traces", - "azureTraces": { - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1", "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r2"], - "resultFormat": "%s" - } - }`, dataquery.ResultFormatTrace)), - Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1", "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r2"}, - TimeRange: timeRange, - QueryType: dataquery.AzureQueryTypeAzureTraces, - TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests` + - `| where (operation_Id != '' and operation_Id == '${__data.fields.traceID}') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == '${__data.fields.traceID}')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - TraceParentExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests` + - `| where (operation_Id != '' and operation_Id == '${__data.fields.traceID}') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == '${__data.fields.traceID}')` + - `| where (operation_ParentId != '' and operation_ParentId == '${__data.fields.parentSpanID}')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - TraceLogsExploreQuery: "union *,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').traces\n" + - "| where operation_Id == \"${__data.fields.traceID}\"", - AppInsightsQuery: true, - DashboardTime: true, - TimeColumn: "timestamp", - }, - }, - Err: require.NoError, - }, - { - name: "trace query with multiple resources and overlapping correlated workspaces", - queryModel: []backend.DataQuery{ - { - JSON: []byte(fmt.Sprintf(`{ - "queryType": "Azure Traces", - "azureTraces": { - "operationId": "op-id-multi", - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1", "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r2"], - "resultFormat": "%s" - } - }`, dataquery.ResultFormatTrace)), - RefID: "A", - TimeRange: timeRange, - QueryType: string(dataquery.AzureQueryTypeAzureTraces), - }, - }, - azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{ - { - RefID: "A", - ResultFormat: dataquery.ResultFormatTrace, - URL: "v1/apps/r1/query", - JSON: []byte(fmt.Sprintf(`{ - "queryType": "Azure Traces", - "azureTraces": { - "operationId": "op-id-multi", - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1", "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r2"], - "resultFormat": "%s" - } - }`, dataquery.ResultFormatTrace)), - Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests` + - `| where (operation_Id != '' and operation_Id == 'op-id-multi') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'op-id-multi')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1", "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r2"}, - TimeRange: timeRange, - QueryType: dataquery.AzureQueryTypeAzureTraces, - TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests` + - `| where (operation_Id != '' and operation_Id == 'op-id-multi') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'op-id-multi')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - TraceParentExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests` + - `| where (operation_Id != '' and operation_Id == 'op-id-multi') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'op-id-multi')` + - `| where (operation_ParentId != '' and operation_ParentId == '${__data.fields.parentSpanID}')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - TraceLogsExploreQuery: "union *,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').traces\n" + - "| where operation_Id == \"op-id-multi\"", - AppInsightsQuery: true, - DashboardTime: true, - TimeColumn: "timestamp", - }, - }, - Err: require.NoError, - }, - { - name: "trace query with multiple resources and non-overlapping correlated workspaces", - queryModel: []backend.DataQuery{ - { - JSON: []byte(fmt.Sprintf(`{ - "queryType": "Azure Traces", - "azureTraces": { - "operationId": "op-id-non-overlapping", - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1", "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r2"], - "resultFormat": "%s" - } - }`, dataquery.ResultFormatTrace)), - RefID: "A", - TimeRange: timeRange, - QueryType: string(dataquery.AzureQueryTypeAzureTraces), - }, - }, - azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{ - { - RefID: "A", - ResultFormat: dataquery.ResultFormatTrace, - URL: "v1/apps/r1/query", - JSON: []byte(fmt.Sprintf(`{ - "queryType": "Azure Traces", - "azureTraces": { - "operationId": "op-id-non-overlapping", - "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1", "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r2"], - "resultFormat": "%s" - } - }`, dataquery.ResultFormatTrace)), - Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').requests` + - `| where (operation_Id != '' and operation_Id == 'op-id-non-overlapping') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'op-id-non-overlapping')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1", "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r2"}, - TimeRange: timeRange, - QueryType: dataquery.AzureQueryTypeAzureTraces, - TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').requests` + - `| where (operation_Id != '' and operation_Id == 'op-id-non-overlapping') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'op-id-non-overlapping')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - TraceParentExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').requests` + - `| where (operation_Id != '' and operation_Id == 'op-id-non-overlapping') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'op-id-non-overlapping')` + - `| where (operation_ParentId != '' and operation_ParentId == '${__data.fields.parentSpanID}')` + - `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + - `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + - `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + - `| extend serviceName = cloud_RoleName| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + - `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + - `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + - `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + - `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + - `| order by startTime asc`, - TraceLogsExploreQuery: "union *,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').traces,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').availabilityResults,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').customEvents,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').dependencies,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').exceptions,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').pageViews,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').requests,\n" + - "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').traces\n" + - "| where operation_Id == \"op-id-non-overlapping\"", - AppInsightsQuery: true, - DashboardTime: true, - TimeColumn: "timestamp", - }, + }`, dataquery.ResultFormatTimeSeries)), + Query: "Perf", + Resources: []string{"/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace"}, + TimeRange: timeRange, + QueryType: dataquery.AzureQueryTypeAzureLogAnalytics, + AppInsightsQuery: false, + DashboardTime: true, + TimeColumn: "TimeGenerated", }, Err: require.NoError, }, @@ -1450,9 +324,9 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - queries, err := datasource.buildQueries(ctx, tt.queryModel, dsInfo) + query, err := buildLogAnalyticsQuery(tt.queryModel, dsInfo, appInsightsRegExp) tt.Err(t, err) - if diff := cmp.Diff(tt.azureLogAnalyticsQueries[0], queries[0]); diff != "" { + if diff := cmp.Diff(&tt.azureLogAnalyticsQuery, query); diff != "" { t.Errorf("Result mismatch (-want +got): \n%s", diff) } }) diff --git a/pkg/tsdb/azuremonitor/loganalytics/traces.go b/pkg/tsdb/azuremonitor/loganalytics/traces.go new file mode 100644 index 00000000000..bdd0075388d --- /dev/null +++ b/pkg/tsdb/azuremonitor/loganalytics/traces.go @@ -0,0 +1,255 @@ +package loganalytics + +import ( + "context" + "encoding/json" + "fmt" + "regexp" + "sort" + "strings" + + "github.com/grafana/grafana-plugin-sdk-go/backend" + "github.com/grafana/grafana/pkg/tsdb/azuremonitor/kinds/dataquery" + "github.com/grafana/grafana/pkg/tsdb/azuremonitor/macros" + "github.com/grafana/grafana/pkg/tsdb/azuremonitor/types" + "k8s.io/utils/strings/slices" +) + +type TraceQueries struct { + TraceExploreQuery string + TraceParentExploreQuery string + TraceLogsExploreQuery string +} + +func buildTracesQuery(operationId string, parentSpanID *string, traceTypes []string, filters []dataquery.AzureTracesFilter, resultFormat *dataquery.ResultFormat, resources []string) string { + types := traceTypes + if len(types) == 0 { + types = Tables + } + + filteredTypes := make([]string, 0) + // If the result format is set to trace then we filter out all events that are of the type traces as they don't make sense when visualised as a span + if resultFormat != nil && *resultFormat == dataquery.ResultFormatTrace { + filteredTypes = slices.Filter(filteredTypes, types, func(s string) bool { return s != "traces" }) + } else { + filteredTypes = types + } + sort.Strings(filteredTypes) + + if len(filteredTypes) == 0 { + return "" + } + + resourcesQuery := strings.Join(filteredTypes, ",") + if len(resources) > 0 { + intermediate := make([]string, 0) + for _, resource := range resources { + for _, table := range filteredTypes { + intermediate = append(intermediate, fmt.Sprintf("app('%s').%s", resource, table)) + } + } + resourcesQuery += "," + strings.Join(intermediate, ",") + } + + tagsMap := make(map[string]bool) + var tags []string + for _, t := range filteredTypes { + tableTags := getTagsForTable(t) + for _, i := range tableTags { + if tagsMap[i] { + continue + } + if i == "cloud_RoleInstance" || i == "cloud_RoleName" || i == "customDimensions" || i == "customMeasurements" { + continue + } + tags = append(tags, i) + tagsMap[i] = true + } + } + sort.Strings(tags) + + whereClause := "" + + if operationId != "" { + whereClause = fmt.Sprintf("| where (operation_Id != '' and operation_Id == '%s') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == '%s')", operationId, operationId) + } + + parentWhereClause := "" + if parentSpanID != nil && *parentSpanID != "" { + parentWhereClause = fmt.Sprintf("| where (operation_ParentId != '' and operation_ParentId == '%s')", *parentSpanID) + } + + filtersClause := "" + + if len(filters) > 0 { + for _, filter := range filters { + if len(filter.Filters) == 0 { + continue + } + operation := "in" + if filter.Operation == "ne" { + operation = "!in" + } + filterValues := []string{} + for _, val := range filter.Filters { + filterValues = append(filterValues, fmt.Sprintf(`"%s"`, val)) + } + filtersClause += fmt.Sprintf("| where %s %s (%s)", filter.Property, operation, strings.Join(filterValues, ",")) + } + } + + propertiesFunc := "bag_merge(customDimensions, customMeasurements)" + if len(tags) > 0 { + propertiesFunc = fmt.Sprintf("bag_merge(bag_pack_columns(%s), customDimensions, customMeasurements)", strings.Join(tags, ",")) + } + + errorProperty := `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + baseQuery := fmt.Sprintf(`set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true %s`, resourcesQuery) + propertiesStaticQuery := `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + propertiesQuery := fmt.Sprintf(`| extend tags = %s`, propertiesFunc) + projectClause := `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc` + return baseQuery + whereClause + parentWhereClause + propertiesStaticQuery + errorProperty + propertiesQuery + filtersClause + projectClause +} + +func buildTracesLogsQuery(operationId string, resources []string) string { + types := Tables + sort.Strings(types) + selectors := "union " + strings.Join(types, ",\n") + "\n" + if len(resources) > 0 { + intermediate := make([]string, 0) + for _, resource := range resources { + for _, table := range types { + intermediate = append(intermediate, fmt.Sprintf("app('%s').%s", resource, table)) + } + } + sort.Strings(intermediate) + types = intermediate + selectors = strings.Join(append([]string{"union *"}, types...), ",\n") + "\n" + } + + query := selectors + query += fmt.Sprintf(`| where operation_Id == "%s"`, operationId) + return query +} + +func buildTraceQueries(query backend.DataQuery, dsInfo types.DatasourceInfo, tracesQuery dataquery.AzureTracesQuery, operationId string, resultFormat dataquery.ResultFormat, queryResources []string) (string, *TraceQueries, error) { + traceExploreQuery := "" + traceParentExploreQuery := "" + traceLogsExploreQuery := "" + traceIdVariable := "${__data.fields.traceID}" + parentSpanIdVariable := "${__data.fields.parentSpanID}" + var err error + + traceQueries := TraceQueries{} + + queryString := buildTracesQuery(operationId, nil, tracesQuery.TraceTypes, tracesQuery.Filters, &resultFormat, queryResources) + + if operationId == "" { + traceExploreQuery = buildTracesQuery(traceIdVariable, nil, tracesQuery.TraceTypes, tracesQuery.Filters, &resultFormat, queryResources) + traceParentExploreQuery = buildTracesQuery(traceIdVariable, &parentSpanIdVariable, tracesQuery.TraceTypes, tracesQuery.Filters, &resultFormat, queryResources) + traceLogsExploreQuery = buildTracesLogsQuery(traceIdVariable, queryResources) + } else { + traceExploreQuery = queryString + traceParentExploreQuery = buildTracesQuery(operationId, &parentSpanIdVariable, tracesQuery.TraceTypes, tracesQuery.Filters, &resultFormat, queryResources) + traceLogsExploreQuery = buildTracesLogsQuery(operationId, queryResources) + } + + traceExploreQuery, err = macros.KqlInterpolate(query, dsInfo, traceExploreQuery, "TimeGenerated") + if err != nil { + return "", &traceQueries, fmt.Errorf("failed to create traces explore query: %s", err) + } + traceQueries.TraceExploreQuery = traceExploreQuery + + traceParentExploreQuery, err = macros.KqlInterpolate(query, dsInfo, traceParentExploreQuery, "TimeGenerated") + if err != nil { + return "", &traceQueries, fmt.Errorf("failed to create parent span traces explore query: %s", err) + } + traceQueries.TraceParentExploreQuery = traceParentExploreQuery + + traceLogsExploreQuery, err = macros.KqlInterpolate(query, dsInfo, traceLogsExploreQuery, "TimeGenerated") + if err != nil { + return "", &traceQueries, fmt.Errorf("failed to create traces logs explore query: %s", err) + } + traceQueries.TraceLogsExploreQuery = traceLogsExploreQuery + + return queryString, &traceQueries, nil +} + +func buildAppInsightsQuery(ctx context.Context, query backend.DataQuery, dsInfo types.DatasourceInfo, appInsightsRegExp *regexp.Regexp) (*AzureLogAnalyticsQuery, error) { + dashboardTime := true + timeColumn := "" + queryJSONModel := types.TracesJSONQuery{} + err := json.Unmarshal(query.JSON, &queryJSONModel) + if err != nil { + return nil, fmt.Errorf("failed to decode the Azure Traces query object from JSON: %w", err) + } + + azureTracesTarget := queryJSONModel.AzureTraces + + resultFormat := ParseResultFormat(azureTracesTarget.ResultFormat, dataquery.AzureQueryTypeAzureTraces) + + resources := azureTracesTarget.Resources + resourceOrWorkspace := azureTracesTarget.Resources[0] + appInsightsQuery := appInsightsRegExp.Match([]byte(resourceOrWorkspace)) + resourcesMap := make(map[string]bool, 0) + if len(resources) > 1 { + for _, resource := range resources { + resourcesMap[strings.ToLower(resource)] = true + } + // Remove the base resource as that's where the query is run anyway + delete(resourcesMap, strings.ToLower(resourceOrWorkspace)) + } + + operationId := "" + if queryJSONModel.AzureTraces.OperationId != nil && *queryJSONModel.AzureTraces.OperationId != "" { + operationId = *queryJSONModel.AzureTraces.OperationId + resourcesMap, err = getCorrelationWorkspaces(ctx, resourceOrWorkspace, resourcesMap, dsInfo, operationId) + if err != nil { + return nil, fmt.Errorf("failed to retrieve correlation resources for operation ID - %s: %s", operationId, err) + } + } + + queryResources := make([]string, 0) + for resource := range resourcesMap { + queryResources = append(queryResources, resource) + } + sort.Strings(queryResources) + + queryString, traceQueries, err := buildTraceQueries(query, dsInfo, queryJSONModel.AzureTraces, operationId, resultFormat, queryResources) + if err != nil { + return nil, err + } + + apiURL := getApiURL(resourceOrWorkspace, appInsightsQuery) + + rawQuery, err := macros.KqlInterpolate(query, dsInfo, queryString, "TimeGenerated") + if err != nil { + return nil, err + } + + timeColumn = "timestamp" + + return &AzureLogAnalyticsQuery{ + RefID: query.RefID, + ResultFormat: resultFormat, + URL: apiURL, + JSON: query.JSON, + TimeRange: query.TimeRange, + Query: rawQuery, + Resources: resources, + QueryType: dataquery.AzureQueryType(query.QueryType), + TraceExploreQuery: traceQueries.TraceExploreQuery, + TraceParentExploreQuery: traceQueries.TraceParentExploreQuery, + TraceLogsExploreQuery: traceQueries.TraceLogsExploreQuery, + AppInsightsQuery: appInsightsQuery, + DashboardTime: dashboardTime, + TimeColumn: timeColumn, + }, nil +} diff --git a/pkg/tsdb/azuremonitor/loganalytics/traces_test.go b/pkg/tsdb/azuremonitor/loganalytics/traces_test.go new file mode 100644 index 00000000000..16725132ef7 --- /dev/null +++ b/pkg/tsdb/azuremonitor/loganalytics/traces_test.go @@ -0,0 +1,1160 @@ +package loganalytics + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "net/http/httptest" + "regexp" + "strings" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/grafana/grafana-plugin-sdk-go/backend" + "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient" + "github.com/grafana/grafana/pkg/tsdb/azuremonitor/kinds/dataquery" + "github.com/grafana/grafana/pkg/tsdb/azuremonitor/types" + "github.com/stretchr/testify/require" +) + +func TestBuildAppInsightsQuery(t *testing.T) { + fromStart := time.Date(2018, 3, 15, 13, 0, 0, 0, time.UTC).In(time.Local) + timeRange := backend.TimeRange{From: fromStart, To: fromStart.Add(34 * time.Minute)} + ctx := context.Background() + svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + var correlationRes AzureCorrelationAPIResponse + if strings.Contains(r.URL.Path, "test-op-id") { + correlationRes = AzureCorrelationAPIResponse{ + ID: "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1", + Name: "guid-1", + Type: "microsoft.insights/transactions", + Properties: AzureCorrelationAPIResponseProperties{ + Resources: []string{ + "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1", + }, + NextLink: nil, + }, + } + } else if strings.Contains(r.URL.Path, "op-id-multi") { + correlationRes = AzureCorrelationAPIResponse{ + ID: "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1", + Name: "guid-1", + Type: "microsoft.insights/transactions", + Properties: AzureCorrelationAPIResponseProperties{ + Resources: []string{ + "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1", + "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r2", + }, + NextLink: nil, + }, + } + } else if strings.Contains(r.URL.Path, "op-id-non-overlapping") { + correlationRes = AzureCorrelationAPIResponse{ + ID: "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1", + Name: "guid-1", + Type: "microsoft.insights/transactions", + Properties: AzureCorrelationAPIResponseProperties{ + Resources: []string{ + "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1", + "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r3", + }, + NextLink: nil, + }, + } + } + err := json.NewEncoder(w).Encode(correlationRes) + if err != nil { + t.Errorf("failed to encode correlation API response") + } + })) + + provider := httpclient.NewProvider(httpclient.ProviderOptions{Timeout: &httpclient.DefaultTimeoutOptions}) + client, err := provider.New() + if err != nil { + t.Errorf("failed to create fake client") + } + + dsInfo := types.DatasourceInfo{ + Services: map[string]types.DatasourceService{ + "Azure Monitor": {URL: svr.URL, HTTPClient: client}, + }, + JSONData: map[string]any{ + "azureLogAnalyticsSameAs": false, + }, + } + appInsightsRegExp, err := regexp.Compile("providers/Microsoft.Insights/components") + if err != nil { + t.Error("failed to compile reg: %w", err) + } + + tests := []struct { + name string + queryModel backend.DataQuery + azureLogAnalyticsQuery AzureLogAnalyticsQuery + Err require.ErrorAssertionFunc + }{ + { + name: "trace query", + queryModel: backend.DataQuery{ + JSON: []byte(fmt.Sprintf(`{ + "queryType": "Azure Traces", + "azureTraces": { + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], + "resultFormat": "%s", + "traceTypes": ["trace"], + "operationId": "test-op-id" + } + }`, dataquery.ResultFormatTable)), + RefID: "A", + TimeRange: timeRange, + QueryType: string(dataquery.AzureQueryTypeAzureTraces), + }, + azureLogAnalyticsQuery: AzureLogAnalyticsQuery{ + RefID: "A", + ResultFormat: dataquery.ResultFormatTable, + URL: "v1/apps/r1/query", + JSON: []byte(fmt.Sprintf(`{ + "queryType": "Azure Traces", + "azureTraces": { + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], + "resultFormat": "%s", + "traceTypes": ["trace"], + "operationId": "test-op-id" + } + }`, dataquery.ResultFormatTable)), + Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true trace` + + `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"}, + TimeRange: timeRange, + QueryType: dataquery.AzureQueryTypeAzureTraces, + TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true trace` + + `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + TraceParentExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true trace` + + `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + + `| where (operation_ParentId != '' and operation_ParentId == '${__data.fields.parentSpanID}')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + TraceLogsExploreQuery: "union availabilityResults,\n" + "customEvents,\n" + "dependencies,\n" + "exceptions,\n" + "pageViews,\n" + "requests,\n" + "traces\n" + + "| where operation_Id == \"test-op-id\"", + AppInsightsQuery: true, + DashboardTime: true, + TimeColumn: "timestamp", + }, + Err: require.NoError, + }, + { + name: "trace query with no result format set", + queryModel: backend.DataQuery{ + JSON: []byte(`{ + "queryType": "Azure Traces", + "azureTraces": { + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], + "traceTypes": ["trace"], + "operationId": "test-op-id" + } + }`), + RefID: "A", + TimeRange: timeRange, + QueryType: string(dataquery.AzureQueryTypeAzureTraces), + }, + azureLogAnalyticsQuery: AzureLogAnalyticsQuery{ + RefID: "A", + ResultFormat: dataquery.ResultFormatTable, + URL: "v1/apps/r1/query", + JSON: []byte(`{ + "queryType": "Azure Traces", + "azureTraces": { + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], + "traceTypes": ["trace"], + "operationId": "test-op-id" + } + }`), + Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true trace` + + `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"}, + TimeRange: timeRange, + QueryType: dataquery.AzureQueryTypeAzureTraces, + TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true trace` + + `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + TraceParentExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true trace` + + `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + + `| where (operation_ParentId != '' and operation_ParentId == '${__data.fields.parentSpanID}')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + TraceLogsExploreQuery: "union availabilityResults,\n" + "customEvents,\n" + "dependencies,\n" + "exceptions,\n" + "pageViews,\n" + "requests,\n" + "traces\n" + + "| where operation_Id == \"test-op-id\"", + AppInsightsQuery: true, + DashboardTime: true, + TimeColumn: "timestamp", + }, + Err: require.NoError, + }, + { + name: "trace query with no operation ID", + queryModel: backend.DataQuery{ + JSON: []byte(fmt.Sprintf(`{ + "queryType": "Azure Traces", + "azureTraces": { + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], + "resultFormat": "%s" + } + }`, dataquery.ResultFormatTable)), + RefID: "A", + TimeRange: timeRange, + QueryType: string(dataquery.AzureQueryTypeAzureTraces), + }, + azureLogAnalyticsQuery: AzureLogAnalyticsQuery{ + RefID: "A", + ResultFormat: dataquery.ResultFormatTable, + URL: "v1/apps/r1/query", + JSON: []byte(fmt.Sprintf(`{ + "queryType": "Azure Traces", + "azureTraces": { + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], + "resultFormat": "%s" + } + }`, dataquery.ResultFormatTable)), + Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"}, + TimeRange: timeRange, + QueryType: dataquery.AzureQueryTypeAzureTraces, + TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + + `| where (operation_Id != '' and operation_Id == '${__data.fields.traceID}') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == '${__data.fields.traceID}')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + TraceParentExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + + `| where (operation_Id != '' and operation_Id == '${__data.fields.traceID}') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == '${__data.fields.traceID}')` + + `| where (operation_ParentId != '' and operation_ParentId == '${__data.fields.parentSpanID}')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + TraceLogsExploreQuery: "union availabilityResults,\n" + "customEvents,\n" + "dependencies,\n" + "exceptions,\n" + "pageViews,\n" + "requests,\n" + "traces\n" + + "| where operation_Id == \"${__data.fields.traceID}\"", + AppInsightsQuery: true, + DashboardTime: true, + TimeColumn: "timestamp", + }, + Err: require.NoError, + }, + { + name: "trace query with no types", + queryModel: backend.DataQuery{ + JSON: []byte(fmt.Sprintf(`{ + "queryType": "Azure Traces", + "azureTraces": { + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], + "resultFormat": "%s", + "operationId": "test-op-id" + } + }`, dataquery.ResultFormatTable)), + RefID: "A", + TimeRange: timeRange, + QueryType: string(dataquery.AzureQueryTypeAzureTraces), + }, + azureLogAnalyticsQuery: AzureLogAnalyticsQuery{ + RefID: "A", + ResultFormat: dataquery.ResultFormatTable, + URL: "v1/apps/r1/query", + JSON: []byte(fmt.Sprintf(`{ + "queryType": "Azure Traces", + "azureTraces": { + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], + "resultFormat": "%s", + "operationId": "test-op-id" + } + }`, dataquery.ResultFormatTable)), + Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + + `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"}, + TimeRange: timeRange, + QueryType: dataquery.AzureQueryTypeAzureTraces, + TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + + `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + TraceParentExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + + `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + + `| where (operation_ParentId != '' and operation_ParentId == '${__data.fields.parentSpanID}')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + TraceLogsExploreQuery: "union availabilityResults,\n" + "customEvents,\n" + "dependencies,\n" + "exceptions,\n" + "pageViews,\n" + "requests,\n" + "traces\n" + + "| where operation_Id == \"test-op-id\"", + AppInsightsQuery: true, + DashboardTime: true, + TimeColumn: "timestamp", + }, + Err: require.NoError, + }, + { + name: "trace query with eq filter", + queryModel: backend.DataQuery{ + JSON: []byte(fmt.Sprintf(`{ + "queryType": "Azure Traces", + "azureTraces": { + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], + "resultFormat": "%s", + "operationId": "test-op-id", + "filters": [{"filters": ["test-app-id"], "property": "appId", "operation": "eq"}] + } + }`, dataquery.ResultFormatTable)), + RefID: "A", + TimeRange: timeRange, + QueryType: string(dataquery.AzureQueryTypeAzureTraces), + }, + azureLogAnalyticsQuery: AzureLogAnalyticsQuery{ + RefID: "A", + ResultFormat: dataquery.ResultFormatTable, + URL: "v1/apps/r1/query", + JSON: []byte(fmt.Sprintf(`{ + "queryType": "Azure Traces", + "azureTraces": { + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], + "resultFormat": "%s", + "operationId": "test-op-id", + "filters": [{"filters": ["test-app-id"], "property": "appId", "operation": "eq"}] + } + }`, dataquery.ResultFormatTable)), + Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + + `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| where appId in ("test-app-id")` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"}, + TimeRange: timeRange, + QueryType: dataquery.AzureQueryTypeAzureTraces, + TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + + `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| where appId in ("test-app-id")` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + TraceParentExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + + `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + + `| where (operation_ParentId != '' and operation_ParentId == '${__data.fields.parentSpanID}')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| where appId in ("test-app-id")` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + TraceLogsExploreQuery: "union availabilityResults,\n" + "customEvents,\n" + "dependencies,\n" + "exceptions,\n" + "pageViews,\n" + "requests,\n" + "traces\n" + + "| where operation_Id == \"test-op-id\"", + AppInsightsQuery: true, + DashboardTime: true, + TimeColumn: "timestamp", + }, + Err: require.NoError, + }, + { + name: "trace query with ne filter", + queryModel: backend.DataQuery{ + JSON: []byte(fmt.Sprintf(`{ + "queryType": "Azure Traces", + "azureTraces": { + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], + "resultFormat": "%s", + "operationId": "test-op-id", + "filters": [{"filters": ["test-app-id"], "property": "appId", "operation": "ne"}] + } + }`, dataquery.ResultFormatTable)), + RefID: "A", + TimeRange: timeRange, + QueryType: string(dataquery.AzureQueryTypeAzureTraces), + }, + azureLogAnalyticsQuery: AzureLogAnalyticsQuery{ + RefID: "A", + ResultFormat: dataquery.ResultFormatTable, + URL: "v1/apps/r1/query", + JSON: []byte(fmt.Sprintf(`{ + "queryType": "Azure Traces", + "azureTraces": { + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], + "resultFormat": "%s", + "operationId": "test-op-id", + "filters": [{"filters": ["test-app-id"], "property": "appId", "operation": "ne"}] + } + }`, dataquery.ResultFormatTable)), + Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + + `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| where appId !in ("test-app-id")` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"}, + TimeRange: timeRange, + QueryType: dataquery.AzureQueryTypeAzureTraces, + TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + + `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| where appId !in ("test-app-id")` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + TraceParentExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + + `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + + `| where (operation_ParentId != '' and operation_ParentId == '${__data.fields.parentSpanID}')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| where appId !in ("test-app-id")` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + TraceLogsExploreQuery: "union availabilityResults,\n" + "customEvents,\n" + "dependencies,\n" + "exceptions,\n" + "pageViews,\n" + "requests,\n" + "traces\n" + + "| where operation_Id == \"test-op-id\"", + AppInsightsQuery: true, + DashboardTime: true, + TimeColumn: "timestamp", + }, + Err: require.NoError, + }, + { + name: "trace query with multiple filters", + queryModel: backend.DataQuery{ + JSON: []byte(fmt.Sprintf(`{ + "queryType": "Azure Traces", + "azureTraces": { + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], + "resultFormat": "%s", + "operationId": "test-op-id", + "filters": [{"filters": ["test-app-id"], "property": "appId", "operation": "ne"},{"filters": ["test-client-id"], "property": "clientId", "operation": "eq"}] + } + }`, dataquery.ResultFormatTable)), + RefID: "A", + TimeRange: timeRange, + QueryType: string(dataquery.AzureQueryTypeAzureTraces), + }, + azureLogAnalyticsQuery: AzureLogAnalyticsQuery{ + RefID: "A", + ResultFormat: dataquery.ResultFormatTable, + URL: "v1/apps/r1/query", + JSON: []byte(fmt.Sprintf(`{ + "queryType": "Azure Traces", + "azureTraces": { + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], + "resultFormat": "%s", + "operationId": "test-op-id", + "filters": [{"filters": ["test-app-id"], "property": "appId", "operation": "ne"},{"filters": ["test-client-id"], "property": "clientId", "operation": "eq"}] + } + }`, dataquery.ResultFormatTable)), + Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + + `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| where appId !in ("test-app-id")| where clientId in ("test-client-id")` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"}, + TimeRange: timeRange, + QueryType: dataquery.AzureQueryTypeAzureTraces, + TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + + `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| where appId !in ("test-app-id")| where clientId in ("test-client-id")` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + TraceParentExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces` + + `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + + `| where (operation_ParentId != '' and operation_ParentId == '${__data.fields.parentSpanID}')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| where appId !in ("test-app-id")| where clientId in ("test-client-id")` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + TraceLogsExploreQuery: "union availabilityResults,\n" + "customEvents,\n" + "dependencies,\n" + "exceptions,\n" + "pageViews,\n" + "requests,\n" + "traces\n" + + "| where operation_Id == \"test-op-id\"", + AppInsightsQuery: true, + DashboardTime: true, + TimeColumn: "timestamp", + }, + Err: require.NoError, + }, + { + name: "trace query with trace result format", + queryModel: backend.DataQuery{ + JSON: []byte(fmt.Sprintf(`{ + "queryType": "Azure Traces", + "azureTraces": { + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], + "resultFormat": "%s" + } + }`, dataquery.ResultFormatTrace)), + RefID: "A", + TimeRange: timeRange, + QueryType: string(dataquery.AzureQueryTypeAzureTraces), + }, + azureLogAnalyticsQuery: AzureLogAnalyticsQuery{ + RefID: "A", + ResultFormat: dataquery.ResultFormatTrace, + URL: "v1/apps/r1/query", + JSON: []byte(fmt.Sprintf(`{ + "queryType": "Azure Traces", + "azureTraces": { + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], + "resultFormat": "%s" + } + }`, dataquery.ResultFormatTrace)), + Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"}, + TimeRange: timeRange, + QueryType: dataquery.AzureQueryTypeAzureTraces, + TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests` + + `| where (operation_Id != '' and operation_Id == '${__data.fields.traceID}') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == '${__data.fields.traceID}')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + TraceParentExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests` + + `| where (operation_Id != '' and operation_Id == '${__data.fields.traceID}') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == '${__data.fields.traceID}')` + + `| where (operation_ParentId != '' and operation_ParentId == '${__data.fields.parentSpanID}')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + TraceLogsExploreQuery: "union availabilityResults,\n" + "customEvents,\n" + "dependencies,\n" + "exceptions,\n" + "pageViews,\n" + "requests,\n" + "traces\n" + + "| where operation_Id == \"${__data.fields.traceID}\"", + AppInsightsQuery: true, + DashboardTime: true, + TimeColumn: "timestamp", + }, + Err: require.NoError, + }, + { + name: "trace query with trace result format and operation ID", + queryModel: backend.DataQuery{ + JSON: []byte(fmt.Sprintf(`{ + "queryType": "Azure Traces", + "azureTraces": { + "operationId": "test-op-id", + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], + "resultFormat": "%s" + } + }`, dataquery.ResultFormatTrace)), + RefID: "A", + TimeRange: timeRange, + QueryType: string(dataquery.AzureQueryTypeAzureTraces), + }, + azureLogAnalyticsQuery: AzureLogAnalyticsQuery{ + RefID: "A", + ResultFormat: dataquery.ResultFormatTrace, + URL: "v1/apps/r1/query", + JSON: []byte(fmt.Sprintf(`{ + "queryType": "Azure Traces", + "azureTraces": { + "operationId": "test-op-id", + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], + "resultFormat": "%s" + } + }`, dataquery.ResultFormatTrace)), + Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests` + + `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"}, + TimeRange: timeRange, + QueryType: dataquery.AzureQueryTypeAzureTraces, + TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests` + + `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + TraceParentExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests` + + `| where (operation_Id != '' and operation_Id == 'test-op-id') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'test-op-id')` + + `| where (operation_ParentId != '' and operation_ParentId == '${__data.fields.parentSpanID}')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName` + + `| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + TraceLogsExploreQuery: "union availabilityResults,\n" + "customEvents,\n" + "dependencies,\n" + "exceptions,\n" + "pageViews,\n" + "requests,\n" + "traces\n" + + "| where operation_Id == \"test-op-id\"", + AppInsightsQuery: true, + DashboardTime: true, + TimeColumn: "timestamp", + }, + Err: require.NoError, + }, + { + name: "trace query with trace result format and only trace type", + queryModel: backend.DataQuery{ + JSON: []byte(fmt.Sprintf(`{ + "queryType": "Azure Traces", + "azureTraces": { + "operationId": "test-op-id", + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], + "resultFormat": "%s", + "traceTypes": ["traces"] + } + }`, dataquery.ResultFormatTrace)), + RefID: "A", + TimeRange: timeRange, + QueryType: string(dataquery.AzureQueryTypeAzureTraces), + }, + azureLogAnalyticsQuery: AzureLogAnalyticsQuery{ + RefID: "A", + ResultFormat: dataquery.ResultFormatTrace, + URL: "v1/apps/r1/query", + JSON: []byte(fmt.Sprintf(`{ + "queryType": "Azure Traces", + "azureTraces": { + "operationId": "test-op-id", + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], + "resultFormat": "%s", + "traceTypes": ["traces"] + } + }`, dataquery.ResultFormatTrace)), + Query: "", + Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"}, + TimeRange: timeRange, + QueryType: dataquery.AzureQueryTypeAzureTraces, + TraceExploreQuery: "", + TraceParentExploreQuery: "", + TraceLogsExploreQuery: "union availabilityResults,\n" + "customEvents,\n" + "dependencies,\n" + "exceptions,\n" + "pageViews,\n" + "requests,\n" + "traces\n" + + "| where operation_Id == \"test-op-id\"", + AppInsightsQuery: true, + DashboardTime: true, + TimeColumn: "timestamp", + }, + Err: require.NoError, + }, + { + name: "trace query with operation ID and correlated workspaces", + queryModel: backend.DataQuery{ + JSON: []byte(fmt.Sprintf(`{ + "queryType": "Azure Traces", + "azureTraces": { + "operationId": "op-id-multi", + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], + "resultFormat": "%s" + } + }`, dataquery.ResultFormatTrace)), + RefID: "A", + TimeRange: timeRange, + QueryType: string(dataquery.AzureQueryTypeAzureTraces), + }, + azureLogAnalyticsQuery: AzureLogAnalyticsQuery{ + RefID: "A", + ResultFormat: dataquery.ResultFormatTrace, + URL: "v1/apps/r1/query", + JSON: []byte(fmt.Sprintf(`{ + "queryType": "Azure Traces", + "azureTraces": { + "operationId": "op-id-multi", + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"], + "resultFormat": "%s" + } + }`, dataquery.ResultFormatTrace)), + Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests` + + `| where (operation_Id != '' and operation_Id == 'op-id-multi') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'op-id-multi')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"}, + TimeRange: timeRange, + QueryType: dataquery.AzureQueryTypeAzureTraces, + TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests` + + `| where (operation_Id != '' and operation_Id == 'op-id-multi') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'op-id-multi')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + TraceParentExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests` + + `| where (operation_Id != '' and operation_Id == 'op-id-multi') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'op-id-multi')` + + `| where (operation_ParentId != '' and operation_ParentId == '${__data.fields.parentSpanID}')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + TraceLogsExploreQuery: "union *,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').traces\n" + + "| where operation_Id == \"op-id-multi\"", + AppInsightsQuery: true, + DashboardTime: true, + TimeColumn: "timestamp", + }, + Err: require.NoError, + }, + { + name: "trace query with multiple resources", + queryModel: backend.DataQuery{ + JSON: []byte(fmt.Sprintf(`{ + "queryType": "Azure Traces", + "azureTraces": { + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1", "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r2"], + "resultFormat": "%s" + } + }`, dataquery.ResultFormatTrace)), + RefID: "A", + TimeRange: timeRange, + QueryType: string(dataquery.AzureQueryTypeAzureTraces), + }, + azureLogAnalyticsQuery: AzureLogAnalyticsQuery{ + RefID: "A", + ResultFormat: dataquery.ResultFormatTrace, + URL: "v1/apps/r1/query", + JSON: []byte(fmt.Sprintf(`{ + "queryType": "Azure Traces", + "azureTraces": { + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1", "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r2"], + "resultFormat": "%s" + } + }`, dataquery.ResultFormatTrace)), + Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1", "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r2"}, + TimeRange: timeRange, + QueryType: dataquery.AzureQueryTypeAzureTraces, + TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests` + + `| where (operation_Id != '' and operation_Id == '${__data.fields.traceID}') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == '${__data.fields.traceID}')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + TraceParentExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests` + + `| where (operation_Id != '' and operation_Id == '${__data.fields.traceID}') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == '${__data.fields.traceID}')` + + `| where (operation_ParentId != '' and operation_ParentId == '${__data.fields.parentSpanID}')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + TraceLogsExploreQuery: "union *,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').traces\n" + + "| where operation_Id == \"${__data.fields.traceID}\"", + AppInsightsQuery: true, + DashboardTime: true, + TimeColumn: "timestamp", + }, + Err: require.NoError, + }, + { + name: "trace query with multiple resources and overlapping correlated workspaces", + queryModel: backend.DataQuery{ + JSON: []byte(fmt.Sprintf(`{ + "queryType": "Azure Traces", + "azureTraces": { + "operationId": "op-id-multi", + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1", "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r2"], + "resultFormat": "%s" + } + }`, dataquery.ResultFormatTrace)), + RefID: "A", + TimeRange: timeRange, + QueryType: string(dataquery.AzureQueryTypeAzureTraces), + }, + azureLogAnalyticsQuery: AzureLogAnalyticsQuery{ + RefID: "A", + ResultFormat: dataquery.ResultFormatTrace, + URL: "v1/apps/r1/query", + JSON: []byte(fmt.Sprintf(`{ + "queryType": "Azure Traces", + "azureTraces": { + "operationId": "op-id-multi", + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1", "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r2"], + "resultFormat": "%s" + } + }`, dataquery.ResultFormatTrace)), + Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests` + + `| where (operation_Id != '' and operation_Id == 'op-id-multi') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'op-id-multi')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1", "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r2"}, + TimeRange: timeRange, + QueryType: dataquery.AzureQueryTypeAzureTraces, + TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests` + + `| where (operation_Id != '' and operation_Id == 'op-id-multi') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'op-id-multi')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + TraceParentExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests` + + `| where (operation_Id != '' and operation_Id == 'op-id-multi') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'op-id-multi')` + + `| where (operation_ParentId != '' and operation_ParentId == '${__data.fields.parentSpanID}')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + TraceLogsExploreQuery: "union *,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').traces\n" + + "| where operation_Id == \"op-id-multi\"", + AppInsightsQuery: true, + DashboardTime: true, + TimeColumn: "timestamp", + }, + Err: require.NoError, + }, + { + name: "trace query with multiple resources and non-overlapping correlated workspaces", + queryModel: backend.DataQuery{ + JSON: []byte(fmt.Sprintf(`{ + "queryType": "Azure Traces", + "azureTraces": { + "operationId": "op-id-non-overlapping", + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1", "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r2"], + "resultFormat": "%s" + } + }`, dataquery.ResultFormatTrace)), + RefID: "A", + TimeRange: timeRange, + QueryType: string(dataquery.AzureQueryTypeAzureTraces), + }, + azureLogAnalyticsQuery: AzureLogAnalyticsQuery{ + RefID: "A", + ResultFormat: dataquery.ResultFormatTrace, + URL: "v1/apps/r1/query", + JSON: []byte(fmt.Sprintf(`{ + "queryType": "Azure Traces", + "azureTraces": { + "operationId": "op-id-non-overlapping", + "resources": ["/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1", "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r2"], + "resultFormat": "%s" + } + }`, dataquery.ResultFormatTrace)), + Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').requests` + + `| where (operation_Id != '' and operation_Id == 'op-id-non-overlapping') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'op-id-non-overlapping')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1", "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r2"}, + TimeRange: timeRange, + QueryType: dataquery.AzureQueryTypeAzureTraces, + TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').requests` + + `| where (operation_Id != '' and operation_Id == 'op-id-non-overlapping') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'op-id-non-overlapping')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + TraceParentExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').availabilityResults,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').customEvents,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').dependencies,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').exceptions,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').pageViews,app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').requests` + + `| where (operation_Id != '' and operation_Id == 'op-id-non-overlapping') or (customDimensions.ai_legacyRootId != '' and customDimensions.ai_legacyRootId == 'op-id-non-overlapping')` + + `| where (operation_ParentId != '' and operation_ParentId == '${__data.fields.parentSpanID}')` + + `| extend duration = iff(isnull(column_ifexists("duration", real(null))), toreal(0), column_ifexists("duration", real(null)))` + + `| extend spanID = iff(itemType == "pageView" or isempty(column_ifexists("id", "")), tostring(new_guid()), column_ifexists("id", ""))` + + `| extend operationName = iff(isempty(column_ifexists("name", "")), column_ifexists("problemId", ""), column_ifexists("name", ""))` + + `| extend serviceName = cloud_RoleName| extend serviceTags = bag_pack_columns(cloud_RoleInstance, cloud_RoleName)` + + `| extend error = todynamic(iff(itemType == "exception", "true", "false"))` + + `| extend tags = bag_merge(bag_pack_columns(appId,appName,application_Version,assembly,client_Browser,client_City,client_CountryOrRegion,client_IP,client_Model,client_OS,client_StateOrProvince,client_Type,data,details,duration,error,handledAt,iKey,id,innermostAssembly,innermostMessage,innermostMethod,innermostType,itemCount,itemId,itemType,location,message,method,name,operation_Id,operation_Name,operation_ParentId,operation_SyntheticSource,outerAssembly,outerMessage,outerMethod,outerType,performanceBucket,problemId,resultCode,sdkVersion,session_Id,severityLevel,size,source,success,target,timestamp,type,url,user_AccountId,user_AuthenticatedId,user_Id), customDimensions, customMeasurements)` + + `| project-rename traceID = operation_Id, parentSpanID = operation_ParentId, startTime = timestamp` + + `| project startTime, itemType, serviceName, duration, traceID, spanID, parentSpanID, operationName, serviceTags, tags, itemId` + + `| order by startTime asc`, + TraceLogsExploreQuery: "union *,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').availabilityResults,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').customEvents,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').dependencies,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').exceptions,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').pageViews,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').requests,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r2').traces,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').availabilityResults,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').customEvents,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').dependencies,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').exceptions,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').pageViews,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').requests,\n" + + "app('/subscriptions/test-sub/resourcegroups/test-rg/providers/microsoft.insights/components/r3').traces\n" + + "| where operation_Id == \"op-id-non-overlapping\"", + AppInsightsQuery: true, + DashboardTime: true, + TimeColumn: "timestamp", + }, + Err: require.NoError, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + query, err := buildAppInsightsQuery(ctx, tt.queryModel, dsInfo, appInsightsRegExp) + tt.Err(t, err) + if diff := cmp.Diff(&tt.azureLogAnalyticsQuery, query); diff != "" { + t.Errorf("Result mismatch (-want +got): \n%s", diff) + } + }) + } +} diff --git a/pkg/tsdb/azuremonitor/loganalytics/types.go b/pkg/tsdb/azuremonitor/loganalytics/types.go new file mode 100644 index 00000000000..d75ad879092 --- /dev/null +++ b/pkg/tsdb/azuremonitor/loganalytics/types.go @@ -0,0 +1,75 @@ +package loganalytics + +import ( + "encoding/json" + + "github.com/grafana/grafana-plugin-sdk-go/backend" + "github.com/grafana/grafana-plugin-sdk-go/backend/log" + "github.com/grafana/grafana/pkg/tsdb/azuremonitor/kinds/dataquery" + "github.com/grafana/grafana/pkg/tsdb/azuremonitor/types" +) + +// AzureLogAnalyticsDatasource calls the Azure Log Analytics API's +type AzureLogAnalyticsDatasource struct { + Proxy types.ServiceProxy + Logger log.Logger +} + +// AzureLogAnalyticsQuery is the query request that is built from the saved values for +// from the UI +type AzureLogAnalyticsQuery struct { + RefID string + ResultFormat dataquery.ResultFormat + URL string + TraceExploreQuery string + TraceParentExploreQuery string + TraceLogsExploreQuery string + JSON json.RawMessage + TimeRange backend.TimeRange + Query string + Resources []string + QueryType dataquery.AzureQueryType + AppInsightsQuery bool + DashboardTime bool + TimeColumn string +} + +// Error definition has been inferred from real data and other model definitions like +// https://github.com/Azure/azure-sdk-for-go/blob/3640559afddbad452d265b54fb1c20b30be0b062/services/preview/virtualmachineimagebuilder/mgmt/2019-05-01-preview/virtualmachineimagebuilder/models.go +type AzureLogAnalyticsAPIError struct { + Details *[]AzureLogAnalyticsAPIErrorBase `json:"details,omitempty"` + Code *string `json:"code,omitempty"` + Message *string `json:"message,omitempty"` +} + +type AzureLogAnalyticsAPIErrorBase struct { + Code *string `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Innererror *AzureLogAnalyticsInnerError `json:"innererror,omitempty"` +} + +type AzureLogAnalyticsInnerError struct { + Code *string `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Severity *int `json:"severity,omitempty"` + SeverityName *string `json:"severityName,omitempty"` +} + +// AzureLogAnalyticsResponse is the json response object from the Azure Log Analytics API. +type AzureLogAnalyticsResponse struct { + Tables []types.AzureResponseTable `json:"tables"` + Error *AzureLogAnalyticsAPIError `json:"error,omitempty"` +} + +type AzureCorrelationAPIResponse struct { + ID string `json:"id"` + Name string `json:"name"` + Type string `json:"type"` + Properties AzureCorrelationAPIResponseProperties `json:"properties"` + Error *AzureLogAnalyticsAPIError `json:"error,omitempty"` +} + +type AzureCorrelationAPIResponseProperties struct { + Resources []string `json:"resources"` + NextLink *string `json:"nextLink,omitempty"` +} diff --git a/pkg/tsdb/azuremonitor/loganalytics/utils.go b/pkg/tsdb/azuremonitor/loganalytics/utils.go index 13c6b1afd33..b5810316108 100644 --- a/pkg/tsdb/azuremonitor/loganalytics/utils.go +++ b/pkg/tsdb/azuremonitor/loganalytics/utils.go @@ -1,7 +1,12 @@ package loganalytics import ( + "fmt" + "regexp" + "strings" + "github.com/grafana/grafana-plugin-sdk-go/data" + "github.com/grafana/grafana/pkg/tsdb/azuremonitor/kinds/dataquery" ) func AddCustomDataLink(frame data.Frame, dataLink data.DataLink) data.Frame { @@ -31,3 +36,55 @@ func AddConfigLinks(frame data.Frame, dl string, title *string) data.Frame { return frame } + +func ParseResultFormat(queryResultFormat *dataquery.ResultFormat, queryType dataquery.AzureQueryType) dataquery.ResultFormat { + var resultFormat dataquery.ResultFormat + if queryResultFormat != nil { + resultFormat = *queryResultFormat + } + if resultFormat == "" { + if queryType == dataquery.AzureQueryTypeAzureLogAnalytics { + // Default to logs format for logs queries + resultFormat = dataquery.ResultFormatLogs + } + if queryType == dataquery.AzureQueryTypeAzureTraces { + // Default to table format for traces queries as many traces may be returned + resultFormat = dataquery.ResultFormatTable + } + } + return resultFormat +} + +func getApiURL(resourceOrWorkspace string, isAppInsightsQuery bool) string { + matchesResourceURI, _ := regexp.MatchString("^/subscriptions/", resourceOrWorkspace) + + if matchesResourceURI { + if isAppInsightsQuery { + componentName := resourceOrWorkspace[strings.LastIndex(resourceOrWorkspace, "/")+1:] + return fmt.Sprintf("v1/apps/%s/query", componentName) + } + return fmt.Sprintf("v1%s/query", resourceOrWorkspace) + } else { + return fmt.Sprintf("v1/workspaces/%s/query", resourceOrWorkspace) + } +} + +// Legacy queries only specify a Workspace GUID, which we need to use the old workspace-centric +// API URL for, and newer queries specifying a resource URI should use resource-centric API. +// However, legacy workspace queries using a `workspaces()` template variable will be resolved +// to a resource URI, so they should use the new resource-centric. +func retrieveResources(query dataquery.AzureLogsQuery) ([]string, string) { + resources := []string{} + var resourceOrWorkspace string + if len(query.Resources) > 0 { + resources = query.Resources + resourceOrWorkspace = query.Resources[0] + } else if query.Resource != nil && *query.Resource != "" { + resources = []string{*query.Resource} + resourceOrWorkspace = *query.Resource + } else if query.Workspace != nil { + resourceOrWorkspace = *query.Workspace + } + + return resources, resourceOrWorkspace +} diff --git a/pkg/tsdb/azuremonitor/loganalytics/utils_test.go b/pkg/tsdb/azuremonitor/loganalytics/utils_test.go new file mode 100644 index 00000000000..168d2f0b6a4 --- /dev/null +++ b/pkg/tsdb/azuremonitor/loganalytics/utils_test.go @@ -0,0 +1,101 @@ +package loganalytics + +import ( + "testing" + + "github.com/grafana/grafana/pkg/tsdb/azuremonitor/kinds/dataquery" + "github.com/stretchr/testify/assert" +) + +func TestParseResultFormat(t *testing.T) { + emptyResultFormat := dataquery.ResultFormat("") + traceFormat := dataquery.ResultFormatTrace + testCases := []struct { + name string + queryResultFormat *dataquery.ResultFormat + queryType dataquery.AzureQueryType + expectedResultFormat dataquery.ResultFormat + }{ + { + name: "returns the logs format as default for logs queries if input format is nil", + queryResultFormat: nil, + queryType: dataquery.AzureQueryTypeAzureLogAnalytics, + expectedResultFormat: dataquery.ResultFormatLogs, + }, + { + name: "returns the table format as default for traces queries if input format is nil", + queryResultFormat: nil, + queryType: dataquery.AzureQueryTypeAzureTraces, + expectedResultFormat: dataquery.ResultFormatTable, + }, + { + name: "returns the logs format as default for logs queries if input format is empty", + queryResultFormat: &emptyResultFormat, + queryType: dataquery.AzureQueryTypeAzureLogAnalytics, + expectedResultFormat: dataquery.ResultFormatLogs, + }, + { + name: "returns the table format as default for traces queries if input format is empty", + queryResultFormat: &emptyResultFormat, + queryType: dataquery.AzureQueryTypeAzureTraces, + expectedResultFormat: dataquery.ResultFormatTable, + }, + { + name: "returns the query result format", + queryResultFormat: &traceFormat, + queryType: dataquery.AzureQueryTypeAzureTraces, + expectedResultFormat: dataquery.ResultFormatTrace, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + rf := ParseResultFormat(tc.queryResultFormat, tc.queryType) + assert.Equal(t, tc.expectedResultFormat, rf) + }) + } +} + +func TestRetrieveResources(t *testing.T) { + legacyResource := "test-single-resource" + legacyWorkspace := "test-workspace" + testCases := []struct { + name string + query dataquery.AzureLogsQuery + expectedResources []string + expectedResourceOrWorkspace string + }{ + { + name: "current resource query returns the resources and the first resource", + query: dataquery.AzureLogsQuery{ + Resources: []string{"test-resource"}, + }, + expectedResources: []string{"test-resource"}, + expectedResourceOrWorkspace: "test-resource", + }, + { + name: "legacy query with resource specified", + query: dataquery.AzureLogsQuery{ + Resource: &legacyResource, + }, + expectedResources: []string{"test-single-resource"}, + expectedResourceOrWorkspace: "test-single-resource", + }, + { + name: "legacy query with workspace specified", + query: dataquery.AzureLogsQuery{ + Workspace: &legacyWorkspace, + }, + expectedResources: []string{}, + expectedResourceOrWorkspace: "test-workspace", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + resources, resourceOrWorkspace := retrieveResources(tc.query) + assert.Equal(t, tc.expectedResources, resources) + assert.Equal(t, tc.expectedResourceOrWorkspace, resourceOrWorkspace) + }) + } +} diff --git a/pkg/tsdb/azuremonitor/types/types.go b/pkg/tsdb/azuremonitor/types/types.go index 341e5f60b41..1e3e7f2073e 100644 --- a/pkg/tsdb/azuremonitor/types/types.go +++ b/pkg/tsdb/azuremonitor/types/types.go @@ -15,12 +15,6 @@ import ( "github.com/grafana/grafana/pkg/tsdb/azuremonitor/kinds/dataquery" ) -const ( - TimeSeries = "time_series" - Table = "table" - Trace = "trace" -) - var ( LegendKeyFormat = regexp.MustCompile(`\{\{\s*(.+?)\s*\}\}`) )