mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Azure monitor: Support Logs visualization (#76594)
* logs view * cant add a library * gzip doesnt work * remove link code :( * clean up * linter * linter * betterer. cant run this locally?? * Remove unneeded conversions * Return portal link for log queries from backend * Display portal link * Update tests * Lint * Prettier * Unused import * Add Azure Monitor to explore docs --------- Co-authored-by: Andreas Christou <andreas.christou@grafana.com>
This commit is contained in:
parent
17fe1d3fc7
commit
91ad07719f
@ -20,6 +20,7 @@ Explore is a powerful tool for logging and log analysis. It allows you to invest
|
||||
- [Elasticsearch]({{< relref "../datasources/elasticsearch" >}})
|
||||
- [Cloudwatch]({{< relref "../datasources/aws-cloudwatch" >}})
|
||||
- [InfluxDB]({{< relref "../datasources/influxdb" >}})
|
||||
- [Azure Monitor]({{< relref "../datasources/azure-monitor" >}})
|
||||
|
||||
With Explore, you can efficiently monitor, troubleshoot, and respond to incidents by analyzing your logs and identifying the root causes. It also helps you to correlate logs with other telemetry signals such as metrics, traces or profiles, by viewing them side-by-side.
|
||||
|
||||
|
@ -258,6 +258,7 @@ export const defaultAzureTracesFilter: Partial<AzureTracesFilter> = {
|
||||
};
|
||||
|
||||
export enum ResultFormat {
|
||||
Logs = 'logs',
|
||||
Table = 'table',
|
||||
TimeSeries = 'time_series',
|
||||
Trace = 'trace',
|
||||
|
@ -75,6 +75,7 @@ const (
|
||||
|
||||
// Defines values for ResultFormat.
|
||||
const (
|
||||
ResultFormatLogs ResultFormat = "logs"
|
||||
ResultFormatTable ResultFormat = "table"
|
||||
ResultFormatTimeSeries ResultFormat = "time_series"
|
||||
ResultFormatTrace ResultFormat = "trace"
|
||||
|
@ -37,7 +37,7 @@ type AzureLogAnalyticsDatasource struct {
|
||||
// from the UI
|
||||
type AzureLogAnalyticsQuery struct {
|
||||
RefID string
|
||||
ResultFormat string
|
||||
ResultFormat dataquery.ResultFormat
|
||||
URL string
|
||||
TraceExploreQuery string
|
||||
TraceParentExploreQuery string
|
||||
@ -46,7 +46,7 @@ type AzureLogAnalyticsQuery struct {
|
||||
TimeRange backend.TimeRange
|
||||
Query string
|
||||
Resources []string
|
||||
QueryType string
|
||||
QueryType dataquery.AzureQueryType
|
||||
AppInsightsQuery bool
|
||||
DashboardTime bool
|
||||
TimeColumn string
|
||||
@ -242,13 +242,13 @@ func (e *AzureLogAnalyticsDatasource) buildQueries(ctx context.Context, queries
|
||||
|
||||
azureLogAnalyticsQueries = append(azureLogAnalyticsQueries, &AzureLogAnalyticsQuery{
|
||||
RefID: query.RefID,
|
||||
ResultFormat: string(resultFormat),
|
||||
ResultFormat: resultFormat,
|
||||
URL: apiURL,
|
||||
JSON: query.JSON,
|
||||
TimeRange: query.TimeRange,
|
||||
Query: rawQuery,
|
||||
Resources: resources,
|
||||
QueryType: query.QueryType,
|
||||
QueryType: dataquery.AzureQueryType(query.QueryType),
|
||||
TraceExploreQuery: traceExploreQuery,
|
||||
TraceParentExploreQuery: traceParentExploreQuery,
|
||||
TraceLogsExploreQuery: traceLogsExploreQuery,
|
||||
@ -273,8 +273,8 @@ func (e *AzureLogAnalyticsDatasource) executeQuery(ctx context.Context, query *A
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if query.QueryType == string(dataquery.AzureQueryTypeAzureTraces) {
|
||||
if dataquery.ResultFormat(query.ResultFormat) == (dataquery.ResultFormatTrace) && query.Query == "" {
|
||||
if query.QueryType == dataquery.AzureQueryTypeAzureTraces {
|
||||
if query.ResultFormat == dataquery.ResultFormatTrace && query.Query == "" {
|
||||
return nil, fmt.Errorf("cannot visualise trace events using the trace visualiser")
|
||||
}
|
||||
}
|
||||
@ -314,7 +314,7 @@ func (e *AzureLogAnalyticsDatasource) executeQuery(ctx context.Context, query *A
|
||||
return nil, err
|
||||
}
|
||||
|
||||
frame, err := ResponseTableToFrame(t, query.RefID, query.Query, dataquery.AzureQueryType(query.QueryType), dataquery.ResultFormat(query.ResultFormat))
|
||||
frame, err := ResponseTableToFrame(t, query.RefID, query.Query, query.QueryType, query.ResultFormat)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -329,12 +329,25 @@ func (e *AzureLogAnalyticsDatasource) executeQuery(ctx context.Context, query *A
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if query.QueryType == string(dataquery.AzureQueryTypeAzureTraces) && query.ResultFormat == string(dataquery.ResultFormatTrace) {
|
||||
frame.Meta.PreferredVisualization = "trace"
|
||||
queryUrl, err := getQueryUrl(query.Query, query.Resources, azurePortalBaseUrl, query.TimeRange)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if query.ResultFormat == string(dataquery.ResultFormatTable) {
|
||||
frame.Meta.PreferredVisualization = "table"
|
||||
if query.QueryType == dataquery.AzureQueryTypeAzureTraces && query.ResultFormat == dataquery.ResultFormatTrace {
|
||||
frame.Meta.PreferredVisualization = data.VisTypeTrace
|
||||
}
|
||||
|
||||
if query.ResultFormat == dataquery.ResultFormatTable {
|
||||
frame.Meta.PreferredVisualization = data.VisTypeTable
|
||||
}
|
||||
|
||||
if query.ResultFormat == dataquery.ResultFormatLogs {
|
||||
frame.Meta.PreferredVisualization = data.VisTypeLogs
|
||||
frame.Meta.Custom = &LogAnalyticsMeta{
|
||||
ColumnTypes: frame.Meta.Custom.(*LogAnalyticsMeta).ColumnTypes,
|
||||
AzurePortalLink: queryUrl,
|
||||
}
|
||||
}
|
||||
|
||||
if query.ResultFormat == types.TimeSeries {
|
||||
@ -349,82 +362,103 @@ func (e *AzureLogAnalyticsDatasource) executeQuery(ctx context.Context, query *A
|
||||
}
|
||||
}
|
||||
|
||||
queryUrl, err := getQueryUrl(query.Query, query.Resources, azurePortalBaseUrl, query.TimeRange)
|
||||
// Use the parent span query for the parent span data link
|
||||
err = addDataLinksToFields(query, azurePortalBaseUrl, frame, dsInfo, queryUrl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if query.QueryType == string(dataquery.AzureQueryTypeAzureTraces) {
|
||||
tracesUrl, err := getTracesQueryUrl(query.Resources, azurePortalBaseUrl)
|
||||
dataResponse := backend.DataResponse{Frames: data.Frames{frame}}
|
||||
return &dataResponse, nil
|
||||
}
|
||||
|
||||
func addDataLinksToFields(query *AzureLogAnalyticsQuery, azurePortalBaseUrl string, frame *data.Frame, dsInfo types.DatasourceInfo, queryUrl string) error {
|
||||
if query.QueryType == dataquery.AzureQueryTypeAzureTraces {
|
||||
err := addTraceDataLinksToFields(query, azurePortalBaseUrl, frame, dsInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
queryJSONModel := dataquery.AzureMonitorQuery{}
|
||||
err = json.Unmarshal(query.JSON, &queryJSONModel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
traceIdVariable := "${__data.fields.traceID}"
|
||||
resultFormat := dataquery.ResultFormatTrace
|
||||
queryJSONModel.AzureTraces.ResultFormat = &resultFormat
|
||||
queryJSONModel.AzureTraces.Query = &query.TraceExploreQuery
|
||||
if queryJSONModel.AzureTraces.OperationId == nil || *queryJSONModel.AzureTraces.OperationId == "" {
|
||||
queryJSONModel.AzureTraces.OperationId = &traceIdVariable
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
logsQueryType := string(dataquery.AzureQueryTypeAzureLogAnalytics)
|
||||
logsJSONModel := dataquery.AzureMonitorQuery{
|
||||
DataQuery: dataquery.DataQuery{
|
||||
QueryType: &logsQueryType,
|
||||
},
|
||||
AzureLogAnalytics: &dataquery.AzureLogsQuery{
|
||||
Query: &query.TraceLogsExploreQuery,
|
||||
Resources: []string{queryJSONModel.AzureTraces.Resources[0]},
|
||||
},
|
||||
}
|
||||
if query.ResultFormat == dataquery.ResultFormatLogs {
|
||||
return nil
|
||||
}
|
||||
|
||||
if query.ResultFormat == string(dataquery.ResultFormatTable) {
|
||||
AddCustomDataLink(*frame, data.DataLink{
|
||||
Title: "Explore Trace: ${__data.fields.traceID}",
|
||||
URL: "",
|
||||
Internal: &data.InternalDataLink{
|
||||
DatasourceUID: dsInfo.DatasourceUID,
|
||||
DatasourceName: dsInfo.DatasourceName,
|
||||
Query: queryJSONModel,
|
||||
},
|
||||
})
|
||||
AddConfigLinks(*frame, queryUrl, nil)
|
||||
|
||||
// Use the parent span query for the parent span data link
|
||||
queryJSONModel.AzureTraces.Query = &query.TraceParentExploreQuery
|
||||
AddCustomDataLink(*frame, data.DataLink{
|
||||
Title: "Explore Parent Span: ${__data.fields.parentSpanID}",
|
||||
URL: "",
|
||||
Internal: &data.InternalDataLink{
|
||||
DatasourceUID: dsInfo.DatasourceUID,
|
||||
DatasourceName: dsInfo.DatasourceName,
|
||||
Query: queryJSONModel,
|
||||
},
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
linkTitle := "Explore Trace in Azure Portal"
|
||||
AddConfigLinks(*frame, tracesUrl, &linkTitle)
|
||||
}
|
||||
func addTraceDataLinksToFields(query *AzureLogAnalyticsQuery, azurePortalBaseUrl string, frame *data.Frame, dsInfo types.DatasourceInfo) error {
|
||||
tracesUrl, err := getTracesQueryUrl(query.Resources, azurePortalBaseUrl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
queryJSONModel := dataquery.AzureMonitorQuery{}
|
||||
err = json.Unmarshal(query.JSON, &queryJSONModel)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
traceIdVariable := "${__data.fields.traceID}"
|
||||
resultFormat := dataquery.ResultFormatTrace
|
||||
queryJSONModel.AzureTraces.ResultFormat = &resultFormat
|
||||
queryJSONModel.AzureTraces.Query = &query.TraceExploreQuery
|
||||
if queryJSONModel.AzureTraces.OperationId == nil || *queryJSONModel.AzureTraces.OperationId == "" {
|
||||
queryJSONModel.AzureTraces.OperationId = &traceIdVariable
|
||||
}
|
||||
|
||||
logsQueryType := string(dataquery.AzureQueryTypeAzureLogAnalytics)
|
||||
logsJSONModel := dataquery.AzureMonitorQuery{
|
||||
DataQuery: dataquery.DataQuery{
|
||||
QueryType: &logsQueryType,
|
||||
},
|
||||
AzureLogAnalytics: &dataquery.AzureLogsQuery{
|
||||
Query: &query.TraceLogsExploreQuery,
|
||||
Resources: []string{queryJSONModel.AzureTraces.Resources[0]},
|
||||
},
|
||||
}
|
||||
|
||||
if query.ResultFormat == dataquery.ResultFormatTable {
|
||||
AddCustomDataLink(*frame, data.DataLink{
|
||||
Title: "Explore Trace Logs",
|
||||
Title: "Explore Trace: ${__data.fields.traceID}",
|
||||
URL: "",
|
||||
Internal: &data.InternalDataLink{
|
||||
DatasourceUID: dsInfo.DatasourceUID,
|
||||
DatasourceName: dsInfo.DatasourceName,
|
||||
Query: logsJSONModel,
|
||||
Query: queryJSONModel,
|
||||
},
|
||||
})
|
||||
} else {
|
||||
AddConfigLinks(*frame, queryUrl, nil)
|
||||
|
||||
queryJSONModel.AzureTraces.Query = &query.TraceParentExploreQuery
|
||||
AddCustomDataLink(*frame, data.DataLink{
|
||||
Title: "Explore Parent Span: ${__data.fields.parentSpanID}",
|
||||
URL: "",
|
||||
Internal: &data.InternalDataLink{
|
||||
DatasourceUID: dsInfo.DatasourceUID,
|
||||
DatasourceName: dsInfo.DatasourceName,
|
||||
Query: queryJSONModel,
|
||||
},
|
||||
})
|
||||
|
||||
linkTitle := "Explore Trace in Azure Portal"
|
||||
AddConfigLinks(*frame, tracesUrl, &linkTitle)
|
||||
}
|
||||
dataResponse := backend.DataResponse{Frames: data.Frames{frame}}
|
||||
return &dataResponse, nil
|
||||
|
||||
AddCustomDataLink(*frame, data.DataLink{
|
||||
Title: "Explore Trace Logs",
|
||||
URL: "",
|
||||
Internal: &data.InternalDataLink{
|
||||
DatasourceUID: dsInfo.DatasourceUID,
|
||||
DatasourceName: dsInfo.DatasourceName,
|
||||
Query: logsJSONModel,
|
||||
},
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func appendErrorNotice(frame *data.Frame, err *AzureLogAnalyticsAPIError) *data.Frame {
|
||||
@ -453,7 +487,7 @@ func (e *AzureLogAnalyticsDatasource) createRequest(ctx context.Context, queryUR
|
||||
body["query_datetimescope_column"] = query.TimeColumn
|
||||
}
|
||||
|
||||
if len(query.Resources) > 1 && query.QueryType == string(dataquery.AzureQueryTypeAzureLogAnalytics) && !query.AppInsightsQuery {
|
||||
if len(query.Resources) > 1 && query.QueryType == dataquery.AzureQueryTypeAzureLogAnalytics && !query.AppInsightsQuery {
|
||||
body["workspaces"] = query.Resources
|
||||
}
|
||||
if query.AppInsightsQuery {
|
||||
@ -701,7 +735,8 @@ func (e *AzureLogAnalyticsDatasource) unmarshalResponse(res *http.Response) (Azu
|
||||
|
||||
// LogAnalyticsMeta is a type for the a Frame's Meta's Custom property.
|
||||
type LogAnalyticsMeta struct {
|
||||
ColumnTypes []string `json:"azureColumnTypes"`
|
||||
ColumnTypes []string `json:"azureColumnTypes"`
|
||||
AzurePortalLink string `json:"azurePortalLink,omitempty"`
|
||||
}
|
||||
|
||||
// encodeQuery encodes the query in gzip so the frontend can build links.
|
||||
|
@ -130,7 +130,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
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: string(dataquery.AzureQueryTypeAzureLogAnalytics),
|
||||
QueryType: dataquery.AzureQueryTypeAzureLogAnalytics,
|
||||
AppInsightsQuery: false,
|
||||
DashboardTime: false,
|
||||
},
|
||||
@ -168,7 +168,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
}`, types.TimeSeries)),
|
||||
Query: "Perf",
|
||||
Resources: []string{},
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics),
|
||||
QueryType: dataquery.AzureQueryTypeAzureLogAnalytics,
|
||||
AppInsightsQuery: false,
|
||||
DashboardTime: false,
|
||||
},
|
||||
@ -206,7 +206,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
}`, types.TimeSeries)),
|
||||
Query: "Perf",
|
||||
Resources: []string{},
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics),
|
||||
QueryType: dataquery.AzureQueryTypeAzureLogAnalytics,
|
||||
AppInsightsQuery: false,
|
||||
DashboardTime: false,
|
||||
},
|
||||
@ -246,7 +246,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
}`, types.TimeSeries)),
|
||||
Query: "Perf",
|
||||
Resources: []string{"/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace"},
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics),
|
||||
QueryType: dataquery.AzureQueryTypeAzureLogAnalytics,
|
||||
AppInsightsQuery: false,
|
||||
DashboardTime: false,
|
||||
},
|
||||
@ -288,7 +288,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
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: string(dataquery.AzureQueryTypeAzureLogAnalytics),
|
||||
QueryType: dataquery.AzureQueryTypeAzureLogAnalytics,
|
||||
AppInsightsQuery: false,
|
||||
DashboardTime: false,
|
||||
},
|
||||
@ -332,7 +332,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
Query: "Perf",
|
||||
Resources: []string{"/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace"},
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics),
|
||||
QueryType: dataquery.AzureQueryTypeAzureLogAnalytics,
|
||||
AppInsightsQuery: false,
|
||||
DashboardTime: true,
|
||||
TimeColumn: "TimeGenerated",
|
||||
@ -362,7 +362,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{
|
||||
{
|
||||
RefID: "A",
|
||||
ResultFormat: string(dataquery.ResultFormatTable),
|
||||
ResultFormat: dataquery.ResultFormatTable,
|
||||
URL: "v1/apps/r1/query",
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
@ -387,7 +387,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
`| order by startTime asc`,
|
||||
Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"},
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
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)))` +
|
||||
@ -442,7 +442,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{
|
||||
{
|
||||
RefID: "A",
|
||||
ResultFormat: string(dataquery.ResultFormatTable),
|
||||
ResultFormat: dataquery.ResultFormatTable,
|
||||
URL: "v1/apps/r1/query",
|
||||
JSON: []byte(`{
|
||||
"queryType": "Azure Traces",
|
||||
@ -466,7 +466,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
`| order by startTime asc`,
|
||||
Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"},
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
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)))` +
|
||||
@ -520,7 +520,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{
|
||||
{
|
||||
RefID: "A",
|
||||
ResultFormat: string(dataquery.ResultFormatTable),
|
||||
ResultFormat: dataquery.ResultFormatTable,
|
||||
URL: "v1/apps/r1/query",
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
@ -542,7 +542,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
`| order by startTime asc`,
|
||||
Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"},
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
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)))` +
|
||||
@ -597,7 +597,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{
|
||||
{
|
||||
RefID: "A",
|
||||
ResultFormat: string(dataquery.ResultFormatTable),
|
||||
ResultFormat: dataquery.ResultFormatTable,
|
||||
URL: "v1/apps/r1/query",
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
@ -621,7 +621,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
`| order by startTime asc`,
|
||||
Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"},
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
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)))` +
|
||||
@ -677,7 +677,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{
|
||||
{
|
||||
RefID: "A",
|
||||
ResultFormat: string(dataquery.ResultFormatTable),
|
||||
ResultFormat: dataquery.ResultFormatTable,
|
||||
URL: "v1/apps/r1/query",
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
@ -703,7 +703,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
`| order by startTime asc`,
|
||||
Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"},
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
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)))` +
|
||||
@ -761,7 +761,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{
|
||||
{
|
||||
RefID: "A",
|
||||
ResultFormat: string(dataquery.ResultFormatTable),
|
||||
ResultFormat: dataquery.ResultFormatTable,
|
||||
URL: "v1/apps/r1/query",
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
@ -787,7 +787,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
`| order by startTime asc`,
|
||||
Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"},
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
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)))` +
|
||||
@ -845,7 +845,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{
|
||||
{
|
||||
RefID: "A",
|
||||
ResultFormat: string(dataquery.ResultFormatTable),
|
||||
ResultFormat: dataquery.ResultFormatTable,
|
||||
URL: "v1/apps/r1/query",
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
@ -871,7 +871,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
`| order by startTime asc`,
|
||||
Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"},
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
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)))` +
|
||||
@ -927,7 +927,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{
|
||||
{
|
||||
RefID: "A",
|
||||
ResultFormat: string(dataquery.ResultFormatTrace),
|
||||
ResultFormat: dataquery.ResultFormatTrace,
|
||||
URL: "v1/apps/r1/query",
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
@ -949,7 +949,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
`| order by startTime asc`,
|
||||
Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"},
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
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)))` +
|
||||
@ -1004,7 +1004,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{
|
||||
{
|
||||
RefID: "A",
|
||||
ResultFormat: string(dataquery.ResultFormatTrace),
|
||||
ResultFormat: dataquery.ResultFormatTrace,
|
||||
URL: "v1/apps/r1/query",
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
@ -1028,7 +1028,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
`| order by startTime asc`,
|
||||
Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"},
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
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)))` +
|
||||
@ -1084,7 +1084,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{
|
||||
{
|
||||
RefID: "A",
|
||||
ResultFormat: string(dataquery.ResultFormatTrace),
|
||||
ResultFormat: dataquery.ResultFormatTrace,
|
||||
URL: "v1/apps/r1/query",
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
@ -1098,7 +1098,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
Query: "",
|
||||
Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"},
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
QueryType: dataquery.AzureQueryTypeAzureTraces,
|
||||
TraceExploreQuery: "",
|
||||
TraceParentExploreQuery: "",
|
||||
TraceLogsExploreQuery: "union availabilityResults,\n" + "customEvents,\n" + "dependencies,\n" + "exceptions,\n" + "pageViews,\n" + "requests,\n" + "traces\n" +
|
||||
@ -1130,7 +1130,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{
|
||||
{
|
||||
RefID: "A",
|
||||
ResultFormat: string(dataquery.ResultFormatTrace),
|
||||
ResultFormat: dataquery.ResultFormatTrace,
|
||||
URL: "v1/apps/r1/query",
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
@ -1153,7 +1153,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
`| order by startTime asc`,
|
||||
Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1"},
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
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)))` +
|
||||
@ -1212,7 +1212,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{
|
||||
{
|
||||
RefID: "A",
|
||||
ResultFormat: string(dataquery.ResultFormatTrace),
|
||||
ResultFormat: dataquery.ResultFormatTrace,
|
||||
URL: "v1/apps/r1/query",
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
@ -1233,7 +1233,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
`| 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: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
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)))` +
|
||||
@ -1293,7 +1293,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{
|
||||
{
|
||||
RefID: "A",
|
||||
ResultFormat: string(dataquery.ResultFormatTrace),
|
||||
ResultFormat: dataquery.ResultFormatTrace,
|
||||
URL: "v1/apps/r1/query",
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
@ -1316,7 +1316,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
`| 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: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
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)))` +
|
||||
@ -1376,7 +1376,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{
|
||||
{
|
||||
RefID: "A",
|
||||
ResultFormat: string(dataquery.ResultFormatTrace),
|
||||
ResultFormat: dataquery.ResultFormatTrace,
|
||||
URL: "v1/apps/r1/query",
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
@ -1399,7 +1399,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
`| 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: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
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)))` +
|
||||
@ -1492,7 +1492,7 @@ func TestLogAnalyticsCreateRequest(t *testing.T) {
|
||||
req, err := ds.createRequest(ctx, url, &AzureLogAnalyticsQuery{
|
||||
Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.OperationalInsights/workspaces/r1", "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.OperationalInsights/workspaces/r2"},
|
||||
Query: "Perf",
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics),
|
||||
QueryType: dataquery.AzureQueryTypeAzureLogAnalytics,
|
||||
AppInsightsQuery: false,
|
||||
DashboardTime: false,
|
||||
})
|
||||
@ -1512,7 +1512,7 @@ func TestLogAnalyticsCreateRequest(t *testing.T) {
|
||||
req, err := ds.createRequest(ctx, url, &AzureLogAnalyticsQuery{
|
||||
Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.OperationalInsights/workspaces/r1", "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.OperationalInsights/workspaces/r2"},
|
||||
Query: "Perf",
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics),
|
||||
QueryType: dataquery.AzureQueryTypeAzureLogAnalytics,
|
||||
TimeRange: backend.TimeRange{
|
||||
From: from,
|
||||
To: to,
|
||||
@ -1536,7 +1536,7 @@ func TestLogAnalyticsCreateRequest(t *testing.T) {
|
||||
to := from.Add(3 * time.Hour)
|
||||
req, err := ds.createRequest(ctx, url, &AzureLogAnalyticsQuery{
|
||||
Resources: []string{"/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r1", "/subscriptions/test-sub/resourceGroups/test-rg/providers/Microsoft.Insights/components/r2"},
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
QueryType: dataquery.AzureQueryTypeAzureTraces,
|
||||
TimeRange: backend.TimeRange{
|
||||
From: from,
|
||||
To: to,
|
||||
|
@ -2,6 +2,8 @@ import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import React from 'react';
|
||||
|
||||
import { dateTime, LoadingState } from '@grafana/data';
|
||||
|
||||
import createMockDatasource from '../../__mocks__/datasource';
|
||||
import createMockQuery from '../../__mocks__/query';
|
||||
import { createMockResourcePickerData } from '../MetricsQueryEditor/MetricsQueryEditor.test';
|
||||
@ -211,4 +213,37 @@ describe('LogsQueryEditor', () => {
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
describe('azure portal link', () => {
|
||||
it('should show the link button', async () => {
|
||||
const mockDatasource = createMockDatasource({ resourcePickerData: createMockResourcePickerData() });
|
||||
const query = createMockQuery();
|
||||
const onChange = jest.fn();
|
||||
|
||||
const date = dateTime(new Date());
|
||||
render(
|
||||
<LogsQueryEditor
|
||||
query={query}
|
||||
datasource={mockDatasource}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
onChange={onChange}
|
||||
setError={() => {}}
|
||||
data={{
|
||||
state: LoadingState.Done,
|
||||
timeRange: {
|
||||
from: date,
|
||||
to: date,
|
||||
raw: {
|
||||
from: date,
|
||||
to: date,
|
||||
},
|
||||
},
|
||||
series: [{ refId: query.refId, length: 0, meta: { custom: { azurePortalLink: 'test' } }, fields: [] }],
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(await screen.findByText('View query in Azure Portal')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,7 +1,8 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import { PanelData, TimeRange } from '@grafana/data';
|
||||
import { EditorFieldGroup, EditorRow, EditorRows } from '@grafana/experimental';
|
||||
import { Alert } from '@grafana/ui';
|
||||
import { Alert, LinkButton } from '@grafana/ui';
|
||||
|
||||
import Datasource from '../../datasource';
|
||||
import { selectors } from '../../e2e/selectors';
|
||||
@ -25,6 +26,8 @@ interface LogsQueryEditorProps {
|
||||
variableOptionGroup: { label: string; options: AzureMonitorOption[] };
|
||||
setError: (source: string, error: AzureMonitorErrorish | undefined) => void;
|
||||
hideFormatAs?: boolean;
|
||||
timeRange?: TimeRange;
|
||||
data?: PanelData;
|
||||
}
|
||||
|
||||
const LogsQueryEditor = ({
|
||||
@ -35,6 +38,8 @@ const LogsQueryEditor = ({
|
||||
onChange,
|
||||
setError,
|
||||
hideFormatAs,
|
||||
timeRange,
|
||||
data,
|
||||
}: LogsQueryEditorProps) => {
|
||||
const migrationError = useMigrations(datasource, query, onChange);
|
||||
const disableRow = (row: ResourceRow, selectedRows: ResourceRowGroup) => {
|
||||
@ -60,6 +65,26 @@ const LogsQueryEditor = ({
|
||||
}
|
||||
}, [query.azureLogAnalytics?.resources, datasource.azureLogAnalyticsDatasource]);
|
||||
|
||||
let portalLinkButton = null;
|
||||
|
||||
if (data?.series) {
|
||||
const querySeries = data.series.find((result) => result.refId === query.refId);
|
||||
if (querySeries && querySeries.meta?.custom?.azurePortalLink) {
|
||||
portalLinkButton = (
|
||||
<>
|
||||
<LinkButton
|
||||
size="md"
|
||||
target="_blank"
|
||||
style={{ marginTop: '22px' }}
|
||||
href={querySeries.meta?.custom?.azurePortalLink}
|
||||
>
|
||||
View query in Azure Portal
|
||||
</LinkButton>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<span data-testid={selectors.components.queryEditor.logsQueryEditor.container.input}>
|
||||
<EditorRows>
|
||||
@ -122,15 +147,16 @@ const LogsQueryEditor = ({
|
||||
setError={setError}
|
||||
inputId={'azure-monitor-logs'}
|
||||
options={[
|
||||
{ label: 'Log', value: ResultFormat.Logs },
|
||||
{ label: 'Time series', value: ResultFormat.TimeSeries },
|
||||
{ label: 'Table', value: ResultFormat.Table },
|
||||
]}
|
||||
defaultValue={ResultFormat.Table}
|
||||
defaultValue={ResultFormat.Logs}
|
||||
setFormatAs={setFormatAs}
|
||||
resultFormat={query.azureLogAnalytics?.resultFormat}
|
||||
/>
|
||||
)}
|
||||
|
||||
{portalLinkButton}
|
||||
{migrationError && <Alert title={migrationError.title}>{migrationError.message}</Alert>}
|
||||
</EditorFieldGroup>
|
||||
</EditorRow>
|
||||
|
@ -142,12 +142,14 @@ const EditorForQueryType = ({
|
||||
case AzureQueryType.LogAnalytics:
|
||||
return (
|
||||
<LogsQueryEditor
|
||||
data={data}
|
||||
subscriptionId={subscriptionId}
|
||||
query={query}
|
||||
datasource={datasource}
|
||||
onChange={onChange}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
setError={setError}
|
||||
timeRange={range}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -149,7 +149,7 @@ composableKinds: DataQuery: {
|
||||
filters: [...string]
|
||||
} @cuetsy(kind="interface")
|
||||
|
||||
#ResultFormat: "table" | "time_series" | "trace" @cuetsy(kind="enum", memberNames="Table|TimeSeries|Trace")
|
||||
#ResultFormat: "table" | "time_series" | "trace" | "logs" @cuetsy(kind="enum", memberNames="Table|TimeSeries|Trace|Logs")
|
||||
|
||||
#AzureResourceGraphQuery: {
|
||||
// Azure Resource Graph KQL query to be executed.
|
||||
|
@ -255,6 +255,7 @@ export const defaultAzureTracesFilter: Partial<AzureTracesFilter> = {
|
||||
};
|
||||
|
||||
export enum ResultFormat {
|
||||
Logs = 'logs',
|
||||
Table = 'table',
|
||||
TimeSeries = 'time_series',
|
||||
Trace = 'trace',
|
||||
|
@ -8,6 +8,7 @@ import {
|
||||
DataQueryResponse,
|
||||
DataSourceInstanceSettings,
|
||||
LoadingState,
|
||||
QueryFixAction,
|
||||
ScopedVars,
|
||||
} from '@grafana/data';
|
||||
import { DataSourceWithBackend, getTemplateSrv, TemplateSrv } from '@grafana/runtime';
|
||||
@ -197,6 +198,27 @@ export default class Datasource extends DataSourceWithBackend<AzureMonitorQuery,
|
||||
getVariablesRaw() {
|
||||
return this.templateSrv.getVariables();
|
||||
}
|
||||
|
||||
modifyQuery(query: AzureMonitorQuery, action: QueryFixAction): AzureMonitorQuery {
|
||||
if (!action.options) {
|
||||
return query;
|
||||
}
|
||||
let expression = query.azureLogAnalytics?.query;
|
||||
if (expression === undefined) {
|
||||
return query;
|
||||
}
|
||||
switch (action.type) {
|
||||
case 'ADD_FILTER': {
|
||||
expression += `\n| where ${action.options.key} == "${action.options.value}"`;
|
||||
break;
|
||||
}
|
||||
case 'ADD_FILTER_OUT': {
|
||||
expression += `\n| where ${action.options.key} != "${action.options.value}"`;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return { ...query, azureLogAnalytics: { ...query.azureLogAnalytics, query: expression } };
|
||||
}
|
||||
}
|
||||
|
||||
function hasQueryForType(query: AzureMonitorQuery): boolean {
|
||||
|
@ -99,5 +99,6 @@
|
||||
"metrics": true,
|
||||
"annotations": true,
|
||||
"alerting": true,
|
||||
"backend": true
|
||||
"backend": true,
|
||||
"logs": true
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user