mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
AzureMonitor: Application Insights Traces (#64859)
* Build out barebones Traces editor - Add Traces query type and operation ID prop to query type - Add necessary header types - Update resource picker to appropriately work with traces query type - Build out TracesQueryEditor component - Include logic to retrieve operationId's for AI Workspaces - Add backend route mapping - Update macro to use timestamp as default time field for traces * AzureMonitor: Traces - Response parsing (#65442) * Update FormatAsField component - Add trace ResultFormat type - Generalise FormatAsField component - Add component to TracesQueryEditor - Remove duplicate code in setQueryValue * Add custom filter function to improve performance * Add basic conversion for logs to trace - Add serviceTags converter - Pass through required parameters (queryType and resultFormat) - Appropriately set visualisation * Update parsing to also fill trace tags - Add constant values for each table schema (include legacy mapping for now if needed) - Add constant for list of table tags - Set the foundation for dynamic query building - Update query to build tags value - Appropriately set operationName - Update tagsConverter to filter empty values * Fix lint and test issues * AzureMonitor: Traces - Data links (#65566) * Add portal link for traces - Pull out necessary values (itemId and itemType) - Appropriately construct - Fix ordering * Set default format as value - Also set default visualisation * Fix event schema * Set default formatAsField value * Include logs link on traces results - Adapt config links to allow custom title to be set * Correctly set operationId for query * Update backend types - Include OperationID in query - Pass forward datasource name and UID * Ensure setTime doesn't consistently get called if operationID is defined * Add explore link - Update util functions to allow setting custom datalinks * Fix tests * AzureMonitor: Traces - Query and Editor updates (#66076) * Add initial query - Will query the resource as soon as a resource has been selected - Updates the data links for the query without operationId - Remove initial operationId query and timeRange dependency - Update query building * Add entirely separate traces query property - Update shared types (also including future types for Azure traces) - Update backend log analytics datasource to accept both azureLogAnalytics and azureTraces queries - Update backend specific types - Update frontend datasource for new properties - Update mock query * Update FormatAsField to be entirely generic * Update query building to be done in backend - Add required mappings in backend - Update frontend querying * Fix query and explore data link * Add trace type selection * Better method for setting explore link * Fix operationId updating * Run go mod tidy * Unnecessary changes * Fix tests * AzureMonitor: Traces - Add correlation API support (#65855) Add correlation API support - Add necessary types - Add correlation API request when conditions are met - Update query * Fix property from merge * AzureMonitor: Traces - Filtering (#66303) * Add initial query - Will query the resource as soon as a resource has been selected - Updates the data links for the query without operationId - Remove initial operationId query and timeRange dependency - Update query building * Add entirely separate traces query property - Update shared types (also including future types for Azure traces) - Update backend log analytics datasource to accept both azureLogAnalytics and azureTraces queries - Update backend specific types - Update frontend datasource for new properties - Update mock query * Update FormatAsField to be entirely generic * Update query building to be done in backend - Add required mappings in backend - Update frontend querying * Fix query and explore data link * Add trace type selection * Better method for setting explore link * Fix operationId updating * Run go mod tidy * Unnecessary changes * Fix tests * Start building out Filters component - Configure component to query for Filter property values when a filter property is set - Add setFilters function - Add typing to tablesSchema - Use component in TracesQueryEditor * Update Filters - Asynchronously pull property options - Setup list of Filter components * Update filters component - Remove unused imports - Have local filters state and query filters - Correctly set filters values - Don't update query every time a filter property changes (not performant) * Update properties query - Use current timeRange - Get count to provide informative labels * Reset map when time changes * Add operation selection * Reset filters when property changes * Appropriate label name for empty values * Add filtering to query * Update filter components - Fix rendering issue - Correctly compare and update timeRange - Split out files for simplicity * Add checkbox option to multiselect - Add custom option component - Correctly call onChange - Add variableOptionGroup for template variable selection * Fix adding template vars * Improve labels and refresh labels on query prop changes * AzureMonitor: Traces - Testing (#66474) * Select ds for template variable interpolation * Update az logs ds tests - Add templateVariables test - Add filter test - Update mock - Remove anys * Update QueryEditor test - Update mocks with timeSrv for log analytics datasource - Fix query mock - Use appropriate and consistent selectors * Add TracesQueryEditor test - Update resourcePickerRows mock to include app insights resources - Remove comments and extra new line * Add FormatAsField test - Remove unneeded condition * Update resourcePicker utils test * Don't hide selected options in filters * Fix multi-selection on filters * Add TraceTypeField test - Add test file - Update selectors (remove copy/paste mistake) - Update placeholder text for select and add label * Add basic filters test * Begin filters test * Update filters test * Add final tests and simplify/generalise addFilter helper * Minor update to datasource test * Update macros test * Update selectors in tests * Add response-table-frame tests * Add datasource tests - Use sorting where JSON models are inconsistent - Update filters clause - Dedupe tags - Correct operationId conditions * Don't set a default value for blurInputOnSelect * Simplify datasource test * Update to use CheckGoldenJSON utils - Update with generated frame files - Remove redundant expected frame code - Update all usages * Fix lint * AzureMonitor: Traces feedback (#67292) * Filter traces if the visualisation is set to trace - Update build query logic - Added additional test cases - Return an error if the traces type is set by itself with the trace visualisation - Add descriptions to event types - Update tests * Fix bug for error displaying traces * Update mappings and add error field - Update tests - Remove unnecessary comments * Switch location of Operation ID field * Re-order fields * Update link title * Update label for event type selection * Update correct link title * Update logs datalink to link to Azure Logs in explore * Fix lint
This commit is contained in:
parent
60c4e71962
commit
63383ef545
@ -3779,8 +3779,7 @@ exports[`better eslint`] = {
|
||||
"public/app/plugins/datasource/azuremonitor/azure_log_analytics/azure_log_analytics_datasource.test.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "3"]
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
|
||||
],
|
||||
"public/app/plugins/datasource/azuremonitor/azure_log_analytics/azure_log_analytics_datasource.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
|
@ -93,6 +93,7 @@ export function SelectBase<T>({
|
||||
'aria-label': ariaLabel,
|
||||
autoFocus = false,
|
||||
backspaceRemovesValue = true,
|
||||
blurInputOnSelect,
|
||||
cacheOptions,
|
||||
className,
|
||||
closeMenuOnSelect = true,
|
||||
@ -213,6 +214,7 @@ export function SelectBase<T>({
|
||||
'aria-label': ariaLabel,
|
||||
autoFocus,
|
||||
backspaceRemovesValue,
|
||||
blurInputOnSelect,
|
||||
captureMenuScroll: false,
|
||||
closeMenuOnSelect,
|
||||
// We don't want to close if we're actually scrolling the menu
|
||||
|
@ -23,6 +23,7 @@ export interface SelectCommonProps<T> {
|
||||
/** Focus is set to the Select when rendered*/
|
||||
autoFocus?: boolean;
|
||||
backspaceRemovesValue?: boolean;
|
||||
blurInputOnSelect?: boolean;
|
||||
className?: string;
|
||||
closeMenuOnSelect?: boolean;
|
||||
/** Used for custom components. For more information, see `react-select` */
|
||||
|
@ -35,6 +35,7 @@ func ProvideService(cfg *setting.Cfg, httpClientProvider *httpclient.Provider, t
|
||||
azureMonitor: &metrics.AzureMonitorDatasource{Proxy: proxy},
|
||||
azureLogAnalytics: &loganalytics.AzureLogAnalyticsDatasource{Proxy: proxy},
|
||||
azureResourceGraph: &resourcegraph.AzureResourceGraphDatasource{Proxy: proxy},
|
||||
azureTraces: &loganalytics.AzureLogAnalyticsDatasource{Proxy: proxy},
|
||||
}
|
||||
|
||||
im := datasource.NewInstanceManager(NewInstanceSettings(cfg, httpClientProvider, executors))
|
||||
@ -86,7 +87,7 @@ func NewInstanceSettings(cfg *setting.Cfg, clientProvider *httpclient.Provider,
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading settings: %w", err)
|
||||
}
|
||||
jsonDataObj := map[string]interface{}{}
|
||||
jsonDataObj := map[string]any{}
|
||||
err = json.Unmarshal(settings.JSONData, &jsonDataObj)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading settings: %w", err)
|
||||
@ -176,6 +177,9 @@ func (s *Service) getDataSourceFromPluginReq(req *backend.QueryDataRequest) (typ
|
||||
return types.DatasourceInfo{}, fmt.Errorf("unable to convert datasource from service instance")
|
||||
}
|
||||
dsInfo.OrgID = req.PluginContext.OrgID
|
||||
|
||||
dsInfo.DatasourceName = req.PluginContext.DataSourceInstanceSettings.Name
|
||||
dsInfo.DatasourceUID = req.PluginContext.DataSourceInstanceSettings.UID
|
||||
return dsInfo, nil
|
||||
}
|
||||
|
||||
|
@ -165,6 +165,12 @@ func Test_newMux(t *testing.T) {
|
||||
expectedURL: routes[azureMonitorPublic][azureLogAnalytics].URL,
|
||||
Err: require.NoError,
|
||||
},
|
||||
{
|
||||
name: "creates an Azure Traces executor",
|
||||
queryType: azureTraces,
|
||||
expectedURL: routes[azureMonitorPublic][azureLogAnalytics].URL,
|
||||
Err: require.NoError,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
@ -189,7 +195,12 @@ func Test_newMux(t *testing.T) {
|
||||
}
|
||||
mux := s.newQueryMux()
|
||||
res, err := mux.QueryData(context.Background(), &backend.QueryDataRequest{
|
||||
PluginContext: backend.PluginContext{},
|
||||
PluginContext: backend.PluginContext{
|
||||
DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{
|
||||
Name: "datasource_name",
|
||||
UID: "datasource_UID",
|
||||
},
|
||||
},
|
||||
Queries: []backend.DataQuery{
|
||||
{QueryType: tt.queryType},
|
||||
},
|
||||
|
@ -27,12 +27,21 @@ const (
|
||||
const (
|
||||
AzureLogsQueryResultFormatTable AzureLogsQueryResultFormat = "table"
|
||||
AzureLogsQueryResultFormatTimeSeries AzureLogsQueryResultFormat = "time_series"
|
||||
AzureLogsQueryResultFormatTrace AzureLogsQueryResultFormat = "trace"
|
||||
)
|
||||
|
||||
// Defines values for AzureMonitorQueryAzureLogAnalyticsResultFormat.
|
||||
const (
|
||||
AzureMonitorQueryAzureLogAnalyticsResultFormatTable AzureMonitorQueryAzureLogAnalyticsResultFormat = "table"
|
||||
AzureMonitorQueryAzureLogAnalyticsResultFormatTimeSeries AzureMonitorQueryAzureLogAnalyticsResultFormat = "time_series"
|
||||
AzureMonitorQueryAzureLogAnalyticsResultFormatTrace AzureMonitorQueryAzureLogAnalyticsResultFormat = "trace"
|
||||
)
|
||||
|
||||
// Defines values for AzureMonitorQueryAzureTracesResultFormat.
|
||||
const (
|
||||
AzureMonitorQueryAzureTracesResultFormatTable AzureMonitorQueryAzureTracesResultFormat = "table"
|
||||
AzureMonitorQueryAzureTracesResultFormatTimeSeries AzureMonitorQueryAzureTracesResultFormat = "time_series"
|
||||
AzureMonitorQueryAzureTracesResultFormatTrace AzureMonitorQueryAzureTracesResultFormat = "trace"
|
||||
)
|
||||
|
||||
// Defines values for AzureQueryType.
|
||||
@ -46,10 +55,18 @@ const (
|
||||
AzureQueryTypeAzureResourceGroups AzureQueryType = "Azure Resource Groups"
|
||||
AzureQueryTypeAzureResourceNames AzureQueryType = "Azure Resource Names"
|
||||
AzureQueryTypeAzureSubscriptions AzureQueryType = "Azure Subscriptions"
|
||||
AzureQueryTypeAzureTraces AzureQueryType = "Azure Traces"
|
||||
AzureQueryTypeAzureWorkspaces AzureQueryType = "Azure Workspaces"
|
||||
AzureQueryTypeGrafanaTemplateVariableFunction AzureQueryType = "Grafana Template Variable Function"
|
||||
)
|
||||
|
||||
// Defines values for AzureTracesQueryResultFormat.
|
||||
const (
|
||||
AzureTracesQueryResultFormatTable AzureTracesQueryResultFormat = "table"
|
||||
AzureTracesQueryResultFormatTimeSeries AzureTracesQueryResultFormat = "time_series"
|
||||
AzureTracesQueryResultFormatTrace AzureTracesQueryResultFormat = "trace"
|
||||
)
|
||||
|
||||
// Defines values for GrafanaTemplateVariableQueryType.
|
||||
const (
|
||||
GrafanaTemplateVariableQueryTypeAppInsightsGroupByQuery GrafanaTemplateVariableQueryType = "AppInsightsGroupByQuery"
|
||||
@ -92,6 +109,7 @@ const (
|
||||
const (
|
||||
ResultFormatTable ResultFormat = "table"
|
||||
ResultFormatTimeSeries ResultFormat = "time_series"
|
||||
ResultFormatTrace ResultFormat = "trace"
|
||||
)
|
||||
|
||||
// Defines values for SubscriptionsQueryKind.
|
||||
@ -352,6 +370,36 @@ type AzureMonitorQuery struct {
|
||||
ResultFormat *string `json:"resultFormat,omitempty"`
|
||||
} `json:"azureResourceGraph,omitempty"`
|
||||
|
||||
// Application Insights Traces sub-query properties.
|
||||
AzureTraces *struct {
|
||||
// Filters for property values.
|
||||
Filters []struct {
|
||||
// Values to filter by.
|
||||
Filters []string `json:"filters"`
|
||||
|
||||
// Comparison operator to use. Either equals or not equals.
|
||||
Operation string `json:"operation"`
|
||||
|
||||
// Property name, auto-populated based on available traces.
|
||||
Property string `json:"property"`
|
||||
} `json:"filters,omitempty"`
|
||||
|
||||
// Operation ID. Used only for Traces queries.
|
||||
OperationId *string `json:"operationId,omitempty"`
|
||||
|
||||
// KQL query to be executed.
|
||||
Query *string `json:"query,omitempty"`
|
||||
|
||||
// Array of resource URIs to be queried.
|
||||
Resources []string `json:"resources,omitempty"`
|
||||
|
||||
// Specifies the format results should be returned as.
|
||||
ResultFormat *AzureMonitorQueryAzureTracesResultFormat `json:"resultFormat,omitempty"`
|
||||
|
||||
// Types of events to filter by.
|
||||
TraceTypes []string `json:"traceTypes,omitempty"`
|
||||
} `json:"azureTraces,omitempty"`
|
||||
|
||||
// For mixed data sources the selected datasource is on the query level.
|
||||
// For non mixed scenarios this is undefined.
|
||||
// TODO find a better way to do this ^ that's friendly to schema
|
||||
@ -394,6 +442,9 @@ type AzureMonitorQuery struct {
|
||||
// Specifies the format results should be returned as.
|
||||
type AzureMonitorQueryAzureLogAnalyticsResultFormat string
|
||||
|
||||
// Specifies the format results should be returned as.
|
||||
type AzureMonitorQueryAzureTracesResultFormat string
|
||||
|
||||
// @deprecated Legacy template variable support.
|
||||
type AzureMonitorQueryGrafanaTemplateVariableFn struct {
|
||||
Kind *interface{} `json:"kind,omitempty"`
|
||||
@ -428,6 +479,51 @@ type AzureResourceGraphQuery struct {
|
||||
ResultFormat *string `json:"resultFormat,omitempty"`
|
||||
}
|
||||
|
||||
// AzureTracesFilter defines model for AzureTracesFilter.
|
||||
type AzureTracesFilter struct {
|
||||
// Values to filter by.
|
||||
Filters []string `json:"filters"`
|
||||
|
||||
// Comparison operator to use. Either equals or not equals.
|
||||
Operation string `json:"operation"`
|
||||
|
||||
// Property name, auto-populated based on available traces.
|
||||
Property string `json:"property"`
|
||||
}
|
||||
|
||||
// Application Insights Traces sub-query properties
|
||||
type AzureTracesQuery struct {
|
||||
// Filters for property values.
|
||||
Filters []struct {
|
||||
// Values to filter by.
|
||||
Filters []string `json:"filters"`
|
||||
|
||||
// Comparison operator to use. Either equals or not equals.
|
||||
Operation string `json:"operation"`
|
||||
|
||||
// Property name, auto-populated based on available traces.
|
||||
Property string `json:"property"`
|
||||
} `json:"filters,omitempty"`
|
||||
|
||||
// Operation ID. Used only for Traces queries.
|
||||
OperationId *string `json:"operationId,omitempty"`
|
||||
|
||||
// KQL query to be executed.
|
||||
Query *string `json:"query,omitempty"`
|
||||
|
||||
// Array of resource URIs to be queried.
|
||||
Resources []string `json:"resources,omitempty"`
|
||||
|
||||
// Specifies the format results should be returned as.
|
||||
ResultFormat *AzureTracesQueryResultFormat `json:"resultFormat,omitempty"`
|
||||
|
||||
// Types of events to filter by.
|
||||
TraceTypes []string `json:"traceTypes,omitempty"`
|
||||
}
|
||||
|
||||
// Specifies the format results should be returned as.
|
||||
type AzureTracesQueryResultFormat string
|
||||
|
||||
// BaseGrafanaTemplateVariableQuery defines model for BaseGrafanaTemplateVariableQuery.
|
||||
type BaseGrafanaTemplateVariableQuery struct {
|
||||
RawQuery *string `json:"rawQuery,omitempty"`
|
||||
|
@ -12,14 +12,18 @@ import (
|
||||
"net/url"
|
||||
"path"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"k8s.io/utils/strings/slices"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"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"
|
||||
)
|
||||
@ -32,13 +36,16 @@ type AzureLogAnalyticsDatasource struct {
|
||||
// AzureLogAnalyticsQuery is the query request that is built from the saved values for
|
||||
// from the UI
|
||||
type AzureLogAnalyticsQuery struct {
|
||||
RefID string
|
||||
ResultFormat string
|
||||
URL string
|
||||
JSON json.RawMessage
|
||||
TimeRange backend.TimeRange
|
||||
Query string
|
||||
Resources []string
|
||||
RefID string
|
||||
ResultFormat string
|
||||
URL string
|
||||
TraceExploreQuery string
|
||||
TraceLogsExploreQuery string
|
||||
JSON json.RawMessage
|
||||
TimeRange backend.TimeRange
|
||||
Query string
|
||||
Resources []string
|
||||
QueryType string
|
||||
}
|
||||
|
||||
func (e *AzureLogAnalyticsDatasource) ResourceRequest(rw http.ResponseWriter, req *http.Request, cli *http.Client) {
|
||||
@ -64,22 +71,7 @@ func (e *AzureLogAnalyticsDatasource) ExecuteTimeSeriesQuery(ctx context.Context
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func getApiURL(queryJSONModel types.LogJSONQuery) string {
|
||||
// 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.
|
||||
azureLogAnalyticsTarget := queryJSONModel.AzureLogAnalytics
|
||||
var resourceOrWorkspace string
|
||||
|
||||
if len(azureLogAnalyticsTarget.Resources) > 0 {
|
||||
resourceOrWorkspace = azureLogAnalyticsTarget.Resources[0]
|
||||
} else if azureLogAnalyticsTarget.Resource != "" {
|
||||
resourceOrWorkspace = azureLogAnalyticsTarget.Resource
|
||||
} else {
|
||||
resourceOrWorkspace = azureLogAnalyticsTarget.Workspace
|
||||
}
|
||||
|
||||
func getApiURL(resourceOrWorkspace string) string {
|
||||
matchesResourceURI, _ := regexp.MatchString("^/subscriptions/", resourceOrWorkspace)
|
||||
|
||||
if matchesResourceURI {
|
||||
@ -93,41 +85,108 @@ func (e *AzureLogAnalyticsDatasource) buildQueries(logger log.Logger, queries []
|
||||
azureLogAnalyticsQueries := []*AzureLogAnalyticsQuery{}
|
||||
|
||||
for _, query := range queries {
|
||||
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)
|
||||
resources := []string{}
|
||||
var resourceOrWorkspace string
|
||||
var queryString string
|
||||
var resultFormat string
|
||||
traceExploreQuery := ""
|
||||
traceLogsExploreQuery := ""
|
||||
if query.QueryType == string(dataquery.AzureQueryTypeAzureLogAnalytics) {
|
||||
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)
|
||||
}
|
||||
|
||||
azureLogAnalyticsTarget := queryJSONModel.AzureLogAnalytics
|
||||
logger.Debug("AzureLogAnalytics", "target", azureLogAnalyticsTarget)
|
||||
|
||||
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]
|
||||
} else if azureLogAnalyticsTarget.Resource != "" {
|
||||
resources = []string{azureLogAnalyticsTarget.Resource}
|
||||
resourceOrWorkspace = azureLogAnalyticsTarget.Resource
|
||||
} else {
|
||||
resourceOrWorkspace = azureLogAnalyticsTarget.Workspace
|
||||
}
|
||||
|
||||
queryString = azureLogAnalyticsTarget.Query
|
||||
}
|
||||
|
||||
azureLogAnalyticsTarget := queryJSONModel.AzureLogAnalytics
|
||||
logger.Debug("AzureLogAnalytics", "target", azureLogAnalyticsTarget)
|
||||
if query.QueryType == string(dataquery.AzureQueryTypeAzureTraces) {
|
||||
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)
|
||||
}
|
||||
|
||||
resultFormat := azureLogAnalyticsTarget.ResultFormat
|
||||
if resultFormat == "" {
|
||||
resultFormat = types.TimeSeries
|
||||
azureTracesTarget := queryJSONModel.AzureTraces
|
||||
logger.Debug("AzureTraces", "target", azureTracesTarget)
|
||||
|
||||
if azureTracesTarget.ResultFormat == nil {
|
||||
resultFormat = types.Table
|
||||
} else {
|
||||
resultFormat = string(*azureTracesTarget.ResultFormat)
|
||||
if resultFormat == "" {
|
||||
resultFormat = types.Table
|
||||
}
|
||||
}
|
||||
|
||||
resources = azureTracesTarget.Resources
|
||||
resourceOrWorkspace = azureTracesTarget.Resources[0]
|
||||
|
||||
operationId := ""
|
||||
if queryJSONModel.AzureTraces.OperationId != nil {
|
||||
operationId = *queryJSONModel.AzureTraces.OperationId
|
||||
}
|
||||
|
||||
queryString = buildTracesQuery(operationId, queryJSONModel.AzureTraces.TraceTypes, queryJSONModel.AzureTraces.Filters, &resultFormat)
|
||||
traceIdVariable := "${__data.fields.traceID}"
|
||||
if operationId == "" {
|
||||
traceExploreQuery = buildTracesQuery(traceIdVariable, queryJSONModel.AzureTraces.TraceTypes, queryJSONModel.AzureTraces.Filters, nil)
|
||||
traceLogsExploreQuery = buildTracesLogsQuery(&traceIdVariable)
|
||||
} else {
|
||||
traceExploreQuery = queryString
|
||||
traceLogsExploreQuery = buildTracesLogsQuery(&operationId)
|
||||
}
|
||||
traceExploreQuery, err = macros.KqlInterpolate(logger, query, dsInfo, traceExploreQuery, "TimeGenerated")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create traces explore query: %s", err)
|
||||
}
|
||||
traceLogsExploreQuery, err = macros.KqlInterpolate(logger, query, dsInfo, traceLogsExploreQuery, "TimeGenerated")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create traces logs explore query: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
apiURL := getApiURL(queryJSONModel)
|
||||
apiURL := getApiURL(resourceOrWorkspace)
|
||||
|
||||
rawQuery, err := macros.KqlInterpolate(logger, query, dsInfo, azureLogAnalyticsTarget.Query, "TimeGenerated")
|
||||
rawQuery, err := macros.KqlInterpolate(logger, query, dsInfo, queryString, "TimeGenerated")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resources := []string{}
|
||||
if len(azureLogAnalyticsTarget.Resources) > 0 {
|
||||
resources = azureLogAnalyticsTarget.Resources
|
||||
} else if azureLogAnalyticsTarget.Resource != "" {
|
||||
resources = []string{azureLogAnalyticsTarget.Resource}
|
||||
}
|
||||
azureLogAnalyticsQueries = append(azureLogAnalyticsQueries, &AzureLogAnalyticsQuery{
|
||||
RefID: query.RefID,
|
||||
ResultFormat: resultFormat,
|
||||
URL: apiURL,
|
||||
JSON: query.JSON,
|
||||
TimeRange: query.TimeRange,
|
||||
Query: rawQuery,
|
||||
Resources: resources,
|
||||
RefID: query.RefID,
|
||||
ResultFormat: resultFormat,
|
||||
URL: apiURL,
|
||||
JSON: query.JSON,
|
||||
TimeRange: query.TimeRange,
|
||||
Query: rawQuery,
|
||||
Resources: resources,
|
||||
QueryType: query.QueryType,
|
||||
TraceExploreQuery: traceExploreQuery,
|
||||
TraceLogsExploreQuery: traceLogsExploreQuery,
|
||||
})
|
||||
}
|
||||
|
||||
@ -156,6 +215,26 @@ func (e *AzureLogAnalyticsDatasource) executeQuery(ctx context.Context, logger l
|
||||
return dataResponseErrorWithExecuted(fmt.Errorf("credentials for Log Analytics are no longer supported. Go to the data source configuration to update Azure Monitor credentials"))
|
||||
}
|
||||
|
||||
queryJSONModel := dataquery.AzureMonitorQuery{}
|
||||
err := json.Unmarshal(query.JSON, &queryJSONModel)
|
||||
if err != nil {
|
||||
dataResponse.Error = err
|
||||
return dataResponse
|
||||
}
|
||||
|
||||
if query.QueryType == string(dataquery.AzureQueryTypeAzureTraces) {
|
||||
if queryJSONModel.AzureTraces.OperationId != nil && *queryJSONModel.AzureTraces.OperationId != "" {
|
||||
query, err = getCorrelationWorkspaces(ctx, logger, query, dsInfo, *queryJSONModel.AzureTraces.OperationId, tracer)
|
||||
if err != nil {
|
||||
dataResponse.Error = err
|
||||
return dataResponse
|
||||
}
|
||||
}
|
||||
if dataquery.ResultFormat(query.ResultFormat) == (dataquery.ResultFormatTrace) && query.Query == "" {
|
||||
return dataResponseErrorWithExecuted(fmt.Errorf("cannot visualise trace events using the trace visualiser"))
|
||||
}
|
||||
}
|
||||
|
||||
req, err := e.createRequest(ctx, logger, url, query)
|
||||
if err != nil {
|
||||
dataResponse.Error = err
|
||||
@ -196,7 +275,7 @@ func (e *AzureLogAnalyticsDatasource) executeQuery(ctx context.Context, logger l
|
||||
return dataResponseErrorWithExecuted(err)
|
||||
}
|
||||
|
||||
frame, err := ResponseTableToFrame(t, query.RefID, query.Query)
|
||||
frame, err := ResponseTableToFrame(t, query.RefID, query.Query, dataquery.AzureQueryType(query.QueryType), dataquery.ResultFormat(query.ResultFormat))
|
||||
if err != nil {
|
||||
return dataResponseErrorWithExecuted(err)
|
||||
}
|
||||
@ -211,10 +290,12 @@ func (e *AzureLogAnalyticsDatasource) executeQuery(ctx context.Context, logger l
|
||||
return dataResponse
|
||||
}
|
||||
|
||||
queryUrl, err := getQueryUrl(query.Query, query.Resources, azurePortalBaseUrl)
|
||||
if err != nil {
|
||||
dataResponse.Error = err
|
||||
return dataResponse
|
||||
if query.QueryType == string(dataquery.AzureQueryTypeAzureTraces) && query.ResultFormat == string(dataquery.ResultFormatTrace) {
|
||||
frame.Meta.PreferredVisualization = "trace"
|
||||
}
|
||||
|
||||
if query.ResultFormat == string(dataquery.ResultFormatTable) {
|
||||
frame.Meta.PreferredVisualization = "table"
|
||||
}
|
||||
|
||||
if query.ResultFormat == types.TimeSeries {
|
||||
@ -229,7 +310,72 @@ func (e *AzureLogAnalyticsDatasource) executeQuery(ctx context.Context, logger l
|
||||
}
|
||||
}
|
||||
|
||||
AddConfigLinks(*frame, queryUrl)
|
||||
queryUrl, err := getQueryUrl(query.Query, query.Resources, azurePortalBaseUrl)
|
||||
if err != nil {
|
||||
dataResponse.Error = err
|
||||
return dataResponse
|
||||
}
|
||||
|
||||
if query.QueryType == string(dataquery.AzureQueryTypeAzureTraces) {
|
||||
tracesUrl, err := getTracesQueryUrl(query.Resources, azurePortalBaseUrl)
|
||||
if err != nil {
|
||||
dataResponse.Error = err
|
||||
return dataResponse
|
||||
}
|
||||
linkTitle := "Explore Trace in Azure Portal"
|
||||
AddConfigLinks(*frame, tracesUrl, &linkTitle)
|
||||
|
||||
queryJSONModel := dataquery.AzureMonitorQuery{}
|
||||
err = json.Unmarshal(query.JSON, &queryJSONModel)
|
||||
if err != nil {
|
||||
dataResponse.Error = err
|
||||
return dataResponse
|
||||
}
|
||||
traceIdVariable := "${__data.fields.traceID}"
|
||||
resultFormat := dataquery.AzureMonitorQueryAzureTracesResultFormatTrace
|
||||
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{
|
||||
AzureLogAnalytics: &struct {
|
||||
Query *string "json:\"query,omitempty\""
|
||||
Resource *string "json:\"resource,omitempty\""
|
||||
Resources []string "json:\"resources,omitempty\""
|
||||
ResultFormat *dataquery.AzureMonitorQueryAzureLogAnalyticsResultFormat "json:\"resultFormat,omitempty\""
|
||||
Workspace *string "json:\"workspace,omitempty\""
|
||||
}{
|
||||
Resources: queryJSONModel.AzureTraces.Resources,
|
||||
Query: &query.TraceLogsExploreQuery,
|
||||
},
|
||||
QueryType: &logsQueryType,
|
||||
}
|
||||
|
||||
AddCustomDataLink(*frame, data.DataLink{
|
||||
Title: "Explore Trace: ${__data.fields.traceID}",
|
||||
URL: "",
|
||||
Internal: &data.InternalDataLink{
|
||||
DatasourceUID: dsInfo.DatasourceUID,
|
||||
DatasourceName: dsInfo.DatasourceName,
|
||||
Query: queryJSONModel,
|
||||
},
|
||||
})
|
||||
|
||||
AddCustomDataLink(*frame, data.DataLink{
|
||||
Title: "Explore Trace Logs",
|
||||
URL: "",
|
||||
Internal: &data.InternalDataLink{
|
||||
DatasourceUID: dsInfo.DatasourceUID,
|
||||
DatasourceName: dsInfo.DatasourceName,
|
||||
Query: logsJSONModel,
|
||||
},
|
||||
})
|
||||
} else {
|
||||
AddConfigLinks(*frame, queryUrl, nil)
|
||||
}
|
||||
|
||||
dataResponse.Frames = data.Frames{frame}
|
||||
return dataResponse
|
||||
@ -307,6 +453,113 @@ func getQueryUrl(query string, resources []string, azurePortalUrl string) (strin
|
||||
return portalUrl, nil
|
||||
}
|
||||
|
||||
func getTracesQueryUrl(resources []string, azurePortalUrl string) (string, error) {
|
||||
portalUrl := azurePortalUrl
|
||||
portalUrl += "/#view/AppInsightsExtension/DetailsV2Blade/ComponentId~/"
|
||||
resource := struct {
|
||||
ResourceId string `json:"ResourceId"`
|
||||
}{
|
||||
resources[0],
|
||||
}
|
||||
resourceMarshalled, err := json.Marshal(resource)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to marshal application insights resource: %s", err)
|
||||
}
|
||||
|
||||
portalUrl += url.PathEscape(string(resourceMarshalled))
|
||||
portalUrl += "/DataModel~/"
|
||||
|
||||
// We're making use of data link variables to select the necessary fields in the frontend
|
||||
eventId := "%22eventId%22%3A%22${__data.fields.itemId}%22%2C"
|
||||
timestamp := "%22timestamp%22%3A%22${__data.fields.startTime}%22%2C"
|
||||
eventTable := "%22eventTable%22%3A%22${__data.fields.itemType}%22"
|
||||
traceObject := fmt.Sprintf("%%7B%s%s%s%%7D", eventId, timestamp, eventTable)
|
||||
|
||||
portalUrl += traceObject
|
||||
|
||||
return portalUrl, nil
|
||||
}
|
||||
|
||||
func getCorrelationWorkspaces(ctx context.Context, logger log.Logger, query *AzureLogAnalyticsQuery, dsInfo types.DatasourceInfo, operationId string, tracer tracing.Tracer) (*AzureLogAnalyticsQuery, error) {
|
||||
azMonService := dsInfo.Services["Azure Monitor"]
|
||||
correlationUrl := azMonService.URL + fmt.Sprintf("%s/providers/microsoft.insights/transactions/%s", query.Resources[0], operationId)
|
||||
|
||||
callCorrelationAPI := func(url string) (AzureCorrelationAPIResponse, error) {
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewBuffer([]byte{}))
|
||||
if err != nil {
|
||||
logger.Debug("Failed to create request", "error", err)
|
||||
return AzureCorrelationAPIResponse{}, fmt.Errorf("%v: %w", "failed to create request", err)
|
||||
}
|
||||
req.URL.Path = url
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
values := req.URL.Query()
|
||||
values.Add("api-version", "2019-10-17-preview")
|
||||
req.URL.RawQuery = values.Encode()
|
||||
req.Method = "GET"
|
||||
|
||||
ctx, span := tracer.Start(ctx, "azure traces correlation request")
|
||||
span.SetAttributes("target", req.URL, attribute.Key("target").String(req.URL.String()))
|
||||
span.SetAttributes("datasource_id", dsInfo.DatasourceID, attribute.Key("datasource_id").Int64(dsInfo.DatasourceID))
|
||||
span.SetAttributes("org_id", dsInfo.OrgID, attribute.Key("org_id").Int64(dsInfo.OrgID))
|
||||
|
||||
defer span.End()
|
||||
|
||||
tracer.Inject(ctx, req.Header, span)
|
||||
|
||||
logger.Debug("AzureLogAnalytics", "Traces Correlation ApiURL", req.URL.String())
|
||||
res, err := azMonService.HTTPClient.Do(req)
|
||||
if err != nil {
|
||||
return AzureCorrelationAPIResponse{}, err
|
||||
}
|
||||
body, err := io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return AzureCorrelationAPIResponse{}, err
|
||||
}
|
||||
defer func() {
|
||||
err := res.Body.Close()
|
||||
if err != nil {
|
||||
logger.Warn("failed to close response body", "error", err)
|
||||
}
|
||||
}()
|
||||
|
||||
if res.StatusCode/100 != 2 {
|
||||
logger.Debug("Request failed", "status", res.Status, "body", string(body))
|
||||
return AzureCorrelationAPIResponse{}, fmt.Errorf("request failed, status: %s, body: %s", res.Status, string(body))
|
||||
}
|
||||
var data AzureCorrelationAPIResponse
|
||||
d := json.NewDecoder(bytes.NewReader(body))
|
||||
d.UseNumber()
|
||||
err = d.Decode(&data)
|
||||
if err != nil {
|
||||
logger.Debug("Failed to unmarshal Azure Traces correlation API response", "error", err, "status", res.Status, "body", string(body))
|
||||
return AzureCorrelationAPIResponse{}, err
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
var nextLink *string
|
||||
var correlationResponse AzureCorrelationAPIResponse
|
||||
|
||||
correlationResponse, err := callCorrelationAPI(correlationUrl)
|
||||
if err != nil {
|
||||
return query, err
|
||||
}
|
||||
nextLink = correlationResponse.Properties.NextLink
|
||||
query.Resources = correlationResponse.Properties.Resources
|
||||
|
||||
for nextLink != nil {
|
||||
correlationResponse, err := callCorrelationAPI(correlationUrl)
|
||||
if err != nil {
|
||||
return query, err
|
||||
}
|
||||
query.Resources = append(query.Resources, correlationResponse.Properties.Resources...)
|
||||
nextLink = correlationResponse.Properties.NextLink
|
||||
}
|
||||
|
||||
return query, 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 {
|
||||
@ -334,6 +587,19 @@ type AzureLogAnalyticsResponse struct {
|
||||
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) {
|
||||
@ -392,3 +658,94 @@ func encodeQuery(rawQuery string) (string, error) {
|
||||
|
||||
return base64.StdEncoding.EncodeToString(b.Bytes()), nil
|
||||
}
|
||||
|
||||
func buildTracesQuery(operationId string, traceTypes []string, filters []types.TracesFilters, resultFormat *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 && dataquery.ResultFormat(*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 ""
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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 := ""
|
||||
if slices.Contains(filteredTypes, "exceptions") {
|
||||
errorProperty = `| extend error = iff(itemType == "exceptions", true, false)`
|
||||
}
|
||||
|
||||
baseQuery := fmt.Sprintf(`set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true %s | where $__timeFilter()`, strings.Join(filteredTypes, ","))
|
||||
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 + propertiesStaticQuery + propertiesQuery + errorProperty + filtersClause + projectClause
|
||||
}
|
||||
|
||||
func buildTracesLogsQuery(operationId *string) string {
|
||||
tables := `union *, traces, customEvents, pageViews, requests, dependencies, exceptions, customMetrics, availabilityResults`
|
||||
time := `| where $__timeFilter()`
|
||||
operationIdFilter := fmt.Sprintf(`| where operation_Id == "%s"`, *operationId)
|
||||
return strings.Join([]string{tables, time, operationIdFilter}, " \n")
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/kinds/dataquery"
|
||||
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/types"
|
||||
)
|
||||
|
||||
@ -45,6 +46,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
}`, types.TimeSeries)),
|
||||
RefID: "A",
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics),
|
||||
},
|
||||
},
|
||||
azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{
|
||||
@ -63,11 +65,11 @@ 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),
|
||||
},
|
||||
},
|
||||
Err: require.NoError,
|
||||
},
|
||||
|
||||
{
|
||||
name: "Legacy queries with a workspace GUID should use workspace-centric url",
|
||||
queryModel: []backend.DataQuery{
|
||||
@ -80,7 +82,8 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
"resultFormat": "%s"
|
||||
}
|
||||
}`, types.TimeSeries)),
|
||||
RefID: "A",
|
||||
RefID: "A",
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics),
|
||||
},
|
||||
},
|
||||
azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{
|
||||
@ -98,11 +101,11 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
}`, types.TimeSeries)),
|
||||
Query: "Perf",
|
||||
Resources: []string{},
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics),
|
||||
},
|
||||
},
|
||||
Err: require.NoError,
|
||||
},
|
||||
|
||||
{
|
||||
name: "Legacy workspace queries with a resource URI (from a template variable) should use resource-centric url",
|
||||
queryModel: []backend.DataQuery{
|
||||
@ -115,7 +118,8 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
"resultFormat": "%s"
|
||||
}
|
||||
}`, types.TimeSeries)),
|
||||
RefID: "A",
|
||||
RefID: "A",
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics),
|
||||
},
|
||||
},
|
||||
azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{
|
||||
@ -133,11 +137,11 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
}`, types.TimeSeries)),
|
||||
Query: "Perf",
|
||||
Resources: []string{},
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics),
|
||||
},
|
||||
},
|
||||
Err: require.NoError,
|
||||
},
|
||||
|
||||
{
|
||||
name: "Queries with multiple resources",
|
||||
queryModel: []backend.DataQuery{
|
||||
@ -150,7 +154,8 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
"resultFormat": "%s"
|
||||
}
|
||||
}`, types.TimeSeries)),
|
||||
RefID: "A",
|
||||
RefID: "A",
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics),
|
||||
},
|
||||
},
|
||||
azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{
|
||||
@ -168,6 +173,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),
|
||||
},
|
||||
},
|
||||
Err: require.NoError,
|
||||
@ -186,6 +192,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
}`, types.TimeSeries)),
|
||||
RefID: "A",
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics),
|
||||
},
|
||||
},
|
||||
azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{
|
||||
@ -204,6 +211,632 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
Query: "Perf",
|
||||
Resources: []string{"/subscriptions/r1", "/subscriptions/r2"},
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureLogAnalytics),
|
||||
},
|
||||
},
|
||||
Err: require.NoError,
|
||||
},
|
||||
|
||||
{
|
||||
name: "trace query",
|
||||
queryModel: []backend.DataQuery{
|
||||
{
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
"azureTraces": {
|
||||
"resources": ["/subscriptions/r1"],
|
||||
"resultFormat": "%s",
|
||||
"traceTypes": ["trace"],
|
||||
"operationId": "test-op-id"
|
||||
}
|
||||
}`, dataquery.ResultFormatTable)),
|
||||
RefID: "A",
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
},
|
||||
},
|
||||
azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{
|
||||
{
|
||||
RefID: "A",
|
||||
ResultFormat: string(dataquery.ResultFormatTable),
|
||||
URL: "v1/subscriptions/r1/query",
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
"azureTraces": {
|
||||
"resources": ["/subscriptions/r1"],
|
||||
"resultFormat": "%s",
|
||||
"traceTypes": ["trace"],
|
||||
"operationId": "test-op-id"
|
||||
}
|
||||
}`, dataquery.ResultFormatTable)),
|
||||
Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true trace | where ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z')` +
|
||||
`| 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 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/r1"},
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true trace | where ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z')` +
|
||||
`| 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 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 *, traces, customEvents, pageViews, requests, dependencies, exceptions, customMetrics, availabilityResults \n" +
|
||||
"| where ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z') \n" +
|
||||
"| where operation_Id == \"test-op-id\"",
|
||||
},
|
||||
},
|
||||
Err: require.NoError,
|
||||
},
|
||||
{
|
||||
name: "trace query with no result format set",
|
||||
queryModel: []backend.DataQuery{
|
||||
{
|
||||
JSON: []byte(`{
|
||||
"queryType": "Azure Traces",
|
||||
"azureTraces": {
|
||||
"resources": ["/subscriptions/r1"],
|
||||
"traceTypes": ["trace"],
|
||||
"operationId": "test-op-id"
|
||||
}
|
||||
}`),
|
||||
RefID: "A",
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
},
|
||||
},
|
||||
azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{
|
||||
{
|
||||
RefID: "A",
|
||||
ResultFormat: string(dataquery.ResultFormatTable),
|
||||
URL: "v1/subscriptions/r1/query",
|
||||
JSON: []byte(`{
|
||||
"queryType": "Azure Traces",
|
||||
"azureTraces": {
|
||||
"resources": ["/subscriptions/r1"],
|
||||
"traceTypes": ["trace"],
|
||||
"operationId": "test-op-id"
|
||||
}
|
||||
}`),
|
||||
Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true trace | where ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z')` +
|
||||
`| 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 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/r1"},
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true trace | where ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z')` +
|
||||
`| 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 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 *, traces, customEvents, pageViews, requests, dependencies, exceptions, customMetrics, availabilityResults \n" +
|
||||
"| where ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z') \n" +
|
||||
"| where operation_Id == \"test-op-id\"",
|
||||
},
|
||||
},
|
||||
Err: require.NoError,
|
||||
},
|
||||
{
|
||||
name: "trace query with no operation ID",
|
||||
queryModel: []backend.DataQuery{
|
||||
{
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
"azureTraces": {
|
||||
"resources": ["/subscriptions/r1"],
|
||||
"resultFormat": "%s"
|
||||
}
|
||||
}`, dataquery.ResultFormatTable)),
|
||||
RefID: "A",
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
},
|
||||
},
|
||||
azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{
|
||||
{
|
||||
RefID: "A",
|
||||
ResultFormat: string(dataquery.ResultFormatTable),
|
||||
URL: "v1/subscriptions/r1/query",
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
"azureTraces": {
|
||||
"resources": ["/subscriptions/r1"],
|
||||
"resultFormat": "%s"
|
||||
}
|
||||
}`, dataquery.ResultFormatTable)),
|
||||
Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces | where ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z')` +
|
||||
`| 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 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,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)` +
|
||||
`| extend error = iff(itemType == "exceptions", true, false)` +
|
||||
`| 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/r1"},
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces | where ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z')` +
|
||||
`| 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 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,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)` +
|
||||
`| extend error = iff(itemType == "exceptions", true, false)` +
|
||||
`| 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 *, traces, customEvents, pageViews, requests, dependencies, exceptions, customMetrics, availabilityResults \n" +
|
||||
"| where ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z') \n" +
|
||||
"| where operation_Id == \"${__data.fields.traceID}\"",
|
||||
},
|
||||
},
|
||||
Err: require.NoError,
|
||||
},
|
||||
{
|
||||
name: "trace query with no types",
|
||||
queryModel: []backend.DataQuery{
|
||||
{
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
"azureTraces": {
|
||||
"resources": ["/subscriptions/r1"],
|
||||
"resultFormat": "%s",
|
||||
"operationId": "test-op-id"
|
||||
}
|
||||
}`, dataquery.ResultFormatTable)),
|
||||
RefID: "A",
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
},
|
||||
},
|
||||
azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{
|
||||
{
|
||||
RefID: "A",
|
||||
ResultFormat: string(dataquery.ResultFormatTable),
|
||||
URL: "v1/subscriptions/r1/query",
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
"azureTraces": {
|
||||
"resources": ["/subscriptions/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 ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z')` +
|
||||
`| 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 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,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)` +
|
||||
`| extend error = iff(itemType == "exceptions", true, false)` +
|
||||
`| 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/r1"},
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces | where ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z')` +
|
||||
`| 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 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,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)` +
|
||||
`| extend error = iff(itemType == "exceptions", true, false)` +
|
||||
`| 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 *, traces, customEvents, pageViews, requests, dependencies, exceptions, customMetrics, availabilityResults \n" +
|
||||
"| where ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z') \n" +
|
||||
"| where operation_Id == \"test-op-id\"",
|
||||
},
|
||||
},
|
||||
Err: require.NoError,
|
||||
},
|
||||
{
|
||||
name: "trace query with eq filter",
|
||||
queryModel: []backend.DataQuery{
|
||||
{
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
"azureTraces": {
|
||||
"resources": ["/subscriptions/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: string(dataquery.ResultFormatTable),
|
||||
URL: "v1/subscriptions/r1/query",
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
"azureTraces": {
|
||||
"resources": ["/subscriptions/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 ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z')` +
|
||||
`| 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 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,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)` +
|
||||
`| extend error = iff(itemType == "exceptions", true, false)` +
|
||||
`| 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/r1"},
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces | where ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z')` +
|
||||
`| 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 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,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)` +
|
||||
`| extend error = iff(itemType == "exceptions", true, false)` +
|
||||
`| 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 *, traces, customEvents, pageViews, requests, dependencies, exceptions, customMetrics, availabilityResults \n" +
|
||||
"| where ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z') \n" +
|
||||
"| where operation_Id == \"test-op-id\"",
|
||||
},
|
||||
},
|
||||
Err: require.NoError,
|
||||
},
|
||||
{
|
||||
name: "trace query with ne filter",
|
||||
queryModel: []backend.DataQuery{
|
||||
{
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
"azureTraces": {
|
||||
"resources": ["/subscriptions/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: string(dataquery.ResultFormatTable),
|
||||
URL: "v1/subscriptions/r1/query",
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
"azureTraces": {
|
||||
"resources": ["/subscriptions/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 ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z')` +
|
||||
`| 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 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,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)` +
|
||||
`| extend error = iff(itemType == "exceptions", true, false)` +
|
||||
`| 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/r1"},
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces | where ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z')` +
|
||||
`| 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 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,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)` +
|
||||
`| extend error = iff(itemType == "exceptions", true, false)` +
|
||||
`| 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 *, traces, customEvents, pageViews, requests, dependencies, exceptions, customMetrics, availabilityResults \n" +
|
||||
"| where ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z') \n" +
|
||||
"| where operation_Id == \"test-op-id\"",
|
||||
},
|
||||
},
|
||||
Err: require.NoError,
|
||||
},
|
||||
{
|
||||
name: "trace query with multiple filters",
|
||||
queryModel: []backend.DataQuery{
|
||||
{
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
"azureTraces": {
|
||||
"resources": ["/subscriptions/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: string(dataquery.ResultFormatTable),
|
||||
URL: "v1/subscriptions/r1/query",
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
"azureTraces": {
|
||||
"resources": ["/subscriptions/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 ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z')` +
|
||||
`| 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 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,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)` +
|
||||
`| extend error = iff(itemType == "exceptions", true, false)` +
|
||||
`| 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/r1"},
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces | where ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z')` +
|
||||
`| 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 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,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)` +
|
||||
`| extend error = iff(itemType == "exceptions", true, false)` +
|
||||
`| 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 *, traces, customEvents, pageViews, requests, dependencies, exceptions, customMetrics, availabilityResults \n" +
|
||||
"| where ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z') \n" +
|
||||
"| where operation_Id == \"test-op-id\"",
|
||||
},
|
||||
},
|
||||
Err: require.NoError,
|
||||
},
|
||||
{
|
||||
name: "trace query with trace result format",
|
||||
queryModel: []backend.DataQuery{
|
||||
{
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
"azureTraces": {
|
||||
"resources": ["/subscriptions/r1"],
|
||||
"resultFormat": "%s"
|
||||
}
|
||||
}`, dataquery.ResultFormatTrace)),
|
||||
RefID: "A",
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
},
|
||||
},
|
||||
azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{
|
||||
{
|
||||
RefID: "A",
|
||||
ResultFormat: string(dataquery.ResultFormatTrace),
|
||||
URL: "v1/subscriptions/r1/query",
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
"azureTraces": {
|
||||
"resources": ["/subscriptions/r1"],
|
||||
"resultFormat": "%s"
|
||||
}
|
||||
}`, dataquery.ResultFormatTrace)),
|
||||
Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests | where ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z')` +
|
||||
`| 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 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,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)` +
|
||||
`| extend error = iff(itemType == "exceptions", true, false)` +
|
||||
`| 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/r1"},
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests,traces | where ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z')` +
|
||||
`| 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 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,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)` +
|
||||
`| extend error = iff(itemType == "exceptions", true, false)` +
|
||||
`| 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 *, traces, customEvents, pageViews, requests, dependencies, exceptions, customMetrics, availabilityResults \n" +
|
||||
"| where ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z') \n" +
|
||||
"| where operation_Id == \"${__data.fields.traceID}\"",
|
||||
},
|
||||
},
|
||||
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/r1"],
|
||||
"resultFormat": "%s"
|
||||
}
|
||||
}`, dataquery.ResultFormatTrace)),
|
||||
RefID: "A",
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
},
|
||||
},
|
||||
azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{
|
||||
{
|
||||
RefID: "A",
|
||||
ResultFormat: string(dataquery.ResultFormatTrace),
|
||||
URL: "v1/subscriptions/r1/query",
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
"azureTraces": {
|
||||
"operationId": "test-op-id",
|
||||
"resources": ["/subscriptions/r1"],
|
||||
"resultFormat": "%s"
|
||||
}
|
||||
}`, dataquery.ResultFormatTrace)),
|
||||
Query: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests | where ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z')` +
|
||||
`| 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 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,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)` +
|
||||
`| extend error = iff(itemType == "exceptions", true, false)` +
|
||||
`| 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/r1"},
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
TraceExploreQuery: `set truncationmaxrecords=10000; set truncationmaxsize=67108864; union isfuzzy=true availabilityResults,customEvents,dependencies,exceptions,pageViews,requests | where ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z')` +
|
||||
`| 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 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,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)` +
|
||||
`| extend error = iff(itemType == "exceptions", true, false)` +
|
||||
`| 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 *, traces, customEvents, pageViews, requests, dependencies, exceptions, customMetrics, availabilityResults \n" +
|
||||
"| where ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z') \n" +
|
||||
"| where operation_Id == \"test-op-id\"",
|
||||
},
|
||||
},
|
||||
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/r1"],
|
||||
"resultFormat": "%s",
|
||||
"traceTypes": ["traces"]
|
||||
}
|
||||
}`, dataquery.ResultFormatTrace)),
|
||||
RefID: "A",
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
},
|
||||
},
|
||||
azureLogAnalyticsQueries: []*AzureLogAnalyticsQuery{
|
||||
{
|
||||
RefID: "A",
|
||||
ResultFormat: string(dataquery.ResultFormatTrace),
|
||||
URL: "v1/subscriptions/r1/query",
|
||||
JSON: []byte(fmt.Sprintf(`{
|
||||
"queryType": "Azure Traces",
|
||||
"azureTraces": {
|
||||
"operationId": "test-op-id",
|
||||
"resources": ["/subscriptions/r1"],
|
||||
"resultFormat": "%s",
|
||||
"traceTypes": ["traces"]
|
||||
}
|
||||
}`, dataquery.ResultFormatTrace)),
|
||||
Query: "",
|
||||
Resources: []string{"/subscriptions/r1"},
|
||||
TimeRange: timeRange,
|
||||
QueryType: string(dataquery.AzureQueryTypeAzureTraces),
|
||||
TraceExploreQuery: "",
|
||||
TraceLogsExploreQuery: "union *, traces, customEvents, pageViews, requests, dependencies, exceptions, customMetrics, availabilityResults \n" +
|
||||
"| where ['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z') \n" +
|
||||
"| where operation_Id == \"test-op-id\"",
|
||||
},
|
||||
},
|
||||
Err: require.NoError,
|
||||
@ -215,7 +848,7 @@ func TestBuildingAzureLogAnalyticsQueries(t *testing.T) {
|
||||
queries, err := datasource.buildQueries(logger, tt.queryModel, types.DatasourceInfo{})
|
||||
tt.Err(t, err)
|
||||
if diff := cmp.Diff(tt.azureLogAnalyticsQueries[0], queries[0]); diff != "" {
|
||||
t.Errorf("Result mismatch (-want +got):\n%s", diff)
|
||||
t.Errorf("Result mismatch (-want +got): \n%s", diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -4,11 +4,13 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/kinds/dataquery"
|
||||
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/types"
|
||||
)
|
||||
|
||||
@ -43,12 +45,12 @@ func apiErrorToNotice(err *AzureLogAnalyticsAPIError) data.Notice {
|
||||
}
|
||||
|
||||
// ResponseTableToFrame converts an AzureResponseTable to a data.Frame.
|
||||
func ResponseTableToFrame(table *types.AzureResponseTable, refID string, executedQuery string) (*data.Frame, error) {
|
||||
func ResponseTableToFrame(table *types.AzureResponseTable, refID string, executedQuery string, queryType dataquery.AzureQueryType, resultFormat dataquery.ResultFormat) (*data.Frame, error) {
|
||||
if len(table.Rows) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
converterFrame, err := converterFrameForTable(table)
|
||||
converterFrame, err := converterFrameForTable(table, queryType, resultFormat)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -64,7 +66,7 @@ func ResponseTableToFrame(table *types.AzureResponseTable, refID string, execute
|
||||
return converterFrame.Frame, nil
|
||||
}
|
||||
|
||||
func converterFrameForTable(t *types.AzureResponseTable) (*data.FrameInputConverter, error) {
|
||||
func converterFrameForTable(t *types.AzureResponseTable, queryType dataquery.AzureQueryType, resultFormat dataquery.ResultFormat) (*data.FrameInputConverter, error) {
|
||||
converters := []data.FieldConverter{}
|
||||
colNames := make([]string, len(t.Columns))
|
||||
colTypes := make([]string, len(t.Columns)) // for metadata
|
||||
@ -76,6 +78,9 @@ func converterFrameForTable(t *types.AzureResponseTable) (*data.FrameInputConver
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unsupported analytics column type %v", col.Type)
|
||||
}
|
||||
if queryType == dataquery.AzureQueryTypeAzureTraces && resultFormat == dataquery.ResultFormatTrace && (col.Name == "serviceTags" || col.Name == "tags") {
|
||||
converter = tagsConverter
|
||||
}
|
||||
converters = append(converters, converter)
|
||||
}
|
||||
|
||||
@ -112,6 +117,58 @@ var converterMap = map[string]data.FieldConverter{
|
||||
"number": decimalConverter,
|
||||
}
|
||||
|
||||
type KeyValue struct {
|
||||
Value interface{} `json:"value"`
|
||||
Key string `json:"key"`
|
||||
}
|
||||
|
||||
var tagsConverter = data.FieldConverter{
|
||||
OutputFieldType: data.FieldTypeNullableJSON,
|
||||
Converter: func(v interface{}) (interface{}, error) {
|
||||
if v == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
m := map[string]any{}
|
||||
err := json.Unmarshal([]byte(v.(string)), &m)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal trace tags: %s", err)
|
||||
}
|
||||
|
||||
parsedTags := make([]*KeyValue, 0, len(m)-1)
|
||||
for k, v := range m {
|
||||
if v == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
switch v.(type) {
|
||||
case float64:
|
||||
if v == 0 {
|
||||
continue
|
||||
}
|
||||
case string:
|
||||
if v == "" {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
parsedTags = append(parsedTags, &KeyValue{Key: k, Value: v})
|
||||
}
|
||||
sort.Slice(parsedTags, func(i, j int) bool {
|
||||
return parsedTags[i].Key < parsedTags[j].Key
|
||||
})
|
||||
|
||||
marshalledTags, err := json.Marshal(parsedTags)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to marshal parsed trace tags: %s", err)
|
||||
}
|
||||
|
||||
jsonTags := json.RawMessage(marshalledTags)
|
||||
|
||||
return &jsonTags, nil
|
||||
},
|
||||
}
|
||||
|
||||
var stringConverter = data.FieldConverter{
|
||||
OutputFieldType: data.FieldTypeNullableString,
|
||||
Converter: func(v interface{}) (interface{}, error) {
|
||||
|
@ -2,15 +2,15 @@ package loganalytics
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/kinds/dataquery"
|
||||
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/testdata"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@ -24,175 +24,87 @@ func TestLogTableToFrame(t *testing.T) {
|
||||
{
|
||||
name: "single series",
|
||||
testFile: "loganalytics/1-log-analytics-response-metrics-single-series.json",
|
||||
expectedFrame: func() *data.Frame {
|
||||
frame := data.NewFrame("",
|
||||
data.NewField("TimeGenerated", nil, []*time.Time{
|
||||
util.Pointer(time.Date(2020, 4, 19, 19, 16, 6, 5e8, time.UTC)),
|
||||
util.Pointer(time.Date(2020, 4, 19, 19, 16, 16, 5e8, time.UTC)),
|
||||
util.Pointer(time.Date(2020, 4, 19, 19, 16, 26, 5e8, time.UTC)),
|
||||
}),
|
||||
data.NewField("Computer", nil, []*string{
|
||||
util.Pointer("grafana-vm"),
|
||||
util.Pointer("grafana-vm"),
|
||||
util.Pointer("grafana-vm"),
|
||||
}),
|
||||
data.NewField("avg_CounterValue", nil, []*float64{
|
||||
util.Pointer(1.1),
|
||||
util.Pointer(2.2),
|
||||
util.Pointer(3.3),
|
||||
}),
|
||||
)
|
||||
frame.Meta = &data.FrameMeta{
|
||||
Custom: &LogAnalyticsMeta{ColumnTypes: []string{"datetime", "string", "real"}},
|
||||
}
|
||||
return frame
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "response table",
|
||||
testFile: "loganalytics/6-log-analytics-response-table.json",
|
||||
expectedFrame: func() *data.Frame {
|
||||
frame := data.NewFrame("",
|
||||
data.NewField("TenantId", nil, []*string{
|
||||
util.Pointer("a2c1b44e-3e57-4410-b027-6cc0ae6dee67"),
|
||||
util.Pointer("a2c1b44e-3e57-4410-b027-6cc0ae6dee67"),
|
||||
util.Pointer("a2c1b44e-3e57-4410-b027-6cc0ae6dee67"),
|
||||
}),
|
||||
data.NewField("Computer", nil, []*string{
|
||||
util.Pointer("grafana-vm"),
|
||||
util.Pointer("grafana-vm"),
|
||||
util.Pointer("grafana-vm"),
|
||||
}),
|
||||
data.NewField("ObjectName", nil, []*string{
|
||||
util.Pointer("Memory"),
|
||||
util.Pointer("Memory"),
|
||||
util.Pointer("Memory"),
|
||||
}),
|
||||
data.NewField("CounterName", nil, []*string{
|
||||
util.Pointer("Available MBytes Memory"),
|
||||
util.Pointer("Available MBytes Memory"),
|
||||
util.Pointer("Available MBytes Memory"),
|
||||
}),
|
||||
data.NewField("InstanceName", nil, []*string{
|
||||
util.Pointer("Memory"),
|
||||
util.Pointer("Memory"),
|
||||
util.Pointer("Memory"),
|
||||
}),
|
||||
data.NewField("Min", nil, []*float64{nil, nil, nil}),
|
||||
data.NewField("Max", nil, []*float64{nil, nil, nil}),
|
||||
data.NewField("SampleCount", nil, []*int32{nil, nil, nil}),
|
||||
data.NewField("CounterValue", nil, []*float64{
|
||||
util.Pointer(2040.0),
|
||||
util.Pointer(2066.0),
|
||||
util.Pointer(2066.0),
|
||||
}),
|
||||
data.NewField("TimeGenerated", nil, []*time.Time{
|
||||
util.Pointer(time.Date(2020, 4, 23, 11, 46, 3, 857e6, time.UTC)),
|
||||
util.Pointer(time.Date(2020, 4, 23, 11, 46, 13, 857e6, time.UTC)),
|
||||
util.Pointer(time.Date(2020, 4, 23, 11, 46, 23, 857e6, time.UTC)),
|
||||
}),
|
||||
)
|
||||
frame.Meta = &data.FrameMeta{
|
||||
Custom: &LogAnalyticsMeta{ColumnTypes: []string{"string", "string", "string",
|
||||
"string", "string", "real", "real", "int", "real", "datetime"}},
|
||||
}
|
||||
return frame
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "all supported field types",
|
||||
testFile: "loganalytics/7-log-analytics-all-types-table.json",
|
||||
expectedFrame: func() *data.Frame {
|
||||
frame := data.NewFrame("",
|
||||
data.NewField("XBool", nil, []*bool{util.Pointer(true)}),
|
||||
data.NewField("XString", nil, []*string{util.Pointer("Grafana")}),
|
||||
data.NewField("XDateTime", nil, []*time.Time{util.Pointer(time.Date(2006, 1, 2, 22, 4, 5, 1*1e8, time.UTC))}),
|
||||
data.NewField("XDynamic", nil, []*string{util.Pointer(`[{"person":"Daniel"},{"cats":23},{"diagnosis":"cat problem"}]`)}),
|
||||
data.NewField("XGuid", nil, []*string{util.Pointer("74be27de-1e4e-49d9-b579-fe0b331d3642")}),
|
||||
data.NewField("XInt", nil, []*int32{util.Pointer(int32(2147483647))}),
|
||||
data.NewField("XLong", nil, []*int64{util.Pointer(int64(9223372036854775807))}),
|
||||
data.NewField("XReal", nil, []*float64{util.Pointer(1.797693134862315708145274237317043567981e+308)}),
|
||||
data.NewField("XTimeSpan", nil, []*string{util.Pointer("00:00:00.0000001")}),
|
||||
data.NewField("XDecimal", nil, []*float64{util.Pointer(79228162514264337593543950335.0)}),
|
||||
data.NewField("XObject", nil, []*string{util.Pointer(`"{\"person\": \"Daniel\", \"cats\": 23, \"diagnosis\": \"cat problem\"}"`)}),
|
||||
data.NewField("XNumber", nil, []*float64{util.Pointer(79228162514264337593543950335.0)}),
|
||||
)
|
||||
frame.Meta = &data.FrameMeta{
|
||||
Custom: &LogAnalyticsMeta{ColumnTypes: []string{"bool", "string", "datetime",
|
||||
"dynamic", "guid", "int", "long", "real", "timespan", "decimal", "object", "number"}},
|
||||
}
|
||||
return frame
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "nan and infinity in real response",
|
||||
testFile: "loganalytics/8-log-analytics-response-nan-inf.json",
|
||||
expectedFrame: func() *data.Frame {
|
||||
frame := data.NewFrame("",
|
||||
data.NewField("XInf", nil, []*float64{util.Pointer(math.Inf(0))}),
|
||||
data.NewField("XInfNeg", nil, []*float64{util.Pointer(math.Inf(-2))}),
|
||||
data.NewField("XNan", nil, []*float64{util.Pointer(math.NaN())}),
|
||||
)
|
||||
frame.Meta = &data.FrameMeta{
|
||||
Custom: &LogAnalyticsMeta{ColumnTypes: []string{"real", "real", "real"}},
|
||||
}
|
||||
return frame
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "data and error in real response",
|
||||
testFile: "loganalytics/9-log-analytics-response-error.json",
|
||||
expectedFrame: func() *data.Frame {
|
||||
frame := data.NewFrame("",
|
||||
data.NewField("OperationName", nil, []*string{util.Pointer("Create or Update Virtual Machine")}),
|
||||
data.NewField("Level", nil, []*string{util.Pointer("Informational")}),
|
||||
)
|
||||
frame.Meta = &data.FrameMeta{
|
||||
Custom: &LogAnalyticsMeta{ColumnTypes: []string{"string", "string"}},
|
||||
Notices: []data.Notice{{Severity: data.NoticeSeverityError, Text: "There were some errors when processing your query. Something went wrong processing your query on the server. The results of this query exceed the set limit of 1 records."}},
|
||||
}
|
||||
return frame
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "data and warning in real response",
|
||||
testFile: "loganalytics/10-log-analytics-response-warning.json",
|
||||
expectedFrame: func() *data.Frame {
|
||||
frame := data.NewFrame("",
|
||||
data.NewField("OperationName", nil, []*string{util.Pointer("Create or Update Virtual Machine")}),
|
||||
data.NewField("Level", nil, []*string{util.Pointer("Informational")}),
|
||||
)
|
||||
frame.Meta = &data.FrameMeta{
|
||||
Custom: &LogAnalyticsMeta{ColumnTypes: []string{"string", "string"}},
|
||||
Notices: []data.Notice{{Severity: data.NoticeSeverityWarning, Text: "There were some errors when processing your query. Something went wrong processing your query on the server. Not sure what happened."}},
|
||||
}
|
||||
return frame
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "empty data response",
|
||||
testFile: "loganalytics/11-log-analytics-response-empty.json",
|
||||
expectedFrame: func() *data.Frame {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
res := loadLogAnalyticsTestFileWithNumber(t, tt.testFile)
|
||||
frame, err := ResponseTableToFrame(&res.Tables[0], "A", "query")
|
||||
res := loadTestFileWithNumber(t, tt.testFile)
|
||||
frame, err := ResponseTableToFrame(&res.Tables[0], "A", "query", dataquery.AzureQueryTypeAzureLogAnalytics, dataquery.ResultFormatTable)
|
||||
appendErrorNotice(frame, res.Error)
|
||||
require.NoError(t, err)
|
||||
|
||||
if diff := cmp.Diff(tt.expectedFrame(), frame, data.FrameTestCompareOptions()...); diff != "" {
|
||||
t.Errorf("Result mismatch (-want +got):\n%s", diff)
|
||||
}
|
||||
testdata.CheckGoldenFrame(t, "../testdata", tt.testFile, frame)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func loadLogAnalyticsTestFileWithNumber(t *testing.T, name string) AzureLogAnalyticsResponse {
|
||||
func TestTraceTableToFrame(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
testFile string
|
||||
expectedFrame func() *data.Frame
|
||||
resultFormat dataquery.ResultFormat
|
||||
}{
|
||||
{
|
||||
name: "multi trace",
|
||||
testFile: "traces/1-traces-multiple-table.json",
|
||||
resultFormat: dataquery.ResultFormatTable,
|
||||
},
|
||||
{
|
||||
name: "multi trace as trace format",
|
||||
testFile: "traces/1-traces-multiple-table.json",
|
||||
resultFormat: dataquery.ResultFormatTrace,
|
||||
},
|
||||
{
|
||||
name: "single trace",
|
||||
testFile: "traces/2-traces-single-table.json",
|
||||
resultFormat: dataquery.ResultFormatTable,
|
||||
},
|
||||
{
|
||||
name: "single trace as trace format",
|
||||
testFile: "traces/2-traces-single-table.json",
|
||||
resultFormat: dataquery.ResultFormatTrace,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
res := loadTestFileWithNumber(t, tt.testFile)
|
||||
frame, err := ResponseTableToFrame(&res.Tables[0], "A", "query", dataquery.AzureQueryTypeAzureTraces, tt.resultFormat)
|
||||
appendErrorNotice(frame, res.Error)
|
||||
require.NoError(t, err)
|
||||
|
||||
testdata.CheckGoldenFrame(t, "../testdata", fmt.Sprintf("%s.%s", tt.testFile, strings.ReplaceAll(tt.name, " ", "-")), frame)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func loadTestFileWithNumber(t *testing.T, name string) AzureLogAnalyticsResponse {
|
||||
t.Helper()
|
||||
path := filepath.Join("../testdata", name)
|
||||
// Ignore gosec warning G304 since it's a test
|
||||
|
121
pkg/tsdb/azuremonitor/loganalytics/consts.go
Normal file
121
pkg/tsdb/azuremonitor/loganalytics/consts.go
Normal file
@ -0,0 +1,121 @@
|
||||
package loganalytics
|
||||
|
||||
var Tables = []string{"availabilityResults", "dependencies", "customEvents", "exceptions", "pageViews", "requests", "traces"}
|
||||
|
||||
// AttributesOmit - Properties to omit when generating the attributes bag
|
||||
var AttributesOmit = map[string]string{"operationId": "operationId", "duration": "duration", "id": "id", "name": "name", "problemId": "problemId", "operation_ParentId": "operation_ParentId", "timestamp": "timestamp", "customDimensions": "customDimensions", "operation_Name": "operation_Name"}
|
||||
|
||||
// CommonProperties - common resource centric properties mapped to legacy property names
|
||||
var CommonProperties = map[string]string{
|
||||
"appId": "ResourceGUID",
|
||||
"application_Version": "AppVersion",
|
||||
"appName": "_ResourceId",
|
||||
"client_Browser": "ClientBrowser",
|
||||
"client_City": "ClientCity",
|
||||
"client_CountryOrRegion": "ClientCountryOrRegion",
|
||||
"client_IP": "ClientIP",
|
||||
"client_Model": "ClientModel",
|
||||
"client_OS": "ClientOS",
|
||||
"client_StateOrProvince": "ClientStateOrProvince",
|
||||
"client_Type": "ClientType",
|
||||
"cloud_RoleInstance": "AppRoleInstance",
|
||||
"cloud_RoleName": "AppRoleName",
|
||||
"customDimensions": "Properties",
|
||||
"customMeasurements": "Measurements",
|
||||
"duration": "DurationMs",
|
||||
"id": "Id",
|
||||
"iKey": "IKey",
|
||||
"itemCount": "ItemCount",
|
||||
"itemId": "_ItemId",
|
||||
"itemType": "Type",
|
||||
"name": "Name",
|
||||
"operation_Id": "OperationId",
|
||||
"operation_Name": "OperationName",
|
||||
"operation_ParentId": "OperationParentId",
|
||||
"operation_SyntheticSource": "OperationSyntheticSource",
|
||||
"performanceBucket": "PerformanceBucket",
|
||||
"sdkVersion": "SDKVersion",
|
||||
"session_Id": "SessionId",
|
||||
"success": "Success",
|
||||
"timestamp": "TimeGenerated",
|
||||
"user_AccountId": "UserAccountId",
|
||||
"user_AuthenticatedId": "UserAuthenticatedId",
|
||||
"user_Id": "UserId",
|
||||
}
|
||||
|
||||
func copyCommonProperties(dst map[string]string, omit map[string]string) map[string]string {
|
||||
for k, v := range CommonProperties {
|
||||
if _, ok := omit[k]; !ok {
|
||||
dst[k] = v
|
||||
}
|
||||
}
|
||||
return dst
|
||||
}
|
||||
|
||||
var emptyMap = map[string]string{}
|
||||
|
||||
var AvailabilityResultsSchema = copyCommonProperties(map[string]string{
|
||||
"location": "Location",
|
||||
"message": "Message",
|
||||
"size": "Size",
|
||||
}, emptyMap)
|
||||
|
||||
var DependenciesSchema = copyCommonProperties(map[string]string{
|
||||
"data": "Data",
|
||||
"resultCode": "ResultCode",
|
||||
"target": "Target",
|
||||
"type": "DependencyType",
|
||||
}, emptyMap)
|
||||
|
||||
var EventsSchema = copyCommonProperties(map[string]string{}, map[string]string{"duration": "duration", "id": "id", "success": "success", "performanceBucket": "performanceBucket"})
|
||||
|
||||
var PageViewsSchema = copyCommonProperties(map[string]string{"url": "Url"}, map[string]string{"success": "success"})
|
||||
|
||||
var RequestsSchema = copyCommonProperties(map[string]string{"resultCode": "ResultCode",
|
||||
"source": "Source",
|
||||
"url": "Url"}, map[string]string{})
|
||||
|
||||
var ExceptionsSchema = copyCommonProperties(map[string]string{
|
||||
"assembly": "Assembly",
|
||||
"details": "Details",
|
||||
"handledAt": "HandledAt",
|
||||
"innermostAssembly": "InnermostAssembly",
|
||||
"innermostMessage": "InnermostMessage",
|
||||
"innermostMethod": "InnermostMethod",
|
||||
"innermostType": "InnermostType",
|
||||
"message": "Message",
|
||||
"method": "Method",
|
||||
"outerAssembly": "OuterAssembly",
|
||||
"outerMessage": "OuterMessage",
|
||||
"outerMethod": "OuterMethod",
|
||||
"outerType": "OuterType",
|
||||
"problemId": "ProblemId",
|
||||
"severityLevel": "SeverityLevel",
|
||||
"type": "ExceptionType",
|
||||
}, map[string]string{"duration": "duration", "id": "id", "name": "name", "performanceBucket": "performanceBucket", "success": "success"})
|
||||
|
||||
var TracesSchema = copyCommonProperties(map[string]string{
|
||||
"message": "Message",
|
||||
"severityLevel": "SeverityLevel",
|
||||
}, map[string]string{"duration": "duration", "id": "id", "name": "name", "performanceBucket": "performanceBucket", "success": "success"})
|
||||
|
||||
var TablesSchema = map[string]map[string]string{
|
||||
"availabilityResults": AvailabilityResultsSchema,
|
||||
"dependencies": DependenciesSchema,
|
||||
"customEvents": EventsSchema,
|
||||
"exceptions": ExceptionsSchema,
|
||||
"pageViews": PageViewsSchema,
|
||||
"requests": RequestsSchema,
|
||||
"traces": TracesSchema,
|
||||
}
|
||||
|
||||
func getTagsForTable(table string) []string {
|
||||
tagsMap := TablesSchema[table]
|
||||
tags := []string{}
|
||||
|
||||
for k := range tagsMap {
|
||||
tags = append(tags, k)
|
||||
}
|
||||
|
||||
return tags
|
||||
}
|
@ -7,21 +7,34 @@ import (
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
)
|
||||
|
||||
func AddConfigLinks(frame data.Frame, dl string) data.Frame {
|
||||
func AddCustomDataLink(frame data.Frame, dataLink data.DataLink) data.Frame {
|
||||
for i := range frame.Fields {
|
||||
if frame.Fields[i].Config == nil {
|
||||
frame.Fields[i].Config = &data.FieldConfig{}
|
||||
}
|
||||
deepLink := data.DataLink{
|
||||
Title: "View in Azure Portal",
|
||||
TargetBlank: true,
|
||||
URL: dl,
|
||||
}
|
||||
frame.Fields[i].Config.Links = append(frame.Fields[i].Config.Links, deepLink)
|
||||
|
||||
frame.Fields[i].Config.Links = append(frame.Fields[i].Config.Links, dataLink)
|
||||
}
|
||||
return frame
|
||||
}
|
||||
|
||||
func AddConfigLinks(frame data.Frame, dl string, title *string) data.Frame {
|
||||
linkTitle := "View in Azure Portal"
|
||||
if title != nil {
|
||||
linkTitle = *title
|
||||
}
|
||||
|
||||
deepLink := data.DataLink{
|
||||
Title: linkTitle,
|
||||
TargetBlank: true,
|
||||
URL: dl,
|
||||
}
|
||||
|
||||
frame = AddCustomDataLink(frame, deepLink)
|
||||
|
||||
return frame
|
||||
}
|
||||
|
||||
func GetAzurePortalUrl(azureCloud string) (string, error) {
|
||||
switch azureCloud {
|
||||
case azsettings.AzurePublic:
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/kinds/dataquery"
|
||||
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/types"
|
||||
"github.com/grafana/grafana/pkg/tsdb/legacydata/interval"
|
||||
)
|
||||
@ -38,7 +39,7 @@ func KqlInterpolate(logger log.Logger, query backend.DataQuery, dsInfo types.Dat
|
||||
engine := kqlMacroEngine{}
|
||||
|
||||
defaultTimeFieldForAllDatasources := "timestamp"
|
||||
if len(defaultTimeField) > 0 {
|
||||
if len(defaultTimeField) > 0 && query.QueryType != string(dataquery.AzureQueryTypeAzureTraces) {
|
||||
defaultTimeFieldForAllDatasources = defaultTimeField[0]
|
||||
}
|
||||
return engine.Interpolate(logger, query, dsInfo, kql, defaultTimeFieldForAllDatasources)
|
||||
|
@ -123,6 +123,16 @@ func TestAzureLogAnalyticsMacros(t *testing.T) {
|
||||
expected: "",
|
||||
Err: require.Error,
|
||||
},
|
||||
{
|
||||
name: "traces time field should remain as timestamp",
|
||||
query: backend.DataQuery{
|
||||
QueryType: "Azure Traces",
|
||||
TimeRange: timeRange,
|
||||
},
|
||||
kql: `$__timeFilter()`,
|
||||
expected: "['timestamp'] >= datetime('2018-03-15T13:00:00Z') and ['timestamp'] <= datetime('2018-03-15T13:34:00Z')",
|
||||
Err: require.NoError,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
@ -379,7 +379,7 @@ func (e *AzureMonitorDatasource) parseResponse(amr types.AzureMonitorResponse, q
|
||||
return nil, err
|
||||
}
|
||||
|
||||
frameWithLink := loganalytics.AddConfigLinks(*frame, queryUrl)
|
||||
frameWithLink := loganalytics.AddConfigLinks(*frame, queryUrl, nil)
|
||||
frames = append(frames, &frameWithLink)
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -20,6 +21,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/testdata"
|
||||
azTime "github.com/grafana/grafana/pkg/tsdb/azuremonitor/time"
|
||||
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/types"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
@ -351,42 +353,7 @@ func TestCustomNamespace(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func makeDates(startDate time.Time, count int, interval time.Duration) (times []time.Time) {
|
||||
for i := 0; i < count; i++ {
|
||||
times = append(times, startDate.Add(interval*time.Duration(i)))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func makeTestDataLink(url string) data.DataLink {
|
||||
return data.DataLink{
|
||||
Title: "View in Azure Portal",
|
||||
TargetBlank: true,
|
||||
URL: url,
|
||||
}
|
||||
}
|
||||
|
||||
func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
// datalinks for the test frames
|
||||
averageLink := makeTestDataLink(`http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/` +
|
||||
`ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C` +
|
||||
`%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D`)
|
||||
averageLink2 := makeTestDataLink(`http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/` +
|
||||
`ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana-1%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C` +
|
||||
`%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana-1%22%7D%7D%5D%7D%5D%7D`)
|
||||
totalLink := makeTestDataLink(`http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/` +
|
||||
`ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A1%2C%22namespace%22%3A%22%22%2C` +
|
||||
`%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D`)
|
||||
maxLink := makeTestDataLink(`http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/` +
|
||||
`ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A3%2C%22namespace%22%3A%22%22%2C` +
|
||||
`%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D`)
|
||||
minLink := makeTestDataLink(`http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/` +
|
||||
`ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A2%2C%22namespace%22%3A%22%22%2C` +
|
||||
`%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D`)
|
||||
countLink := makeTestDataLink(`http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/` +
|
||||
`ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A7%2C%22namespace%22%3A%22%22%2C` +
|
||||
`%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D`)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
responseFile string
|
||||
@ -396,137 +363,67 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "average aggregate time series response",
|
||||
responseFile: "1-azure-monitor-response-avg.json",
|
||||
responseFile: "azuremonitor/1-azure-monitor-response-avg.json",
|
||||
mockQuery: &types.AzureMonitorQuery{
|
||||
URL: "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics",
|
||||
Params: url.Values{
|
||||
"aggregation": {"Average"},
|
||||
},
|
||||
},
|
||||
expectedFrames: data.Frames{
|
||||
data.NewFrame("",
|
||||
data.NewField("Time", nil,
|
||||
makeDates(time.Date(2019, 2, 8, 10, 13, 0, 0, time.UTC), 5, time.Minute),
|
||||
).SetConfig(&data.FieldConfig{Links: []data.DataLink{averageLink}}),
|
||||
data.NewField("Percentage CPU", nil, []*float64{
|
||||
util.Pointer(2.0875), util.Pointer(2.1525), util.Pointer(2.155), util.Pointer(3.6925), util.Pointer(2.44),
|
||||
}).SetConfig(&data.FieldConfig{Unit: "percent", Links: []data.DataLink{averageLink}})),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "total aggregate time series response",
|
||||
responseFile: "2-azure-monitor-response-total.json",
|
||||
responseFile: "azuremonitor/2-azure-monitor-response-total.json",
|
||||
mockQuery: &types.AzureMonitorQuery{
|
||||
URL: "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics",
|
||||
Params: url.Values{
|
||||
"aggregation": {"Total"},
|
||||
},
|
||||
},
|
||||
expectedFrames: data.Frames{
|
||||
data.NewFrame("",
|
||||
data.NewField("Time", nil,
|
||||
makeDates(time.Date(2019, 2, 9, 13, 29, 0, 0, time.UTC), 5, time.Minute),
|
||||
).SetConfig(&data.FieldConfig{Links: []data.DataLink{totalLink}}),
|
||||
data.NewField("Percentage CPU", nil, []*float64{
|
||||
util.Pointer(8.26), util.Pointer(8.7), util.Pointer(14.82), util.Pointer(10.07), util.Pointer(8.52),
|
||||
}).SetConfig(&data.FieldConfig{Unit: "percent", Links: []data.DataLink{totalLink}})),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "maximum aggregate time series response",
|
||||
responseFile: "3-azure-monitor-response-maximum.json",
|
||||
responseFile: "azuremonitor/3-azure-monitor-response-maximum.json",
|
||||
mockQuery: &types.AzureMonitorQuery{
|
||||
URL: "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics",
|
||||
Params: url.Values{
|
||||
"aggregation": {"Maximum"},
|
||||
},
|
||||
},
|
||||
expectedFrames: data.Frames{
|
||||
data.NewFrame("",
|
||||
data.NewField("Time", nil,
|
||||
makeDates(time.Date(2019, 2, 9, 14, 26, 0, 0, time.UTC), 5, time.Minute),
|
||||
).SetConfig(&data.FieldConfig{Links: []data.DataLink{maxLink}}),
|
||||
data.NewField("Percentage CPU", nil, []*float64{
|
||||
util.Pointer(3.07), util.Pointer(2.92), util.Pointer(2.87), util.Pointer(2.27), util.Pointer(2.52),
|
||||
}).SetConfig(&data.FieldConfig{Unit: "percent", Links: []data.DataLink{maxLink}})),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "minimum aggregate time series response",
|
||||
responseFile: "4-azure-monitor-response-minimum.json",
|
||||
responseFile: "azuremonitor/4-azure-monitor-response-minimum.json",
|
||||
mockQuery: &types.AzureMonitorQuery{
|
||||
URL: "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics",
|
||||
Params: url.Values{
|
||||
"aggregation": {"Minimum"},
|
||||
},
|
||||
},
|
||||
expectedFrames: data.Frames{
|
||||
data.NewFrame("",
|
||||
data.NewField("Time", nil,
|
||||
makeDates(time.Date(2019, 2, 9, 14, 43, 0, 0, time.UTC), 5, time.Minute),
|
||||
).SetConfig(&data.FieldConfig{Links: []data.DataLink{minLink}}),
|
||||
data.NewField("Percentage CPU", nil, []*float64{
|
||||
util.Pointer(1.51), util.Pointer(2.38), util.Pointer(1.69), util.Pointer(2.27), util.Pointer(1.96),
|
||||
}).SetConfig(&data.FieldConfig{Unit: "percent", Links: []data.DataLink{minLink}})),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "count aggregate time series response",
|
||||
responseFile: "5-azure-monitor-response-count.json",
|
||||
responseFile: "azuremonitor/5-azure-monitor-response-count.json",
|
||||
mockQuery: &types.AzureMonitorQuery{
|
||||
URL: "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics",
|
||||
Params: url.Values{
|
||||
"aggregation": {"Count"},
|
||||
},
|
||||
},
|
||||
expectedFrames: data.Frames{
|
||||
data.NewFrame("",
|
||||
data.NewField("Time", nil,
|
||||
makeDates(time.Date(2019, 2, 9, 14, 44, 0, 0, time.UTC), 5, time.Minute),
|
||||
).SetConfig(&data.FieldConfig{Links: []data.DataLink{countLink}}),
|
||||
data.NewField("Percentage CPU", nil, []*float64{
|
||||
util.Pointer(4.0), util.Pointer(4.0), util.Pointer(4.0), util.Pointer(4.0), util.Pointer(4.0),
|
||||
}).SetConfig(&data.FieldConfig{Unit: "percent", Links: []data.DataLink{countLink}})),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "single dimension time series response",
|
||||
responseFile: "6-azure-monitor-response-single-dimension.json",
|
||||
responseFile: "azuremonitor/6-azure-monitor-response-single-dimension.json",
|
||||
mockQuery: &types.AzureMonitorQuery{
|
||||
URL: "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics",
|
||||
Params: url.Values{
|
||||
"aggregation": {"Average"},
|
||||
},
|
||||
},
|
||||
expectedFrames: data.Frames{
|
||||
data.NewFrame("",
|
||||
data.NewField("Time", nil,
|
||||
makeDates(time.Date(2019, 2, 9, 15, 21, 0, 0, time.UTC), 6, time.Hour),
|
||||
).SetConfig(&data.FieldConfig{Links: []data.DataLink{averageLink}}),
|
||||
data.NewField("Blob Count", data.Labels{"blobtype": "PageBlob"},
|
||||
[]*float64{util.Pointer(3.0), util.Pointer(3.0), util.Pointer(3.0), util.Pointer(3.0), util.Pointer(3.0), nil}).
|
||||
SetConfig(&data.FieldConfig{Unit: "short", Links: []data.DataLink{averageLink}})),
|
||||
|
||||
data.NewFrame("",
|
||||
data.NewField("Time", nil,
|
||||
makeDates(time.Date(2019, 2, 9, 15, 21, 0, 0, time.UTC), 6, time.Hour),
|
||||
).SetConfig(&data.FieldConfig{Links: []data.DataLink{averageLink}}),
|
||||
data.NewField("Blob Count", data.Labels{"blobtype": "BlockBlob"},
|
||||
[]*float64{util.Pointer(1.0), util.Pointer(1.0), util.Pointer(1.0), util.Pointer(1.0), util.Pointer(1.0), nil}).
|
||||
SetConfig(&data.FieldConfig{Unit: "short", Links: []data.DataLink{averageLink}})),
|
||||
|
||||
data.NewFrame("",
|
||||
data.NewField("Time", nil,
|
||||
makeDates(time.Date(2019, 2, 9, 15, 21, 0, 0, time.UTC), 6, time.Hour),
|
||||
).SetConfig(&data.FieldConfig{Links: []data.DataLink{averageLink}}),
|
||||
data.NewField("Blob Count", data.Labels{"blobtype": "Azure Data Lake Storage"},
|
||||
[]*float64{util.Pointer(0.0), util.Pointer(0.0), util.Pointer(0.0), util.Pointer(0.0), util.Pointer(0.0), nil}).
|
||||
SetConfig(&data.FieldConfig{Unit: "short", Links: []data.DataLink{averageLink}})),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with alias patterns in the query",
|
||||
responseFile: "2-azure-monitor-response-total.json",
|
||||
responseFile: "azuremonitor/2-azure-monitor-response-total.json",
|
||||
mockQuery: &types.AzureMonitorQuery{
|
||||
URL: "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics",
|
||||
Alias: "custom {{resourcegroup}} {{namespace}} {{resourceName}} {{metric}}",
|
||||
@ -534,19 +431,10 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
"aggregation": {"Total"},
|
||||
},
|
||||
},
|
||||
expectedFrames: data.Frames{
|
||||
data.NewFrame("",
|
||||
data.NewField("Time", nil,
|
||||
makeDates(time.Date(2019, 2, 9, 13, 29, 0, 0, time.UTC), 5, time.Minute),
|
||||
).SetConfig(&data.FieldConfig{Links: []data.DataLink{totalLink}}),
|
||||
data.NewField("Percentage CPU", nil, []*float64{
|
||||
util.Pointer(8.26), util.Pointer(8.7), util.Pointer(14.82), util.Pointer(10.07), util.Pointer(8.52),
|
||||
}).SetConfig(&data.FieldConfig{Unit: "percent", DisplayName: "custom grafanastaging Microsoft.Compute/virtualMachines grafana Percentage CPU", Links: []data.DataLink{totalLink}})),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "single dimension with alias",
|
||||
responseFile: "6-azure-monitor-response-single-dimension.json",
|
||||
responseFile: "azuremonitor/6-azure-monitor-response-single-dimension.json",
|
||||
mockQuery: &types.AzureMonitorQuery{
|
||||
URL: "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics",
|
||||
Alias: "{{dimensionname}}={{DimensionValue}}",
|
||||
@ -554,34 +442,10 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
"aggregation": {"Average"},
|
||||
},
|
||||
},
|
||||
expectedFrames: data.Frames{
|
||||
data.NewFrame("",
|
||||
data.NewField("Time", nil,
|
||||
makeDates(time.Date(2019, 2, 9, 15, 21, 0, 0, time.UTC), 6, time.Hour),
|
||||
).SetConfig(&data.FieldConfig{Links: []data.DataLink{averageLink}}),
|
||||
data.NewField("Blob Count", data.Labels{"blobtype": "PageBlob"},
|
||||
[]*float64{util.Pointer(3.0), util.Pointer(3.0), util.Pointer(3.0), util.Pointer(3.0), util.Pointer(3.0), nil}).SetConfig(&data.FieldConfig{Unit: "short", DisplayName: "blobtype=PageBlob", Links: []data.DataLink{averageLink}})),
|
||||
|
||||
data.NewFrame("",
|
||||
data.NewField("Time", nil,
|
||||
makeDates(time.Date(2019, 2, 9, 15, 21, 0, 0, time.UTC), 6, time.Hour),
|
||||
).SetConfig(&data.FieldConfig{Links: []data.DataLink{averageLink}}),
|
||||
data.NewField("Blob Count", data.Labels{"blobtype": "BlockBlob"}, []*float64{
|
||||
util.Pointer(1.0), util.Pointer(1.0), util.Pointer(1.0), util.Pointer(1.0), util.Pointer(1.0), nil,
|
||||
}).SetConfig(&data.FieldConfig{Unit: "short", DisplayName: "blobtype=BlockBlob", Links: []data.DataLink{averageLink}})),
|
||||
|
||||
data.NewFrame("",
|
||||
data.NewField("Time", nil,
|
||||
makeDates(time.Date(2019, 2, 9, 15, 21, 0, 0, time.UTC), 6, time.Hour),
|
||||
).SetConfig(&data.FieldConfig{Links: []data.DataLink{averageLink}}),
|
||||
data.NewField("Blob Count", data.Labels{"blobtype": "Azure Data Lake Storage"}, []*float64{
|
||||
util.Pointer(0.0), util.Pointer(0.0), util.Pointer(0.0), util.Pointer(0.0), util.Pointer(0.0), nil,
|
||||
}).SetConfig(&data.FieldConfig{Unit: "short", DisplayName: "blobtype=Azure Data Lake Storage", Links: []data.DataLink{averageLink}})),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "multiple dimension time series response with label alias",
|
||||
responseFile: "7-azure-monitor-response-multi-dimension.json",
|
||||
responseFile: "azuremonitor/7-azure-monitor-response-multi-dimension.json",
|
||||
mockQuery: &types.AzureMonitorQuery{
|
||||
URL: "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics",
|
||||
Alias: "{{resourcegroup}} {Blob Type={{blobtype}}, Tier={{Tier}}}",
|
||||
@ -589,35 +453,10 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
"aggregation": {"Average"},
|
||||
},
|
||||
},
|
||||
expectedFrames: data.Frames{
|
||||
data.NewFrame("",
|
||||
data.NewField("Time", nil,
|
||||
makeDates(time.Date(2020, 06, 30, 9, 58, 0, 0, time.UTC), 3, time.Hour),
|
||||
).SetConfig(&data.FieldConfig{Links: []data.DataLink{averageLink}}),
|
||||
data.NewField("Blob Capacity", data.Labels{"blobtype": "PageBlob", "tier": "Standard"},
|
||||
[]*float64{util.Pointer(675530.0), util.Pointer(675530.0), util.Pointer(675530.0)}).SetConfig(
|
||||
&data.FieldConfig{Unit: "decbytes", DisplayName: "danieltest {Blob Type=PageBlob, Tier=Standard}", Links: []data.DataLink{averageLink}})),
|
||||
|
||||
data.NewFrame("",
|
||||
data.NewField("Time", nil,
|
||||
makeDates(time.Date(2020, 06, 30, 9, 58, 0, 0, time.UTC), 3, time.Hour),
|
||||
).SetConfig(&data.FieldConfig{Links: []data.DataLink{averageLink}}),
|
||||
data.NewField("Blob Capacity", data.Labels{"blobtype": "BlockBlob", "tier": "Hot"},
|
||||
[]*float64{util.Pointer(0.0), util.Pointer(0.0), util.Pointer(0.0)}).SetConfig(
|
||||
&data.FieldConfig{Unit: "decbytes", DisplayName: "danieltest {Blob Type=BlockBlob, Tier=Hot}", Links: []data.DataLink{averageLink}})),
|
||||
|
||||
data.NewFrame("",
|
||||
data.NewField("Time", nil,
|
||||
makeDates(time.Date(2020, 06, 30, 9, 58, 0, 0, time.UTC), 3, time.Hour),
|
||||
).SetConfig(&data.FieldConfig{Links: []data.DataLink{averageLink}}),
|
||||
data.NewField("Blob Capacity", data.Labels{"blobtype": "Azure Data Lake Storage", "tier": "Cool"},
|
||||
[]*float64{util.Pointer(0.0), util.Pointer(0.0), util.Pointer(0.0)}).SetConfig(
|
||||
&data.FieldConfig{Unit: "decbytes", DisplayName: "danieltest {Blob Type=Azure Data Lake Storage, Tier=Cool}", Links: []data.DataLink{averageLink}})),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "unspecified unit with alias should not panic",
|
||||
responseFile: "8-azure-monitor-response-unspecified-unit.json",
|
||||
responseFile: "azuremonitor/8-azure-monitor-response-unspecified-unit.json",
|
||||
mockQuery: &types.AzureMonitorQuery{
|
||||
URL: "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics",
|
||||
Alias: "custom",
|
||||
@ -625,19 +464,10 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
"aggregation": {"Average"},
|
||||
},
|
||||
},
|
||||
expectedFrames: data.Frames{
|
||||
data.NewFrame("",
|
||||
data.NewField("Time", nil,
|
||||
[]time.Time{time.Date(2019, 2, 8, 10, 13, 0, 0, time.UTC)},
|
||||
).SetConfig(&data.FieldConfig{Links: []data.DataLink{averageLink}}),
|
||||
data.NewField("Percentage CPU", nil, []*float64{
|
||||
util.Pointer(2.0875),
|
||||
}).SetConfig(&data.FieldConfig{DisplayName: "custom", Links: []data.DataLink{averageLink}})),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with legacy azure monitor query properties and without a resource uri",
|
||||
responseFile: "2-azure-monitor-response-total.json",
|
||||
responseFile: "azuremonitor/2-azure-monitor-response-total.json",
|
||||
mockQuery: &types.AzureMonitorQuery{
|
||||
URL: "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics",
|
||||
Alias: "custom {{resourcegroup}} {{namespace}} {{resourceName}} {{metric}}",
|
||||
@ -645,19 +475,10 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
"aggregation": {"Total"},
|
||||
},
|
||||
},
|
||||
expectedFrames: data.Frames{
|
||||
data.NewFrame("",
|
||||
data.NewField("Time", nil,
|
||||
makeDates(time.Date(2019, 2, 9, 13, 29, 0, 0, time.UTC), 5, time.Minute),
|
||||
).SetConfig(&data.FieldConfig{Links: []data.DataLink{totalLink}}),
|
||||
data.NewField("Percentage CPU", nil, []*float64{
|
||||
util.Pointer(8.26), util.Pointer(8.7), util.Pointer(14.82), util.Pointer(10.07), util.Pointer(8.52),
|
||||
}).SetConfig(&data.FieldConfig{Unit: "percent", DisplayName: "custom grafanastaging Microsoft.Compute/virtualMachines grafana Percentage CPU", Links: []data.DataLink{totalLink}})),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with legacy azure monitor query properties and with a resource uri it should use the resource uri",
|
||||
responseFile: "2-azure-monitor-response-total.json",
|
||||
responseFile: "azuremonitor/2-azure-monitor-response-total.json",
|
||||
mockQuery: &types.AzureMonitorQuery{
|
||||
URL: "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics",
|
||||
Alias: "custom {{resourcegroup}} {{namespace}} {{resourceName}} {{metric}}",
|
||||
@ -665,93 +486,38 @@ func TestAzureMonitorParseResponse(t *testing.T) {
|
||||
"aggregation": {"Total"},
|
||||
},
|
||||
},
|
||||
expectedFrames: data.Frames{
|
||||
data.NewFrame("",
|
||||
data.NewField("Time", nil,
|
||||
makeDates(time.Date(2019, 2, 9, 13, 29, 0, 0, time.UTC), 5, time.Minute),
|
||||
).SetConfig(&data.FieldConfig{Links: []data.DataLink{totalLink}}),
|
||||
data.NewField("Percentage CPU", nil, []*float64{
|
||||
util.Pointer(8.26), util.Pointer(8.7), util.Pointer(14.82), util.Pointer(10.07), util.Pointer(8.52),
|
||||
}).SetConfig(&data.FieldConfig{Unit: "percent", DisplayName: "custom grafanastaging Microsoft.Compute/virtualMachines grafana Percentage CPU", Links: []data.DataLink{totalLink}})),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "multiple time series response",
|
||||
responseFile: "9-azure-monitor-response-multi.json",
|
||||
responseFile: "azuremonitor/9-azure-monitor-response-multi.json",
|
||||
mockQuery: &types.AzureMonitorQuery{
|
||||
URL: "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/providers/microsoft.insights/metrics",
|
||||
Params: url.Values{
|
||||
"aggregation": {"Average"},
|
||||
},
|
||||
},
|
||||
expectedFrames: data.Frames{
|
||||
data.NewFrame("",
|
||||
data.NewField("Time", nil,
|
||||
makeDates(time.Date(2019, 2, 8, 10, 13, 0, 0, time.UTC), 5, time.Minute),
|
||||
).SetConfig(&data.FieldConfig{Links: []data.DataLink{averageLink}}),
|
||||
data.NewField("Percentage CPU", data.Labels{"resourceName": "grafana"}, []*float64{
|
||||
util.Pointer(2.0875), util.Pointer(2.1525), util.Pointer(2.155), util.Pointer(3.6925), util.Pointer(2.44),
|
||||
}).SetConfig(&data.FieldConfig{Unit: "percent", Links: []data.DataLink{averageLink}}),
|
||||
),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "multiple time series response with multiple dimensions",
|
||||
responseFile: "10-azure-monitor-response-multi-with-dimensions.json",
|
||||
responseFile: "azuremonitor/10-azure-monitor-response-multi-with-dimensions.json",
|
||||
mockQuery: &types.AzureMonitorQuery{
|
||||
URL: "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/providers/microsoft.insights/metrics",
|
||||
Params: url.Values{
|
||||
"aggregation": {"Average"},
|
||||
},
|
||||
},
|
||||
expectedFrames: data.Frames{
|
||||
data.NewFrame("",
|
||||
data.NewField("Time", nil,
|
||||
makeDates(time.Date(2019, 2, 8, 10, 13, 0, 0, time.UTC), 5, time.Minute),
|
||||
).SetConfig(&data.FieldConfig{Links: []data.DataLink{averageLink}}),
|
||||
data.NewField("Percentage CPU", data.Labels{"resourceName": "grafana", "Test Dimension": "value-1"}, []*float64{
|
||||
util.Pointer(2.0875), util.Pointer(2.1525), util.Pointer(2.155), util.Pointer(3.6925), util.Pointer(2.44),
|
||||
}).SetConfig(&data.FieldConfig{Unit: "percent", Links: []data.DataLink{averageLink}}),
|
||||
),
|
||||
data.NewFrame("",
|
||||
data.NewField("Time", nil,
|
||||
makeDates(time.Date(2019, 2, 8, 10, 13, 0, 0, time.UTC), 5, time.Minute),
|
||||
).SetConfig(&data.FieldConfig{Links: []data.DataLink{averageLink}}),
|
||||
data.NewField("Percentage CPU", data.Labels{"resourceName": "grafana", "Test Dimension": "value-2"}, []*float64{
|
||||
util.Pointer(2.0875), util.Pointer(2.1525), util.Pointer(2.155), util.Pointer(3.6925), util.Pointer(2.44),
|
||||
}).SetConfig(&data.FieldConfig{Unit: "percent", Links: []data.DataLink{averageLink}}),
|
||||
),
|
||||
data.NewFrame("",
|
||||
data.NewField("Time", nil,
|
||||
makeDates(time.Date(2019, 2, 8, 10, 13, 0, 0, time.UTC), 5, time.Minute),
|
||||
).SetConfig(&data.FieldConfig{Links: []data.DataLink{averageLink2}}),
|
||||
data.NewField("Percentage CPU", data.Labels{"resourceName": "grafana-1", "Test Dimension": "value-1"}, []*float64{
|
||||
util.Pointer(2.0875), util.Pointer(2.1525), util.Pointer(2.155), util.Pointer(3.6925), util.Pointer(2.44),
|
||||
}).SetConfig(&data.FieldConfig{Unit: "percent", Links: []data.DataLink{averageLink2}}),
|
||||
),
|
||||
data.NewFrame("",
|
||||
data.NewField("Time", nil,
|
||||
makeDates(time.Date(2019, 2, 8, 10, 13, 0, 0, time.UTC), 5, time.Minute),
|
||||
).SetConfig(&data.FieldConfig{Links: []data.DataLink{averageLink2}}),
|
||||
data.NewField("Percentage CPU", data.Labels{"resourceName": "grafana-1", "Test Dimension": "value-3"}, []*float64{
|
||||
util.Pointer(2.0875), util.Pointer(2.1525), util.Pointer(2.155), util.Pointer(3.6925), util.Pointer(2.44),
|
||||
}).SetConfig(&data.FieldConfig{Unit: "percent", Links: []data.DataLink{averageLink2}}),
|
||||
),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
datasource := &AzureMonitorDatasource{}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
azData := loadTestFile(t, "azuremonitor/"+tt.responseFile)
|
||||
azData := loadTestFile(t, tt.responseFile)
|
||||
dframes, err := datasource.parseResponse(azData, tt.mockQuery, "http://ds")
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, dframes)
|
||||
|
||||
if diff := cmp.Diff(tt.expectedFrames, dframes, data.FrameTestCompareOptions()...); diff != "" {
|
||||
t.Errorf("Result mismatch (-want +got):\n%s", diff)
|
||||
}
|
||||
testdata.CheckGoldenFrames(t, "../testdata", fmt.Sprintf("%s.%s", tt.responseFile, strings.ReplaceAll(tt.name, " ", "-")), dframes)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/kinds/dataquery"
|
||||
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/loganalytics"
|
||||
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/macros"
|
||||
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/types"
|
||||
@ -42,6 +43,7 @@ type AzureResourceGraphQuery struct {
|
||||
JSON json.RawMessage
|
||||
InterpolatedQuery string
|
||||
TimeRange backend.TimeRange
|
||||
QueryType string
|
||||
}
|
||||
|
||||
const ArgAPIVersion = "2021-06-01-preview"
|
||||
@ -110,6 +112,7 @@ func (e *AzureResourceGraphDatasource) buildQueries(logger log.Logger, queries [
|
||||
JSON: query.JSON,
|
||||
InterpolatedQuery: interpolatedQuery,
|
||||
TimeRange: query.TimeRange,
|
||||
QueryType: query.QueryType,
|
||||
})
|
||||
}
|
||||
|
||||
@ -193,7 +196,7 @@ func (e *AzureResourceGraphDatasource) executeQuery(ctx context.Context, logger
|
||||
return dataResponseErrorWithExecuted(err)
|
||||
}
|
||||
|
||||
frame, err := loganalytics.ResponseTableToFrame(&argResponse.Data, query.RefID, query.InterpolatedQuery)
|
||||
frame, err := loganalytics.ResponseTableToFrame(&argResponse.Data, query.RefID, query.InterpolatedQuery, dataquery.AzureQueryType(query.QueryType), dataquery.ResultFormat(query.ResultFormat))
|
||||
if err != nil {
|
||||
return dataResponseErrorWithExecuted(err)
|
||||
}
|
||||
@ -208,7 +211,7 @@ func (e *AzureResourceGraphDatasource) executeQuery(ctx context.Context, logger
|
||||
}
|
||||
|
||||
url := azurePortalUrl + "/#blade/HubsExtension/ArgQueryBlade/query/" + url.PathEscape(query.InterpolatedQuery)
|
||||
frameWithLink := loganalytics.AddConfigLinks(*frame, url)
|
||||
frameWithLink := loganalytics.AddConfigLinks(*frame, url, nil)
|
||||
if frameWithLink.Meta == nil {
|
||||
frameWithLink.Meta = &data.FrameMeta{}
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ func TestAddConfigData(t *testing.T) {
|
||||
frame := data.Frame{
|
||||
Fields: []*data.Field{&field},
|
||||
}
|
||||
frameWithLink := loganalytics.AddConfigLinks(frame, "http://ds")
|
||||
frameWithLink := loganalytics.AddConfigLinks(frame, "http://ds", nil)
|
||||
expectedFrameWithLink := data.Frame{
|
||||
Fields: []*data.Field{
|
||||
{
|
||||
|
@ -11,6 +11,7 @@ const (
|
||||
azureMonitor = "Azure Monitor"
|
||||
azureLogAnalytics = "Azure Log Analytics"
|
||||
azureResourceGraph = "Azure Resource Graph"
|
||||
azureTraces = "Azure Traces"
|
||||
)
|
||||
|
||||
var azManagement = types.AzRoute{
|
||||
@ -57,6 +58,7 @@ var (
|
||||
azureMonitor: azManagement,
|
||||
azureLogAnalytics: azLogAnalytics,
|
||||
azureResourceGraph: azManagement,
|
||||
azureTraces: azLogAnalytics,
|
||||
},
|
||||
azsettings.AzureUSGovernment: {
|
||||
azureMonitor: azUSGovManagement,
|
||||
|
@ -0,0 +1,83 @@
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
//
|
||||
// Frame[0]
|
||||
// Name:
|
||||
// Dimensions: 2 Fields by 5 Rows
|
||||
// +-------------------------------+----------------------+
|
||||
// | Name: Time | Name: Percentage CPU |
|
||||
// | Labels: | Labels: |
|
||||
// | Type: []time.Time | Type: []*float64 |
|
||||
// +-------------------------------+----------------------+
|
||||
// | 2019-02-08 10:13:00 +0000 UTC | 2.0875 |
|
||||
// | 2019-02-08 10:14:00 +0000 UTC | 2.1525 |
|
||||
// | 2019-02-08 10:15:00 +0000 UTC | 2.155 |
|
||||
// | 2019-02-08 10:16:00 +0000 UTC | 3.6925 |
|
||||
// | 2019-02-08 10:17:00 +0000 UTC | 2.44 |
|
||||
// +-------------------------------+----------------------+
|
||||
//
|
||||
//
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
{
|
||||
"status": 200,
|
||||
"frames": [
|
||||
{
|
||||
"schema": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "Time",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time"
|
||||
},
|
||||
"config": {
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Percentage CPU",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
},
|
||||
"labels": {},
|
||||
"config": {
|
||||
"unit": "percent",
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
1549620780000,
|
||||
1549620840000,
|
||||
1549620900000,
|
||||
1549620960000,
|
||||
1549621020000
|
||||
],
|
||||
[
|
||||
2.0875,
|
||||
2.1525,
|
||||
2.155,
|
||||
3.6925,
|
||||
2.44
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,323 @@
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
//
|
||||
// Frame[0]
|
||||
// Name:
|
||||
// Dimensions: 2 Fields by 5 Rows
|
||||
// +-------------------------------+------------------------------------------------------+
|
||||
// | Name: Time | Name: Percentage CPU |
|
||||
// | Labels: | Labels: Test Dimension=value-1, resourceName=grafana |
|
||||
// | Type: []time.Time | Type: []*float64 |
|
||||
// +-------------------------------+------------------------------------------------------+
|
||||
// | 2019-02-08 10:13:00 +0000 UTC | 2.0875 |
|
||||
// | 2019-02-08 10:14:00 +0000 UTC | 2.1525 |
|
||||
// | 2019-02-08 10:15:00 +0000 UTC | 2.155 |
|
||||
// | 2019-02-08 10:16:00 +0000 UTC | 3.6925 |
|
||||
// | 2019-02-08 10:17:00 +0000 UTC | 2.44 |
|
||||
// +-------------------------------+------------------------------------------------------+
|
||||
//
|
||||
//
|
||||
//
|
||||
// Frame[1]
|
||||
// Name:
|
||||
// Dimensions: 2 Fields by 5 Rows
|
||||
// +-------------------------------+------------------------------------------------------+
|
||||
// | Name: Time | Name: Percentage CPU |
|
||||
// | Labels: | Labels: Test Dimension=value-2, resourceName=grafana |
|
||||
// | Type: []time.Time | Type: []*float64 |
|
||||
// +-------------------------------+------------------------------------------------------+
|
||||
// | 2019-02-08 10:13:00 +0000 UTC | 2.0875 |
|
||||
// | 2019-02-08 10:14:00 +0000 UTC | 2.1525 |
|
||||
// | 2019-02-08 10:15:00 +0000 UTC | 2.155 |
|
||||
// | 2019-02-08 10:16:00 +0000 UTC | 3.6925 |
|
||||
// | 2019-02-08 10:17:00 +0000 UTC | 2.44 |
|
||||
// +-------------------------------+------------------------------------------------------+
|
||||
//
|
||||
//
|
||||
//
|
||||
// Frame[2]
|
||||
// Name:
|
||||
// Dimensions: 2 Fields by 5 Rows
|
||||
// +-------------------------------+--------------------------------------------------------+
|
||||
// | Name: Time | Name: Percentage CPU |
|
||||
// | Labels: | Labels: Test Dimension=value-1, resourceName=grafana-1 |
|
||||
// | Type: []time.Time | Type: []*float64 |
|
||||
// +-------------------------------+--------------------------------------------------------+
|
||||
// | 2019-02-08 10:13:00 +0000 UTC | 2.0875 |
|
||||
// | 2019-02-08 10:14:00 +0000 UTC | 2.1525 |
|
||||
// | 2019-02-08 10:15:00 +0000 UTC | 2.155 |
|
||||
// | 2019-02-08 10:16:00 +0000 UTC | 3.6925 |
|
||||
// | 2019-02-08 10:17:00 +0000 UTC | 2.44 |
|
||||
// +-------------------------------+--------------------------------------------------------+
|
||||
//
|
||||
//
|
||||
//
|
||||
// Frame[3]
|
||||
// Name:
|
||||
// Dimensions: 2 Fields by 5 Rows
|
||||
// +-------------------------------+--------------------------------------------------------+
|
||||
// | Name: Time | Name: Percentage CPU |
|
||||
// | Labels: | Labels: Test Dimension=value-3, resourceName=grafana-1 |
|
||||
// | Type: []time.Time | Type: []*float64 |
|
||||
// +-------------------------------+--------------------------------------------------------+
|
||||
// | 2019-02-08 10:13:00 +0000 UTC | 2.0875 |
|
||||
// | 2019-02-08 10:14:00 +0000 UTC | 2.1525 |
|
||||
// | 2019-02-08 10:15:00 +0000 UTC | 2.155 |
|
||||
// | 2019-02-08 10:16:00 +0000 UTC | 3.6925 |
|
||||
// | 2019-02-08 10:17:00 +0000 UTC | 2.44 |
|
||||
// +-------------------------------+--------------------------------------------------------+
|
||||
//
|
||||
//
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
{
|
||||
"status": 200,
|
||||
"frames": [
|
||||
{
|
||||
"schema": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "Time",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time"
|
||||
},
|
||||
"config": {
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Percentage CPU",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
},
|
||||
"labels": {
|
||||
"Test Dimension": "value-1",
|
||||
"resourceName": "grafana"
|
||||
},
|
||||
"config": {
|
||||
"unit": "percent",
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
1549620780000,
|
||||
1549620840000,
|
||||
1549620900000,
|
||||
1549620960000,
|
||||
1549621020000
|
||||
],
|
||||
[
|
||||
2.0875,
|
||||
2.1525,
|
||||
2.155,
|
||||
3.6925,
|
||||
2.44
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"schema": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "Time",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time"
|
||||
},
|
||||
"config": {
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Percentage CPU",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
},
|
||||
"labels": {
|
||||
"Test Dimension": "value-2",
|
||||
"resourceName": "grafana"
|
||||
},
|
||||
"config": {
|
||||
"unit": "percent",
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
1549620780000,
|
||||
1549620840000,
|
||||
1549620900000,
|
||||
1549620960000,
|
||||
1549621020000
|
||||
],
|
||||
[
|
||||
2.0875,
|
||||
2.1525,
|
||||
2.155,
|
||||
3.6925,
|
||||
2.44
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"schema": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "Time",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time"
|
||||
},
|
||||
"config": {
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana-1%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana-1%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Percentage CPU",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
},
|
||||
"labels": {
|
||||
"Test Dimension": "value-1",
|
||||
"resourceName": "grafana-1"
|
||||
},
|
||||
"config": {
|
||||
"unit": "percent",
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana-1%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana-1%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
1549620780000,
|
||||
1549620840000,
|
||||
1549620900000,
|
||||
1549620960000,
|
||||
1549621020000
|
||||
],
|
||||
[
|
||||
2.0875,
|
||||
2.1525,
|
||||
2.155,
|
||||
3.6925,
|
||||
2.44
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"schema": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "Time",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time"
|
||||
},
|
||||
"config": {
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana-1%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana-1%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Percentage CPU",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
},
|
||||
"labels": {
|
||||
"Test Dimension": "value-3",
|
||||
"resourceName": "grafana-1"
|
||||
},
|
||||
"config": {
|
||||
"unit": "percent",
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana-1%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana-1%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
1549620780000,
|
||||
1549620840000,
|
||||
1549620900000,
|
||||
1549620960000,
|
||||
1549621020000
|
||||
],
|
||||
[
|
||||
2.0875,
|
||||
2.1525,
|
||||
2.155,
|
||||
3.6925,
|
||||
2.44
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
//
|
||||
// Frame[0]
|
||||
// Name:
|
||||
// Dimensions: 2 Fields by 5 Rows
|
||||
// +-------------------------------+----------------------+
|
||||
// | Name: Time | Name: Percentage CPU |
|
||||
// | Labels: | Labels: |
|
||||
// | Type: []time.Time | Type: []*float64 |
|
||||
// +-------------------------------+----------------------+
|
||||
// | 2019-02-09 13:29:00 +0000 UTC | 8.26 |
|
||||
// | 2019-02-09 13:30:00 +0000 UTC | 8.7 |
|
||||
// | 2019-02-09 13:31:00 +0000 UTC | 14.82 |
|
||||
// | 2019-02-09 13:32:00 +0000 UTC | 10.07 |
|
||||
// | 2019-02-09 13:33:00 +0000 UTC | 8.52 |
|
||||
// +-------------------------------+----------------------+
|
||||
//
|
||||
//
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
{
|
||||
"status": 200,
|
||||
"frames": [
|
||||
{
|
||||
"schema": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "Time",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time"
|
||||
},
|
||||
"config": {
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A1%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Percentage CPU",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
},
|
||||
"labels": {},
|
||||
"config": {
|
||||
"unit": "percent",
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A1%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
1549718940000,
|
||||
1549719000000,
|
||||
1549719060000,
|
||||
1549719120000,
|
||||
1549719180000
|
||||
],
|
||||
[
|
||||
8.26,
|
||||
8.7,
|
||||
14.82,
|
||||
10.07,
|
||||
8.52
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
//
|
||||
// Frame[0]
|
||||
// Name:
|
||||
// Dimensions: 2 Fields by 5 Rows
|
||||
// +-------------------------------+----------------------+
|
||||
// | Name: Time | Name: Percentage CPU |
|
||||
// | Labels: | Labels: |
|
||||
// | Type: []time.Time | Type: []*float64 |
|
||||
// +-------------------------------+----------------------+
|
||||
// | 2019-02-09 13:29:00 +0000 UTC | 8.26 |
|
||||
// | 2019-02-09 13:30:00 +0000 UTC | 8.7 |
|
||||
// | 2019-02-09 13:31:00 +0000 UTC | 14.82 |
|
||||
// | 2019-02-09 13:32:00 +0000 UTC | 10.07 |
|
||||
// | 2019-02-09 13:33:00 +0000 UTC | 8.52 |
|
||||
// +-------------------------------+----------------------+
|
||||
//
|
||||
//
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
{
|
||||
"status": 200,
|
||||
"frames": [
|
||||
{
|
||||
"schema": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "Time",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time"
|
||||
},
|
||||
"config": {
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A1%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Percentage CPU",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
},
|
||||
"labels": {},
|
||||
"config": {
|
||||
"displayName": "custom grafanastaging Microsoft.Compute/virtualMachines grafana Percentage CPU",
|
||||
"unit": "percent",
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A1%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
1549718940000,
|
||||
1549719000000,
|
||||
1549719060000,
|
||||
1549719120000,
|
||||
1549719180000
|
||||
],
|
||||
[
|
||||
8.26,
|
||||
8.7,
|
||||
14.82,
|
||||
10.07,
|
||||
8.52
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
//
|
||||
// Frame[0]
|
||||
// Name:
|
||||
// Dimensions: 2 Fields by 5 Rows
|
||||
// +-------------------------------+----------------------+
|
||||
// | Name: Time | Name: Percentage CPU |
|
||||
// | Labels: | Labels: |
|
||||
// | Type: []time.Time | Type: []*float64 |
|
||||
// +-------------------------------+----------------------+
|
||||
// | 2019-02-09 13:29:00 +0000 UTC | 8.26 |
|
||||
// | 2019-02-09 13:30:00 +0000 UTC | 8.7 |
|
||||
// | 2019-02-09 13:31:00 +0000 UTC | 14.82 |
|
||||
// | 2019-02-09 13:32:00 +0000 UTC | 10.07 |
|
||||
// | 2019-02-09 13:33:00 +0000 UTC | 8.52 |
|
||||
// +-------------------------------+----------------------+
|
||||
//
|
||||
//
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
{
|
||||
"status": 200,
|
||||
"frames": [
|
||||
{
|
||||
"schema": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "Time",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time"
|
||||
},
|
||||
"config": {
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A1%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Percentage CPU",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
},
|
||||
"labels": {},
|
||||
"config": {
|
||||
"displayName": "custom grafanastaging Microsoft.Compute/virtualMachines grafana Percentage CPU",
|
||||
"unit": "percent",
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A1%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
1549718940000,
|
||||
1549719000000,
|
||||
1549719060000,
|
||||
1549719120000,
|
||||
1549719180000
|
||||
],
|
||||
[
|
||||
8.26,
|
||||
8.7,
|
||||
14.82,
|
||||
10.07,
|
||||
8.52
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
//
|
||||
// Frame[0]
|
||||
// Name:
|
||||
// Dimensions: 2 Fields by 5 Rows
|
||||
// +-------------------------------+----------------------+
|
||||
// | Name: Time | Name: Percentage CPU |
|
||||
// | Labels: | Labels: |
|
||||
// | Type: []time.Time | Type: []*float64 |
|
||||
// +-------------------------------+----------------------+
|
||||
// | 2019-02-09 13:29:00 +0000 UTC | 8.26 |
|
||||
// | 2019-02-09 13:30:00 +0000 UTC | 8.7 |
|
||||
// | 2019-02-09 13:31:00 +0000 UTC | 14.82 |
|
||||
// | 2019-02-09 13:32:00 +0000 UTC | 10.07 |
|
||||
// | 2019-02-09 13:33:00 +0000 UTC | 8.52 |
|
||||
// +-------------------------------+----------------------+
|
||||
//
|
||||
//
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
{
|
||||
"status": 200,
|
||||
"frames": [
|
||||
{
|
||||
"schema": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "Time",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time"
|
||||
},
|
||||
"config": {
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A1%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Percentage CPU",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
},
|
||||
"labels": {},
|
||||
"config": {
|
||||
"displayName": "custom grafanastaging Microsoft.Compute/virtualMachines grafana Percentage CPU",
|
||||
"unit": "percent",
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A1%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
1549718940000,
|
||||
1549719000000,
|
||||
1549719060000,
|
||||
1549719120000,
|
||||
1549719180000
|
||||
],
|
||||
[
|
||||
8.26,
|
||||
8.7,
|
||||
14.82,
|
||||
10.07,
|
||||
8.52
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
//
|
||||
// Frame[0]
|
||||
// Name:
|
||||
// Dimensions: 2 Fields by 5 Rows
|
||||
// +-------------------------------+----------------------+
|
||||
// | Name: Time | Name: Percentage CPU |
|
||||
// | Labels: | Labels: |
|
||||
// | Type: []time.Time | Type: []*float64 |
|
||||
// +-------------------------------+----------------------+
|
||||
// | 2019-02-09 14:26:00 +0000 UTC | 3.07 |
|
||||
// | 2019-02-09 14:27:00 +0000 UTC | 2.92 |
|
||||
// | 2019-02-09 14:28:00 +0000 UTC | 2.87 |
|
||||
// | 2019-02-09 14:29:00 +0000 UTC | 2.27 |
|
||||
// | 2019-02-09 14:30:00 +0000 UTC | 2.52 |
|
||||
// +-------------------------------+----------------------+
|
||||
//
|
||||
//
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
{
|
||||
"status": 200,
|
||||
"frames": [
|
||||
{
|
||||
"schema": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "Time",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time"
|
||||
},
|
||||
"config": {
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A3%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Percentage CPU",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
},
|
||||
"labels": {},
|
||||
"config": {
|
||||
"unit": "percent",
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A3%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
1549722360000,
|
||||
1549722420000,
|
||||
1549722480000,
|
||||
1549722540000,
|
||||
1549722600000
|
||||
],
|
||||
[
|
||||
3.07,
|
||||
2.92,
|
||||
2.87,
|
||||
2.27,
|
||||
2.52
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
//
|
||||
// Frame[0]
|
||||
// Name:
|
||||
// Dimensions: 2 Fields by 5 Rows
|
||||
// +-------------------------------+----------------------+
|
||||
// | Name: Time | Name: Percentage CPU |
|
||||
// | Labels: | Labels: |
|
||||
// | Type: []time.Time | Type: []*float64 |
|
||||
// +-------------------------------+----------------------+
|
||||
// | 2019-02-09 14:43:00 +0000 UTC | 1.51 |
|
||||
// | 2019-02-09 14:44:00 +0000 UTC | 2.38 |
|
||||
// | 2019-02-09 14:45:00 +0000 UTC | 1.69 |
|
||||
// | 2019-02-09 14:46:00 +0000 UTC | 2.27 |
|
||||
// | 2019-02-09 14:47:00 +0000 UTC | 1.96 |
|
||||
// +-------------------------------+----------------------+
|
||||
//
|
||||
//
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
{
|
||||
"status": 200,
|
||||
"frames": [
|
||||
{
|
||||
"schema": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "Time",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time"
|
||||
},
|
||||
"config": {
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A2%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Percentage CPU",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
},
|
||||
"labels": {},
|
||||
"config": {
|
||||
"unit": "percent",
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A2%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
1549723380000,
|
||||
1549723440000,
|
||||
1549723500000,
|
||||
1549723560000,
|
||||
1549723620000
|
||||
],
|
||||
[
|
||||
1.51,
|
||||
2.38,
|
||||
1.69,
|
||||
2.27,
|
||||
1.96
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
//
|
||||
// Frame[0]
|
||||
// Name:
|
||||
// Dimensions: 2 Fields by 5 Rows
|
||||
// +-------------------------------+----------------------+
|
||||
// | Name: Time | Name: Percentage CPU |
|
||||
// | Labels: | Labels: |
|
||||
// | Type: []time.Time | Type: []*float64 |
|
||||
// +-------------------------------+----------------------+
|
||||
// | 2019-02-09 14:44:00 +0000 UTC | 4 |
|
||||
// | 2019-02-09 14:45:00 +0000 UTC | 4 |
|
||||
// | 2019-02-09 14:46:00 +0000 UTC | 4 |
|
||||
// | 2019-02-09 14:47:00 +0000 UTC | 4 |
|
||||
// | 2019-02-09 14:48:00 +0000 UTC | 4 |
|
||||
// +-------------------------------+----------------------+
|
||||
//
|
||||
//
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
{
|
||||
"status": 200,
|
||||
"frames": [
|
||||
{
|
||||
"schema": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "Time",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time"
|
||||
},
|
||||
"config": {
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A7%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Percentage CPU",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
},
|
||||
"labels": {},
|
||||
"config": {
|
||||
"unit": "percent",
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A7%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
1549723440000,
|
||||
1549723500000,
|
||||
1549723560000,
|
||||
1549723620000,
|
||||
1549723680000
|
||||
],
|
||||
[
|
||||
4,
|
||||
4,
|
||||
4,
|
||||
4,
|
||||
4
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,250 @@
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
//
|
||||
// Frame[0]
|
||||
// Name:
|
||||
// Dimensions: 2 Fields by 6 Rows
|
||||
// +-------------------------------+---------------------------+
|
||||
// | Name: Time | Name: Blob Count |
|
||||
// | Labels: | Labels: blobtype=PageBlob |
|
||||
// | Type: []time.Time | Type: []*float64 |
|
||||
// +-------------------------------+---------------------------+
|
||||
// | 2019-02-09 15:21:00 +0000 UTC | 3 |
|
||||
// | 2019-02-09 16:21:00 +0000 UTC | 3 |
|
||||
// | 2019-02-09 17:21:00 +0000 UTC | 3 |
|
||||
// | 2019-02-09 18:21:00 +0000 UTC | 3 |
|
||||
// | 2019-02-09 19:21:00 +0000 UTC | 3 |
|
||||
// | 2019-02-09 20:21:00 +0000 UTC | null |
|
||||
// +-------------------------------+---------------------------+
|
||||
//
|
||||
//
|
||||
//
|
||||
// Frame[1]
|
||||
// Name:
|
||||
// Dimensions: 2 Fields by 6 Rows
|
||||
// +-------------------------------+----------------------------+
|
||||
// | Name: Time | Name: Blob Count |
|
||||
// | Labels: | Labels: blobtype=BlockBlob |
|
||||
// | Type: []time.Time | Type: []*float64 |
|
||||
// +-------------------------------+----------------------------+
|
||||
// | 2019-02-09 15:21:00 +0000 UTC | 1 |
|
||||
// | 2019-02-09 16:21:00 +0000 UTC | 1 |
|
||||
// | 2019-02-09 17:21:00 +0000 UTC | 1 |
|
||||
// | 2019-02-09 18:21:00 +0000 UTC | 1 |
|
||||
// | 2019-02-09 19:21:00 +0000 UTC | 1 |
|
||||
// | 2019-02-09 20:21:00 +0000 UTC | null |
|
||||
// +-------------------------------+----------------------------+
|
||||
//
|
||||
//
|
||||
//
|
||||
// Frame[2]
|
||||
// Name:
|
||||
// Dimensions: 2 Fields by 6 Rows
|
||||
// +-------------------------------+------------------------------------------+
|
||||
// | Name: Time | Name: Blob Count |
|
||||
// | Labels: | Labels: blobtype=Azure Data Lake Storage |
|
||||
// | Type: []time.Time | Type: []*float64 |
|
||||
// +-------------------------------+------------------------------------------+
|
||||
// | 2019-02-09 15:21:00 +0000 UTC | 0 |
|
||||
// | 2019-02-09 16:21:00 +0000 UTC | 0 |
|
||||
// | 2019-02-09 17:21:00 +0000 UTC | 0 |
|
||||
// | 2019-02-09 18:21:00 +0000 UTC | 0 |
|
||||
// | 2019-02-09 19:21:00 +0000 UTC | 0 |
|
||||
// | 2019-02-09 20:21:00 +0000 UTC | null |
|
||||
// +-------------------------------+------------------------------------------+
|
||||
//
|
||||
//
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
{
|
||||
"status": 200,
|
||||
"frames": [
|
||||
{
|
||||
"schema": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "Time",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time"
|
||||
},
|
||||
"config": {
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Blob Count",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
},
|
||||
"labels": {
|
||||
"blobtype": "PageBlob"
|
||||
},
|
||||
"config": {
|
||||
"unit": "short",
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
1549725660000,
|
||||
1549729260000,
|
||||
1549732860000,
|
||||
1549736460000,
|
||||
1549740060000,
|
||||
1549743660000
|
||||
],
|
||||
[
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
null
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"schema": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "Time",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time"
|
||||
},
|
||||
"config": {
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Blob Count",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
},
|
||||
"labels": {
|
||||
"blobtype": "BlockBlob"
|
||||
},
|
||||
"config": {
|
||||
"unit": "short",
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
1549725660000,
|
||||
1549729260000,
|
||||
1549732860000,
|
||||
1549736460000,
|
||||
1549740060000,
|
||||
1549743660000
|
||||
],
|
||||
[
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
null
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"schema": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "Time",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time"
|
||||
},
|
||||
"config": {
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Blob Count",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
},
|
||||
"labels": {
|
||||
"blobtype": "Azure Data Lake Storage"
|
||||
},
|
||||
"config": {
|
||||
"unit": "short",
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
1549725660000,
|
||||
1549729260000,
|
||||
1549732860000,
|
||||
1549736460000,
|
||||
1549740060000,
|
||||
1549743660000
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,253 @@
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
//
|
||||
// Frame[0]
|
||||
// Name:
|
||||
// Dimensions: 2 Fields by 6 Rows
|
||||
// +-------------------------------+---------------------------+
|
||||
// | Name: Time | Name: Blob Count |
|
||||
// | Labels: | Labels: blobtype=PageBlob |
|
||||
// | Type: []time.Time | Type: []*float64 |
|
||||
// +-------------------------------+---------------------------+
|
||||
// | 2019-02-09 15:21:00 +0000 UTC | 3 |
|
||||
// | 2019-02-09 16:21:00 +0000 UTC | 3 |
|
||||
// | 2019-02-09 17:21:00 +0000 UTC | 3 |
|
||||
// | 2019-02-09 18:21:00 +0000 UTC | 3 |
|
||||
// | 2019-02-09 19:21:00 +0000 UTC | 3 |
|
||||
// | 2019-02-09 20:21:00 +0000 UTC | null |
|
||||
// +-------------------------------+---------------------------+
|
||||
//
|
||||
//
|
||||
//
|
||||
// Frame[1]
|
||||
// Name:
|
||||
// Dimensions: 2 Fields by 6 Rows
|
||||
// +-------------------------------+----------------------------+
|
||||
// | Name: Time | Name: Blob Count |
|
||||
// | Labels: | Labels: blobtype=BlockBlob |
|
||||
// | Type: []time.Time | Type: []*float64 |
|
||||
// +-------------------------------+----------------------------+
|
||||
// | 2019-02-09 15:21:00 +0000 UTC | 1 |
|
||||
// | 2019-02-09 16:21:00 +0000 UTC | 1 |
|
||||
// | 2019-02-09 17:21:00 +0000 UTC | 1 |
|
||||
// | 2019-02-09 18:21:00 +0000 UTC | 1 |
|
||||
// | 2019-02-09 19:21:00 +0000 UTC | 1 |
|
||||
// | 2019-02-09 20:21:00 +0000 UTC | null |
|
||||
// +-------------------------------+----------------------------+
|
||||
//
|
||||
//
|
||||
//
|
||||
// Frame[2]
|
||||
// Name:
|
||||
// Dimensions: 2 Fields by 6 Rows
|
||||
// +-------------------------------+------------------------------------------+
|
||||
// | Name: Time | Name: Blob Count |
|
||||
// | Labels: | Labels: blobtype=Azure Data Lake Storage |
|
||||
// | Type: []time.Time | Type: []*float64 |
|
||||
// +-------------------------------+------------------------------------------+
|
||||
// | 2019-02-09 15:21:00 +0000 UTC | 0 |
|
||||
// | 2019-02-09 16:21:00 +0000 UTC | 0 |
|
||||
// | 2019-02-09 17:21:00 +0000 UTC | 0 |
|
||||
// | 2019-02-09 18:21:00 +0000 UTC | 0 |
|
||||
// | 2019-02-09 19:21:00 +0000 UTC | 0 |
|
||||
// | 2019-02-09 20:21:00 +0000 UTC | null |
|
||||
// +-------------------------------+------------------------------------------+
|
||||
//
|
||||
//
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
{
|
||||
"status": 200,
|
||||
"frames": [
|
||||
{
|
||||
"schema": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "Time",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time"
|
||||
},
|
||||
"config": {
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Blob Count",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
},
|
||||
"labels": {
|
||||
"blobtype": "PageBlob"
|
||||
},
|
||||
"config": {
|
||||
"displayName": "blobtype=PageBlob",
|
||||
"unit": "short",
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
1549725660000,
|
||||
1549729260000,
|
||||
1549732860000,
|
||||
1549736460000,
|
||||
1549740060000,
|
||||
1549743660000
|
||||
],
|
||||
[
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
3,
|
||||
null
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"schema": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "Time",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time"
|
||||
},
|
||||
"config": {
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Blob Count",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
},
|
||||
"labels": {
|
||||
"blobtype": "BlockBlob"
|
||||
},
|
||||
"config": {
|
||||
"displayName": "blobtype=BlockBlob",
|
||||
"unit": "short",
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
1549725660000,
|
||||
1549729260000,
|
||||
1549732860000,
|
||||
1549736460000,
|
||||
1549740060000,
|
||||
1549743660000
|
||||
],
|
||||
[
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
null
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"schema": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "Time",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time"
|
||||
},
|
||||
"config": {
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Blob Count",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
},
|
||||
"labels": {
|
||||
"blobtype": "Azure Data Lake Storage"
|
||||
},
|
||||
"config": {
|
||||
"displayName": "blobtype=Azure Data Lake Storage",
|
||||
"unit": "short",
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
1549725660000,
|
||||
1549729260000,
|
||||
1549732860000,
|
||||
1549736460000,
|
||||
1549740060000,
|
||||
1549743660000
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
null
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,229 @@
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
//
|
||||
// Frame[0]
|
||||
// Name:
|
||||
// Dimensions: 2 Fields by 3 Rows
|
||||
// +-------------------------------+------------------------------------------+
|
||||
// | Name: Time | Name: Blob Capacity |
|
||||
// | Labels: | Labels: blobtype=PageBlob, tier=Standard |
|
||||
// | Type: []time.Time | Type: []*float64 |
|
||||
// +-------------------------------+------------------------------------------+
|
||||
// | 2020-06-30 09:58:00 +0000 UTC | 675530 |
|
||||
// | 2020-06-30 10:58:00 +0000 UTC | 675530 |
|
||||
// | 2020-06-30 11:58:00 +0000 UTC | 675530 |
|
||||
// +-------------------------------+------------------------------------------+
|
||||
//
|
||||
//
|
||||
//
|
||||
// Frame[1]
|
||||
// Name:
|
||||
// Dimensions: 2 Fields by 3 Rows
|
||||
// +-------------------------------+--------------------------------------+
|
||||
// | Name: Time | Name: Blob Capacity |
|
||||
// | Labels: | Labels: blobtype=BlockBlob, tier=Hot |
|
||||
// | Type: []time.Time | Type: []*float64 |
|
||||
// +-------------------------------+--------------------------------------+
|
||||
// | 2020-06-30 09:58:00 +0000 UTC | 0 |
|
||||
// | 2020-06-30 10:58:00 +0000 UTC | 0 |
|
||||
// | 2020-06-30 11:58:00 +0000 UTC | 0 |
|
||||
// +-------------------------------+--------------------------------------+
|
||||
//
|
||||
//
|
||||
//
|
||||
// Frame[2]
|
||||
// Name:
|
||||
// Dimensions: 2 Fields by 3 Rows
|
||||
// +-------------------------------+-----------------------------------------------------+
|
||||
// | Name: Time | Name: Blob Capacity |
|
||||
// | Labels: | Labels: blobtype=Azure Data Lake Storage, tier=Cool |
|
||||
// | Type: []time.Time | Type: []*float64 |
|
||||
// +-------------------------------+-----------------------------------------------------+
|
||||
// | 2020-06-30 09:58:00 +0000 UTC | 0 |
|
||||
// | 2020-06-30 10:58:00 +0000 UTC | 0 |
|
||||
// | 2020-06-30 11:58:00 +0000 UTC | 0 |
|
||||
// +-------------------------------+-----------------------------------------------------+
|
||||
//
|
||||
//
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
{
|
||||
"status": 200,
|
||||
"frames": [
|
||||
{
|
||||
"schema": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "Time",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time"
|
||||
},
|
||||
"config": {
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Blob Capacity",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
},
|
||||
"labels": {
|
||||
"blobtype": "PageBlob",
|
||||
"tier": "Standard"
|
||||
},
|
||||
"config": {
|
||||
"displayName": "danieltest {Blob Type=PageBlob, Tier=Standard}",
|
||||
"unit": "decbytes",
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
1593511080000,
|
||||
1593514680000,
|
||||
1593518280000
|
||||
],
|
||||
[
|
||||
675530,
|
||||
675530,
|
||||
675530
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"schema": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "Time",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time"
|
||||
},
|
||||
"config": {
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Blob Capacity",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
},
|
||||
"labels": {
|
||||
"blobtype": "BlockBlob",
|
||||
"tier": "Hot"
|
||||
},
|
||||
"config": {
|
||||
"displayName": "danieltest {Blob Type=BlockBlob, Tier=Hot}",
|
||||
"unit": "decbytes",
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
1593511080000,
|
||||
1593514680000,
|
||||
1593518280000
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"schema": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "Time",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time"
|
||||
},
|
||||
"config": {
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Blob Capacity",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
},
|
||||
"labels": {
|
||||
"blobtype": "Azure Data Lake Storage",
|
||||
"tier": "Cool"
|
||||
},
|
||||
"config": {
|
||||
"displayName": "danieltest {Blob Type=Azure Data Lake Storage, Tier=Cool}",
|
||||
"unit": "decbytes",
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
1593511080000,
|
||||
1593514680000,
|
||||
1593518280000
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
//
|
||||
// Frame[0]
|
||||
// Name:
|
||||
// Dimensions: 2 Fields by 1 Rows
|
||||
// +-------------------------------+----------------------+
|
||||
// | Name: Time | Name: Percentage CPU |
|
||||
// | Labels: | Labels: |
|
||||
// | Type: []time.Time | Type: []*float64 |
|
||||
// +-------------------------------+----------------------+
|
||||
// | 2019-02-08 10:13:00 +0000 UTC | 2.0875 |
|
||||
// +-------------------------------+----------------------+
|
||||
//
|
||||
//
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
{
|
||||
"status": 200,
|
||||
"frames": [
|
||||
{
|
||||
"schema": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "Time",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time"
|
||||
},
|
||||
"config": {
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Percentage CPU",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
},
|
||||
"labels": {},
|
||||
"config": {
|
||||
"displayName": "custom",
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
1549620780000
|
||||
],
|
||||
[
|
||||
2.0875
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
//
|
||||
// Frame[0]
|
||||
// Name:
|
||||
// Dimensions: 2 Fields by 5 Rows
|
||||
// +-------------------------------+------------------------------+
|
||||
// | Name: Time | Name: Percentage CPU |
|
||||
// | Labels: | Labels: resourceName=grafana |
|
||||
// | Type: []time.Time | Type: []*float64 |
|
||||
// +-------------------------------+------------------------------+
|
||||
// | 2019-02-08 10:13:00 +0000 UTC | 2.0875 |
|
||||
// | 2019-02-08 10:14:00 +0000 UTC | 2.1525 |
|
||||
// | 2019-02-08 10:15:00 +0000 UTC | 2.155 |
|
||||
// | 2019-02-08 10:16:00 +0000 UTC | 3.6925 |
|
||||
// | 2019-02-08 10:17:00 +0000 UTC | 2.44 |
|
||||
// +-------------------------------+------------------------------+
|
||||
//
|
||||
//
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
{
|
||||
"status": 200,
|
||||
"frames": [
|
||||
{
|
||||
"schema": {
|
||||
"fields": [
|
||||
{
|
||||
"name": "Time",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time"
|
||||
},
|
||||
"config": {
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Percentage CPU",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
},
|
||||
"labels": {
|
||||
"resourceName": "grafana"
|
||||
},
|
||||
"config": {
|
||||
"unit": "percent",
|
||||
"links": [
|
||||
{
|
||||
"title": "View in Azure Portal",
|
||||
"targetBlank": true,
|
||||
"url": "http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
1549620780000,
|
||||
1549620840000,
|
||||
1549620900000,
|
||||
1549620960000,
|
||||
1549621020000
|
||||
],
|
||||
[
|
||||
2.0875,
|
||||
2.1525,
|
||||
2.155,
|
||||
3.6925,
|
||||
2.44
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
//
|
||||
// Frame[0] {
|
||||
// "typeVersion": [
|
||||
// 0,
|
||||
// 0
|
||||
// ],
|
||||
// "custom": {
|
||||
// "azureColumnTypes": [
|
||||
// "datetime",
|
||||
// "string",
|
||||
// "real"
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
// Name:
|
||||
// Dimensions: 3 Fields by 3 Rows
|
||||
// +---------------------------------+-----------------+------------------------+
|
||||
// | Name: TimeGenerated | Name: Computer | Name: avg_CounterValue |
|
||||
// | Labels: | Labels: | Labels: |
|
||||
// | Type: []*time.Time | Type: []*string | Type: []*float64 |
|
||||
// +---------------------------------+-----------------+------------------------+
|
||||
// | 2020-04-19 19:16:06.5 +0000 UTC | grafana-vm | 1.1 |
|
||||
// | 2020-04-19 19:16:16.5 +0000 UTC | grafana-vm | 2.2 |
|
||||
// | 2020-04-19 19:16:26.5 +0000 UTC | grafana-vm | 3.3 |
|
||||
// +---------------------------------+-----------------+------------------------+
|
||||
//
|
||||
//
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
{
|
||||
"status": 200,
|
||||
"frames": [
|
||||
{
|
||||
"schema": {
|
||||
"meta": {
|
||||
"typeVersion": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"custom": {
|
||||
"azureColumnTypes": [
|
||||
"datetime",
|
||||
"string",
|
||||
"real"
|
||||
]
|
||||
}
|
||||
},
|
||||
"fields": [
|
||||
{
|
||||
"name": "TimeGenerated",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Computer",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "avg_CounterValue",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
1587323766500,
|
||||
1587323776500,
|
||||
1587323786500
|
||||
],
|
||||
[
|
||||
"grafana-vm",
|
||||
"grafana-vm",
|
||||
"grafana-vm"
|
||||
],
|
||||
[
|
||||
1.1,
|
||||
2.2,
|
||||
3.3
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
87
pkg/tsdb/azuremonitor/testdata/loganalytics/10-log-analytics-response-warning.json.golden.jsonc
vendored
Normal file
87
pkg/tsdb/azuremonitor/testdata/loganalytics/10-log-analytics-response-warning.json.golden.jsonc
vendored
Normal file
@ -0,0 +1,87 @@
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
//
|
||||
// Frame[0] {
|
||||
// "typeVersion": [
|
||||
// 0,
|
||||
// 0
|
||||
// ],
|
||||
// "custom": {
|
||||
// "azureColumnTypes": [
|
||||
// "string",
|
||||
// "string"
|
||||
// ]
|
||||
// },
|
||||
// "notices": [
|
||||
// {
|
||||
// "severity": "warning",
|
||||
// "text": "There were some errors when processing your query. Something went wrong processing your query on the server. Not sure what happened."
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// Name:
|
||||
// Dimensions: 2 Fields by 1 Rows
|
||||
// +----------------------------------+-----------------+
|
||||
// | Name: OperationName | Name: Level |
|
||||
// | Labels: | Labels: |
|
||||
// | Type: []*string | Type: []*string |
|
||||
// +----------------------------------+-----------------+
|
||||
// | Create or Update Virtual Machine | Informational |
|
||||
// +----------------------------------+-----------------+
|
||||
//
|
||||
//
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
{
|
||||
"status": 200,
|
||||
"frames": [
|
||||
{
|
||||
"schema": {
|
||||
"meta": {
|
||||
"typeVersion": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"custom": {
|
||||
"azureColumnTypes": [
|
||||
"string",
|
||||
"string"
|
||||
]
|
||||
},
|
||||
"notices": [
|
||||
{
|
||||
"severity": "warning",
|
||||
"text": "There were some errors when processing your query. Something went wrong processing your query on the server. Not sure what happened."
|
||||
}
|
||||
]
|
||||
},
|
||||
"fields": [
|
||||
{
|
||||
"name": "OperationName",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Level",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
"Create or Update Virtual Machine"
|
||||
],
|
||||
[
|
||||
"Informational"
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
{
|
||||
"status": 200
|
||||
}
|
201
pkg/tsdb/azuremonitor/testdata/loganalytics/6-log-analytics-response-table.json.golden.jsonc
vendored
Normal file
201
pkg/tsdb/azuremonitor/testdata/loganalytics/6-log-analytics-response-table.json.golden.jsonc
vendored
Normal file
@ -0,0 +1,201 @@
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
//
|
||||
// Frame[0] {
|
||||
// "typeVersion": [
|
||||
// 0,
|
||||
// 0
|
||||
// ],
|
||||
// "custom": {
|
||||
// "azureColumnTypes": [
|
||||
// "string",
|
||||
// "string",
|
||||
// "string",
|
||||
// "string",
|
||||
// "string",
|
||||
// "real",
|
||||
// "real",
|
||||
// "int",
|
||||
// "real",
|
||||
// "datetime"
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
// Name:
|
||||
// Dimensions: 10 Fields by 3 Rows
|
||||
// +--------------------------------------+-----------------+------------------+-------------------------+--------------------+------------------+------------------+-------------------+--------------------+-----------------------------------+
|
||||
// | Name: TenantId | Name: Computer | Name: ObjectName | Name: CounterName | Name: InstanceName | Name: Min | Name: Max | Name: SampleCount | Name: CounterValue | Name: TimeGenerated |
|
||||
// | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: |
|
||||
// | Type: []*string | Type: []*string | Type: []*string | Type: []*string | Type: []*string | Type: []*float64 | Type: []*float64 | Type: []*int32 | Type: []*float64 | Type: []*time.Time |
|
||||
// +--------------------------------------+-----------------+------------------+-------------------------+--------------------+------------------+------------------+-------------------+--------------------+-----------------------------------+
|
||||
// | a2c1b44e-3e57-4410-b027-6cc0ae6dee67 | grafana-vm | Memory | Available MBytes Memory | Memory | null | null | null | 2040 | 2020-04-23 11:46:03.857 +0000 UTC |
|
||||
// | a2c1b44e-3e57-4410-b027-6cc0ae6dee67 | grafana-vm | Memory | Available MBytes Memory | Memory | null | null | null | 2066 | 2020-04-23 11:46:13.857 +0000 UTC |
|
||||
// | a2c1b44e-3e57-4410-b027-6cc0ae6dee67 | grafana-vm | Memory | Available MBytes Memory | Memory | null | null | null | 2066 | 2020-04-23 11:46:23.857 +0000 UTC |
|
||||
// +--------------------------------------+-----------------+------------------+-------------------------+--------------------+------------------+------------------+-------------------+--------------------+-----------------------------------+
|
||||
//
|
||||
//
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
{
|
||||
"status": 200,
|
||||
"frames": [
|
||||
{
|
||||
"schema": {
|
||||
"meta": {
|
||||
"typeVersion": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"custom": {
|
||||
"azureColumnTypes": [
|
||||
"string",
|
||||
"string",
|
||||
"string",
|
||||
"string",
|
||||
"string",
|
||||
"real",
|
||||
"real",
|
||||
"int",
|
||||
"real",
|
||||
"datetime"
|
||||
]
|
||||
}
|
||||
},
|
||||
"fields": [
|
||||
{
|
||||
"name": "TenantId",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Computer",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ObjectName",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "CounterName",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "InstanceName",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Min",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Max",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "SampleCount",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "int32",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "CounterValue",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "TimeGenerated",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time",
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
"a2c1b44e-3e57-4410-b027-6cc0ae6dee67",
|
||||
"a2c1b44e-3e57-4410-b027-6cc0ae6dee67",
|
||||
"a2c1b44e-3e57-4410-b027-6cc0ae6dee67"
|
||||
],
|
||||
[
|
||||
"grafana-vm",
|
||||
"grafana-vm",
|
||||
"grafana-vm"
|
||||
],
|
||||
[
|
||||
"Memory",
|
||||
"Memory",
|
||||
"Memory"
|
||||
],
|
||||
[
|
||||
"Available MBytes Memory",
|
||||
"Available MBytes Memory",
|
||||
"Available MBytes Memory"
|
||||
],
|
||||
[
|
||||
"Memory",
|
||||
"Memory",
|
||||
"Memory"
|
||||
],
|
||||
[
|
||||
null,
|
||||
null,
|
||||
null
|
||||
],
|
||||
[
|
||||
null,
|
||||
null,
|
||||
null
|
||||
],
|
||||
[
|
||||
null,
|
||||
null,
|
||||
null
|
||||
],
|
||||
[
|
||||
2040,
|
||||
2066,
|
||||
2066
|
||||
],
|
||||
[
|
||||
1587642363857,
|
||||
1587642373857,
|
||||
1587642383857
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
205
pkg/tsdb/azuremonitor/testdata/loganalytics/7-log-analytics-all-types-table.json.golden.jsonc
vendored
Normal file
205
pkg/tsdb/azuremonitor/testdata/loganalytics/7-log-analytics-all-types-table.json.golden.jsonc
vendored
Normal file
@ -0,0 +1,205 @@
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
//
|
||||
// Frame[0] {
|
||||
// "typeVersion": [
|
||||
// 0,
|
||||
// 0
|
||||
// ],
|
||||
// "custom": {
|
||||
// "azureColumnTypes": [
|
||||
// "bool",
|
||||
// "string",
|
||||
// "datetime",
|
||||
// "dynamic",
|
||||
// "guid",
|
||||
// "int",
|
||||
// "long",
|
||||
// "real",
|
||||
// "timespan",
|
||||
// "decimal",
|
||||
// "object",
|
||||
// "number"
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
// Name:
|
||||
// Dimensions: 12 Fields by 1 Rows
|
||||
// +---------------+-----------------+---------------------------------+---------------------------------------------------------------+--------------------------------------+----------------+---------------------+-------------------------+------------------+-----------------------+--------------------------------------------------------------------------+-----------------------+
|
||||
// | Name: XBool | Name: XString | Name: XDateTime | Name: XDynamic | Name: XGuid | Name: XInt | Name: XLong | Name: XReal | Name: XTimeSpan | Name: XDecimal | Name: XObject | Name: XNumber |
|
||||
// | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: |
|
||||
// | Type: []*bool | Type: []*string | Type: []*time.Time | Type: []*string | Type: []*string | Type: []*int32 | Type: []*int64 | Type: []*float64 | Type: []*string | Type: []*float64 | Type: []*string | Type: []*float64 |
|
||||
// +---------------+-----------------+---------------------------------+---------------------------------------------------------------+--------------------------------------+----------------+---------------------+-------------------------+------------------+-----------------------+--------------------------------------------------------------------------+-----------------------+
|
||||
// | true | Grafana | 2006-01-02 22:04:05.1 +0000 UTC | [{"person":"Daniel"},{"cats":23},{"diagnosis":"cat problem"}] | 74be27de-1e4e-49d9-b579-fe0b331d3642 | 2147483647 | 9223372036854775807 | 1.7976931348623157e+308 | 00:00:00.0000001 | 7.922816251426434e+28 | "{\"person\": \"Daniel\", \"cats\": 23, \"diagnosis\": \"cat problem\"}" | 7.922816251426434e+28 |
|
||||
// +---------------+-----------------+---------------------------------+---------------------------------------------------------------+--------------------------------------+----------------+---------------------+-------------------------+------------------+-----------------------+--------------------------------------------------------------------------+-----------------------+
|
||||
//
|
||||
//
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
{
|
||||
"status": 200,
|
||||
"frames": [
|
||||
{
|
||||
"schema": {
|
||||
"meta": {
|
||||
"typeVersion": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"custom": {
|
||||
"azureColumnTypes": [
|
||||
"bool",
|
||||
"string",
|
||||
"datetime",
|
||||
"dynamic",
|
||||
"guid",
|
||||
"int",
|
||||
"long",
|
||||
"real",
|
||||
"timespan",
|
||||
"decimal",
|
||||
"object",
|
||||
"number"
|
||||
]
|
||||
}
|
||||
},
|
||||
"fields": [
|
||||
{
|
||||
"name": "XBool",
|
||||
"type": "boolean",
|
||||
"typeInfo": {
|
||||
"frame": "bool",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "XString",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "XDateTime",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "XDynamic",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "XGuid",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "XInt",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "int32",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "XLong",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "int64",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "XReal",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "XTimeSpan",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "XDecimal",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "XObject",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "XNumber",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
true
|
||||
],
|
||||
[
|
||||
"Grafana"
|
||||
],
|
||||
[
|
||||
1136239445100
|
||||
],
|
||||
[
|
||||
"[{\"person\":\"Daniel\"},{\"cats\":23},{\"diagnosis\":\"cat problem\"}]"
|
||||
],
|
||||
[
|
||||
"74be27de-1e4e-49d9-b579-fe0b331d3642"
|
||||
],
|
||||
[
|
||||
2147483647
|
||||
],
|
||||
[
|
||||
9223372036854775807
|
||||
],
|
||||
[
|
||||
1.7976931348623157e+308
|
||||
],
|
||||
[
|
||||
"00:00:00.0000001"
|
||||
],
|
||||
[
|
||||
7.922816251426434e+28
|
||||
],
|
||||
[
|
||||
"\"{\\\"person\\\": \\\"Daniel\\\", \\\"cats\\\": 23, \\\"diagnosis\\\": \\\"cat problem\\\"}\""
|
||||
],
|
||||
[
|
||||
7.922816251426434e+28
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
105
pkg/tsdb/azuremonitor/testdata/loganalytics/8-log-analytics-response-nan-inf.json.golden.jsonc
vendored
Normal file
105
pkg/tsdb/azuremonitor/testdata/loganalytics/8-log-analytics-response-nan-inf.json.golden.jsonc
vendored
Normal file
@ -0,0 +1,105 @@
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
//
|
||||
// Frame[0] {
|
||||
// "typeVersion": [
|
||||
// 0,
|
||||
// 0
|
||||
// ],
|
||||
// "custom": {
|
||||
// "azureColumnTypes": [
|
||||
// "real",
|
||||
// "real",
|
||||
// "real"
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
// Name:
|
||||
// Dimensions: 3 Fields by 1 Rows
|
||||
// +------------------+------------------+------------------+
|
||||
// | Name: XInf | Name: XInfNeg | Name: XNan |
|
||||
// | Labels: | Labels: | Labels: |
|
||||
// | Type: []*float64 | Type: []*float64 | Type: []*float64 |
|
||||
// +------------------+------------------+------------------+
|
||||
// | +Inf | -Inf | NaN |
|
||||
// +------------------+------------------+------------------+
|
||||
//
|
||||
//
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
{
|
||||
"status": 200,
|
||||
"frames": [
|
||||
{
|
||||
"schema": {
|
||||
"meta": {
|
||||
"typeVersion": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"custom": {
|
||||
"azureColumnTypes": [
|
||||
"real",
|
||||
"real",
|
||||
"real"
|
||||
]
|
||||
}
|
||||
},
|
||||
"fields": [
|
||||
{
|
||||
"name": "XInf",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "XInfNeg",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "XNan",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
null
|
||||
],
|
||||
[
|
||||
null
|
||||
],
|
||||
[
|
||||
null
|
||||
]
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"Inf": [
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"NegInf": [
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"NaN": [
|
||||
0
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
87
pkg/tsdb/azuremonitor/testdata/loganalytics/9-log-analytics-response-error.json.golden.jsonc
vendored
Normal file
87
pkg/tsdb/azuremonitor/testdata/loganalytics/9-log-analytics-response-error.json.golden.jsonc
vendored
Normal file
@ -0,0 +1,87 @@
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
//
|
||||
// Frame[0] {
|
||||
// "typeVersion": [
|
||||
// 0,
|
||||
// 0
|
||||
// ],
|
||||
// "custom": {
|
||||
// "azureColumnTypes": [
|
||||
// "string",
|
||||
// "string"
|
||||
// ]
|
||||
// },
|
||||
// "notices": [
|
||||
// {
|
||||
// "severity": "error",
|
||||
// "text": "There were some errors when processing your query. Something went wrong processing your query on the server. The results of this query exceed the set limit of 1 records."
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// Name:
|
||||
// Dimensions: 2 Fields by 1 Rows
|
||||
// +----------------------------------+-----------------+
|
||||
// | Name: OperationName | Name: Level |
|
||||
// | Labels: | Labels: |
|
||||
// | Type: []*string | Type: []*string |
|
||||
// +----------------------------------+-----------------+
|
||||
// | Create or Update Virtual Machine | Informational |
|
||||
// +----------------------------------+-----------------+
|
||||
//
|
||||
//
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
{
|
||||
"status": 200,
|
||||
"frames": [
|
||||
{
|
||||
"schema": {
|
||||
"meta": {
|
||||
"typeVersion": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"custom": {
|
||||
"azureColumnTypes": [
|
||||
"string",
|
||||
"string"
|
||||
]
|
||||
},
|
||||
"notices": [
|
||||
{
|
||||
"severity": "error",
|
||||
"text": "There were some errors when processing your query. Something went wrong processing your query on the server. The results of this query exceed the set limit of 1 records."
|
||||
}
|
||||
]
|
||||
},
|
||||
"fields": [
|
||||
{
|
||||
"name": "OperationName",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Level",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
"Create or Update Virtual Machine"
|
||||
],
|
||||
[
|
||||
"Informational"
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
94
pkg/tsdb/azuremonitor/testdata/traces/1-traces-multiple-table.json
vendored
Normal file
94
pkg/tsdb/azuremonitor/testdata/traces/1-traces-multiple-table.json
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
{
|
||||
"tables": [
|
||||
{
|
||||
"name": "PrimaryResult",
|
||||
"columns": [
|
||||
{
|
||||
"name": "traceID",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "spanID",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "parentSpanID",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "duration",
|
||||
"type": "real"
|
||||
},
|
||||
{
|
||||
"name": "serviceName",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "operationName",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "startTime",
|
||||
"type": "datetime"
|
||||
},
|
||||
{
|
||||
"name": "serviceTags",
|
||||
"type": "dynamic"
|
||||
},
|
||||
{
|
||||
"name": "tags",
|
||||
"type": "dynamic"
|
||||
},
|
||||
{
|
||||
"name": "itemId",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "itemType",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"rows": [
|
||||
[
|
||||
"cfae497bfd7a44169f35643940820938",
|
||||
"b52403c5-5b27-43a8-9bc6-5938667a4470",
|
||||
"|cfae497bfd7a44169f35643940820938.",
|
||||
0,
|
||||
"",
|
||||
"GET /github/grafana/grafana/commits",
|
||||
"2023-04-17T14:58:10.176Z",
|
||||
"{\"service\":\"github-test-data\",\"limit\":\"5000\",\"remaining\":\"4351\",\"reset\":\"1681746512\",\"used\":\"649\",\"timestamp\":\"2023-04-17T14:58:10.0000000Z\"}",
|
||||
"{\"client_IP\":\"0.0.0.0\",\"operation_Id\":\"cfae497bfd7a44169f35643940820938\",\"duration\":0,\"iKey\":\"195b4fe4-7b01-4814-abca-ffceb1f62c8f\",\"size\":null,\"sdkVersion\":\"node:1.8.9\",\"name\":\"\",\"client_Model\":\"\",\"cloud_RoleName\":\"Web\",\"customMeasurements\":null,\"client_Browser\":\"\",\"operation_Name\":\"GET /github/grafana/grafana/commits\",\"performanceBucket\":\"\",\"client_CountryOrRegion\":\"Ireland\",\"cloud_RoleInstance\":\"test-vm\",\"appName\":\"test-app\",\"client_Type\":\"PC\",\"operation_ParentId\":\"|cfae497bfd7a44169f35643940820938.\",\"success\":\"\",\"application_Version\":\"1.0.0\",\"operation_SyntheticSource\":\"\",\"itemType\":\"trace\",\"user_AccountId\":\"\",\"session_Id\":\"\",\"timestamp\":\"2023-04-17T14:58:10.1760000Z\",\"message\":\"github commits rate limiting info\",\"client_City\":\"Dublin\",\"client_StateOrProvince\":\"Dublin\",\"itemId\":\"65863e6b-dd30-11ed-a808-002248268105\",\"client_OS\":\"Linux 5.4.0-1036-azure\",\"id\":\"\",\"customDimensions\":{\"service\":\"github-test-data\",\"limit\":\"5000\",\"remaining\":\"4351\",\"reset\":\"1681746512\",\"used\":\"649\",\"timestamp\":\"2023-04-17T14:58:10.0000000Z\"},\"itemCount\":1,\"location\":\"\",\"user_AuthenticatedId\":\"\",\"appId\":\"4ad5a808-11f7-49d5-9713-f6ede83141e4\",\"user_Id\":\"\",\"resultCode\":\"\",\"type\":\"\",\"data\":\"\",\"target\":\"\",\"assembly\":\"\",\"outerType\":\"\",\"innermostAssembly\":\"\",\"innermostType\":\"\",\"method\":\"\",\"problemId\":\"\",\"handledAt\":\"\",\"outerMessage\":\"\",\"details\":null,\"innermostMethod\":\"\",\"innermostMessage\":\"\",\"outerAssembly\":\"\",\"outerMethod\":\"\",\"severityLevel\":1,\"url\":\"\",\"source\":\"\"}",
|
||||
"65863e6b-dd30-11ed-a808-002248268105",
|
||||
"trace"
|
||||
],
|
||||
[
|
||||
"e766f18a0adc49418d297b1a244f1bfb",
|
||||
"|e766f18a0adc49418d297b1a244f1bfb.1901.",
|
||||
"|e766f18a0adc49418d297b1a244f1bfb.",
|
||||
330,
|
||||
"GET /repos/grafana/grafana/commits",
|
||||
"GET /github/grafana/grafana/commits",
|
||||
"2023-04-17T14:58:10.764Z",
|
||||
null,
|
||||
"{\"client_IP\":\"0.0.0.0\",\"operation_Id\":\"e766f18a0adc49418d297b1a244f1bfb\",\"duration\":330,\"iKey\":\"195b4fe4-7b01-4814-abca-ffceb1f62c8f\",\"size\":null,\"sdkVersion\":\"node:1.8.9\",\"name\":\"GET /repos/grafana/grafana/commits\",\"client_Model\":\"\",\"cloud_RoleName\":\"Web\",\"customMeasurements\":null,\"client_Browser\":\"\",\"operation_Name\":\"GET /github/grafana/grafana/commits\",\"performanceBucket\":\"250ms-500ms\",\"client_CountryOrRegion\":\"Ireland\",\"cloud_RoleInstance\":\"test-vm\",\"appName\":\"test-app\",\"client_Type\":\"PC\",\"operation_ParentId\":\"|e766f18a0adc49418d297b1a244f1bfb.\",\"success\":\"True\",\"application_Version\":\"1.0.0\",\"operation_SyntheticSource\":\"\",\"itemType\":\"dependency\",\"user_AccountId\":\"\",\"session_Id\":\"\",\"timestamp\":\"2023-04-17T14:58:10.7640000Z\",\"message\":\"\",\"client_City\":\"Dublin\",\"client_StateOrProvince\":\"Dublin\",\"itemId\":\"78c1bcf4-dd30-11ed-a808-0022481f7f28\",\"client_OS\":\"Linux 5.4.0-1036-azure\",\"id\":\"|e766f18a0adc49418d297b1a244f1bfb.1901.\",\"customDimensions\":null,\"itemCount\":1,\"location\":\"\",\"user_AuthenticatedId\":\"\",\"appId\":\"4ad5a808-11f7-49d5-9713-f6ede83141e4\",\"user_Id\":\"\",\"resultCode\":\"200\",\"type\":\"HTTP\",\"data\":\"https://api.github.com/repos/grafana/grafana/commits\",\"target\":\"api.github.com\",\"assembly\":\"\",\"outerType\":\"\",\"innermostAssembly\":\"\",\"innermostType\":\"\",\"method\":\"\",\"problemId\":\"\",\"handledAt\":\"\",\"outerMessage\":\"\",\"details\":null,\"innermostMethod\":\"\",\"innermostMessage\":\"\",\"outerAssembly\":\"\",\"outerMethod\":\"\",\"severityLevel\":null,\"url\":\"\",\"source\":\"\"}",
|
||||
"78c1bcf4-dd30-11ed-a808-0022481f7f28",
|
||||
"dependency"
|
||||
],
|
||||
[
|
||||
"b1f0047386554fa59b7c5330560a0799",
|
||||
"|b1f0047386554fa59b7c5330560a0799.",
|
||||
"b1f0047386554fa59b7c5330560a0799",
|
||||
352,
|
||||
"GET /github/grafana/grafana/commits",
|
||||
"GET /github/grafana/grafana/commits",
|
||||
"2023-04-17T14:58:11.579Z",
|
||||
null,
|
||||
"{\"client_IP\":\"0.0.0.0\",\"operation_Id\":\"b1f0047386554fa59b7c5330560a0799\",\"duration\":352,\"iKey\":\"195b4fe4-7b01-4814-abca-ffceb1f62c8f\",\"size\":null,\"sdkVersion\":\"node:1.8.9\",\"name\":\"GET /github/grafana/grafana/commits\",\"client_Model\":\"\",\"cloud_RoleName\":\"Web\",\"customMeasurements\":null,\"client_Browser\":\"\",\"operation_Name\":\"GET /github/grafana/grafana/commits\",\"performanceBucket\":\"250ms-500ms\",\"client_CountryOrRegion\":\"\",\"cloud_RoleInstance\":\"test-vm\",\"appName\":\"test-app\",\"client_Type\":\"PC\",\"operation_ParentId\":\"b1f0047386554fa59b7c5330560a0799\",\"success\":\"True\",\"application_Version\":\"1.0.0\",\"operation_SyntheticSource\":\"\",\"itemType\":\"request\",\"user_AccountId\":\"\",\"session_Id\":\"\",\"timestamp\":\"2023-04-17T14:58:11.5790000Z\",\"message\":\"\",\"client_City\":\"\",\"client_StateOrProvince\":\"\",\"itemId\":\"5c126241-dd30-11ed-a80a-00224826882d\",\"client_OS\":\"Linux 5.4.0-1036-azure\",\"id\":\"|b1f0047386554fa59b7c5330560a0799.\",\"customDimensions\":null,\"itemCount\":1,\"location\":\"\",\"user_AuthenticatedId\":\"\",\"appId\":\"4ad5a808-11f7-49d5-9713-f6ede83141e4\",\"user_Id\":\"\",\"resultCode\":\"200\",\"type\":\"\",\"data\":\"\",\"target\":\"\",\"assembly\":\"\",\"outerType\":\"\",\"innermostAssembly\":\"\",\"innermostType\":\"\",\"method\":\"\",\"problemId\":\"\",\"handledAt\":\"\",\"outerMessage\":\"\",\"details\":null,\"innermostMethod\":\"\",\"innermostMessage\":\"\",\"outerAssembly\":\"\",\"outerMethod\":\"\",\"severityLevel\":null,\"url\":\"test-url\",\"source\":\"\"}",
|
||||
"5c126241-dd30-11ed-a80a-00224826882d",
|
||||
"request"
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,559 @@
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
//
|
||||
// Frame[0] {
|
||||
// "typeVersion": [
|
||||
// 0,
|
||||
// 0
|
||||
// ],
|
||||
// "custom": {
|
||||
// "azureColumnTypes": [
|
||||
// "string",
|
||||
// "string",
|
||||
// "string",
|
||||
// "real",
|
||||
// "string",
|
||||
// "string",
|
||||
// "datetime",
|
||||
// "dynamic",
|
||||
// "dynamic",
|
||||
// "string",
|
||||
// "string"
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
// Name:
|
||||
// Dimensions: 11 Fields by 3 Rows
|
||||
// +----------------------------------+-----------------------------------------+------------------------------------+------------------+-------------------------------------+-------------------------------------+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------+-----------------+
|
||||
// | Name: traceID | Name: spanID | Name: parentSpanID | Name: duration | Name: serviceName | Name: operationName | Name: startTime | Name: serviceTags | Name: tags | Name: itemId | Name: itemType |
|
||||
// | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: |
|
||||
// | Type: []*string | Type: []*string | Type: []*string | Type: []*float64 | Type: []*string | Type: []*string | Type: []*time.Time | Type: []*json.RawMessage | Type: []*json.RawMessage | Type: []*string | Type: []*string |
|
||||
// +----------------------------------+-----------------------------------------+------------------------------------+------------------+-------------------------------------+-------------------------------------+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------+-----------------+
|
||||
// | cfae497bfd7a44169f35643940820938 | b52403c5-5b27-43a8-9bc6-5938667a4470 | |cfae497bfd7a44169f35643940820938. | 0 | | GET /github/grafana/grafana/commits | 2023-04-17 14:58:10.176 +0000 UTC | [{"value":"5000","key":"limit"},{"value":"4351","key":"remaining"},{"value":"1681746512","key":"reset"},{"value":"github-test-data","key":"service"},{"value":"2023-04-17T14:58:10.0000000Z","key":"timestamp"},{"value":"649","key":"used"}] | [{"value":"4ad5a808-11f7-49d5-9713-f6ede83141e4","key":"appId"},{"value":"test-app","key":"appName"},{"value":"1.0.0","key":"application_Version"},{"value":"Dublin","key":"client_City"},{"value":"Ireland","key":"client_CountryOrRegion"},{"value":"0.0.0.0","key":"client_IP"},{"value":"Linux 5.4.0-1036-azure","key":"client_OS"},{"value":"Dublin","key":"client_StateOrProvince"},{"value":"PC","key":"client_Type"},{"value":"test-vm","key":"cloud_RoleInstance"},{"value":"Web","key":"cloud_RoleName"},{"value":{"limit":"5000","remaining":"4351","reset":"1681746512","service":"github-test-data","timestamp":"2023-04-17T14:58:10.0000000Z","used":"649"},"key":"customDimensions"},{"value":0,"key":"duration"},{"value":"195b4fe4-7b01-4814-abca-ffceb1f62c8f","key":"iKey"},{"value":1,"key":"itemCount"},{"value":"65863e6b-dd30-11ed-a808-002248268105","key":"itemId"},{"value":"trace","key":"itemType"},{"value":"github commits rate limiting info","key":"message"},{"value":"cfae497bfd7a44169f35643940820938","key":"operation_Id"},{"value":"GET /github/grafana/grafana/commits","key":"operation_Name"},{"value":"|cfae497bfd7a44169f35643940820938.","key":"operation_ParentId"},{"value":"node:1.8.9","key":"sdkVersion"},{"value":1,"key":"severityLevel"},{"value":"2023-04-17T14:58:10.1760000Z","key":"timestamp"}] | 65863e6b-dd30-11ed-a808-002248268105 | trace |
|
||||
// | e766f18a0adc49418d297b1a244f1bfb | |e766f18a0adc49418d297b1a244f1bfb.1901. | |e766f18a0adc49418d297b1a244f1bfb. | 330 | GET /repos/grafana/grafana/commits | GET /github/grafana/grafana/commits | 2023-04-17 14:58:10.764 +0000 UTC | null | [{"value":"4ad5a808-11f7-49d5-9713-f6ede83141e4","key":"appId"},{"value":"test-app","key":"appName"},{"value":"1.0.0","key":"application_Version"},{"value":"Dublin","key":"client_City"},{"value":"Ireland","key":"client_CountryOrRegion"},{"value":"0.0.0.0","key":"client_IP"},{"value":"Linux 5.4.0-1036-azure","key":"client_OS"},{"value":"Dublin","key":"client_StateOrProvince"},{"value":"PC","key":"client_Type"},{"value":"test-vm","key":"cloud_RoleInstance"},{"value":"Web","key":"cloud_RoleName"},{"value":"https://api.github.com/repos/grafana/grafana/commits","key":"data"},{"value":330,"key":"duration"},{"value":"195b4fe4-7b01-4814-abca-ffceb1f62c8f","key":"iKey"},{"value":"|e766f18a0adc49418d297b1a244f1bfb.1901.","key":"id"},{"value":1,"key":"itemCount"},{"value":"78c1bcf4-dd30-11ed-a808-0022481f7f28","key":"itemId"},{"value":"dependency","key":"itemType"},{"value":"GET /repos/grafana/grafana/commits","key":"name"},{"value":"e766f18a0adc49418d297b1a244f1bfb","key":"operation_Id"},{"value":"GET /github/grafana/grafana/commits","key":"operation_Name"},{"value":"|e766f18a0adc49418d297b1a244f1bfb.","key":"operation_ParentId"},{"value":"250ms-500ms","key":"performanceBucket"},{"value":"200","key":"resultCode"},{"value":"node:1.8.9","key":"sdkVersion"},{"value":"True","key":"success"},{"value":"api.github.com","key":"target"},{"value":"2023-04-17T14:58:10.7640000Z","key":"timestamp"},{"value":"HTTP","key":"type"}] | 78c1bcf4-dd30-11ed-a808-0022481f7f28 | dependency |
|
||||
// | b1f0047386554fa59b7c5330560a0799 | |b1f0047386554fa59b7c5330560a0799. | b1f0047386554fa59b7c5330560a0799 | 352 | GET /github/grafana/grafana/commits | GET /github/grafana/grafana/commits | 2023-04-17 14:58:11.579 +0000 UTC | null | [{"value":"4ad5a808-11f7-49d5-9713-f6ede83141e4","key":"appId"},{"value":"test-app","key":"appName"},{"value":"1.0.0","key":"application_Version"},{"value":"0.0.0.0","key":"client_IP"},{"value":"Linux 5.4.0-1036-azure","key":"client_OS"},{"value":"PC","key":"client_Type"},{"value":"test-vm","key":"cloud_RoleInstance"},{"value":"Web","key":"cloud_RoleName"},{"value":352,"key":"duration"},{"value":"195b4fe4-7b01-4814-abca-ffceb1f62c8f","key":"iKey"},{"value":"|b1f0047386554fa59b7c5330560a0799.","key":"id"},{"value":1,"key":"itemCount"},{"value":"5c126241-dd30-11ed-a80a-00224826882d","key":"itemId"},{"value":"request","key":"itemType"},{"value":"GET /github/grafana/grafana/commits","key":"name"},{"value":"b1f0047386554fa59b7c5330560a0799","key":"operation_Id"},{"value":"GET /github/grafana/grafana/commits","key":"operation_Name"},{"value":"b1f0047386554fa59b7c5330560a0799","key":"operation_ParentId"},{"value":"250ms-500ms","key":"performanceBucket"},{"value":"200","key":"resultCode"},{"value":"node:1.8.9","key":"sdkVersion"},{"value":"True","key":"success"},{"value":"2023-04-17T14:58:11.5790000Z","key":"timestamp"},{"value":"test-url","key":"url"}] | 5c126241-dd30-11ed-a80a-00224826882d | request |
|
||||
// +----------------------------------+-----------------------------------------+------------------------------------+------------------+-------------------------------------+-------------------------------------+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------+-----------------+
|
||||
//
|
||||
//
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
{
|
||||
"status": 200,
|
||||
"frames": [
|
||||
{
|
||||
"schema": {
|
||||
"meta": {
|
||||
"typeVersion": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"custom": {
|
||||
"azureColumnTypes": [
|
||||
"string",
|
||||
"string",
|
||||
"string",
|
||||
"real",
|
||||
"string",
|
||||
"string",
|
||||
"datetime",
|
||||
"dynamic",
|
||||
"dynamic",
|
||||
"string",
|
||||
"string"
|
||||
]
|
||||
}
|
||||
},
|
||||
"fields": [
|
||||
{
|
||||
"name": "traceID",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "spanID",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "parentSpanID",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "duration",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "serviceName",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "operationName",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "startTime",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "serviceTags",
|
||||
"type": "other",
|
||||
"typeInfo": {
|
||||
"frame": "json.RawMessage",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tags",
|
||||
"type": "other",
|
||||
"typeInfo": {
|
||||
"frame": "json.RawMessage",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "itemId",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "itemType",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
"cfae497bfd7a44169f35643940820938",
|
||||
"e766f18a0adc49418d297b1a244f1bfb",
|
||||
"b1f0047386554fa59b7c5330560a0799"
|
||||
],
|
||||
[
|
||||
"b52403c5-5b27-43a8-9bc6-5938667a4470",
|
||||
"|e766f18a0adc49418d297b1a244f1bfb.1901.",
|
||||
"|b1f0047386554fa59b7c5330560a0799."
|
||||
],
|
||||
[
|
||||
"|cfae497bfd7a44169f35643940820938.",
|
||||
"|e766f18a0adc49418d297b1a244f1bfb.",
|
||||
"b1f0047386554fa59b7c5330560a0799"
|
||||
],
|
||||
[
|
||||
0,
|
||||
330,
|
||||
352
|
||||
],
|
||||
[
|
||||
"",
|
||||
"GET /repos/grafana/grafana/commits",
|
||||
"GET /github/grafana/grafana/commits"
|
||||
],
|
||||
[
|
||||
"GET /github/grafana/grafana/commits",
|
||||
"GET /github/grafana/grafana/commits",
|
||||
"GET /github/grafana/grafana/commits"
|
||||
],
|
||||
[
|
||||
1681743490176,
|
||||
1681743490764,
|
||||
1681743491579
|
||||
],
|
||||
[
|
||||
[
|
||||
{
|
||||
"value": "5000",
|
||||
"key": "limit"
|
||||
},
|
||||
{
|
||||
"value": "4351",
|
||||
"key": "remaining"
|
||||
},
|
||||
{
|
||||
"value": "1681746512",
|
||||
"key": "reset"
|
||||
},
|
||||
{
|
||||
"value": "github-test-data",
|
||||
"key": "service"
|
||||
},
|
||||
{
|
||||
"value": "2023-04-17T14:58:10.0000000Z",
|
||||
"key": "timestamp"
|
||||
},
|
||||
{
|
||||
"value": "649",
|
||||
"key": "used"
|
||||
}
|
||||
],
|
||||
null,
|
||||
null
|
||||
],
|
||||
[
|
||||
[
|
||||
{
|
||||
"value": "4ad5a808-11f7-49d5-9713-f6ede83141e4",
|
||||
"key": "appId"
|
||||
},
|
||||
{
|
||||
"value": "test-app",
|
||||
"key": "appName"
|
||||
},
|
||||
{
|
||||
"value": "1.0.0",
|
||||
"key": "application_Version"
|
||||
},
|
||||
{
|
||||
"value": "Dublin",
|
||||
"key": "client_City"
|
||||
},
|
||||
{
|
||||
"value": "Ireland",
|
||||
"key": "client_CountryOrRegion"
|
||||
},
|
||||
{
|
||||
"value": "0.0.0.0",
|
||||
"key": "client_IP"
|
||||
},
|
||||
{
|
||||
"value": "Linux 5.4.0-1036-azure",
|
||||
"key": "client_OS"
|
||||
},
|
||||
{
|
||||
"value": "Dublin",
|
||||
"key": "client_StateOrProvince"
|
||||
},
|
||||
{
|
||||
"value": "PC",
|
||||
"key": "client_Type"
|
||||
},
|
||||
{
|
||||
"value": "test-vm",
|
||||
"key": "cloud_RoleInstance"
|
||||
},
|
||||
{
|
||||
"value": "Web",
|
||||
"key": "cloud_RoleName"
|
||||
},
|
||||
{
|
||||
"value": {
|
||||
"limit": "5000",
|
||||
"remaining": "4351",
|
||||
"reset": "1681746512",
|
||||
"service": "github-test-data",
|
||||
"timestamp": "2023-04-17T14:58:10.0000000Z",
|
||||
"used": "649"
|
||||
},
|
||||
"key": "customDimensions"
|
||||
},
|
||||
{
|
||||
"value": 0,
|
||||
"key": "duration"
|
||||
},
|
||||
{
|
||||
"value": "195b4fe4-7b01-4814-abca-ffceb1f62c8f",
|
||||
"key": "iKey"
|
||||
},
|
||||
{
|
||||
"value": 1,
|
||||
"key": "itemCount"
|
||||
},
|
||||
{
|
||||
"value": "65863e6b-dd30-11ed-a808-002248268105",
|
||||
"key": "itemId"
|
||||
},
|
||||
{
|
||||
"value": "trace",
|
||||
"key": "itemType"
|
||||
},
|
||||
{
|
||||
"value": "github commits rate limiting info",
|
||||
"key": "message"
|
||||
},
|
||||
{
|
||||
"value": "cfae497bfd7a44169f35643940820938",
|
||||
"key": "operation_Id"
|
||||
},
|
||||
{
|
||||
"value": "GET /github/grafana/grafana/commits",
|
||||
"key": "operation_Name"
|
||||
},
|
||||
{
|
||||
"value": "|cfae497bfd7a44169f35643940820938.",
|
||||
"key": "operation_ParentId"
|
||||
},
|
||||
{
|
||||
"value": "node:1.8.9",
|
||||
"key": "sdkVersion"
|
||||
},
|
||||
{
|
||||
"value": 1,
|
||||
"key": "severityLevel"
|
||||
},
|
||||
{
|
||||
"value": "2023-04-17T14:58:10.1760000Z",
|
||||
"key": "timestamp"
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"value": "4ad5a808-11f7-49d5-9713-f6ede83141e4",
|
||||
"key": "appId"
|
||||
},
|
||||
{
|
||||
"value": "test-app",
|
||||
"key": "appName"
|
||||
},
|
||||
{
|
||||
"value": "1.0.0",
|
||||
"key": "application_Version"
|
||||
},
|
||||
{
|
||||
"value": "Dublin",
|
||||
"key": "client_City"
|
||||
},
|
||||
{
|
||||
"value": "Ireland",
|
||||
"key": "client_CountryOrRegion"
|
||||
},
|
||||
{
|
||||
"value": "0.0.0.0",
|
||||
"key": "client_IP"
|
||||
},
|
||||
{
|
||||
"value": "Linux 5.4.0-1036-azure",
|
||||
"key": "client_OS"
|
||||
},
|
||||
{
|
||||
"value": "Dublin",
|
||||
"key": "client_StateOrProvince"
|
||||
},
|
||||
{
|
||||
"value": "PC",
|
||||
"key": "client_Type"
|
||||
},
|
||||
{
|
||||
"value": "test-vm",
|
||||
"key": "cloud_RoleInstance"
|
||||
},
|
||||
{
|
||||
"value": "Web",
|
||||
"key": "cloud_RoleName"
|
||||
},
|
||||
{
|
||||
"value": "https://api.github.com/repos/grafana/grafana/commits",
|
||||
"key": "data"
|
||||
},
|
||||
{
|
||||
"value": 330,
|
||||
"key": "duration"
|
||||
},
|
||||
{
|
||||
"value": "195b4fe4-7b01-4814-abca-ffceb1f62c8f",
|
||||
"key": "iKey"
|
||||
},
|
||||
{
|
||||
"value": "|e766f18a0adc49418d297b1a244f1bfb.1901.",
|
||||
"key": "id"
|
||||
},
|
||||
{
|
||||
"value": 1,
|
||||
"key": "itemCount"
|
||||
},
|
||||
{
|
||||
"value": "78c1bcf4-dd30-11ed-a808-0022481f7f28",
|
||||
"key": "itemId"
|
||||
},
|
||||
{
|
||||
"value": "dependency",
|
||||
"key": "itemType"
|
||||
},
|
||||
{
|
||||
"value": "GET /repos/grafana/grafana/commits",
|
||||
"key": "name"
|
||||
},
|
||||
{
|
||||
"value": "e766f18a0adc49418d297b1a244f1bfb",
|
||||
"key": "operation_Id"
|
||||
},
|
||||
{
|
||||
"value": "GET /github/grafana/grafana/commits",
|
||||
"key": "operation_Name"
|
||||
},
|
||||
{
|
||||
"value": "|e766f18a0adc49418d297b1a244f1bfb.",
|
||||
"key": "operation_ParentId"
|
||||
},
|
||||
{
|
||||
"value": "250ms-500ms",
|
||||
"key": "performanceBucket"
|
||||
},
|
||||
{
|
||||
"value": "200",
|
||||
"key": "resultCode"
|
||||
},
|
||||
{
|
||||
"value": "node:1.8.9",
|
||||
"key": "sdkVersion"
|
||||
},
|
||||
{
|
||||
"value": "True",
|
||||
"key": "success"
|
||||
},
|
||||
{
|
||||
"value": "api.github.com",
|
||||
"key": "target"
|
||||
},
|
||||
{
|
||||
"value": "2023-04-17T14:58:10.7640000Z",
|
||||
"key": "timestamp"
|
||||
},
|
||||
{
|
||||
"value": "HTTP",
|
||||
"key": "type"
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"value": "4ad5a808-11f7-49d5-9713-f6ede83141e4",
|
||||
"key": "appId"
|
||||
},
|
||||
{
|
||||
"value": "test-app",
|
||||
"key": "appName"
|
||||
},
|
||||
{
|
||||
"value": "1.0.0",
|
||||
"key": "application_Version"
|
||||
},
|
||||
{
|
||||
"value": "0.0.0.0",
|
||||
"key": "client_IP"
|
||||
},
|
||||
{
|
||||
"value": "Linux 5.4.0-1036-azure",
|
||||
"key": "client_OS"
|
||||
},
|
||||
{
|
||||
"value": "PC",
|
||||
"key": "client_Type"
|
||||
},
|
||||
{
|
||||
"value": "test-vm",
|
||||
"key": "cloud_RoleInstance"
|
||||
},
|
||||
{
|
||||
"value": "Web",
|
||||
"key": "cloud_RoleName"
|
||||
},
|
||||
{
|
||||
"value": 352,
|
||||
"key": "duration"
|
||||
},
|
||||
{
|
||||
"value": "195b4fe4-7b01-4814-abca-ffceb1f62c8f",
|
||||
"key": "iKey"
|
||||
},
|
||||
{
|
||||
"value": "|b1f0047386554fa59b7c5330560a0799.",
|
||||
"key": "id"
|
||||
},
|
||||
{
|
||||
"value": 1,
|
||||
"key": "itemCount"
|
||||
},
|
||||
{
|
||||
"value": "5c126241-dd30-11ed-a80a-00224826882d",
|
||||
"key": "itemId"
|
||||
},
|
||||
{
|
||||
"value": "request",
|
||||
"key": "itemType"
|
||||
},
|
||||
{
|
||||
"value": "GET /github/grafana/grafana/commits",
|
||||
"key": "name"
|
||||
},
|
||||
{
|
||||
"value": "b1f0047386554fa59b7c5330560a0799",
|
||||
"key": "operation_Id"
|
||||
},
|
||||
{
|
||||
"value": "GET /github/grafana/grafana/commits",
|
||||
"key": "operation_Name"
|
||||
},
|
||||
{
|
||||
"value": "b1f0047386554fa59b7c5330560a0799",
|
||||
"key": "operation_ParentId"
|
||||
},
|
||||
{
|
||||
"value": "250ms-500ms",
|
||||
"key": "performanceBucket"
|
||||
},
|
||||
{
|
||||
"value": "200",
|
||||
"key": "resultCode"
|
||||
},
|
||||
{
|
||||
"value": "node:1.8.9",
|
||||
"key": "sdkVersion"
|
||||
},
|
||||
{
|
||||
"value": "True",
|
||||
"key": "success"
|
||||
},
|
||||
{
|
||||
"value": "2023-04-17T14:58:11.5790000Z",
|
||||
"key": "timestamp"
|
||||
},
|
||||
{
|
||||
"value": "test-url",
|
||||
"key": "url"
|
||||
}
|
||||
]
|
||||
],
|
||||
[
|
||||
"65863e6b-dd30-11ed-a808-002248268105",
|
||||
"78c1bcf4-dd30-11ed-a808-0022481f7f28",
|
||||
"5c126241-dd30-11ed-a80a-00224826882d"
|
||||
],
|
||||
[
|
||||
"trace",
|
||||
"dependency",
|
||||
"request"
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
216
pkg/tsdb/azuremonitor/testdata/traces/1-traces-multiple-table.json.multi-trace.golden.jsonc
vendored
Normal file
216
pkg/tsdb/azuremonitor/testdata/traces/1-traces-multiple-table.json.multi-trace.golden.jsonc
vendored
Normal file
@ -0,0 +1,216 @@
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
//
|
||||
// Frame[0] {
|
||||
// "typeVersion": [
|
||||
// 0,
|
||||
// 0
|
||||
// ],
|
||||
// "custom": {
|
||||
// "azureColumnTypes": [
|
||||
// "string",
|
||||
// "string",
|
||||
// "string",
|
||||
// "real",
|
||||
// "string",
|
||||
// "string",
|
||||
// "datetime",
|
||||
// "dynamic",
|
||||
// "dynamic",
|
||||
// "string",
|
||||
// "string"
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
// Name:
|
||||
// Dimensions: 11 Fields by 3 Rows
|
||||
// +----------------------------------+-----------------------------------------+------------------------------------+------------------+-------------------------------------+-------------------------------------+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------+-----------------+
|
||||
// | Name: traceID | Name: spanID | Name: parentSpanID | Name: duration | Name: serviceName | Name: operationName | Name: startTime | Name: serviceTags | Name: tags | Name: itemId | Name: itemType |
|
||||
// | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: |
|
||||
// | Type: []*string | Type: []*string | Type: []*string | Type: []*float64 | Type: []*string | Type: []*string | Type: []*time.Time | Type: []*string | Type: []*string | Type: []*string | Type: []*string |
|
||||
// +----------------------------------+-----------------------------------------+------------------------------------+------------------+-------------------------------------+-------------------------------------+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------+-----------------+
|
||||
// | cfae497bfd7a44169f35643940820938 | b52403c5-5b27-43a8-9bc6-5938667a4470 | |cfae497bfd7a44169f35643940820938. | 0 | | GET /github/grafana/grafana/commits | 2023-04-17 14:58:10.176 +0000 UTC | {"service":"github-test-data","limit":"5000","remaining":"4351","reset":"1681746512","used":"649","timestamp":"2023-04-17T14:58:10.0000000Z"} | {"client_IP":"0.0.0.0","operation_Id":"cfae497bfd7a44169f35643940820938","duration":0,"iKey":"195b4fe4-7b01-4814-abca-ffceb1f62c8f","size":null,"sdkVersion":"node:1.8.9","name":"","client_Model":"","cloud_RoleName":"Web","customMeasurements":null,"client_Browser":"","operation_Name":"GET /github/grafana/grafana/commits","performanceBucket":"","client_CountryOrRegion":"Ireland","cloud_RoleInstance":"test-vm","appName":"test-app","client_Type":"PC","operation_ParentId":"|cfae497bfd7a44169f35643940820938.","success":"","application_Version":"1.0.0","operation_SyntheticSource":"","itemType":"trace","user_AccountId":"","session_Id":"","timestamp":"2023-04-17T14:58:10.1760000Z","message":"github commits rate limiting info","client_City":"Dublin","client_StateOrProvince":"Dublin","itemId":"65863e6b-dd30-11ed-a808-002248268105","client_OS":"Linux 5.4.0-1036-azure","id":"","customDimensions":{"service":"github-test-data","limit":"5000","remaining":"4351","reset":"1681746512","used":"649","timestamp":"2023-04-17T14:58:10.0000000Z"},"itemCount":1,"location":"","user_AuthenticatedId":"","appId":"4ad5a808-11f7-49d5-9713-f6ede83141e4","user_Id":"","resultCode":"","type":"","data":"","target":"","assembly":"","outerType":"","innermostAssembly":"","innermostType":"","method":"","problemId":"","handledAt":"","outerMessage":"","details":null,"innermostMethod":"","innermostMessage":"","outerAssembly":"","outerMethod":"","severityLevel":1,"url":"","source":""} | 65863e6b-dd30-11ed-a808-002248268105 | trace |
|
||||
// | e766f18a0adc49418d297b1a244f1bfb | |e766f18a0adc49418d297b1a244f1bfb.1901. | |e766f18a0adc49418d297b1a244f1bfb. | 330 | GET /repos/grafana/grafana/commits | GET /github/grafana/grafana/commits | 2023-04-17 14:58:10.764 +0000 UTC | null | {"client_IP":"0.0.0.0","operation_Id":"e766f18a0adc49418d297b1a244f1bfb","duration":330,"iKey":"195b4fe4-7b01-4814-abca-ffceb1f62c8f","size":null,"sdkVersion":"node:1.8.9","name":"GET /repos/grafana/grafana/commits","client_Model":"","cloud_RoleName":"Web","customMeasurements":null,"client_Browser":"","operation_Name":"GET /github/grafana/grafana/commits","performanceBucket":"250ms-500ms","client_CountryOrRegion":"Ireland","cloud_RoleInstance":"test-vm","appName":"test-app","client_Type":"PC","operation_ParentId":"|e766f18a0adc49418d297b1a244f1bfb.","success":"True","application_Version":"1.0.0","operation_SyntheticSource":"","itemType":"dependency","user_AccountId":"","session_Id":"","timestamp":"2023-04-17T14:58:10.7640000Z","message":"","client_City":"Dublin","client_StateOrProvince":"Dublin","itemId":"78c1bcf4-dd30-11ed-a808-0022481f7f28","client_OS":"Linux 5.4.0-1036-azure","id":"|e766f18a0adc49418d297b1a244f1bfb.1901.","customDimensions":null,"itemCount":1,"location":"","user_AuthenticatedId":"","appId":"4ad5a808-11f7-49d5-9713-f6ede83141e4","user_Id":"","resultCode":"200","type":"HTTP","data":"https://api.github.com/repos/grafana/grafana/commits","target":"api.github.com","assembly":"","outerType":"","innermostAssembly":"","innermostType":"","method":"","problemId":"","handledAt":"","outerMessage":"","details":null,"innermostMethod":"","innermostMessage":"","outerAssembly":"","outerMethod":"","severityLevel":null,"url":"","source":""} | 78c1bcf4-dd30-11ed-a808-0022481f7f28 | dependency |
|
||||
// | b1f0047386554fa59b7c5330560a0799 | |b1f0047386554fa59b7c5330560a0799. | b1f0047386554fa59b7c5330560a0799 | 352 | GET /github/grafana/grafana/commits | GET /github/grafana/grafana/commits | 2023-04-17 14:58:11.579 +0000 UTC | null | {"client_IP":"0.0.0.0","operation_Id":"b1f0047386554fa59b7c5330560a0799","duration":352,"iKey":"195b4fe4-7b01-4814-abca-ffceb1f62c8f","size":null,"sdkVersion":"node:1.8.9","name":"GET /github/grafana/grafana/commits","client_Model":"","cloud_RoleName":"Web","customMeasurements":null,"client_Browser":"","operation_Name":"GET /github/grafana/grafana/commits","performanceBucket":"250ms-500ms","client_CountryOrRegion":"","cloud_RoleInstance":"test-vm","appName":"test-app","client_Type":"PC","operation_ParentId":"b1f0047386554fa59b7c5330560a0799","success":"True","application_Version":"1.0.0","operation_SyntheticSource":"","itemType":"request","user_AccountId":"","session_Id":"","timestamp":"2023-04-17T14:58:11.5790000Z","message":"","client_City":"","client_StateOrProvince":"","itemId":"5c126241-dd30-11ed-a80a-00224826882d","client_OS":"Linux 5.4.0-1036-azure","id":"|b1f0047386554fa59b7c5330560a0799.","customDimensions":null,"itemCount":1,"location":"","user_AuthenticatedId":"","appId":"4ad5a808-11f7-49d5-9713-f6ede83141e4","user_Id":"","resultCode":"200","type":"","data":"","target":"","assembly":"","outerType":"","innermostAssembly":"","innermostType":"","method":"","problemId":"","handledAt":"","outerMessage":"","details":null,"innermostMethod":"","innermostMessage":"","outerAssembly":"","outerMethod":"","severityLevel":null,"url":"test-url","source":""} | 5c126241-dd30-11ed-a80a-00224826882d | request |
|
||||
// +----------------------------------+-----------------------------------------+------------------------------------+------------------+-------------------------------------+-------------------------------------+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------+-----------------+
|
||||
//
|
||||
//
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
{
|
||||
"status": 200,
|
||||
"frames": [
|
||||
{
|
||||
"schema": {
|
||||
"meta": {
|
||||
"typeVersion": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"custom": {
|
||||
"azureColumnTypes": [
|
||||
"string",
|
||||
"string",
|
||||
"string",
|
||||
"real",
|
||||
"string",
|
||||
"string",
|
||||
"datetime",
|
||||
"dynamic",
|
||||
"dynamic",
|
||||
"string",
|
||||
"string"
|
||||
]
|
||||
}
|
||||
},
|
||||
"fields": [
|
||||
{
|
||||
"name": "traceID",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "spanID",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "parentSpanID",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "duration",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "serviceName",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "operationName",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "startTime",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "serviceTags",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tags",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "itemId",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "itemType",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
"cfae497bfd7a44169f35643940820938",
|
||||
"e766f18a0adc49418d297b1a244f1bfb",
|
||||
"b1f0047386554fa59b7c5330560a0799"
|
||||
],
|
||||
[
|
||||
"b52403c5-5b27-43a8-9bc6-5938667a4470",
|
||||
"|e766f18a0adc49418d297b1a244f1bfb.1901.",
|
||||
"|b1f0047386554fa59b7c5330560a0799."
|
||||
],
|
||||
[
|
||||
"|cfae497bfd7a44169f35643940820938.",
|
||||
"|e766f18a0adc49418d297b1a244f1bfb.",
|
||||
"b1f0047386554fa59b7c5330560a0799"
|
||||
],
|
||||
[
|
||||
0,
|
||||
330,
|
||||
352
|
||||
],
|
||||
[
|
||||
"",
|
||||
"GET /repos/grafana/grafana/commits",
|
||||
"GET /github/grafana/grafana/commits"
|
||||
],
|
||||
[
|
||||
"GET /github/grafana/grafana/commits",
|
||||
"GET /github/grafana/grafana/commits",
|
||||
"GET /github/grafana/grafana/commits"
|
||||
],
|
||||
[
|
||||
1681743490176,
|
||||
1681743490764,
|
||||
1681743491579
|
||||
],
|
||||
[
|
||||
"{\"service\":\"github-test-data\",\"limit\":\"5000\",\"remaining\":\"4351\",\"reset\":\"1681746512\",\"used\":\"649\",\"timestamp\":\"2023-04-17T14:58:10.0000000Z\"}",
|
||||
null,
|
||||
null
|
||||
],
|
||||
[
|
||||
"{\"client_IP\":\"0.0.0.0\",\"operation_Id\":\"cfae497bfd7a44169f35643940820938\",\"duration\":0,\"iKey\":\"195b4fe4-7b01-4814-abca-ffceb1f62c8f\",\"size\":null,\"sdkVersion\":\"node:1.8.9\",\"name\":\"\",\"client_Model\":\"\",\"cloud_RoleName\":\"Web\",\"customMeasurements\":null,\"client_Browser\":\"\",\"operation_Name\":\"GET /github/grafana/grafana/commits\",\"performanceBucket\":\"\",\"client_CountryOrRegion\":\"Ireland\",\"cloud_RoleInstance\":\"test-vm\",\"appName\":\"test-app\",\"client_Type\":\"PC\",\"operation_ParentId\":\"|cfae497bfd7a44169f35643940820938.\",\"success\":\"\",\"application_Version\":\"1.0.0\",\"operation_SyntheticSource\":\"\",\"itemType\":\"trace\",\"user_AccountId\":\"\",\"session_Id\":\"\",\"timestamp\":\"2023-04-17T14:58:10.1760000Z\",\"message\":\"github commits rate limiting info\",\"client_City\":\"Dublin\",\"client_StateOrProvince\":\"Dublin\",\"itemId\":\"65863e6b-dd30-11ed-a808-002248268105\",\"client_OS\":\"Linux 5.4.0-1036-azure\",\"id\":\"\",\"customDimensions\":{\"service\":\"github-test-data\",\"limit\":\"5000\",\"remaining\":\"4351\",\"reset\":\"1681746512\",\"used\":\"649\",\"timestamp\":\"2023-04-17T14:58:10.0000000Z\"},\"itemCount\":1,\"location\":\"\",\"user_AuthenticatedId\":\"\",\"appId\":\"4ad5a808-11f7-49d5-9713-f6ede83141e4\",\"user_Id\":\"\",\"resultCode\":\"\",\"type\":\"\",\"data\":\"\",\"target\":\"\",\"assembly\":\"\",\"outerType\":\"\",\"innermostAssembly\":\"\",\"innermostType\":\"\",\"method\":\"\",\"problemId\":\"\",\"handledAt\":\"\",\"outerMessage\":\"\",\"details\":null,\"innermostMethod\":\"\",\"innermostMessage\":\"\",\"outerAssembly\":\"\",\"outerMethod\":\"\",\"severityLevel\":1,\"url\":\"\",\"source\":\"\"}",
|
||||
"{\"client_IP\":\"0.0.0.0\",\"operation_Id\":\"e766f18a0adc49418d297b1a244f1bfb\",\"duration\":330,\"iKey\":\"195b4fe4-7b01-4814-abca-ffceb1f62c8f\",\"size\":null,\"sdkVersion\":\"node:1.8.9\",\"name\":\"GET /repos/grafana/grafana/commits\",\"client_Model\":\"\",\"cloud_RoleName\":\"Web\",\"customMeasurements\":null,\"client_Browser\":\"\",\"operation_Name\":\"GET /github/grafana/grafana/commits\",\"performanceBucket\":\"250ms-500ms\",\"client_CountryOrRegion\":\"Ireland\",\"cloud_RoleInstance\":\"test-vm\",\"appName\":\"test-app\",\"client_Type\":\"PC\",\"operation_ParentId\":\"|e766f18a0adc49418d297b1a244f1bfb.\",\"success\":\"True\",\"application_Version\":\"1.0.0\",\"operation_SyntheticSource\":\"\",\"itemType\":\"dependency\",\"user_AccountId\":\"\",\"session_Id\":\"\",\"timestamp\":\"2023-04-17T14:58:10.7640000Z\",\"message\":\"\",\"client_City\":\"Dublin\",\"client_StateOrProvince\":\"Dublin\",\"itemId\":\"78c1bcf4-dd30-11ed-a808-0022481f7f28\",\"client_OS\":\"Linux 5.4.0-1036-azure\",\"id\":\"|e766f18a0adc49418d297b1a244f1bfb.1901.\",\"customDimensions\":null,\"itemCount\":1,\"location\":\"\",\"user_AuthenticatedId\":\"\",\"appId\":\"4ad5a808-11f7-49d5-9713-f6ede83141e4\",\"user_Id\":\"\",\"resultCode\":\"200\",\"type\":\"HTTP\",\"data\":\"https://api.github.com/repos/grafana/grafana/commits\",\"target\":\"api.github.com\",\"assembly\":\"\",\"outerType\":\"\",\"innermostAssembly\":\"\",\"innermostType\":\"\",\"method\":\"\",\"problemId\":\"\",\"handledAt\":\"\",\"outerMessage\":\"\",\"details\":null,\"innermostMethod\":\"\",\"innermostMessage\":\"\",\"outerAssembly\":\"\",\"outerMethod\":\"\",\"severityLevel\":null,\"url\":\"\",\"source\":\"\"}",
|
||||
"{\"client_IP\":\"0.0.0.0\",\"operation_Id\":\"b1f0047386554fa59b7c5330560a0799\",\"duration\":352,\"iKey\":\"195b4fe4-7b01-4814-abca-ffceb1f62c8f\",\"size\":null,\"sdkVersion\":\"node:1.8.9\",\"name\":\"GET /github/grafana/grafana/commits\",\"client_Model\":\"\",\"cloud_RoleName\":\"Web\",\"customMeasurements\":null,\"client_Browser\":\"\",\"operation_Name\":\"GET /github/grafana/grafana/commits\",\"performanceBucket\":\"250ms-500ms\",\"client_CountryOrRegion\":\"\",\"cloud_RoleInstance\":\"test-vm\",\"appName\":\"test-app\",\"client_Type\":\"PC\",\"operation_ParentId\":\"b1f0047386554fa59b7c5330560a0799\",\"success\":\"True\",\"application_Version\":\"1.0.0\",\"operation_SyntheticSource\":\"\",\"itemType\":\"request\",\"user_AccountId\":\"\",\"session_Id\":\"\",\"timestamp\":\"2023-04-17T14:58:11.5790000Z\",\"message\":\"\",\"client_City\":\"\",\"client_StateOrProvince\":\"\",\"itemId\":\"5c126241-dd30-11ed-a80a-00224826882d\",\"client_OS\":\"Linux 5.4.0-1036-azure\",\"id\":\"|b1f0047386554fa59b7c5330560a0799.\",\"customDimensions\":null,\"itemCount\":1,\"location\":\"\",\"user_AuthenticatedId\":\"\",\"appId\":\"4ad5a808-11f7-49d5-9713-f6ede83141e4\",\"user_Id\":\"\",\"resultCode\":\"200\",\"type\":\"\",\"data\":\"\",\"target\":\"\",\"assembly\":\"\",\"outerType\":\"\",\"innermostAssembly\":\"\",\"innermostType\":\"\",\"method\":\"\",\"problemId\":\"\",\"handledAt\":\"\",\"outerMessage\":\"\",\"details\":null,\"innermostMethod\":\"\",\"innermostMessage\":\"\",\"outerAssembly\":\"\",\"outerMethod\":\"\",\"severityLevel\":null,\"url\":\"test-url\",\"source\":\"\"}"
|
||||
],
|
||||
[
|
||||
"65863e6b-dd30-11ed-a808-002248268105",
|
||||
"78c1bcf4-dd30-11ed-a808-0022481f7f28",
|
||||
"5c126241-dd30-11ed-a80a-00224826882d"
|
||||
],
|
||||
[
|
||||
"trace",
|
||||
"dependency",
|
||||
"request"
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
69
pkg/tsdb/azuremonitor/testdata/traces/2-traces-single-table.json
vendored
Normal file
69
pkg/tsdb/azuremonitor/testdata/traces/2-traces-single-table.json
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
{
|
||||
"tables": [
|
||||
{
|
||||
"name": "PrimaryResult",
|
||||
"columns": [
|
||||
{
|
||||
"name": "traceID",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "spanID",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "parentSpanID",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "duration",
|
||||
"type": "real"
|
||||
},
|
||||
{
|
||||
"name": "serviceName",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "operationName",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "startTime",
|
||||
"type": "datetime"
|
||||
},
|
||||
{
|
||||
"name": "serviceTags",
|
||||
"type": "dynamic"
|
||||
},
|
||||
{
|
||||
"name": "tags",
|
||||
"type": "dynamic"
|
||||
},
|
||||
{
|
||||
"name": "itemId",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "itemType",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"rows": [
|
||||
[
|
||||
"cfae497bfd7a44169f35643940820938",
|
||||
"b52403c5-5b27-43a8-9bc6-5938667a4470",
|
||||
"|cfae497bfd7a44169f35643940820938.",
|
||||
0,
|
||||
"",
|
||||
"GET /github/grafana/grafana/commits",
|
||||
"2023-04-17T14:58:10.176Z",
|
||||
"{\"service\":\"github-test-data\",\"limit\":\"5000\",\"remaining\":\"4351\",\"reset\":\"1681746512\",\"used\":\"649\",\"timestamp\":\"2023-04-17T14:58:10.0000000Z\"}",
|
||||
"{\"client_IP\":\"0.0.0.0\",\"operation_Id\":\"cfae497bfd7a44169f35643940820938\",\"duration\":0,\"iKey\":\"195b4fe4-7b01-4814-abca-ffceb1f62c8f\",\"size\":null,\"sdkVersion\":\"node:1.8.9\",\"name\":\"\",\"client_Model\":\"\",\"cloud_RoleName\":\"Web\",\"customMeasurements\":null,\"client_Browser\":\"\",\"operation_Name\":\"GET /github/grafana/grafana/commits\",\"performanceBucket\":\"\",\"client_CountryOrRegion\":\"Ireland\",\"cloud_RoleInstance\":\"test-vm\",\"appName\":\"test-app\",\"client_Type\":\"PC\",\"operation_ParentId\":\"|cfae497bfd7a44169f35643940820938.\",\"success\":\"\",\"application_Version\":\"1.0.0\",\"operation_SyntheticSource\":\"\",\"itemType\":\"trace\",\"user_AccountId\":\"\",\"session_Id\":\"\",\"timestamp\":\"2023-04-17T14:58:10.1760000Z\",\"message\":\"github commits rate limiting info\",\"client_City\":\"Dublin\",\"client_StateOrProvince\":\"Dublin\",\"itemId\":\"65863e6b-dd30-11ed-a808-002248268105\",\"client_OS\":\"Linux 5.4.0-1036-azure\",\"id\":\"\",\"customDimensions\":{\"service\":\"github-test-data\",\"limit\":\"5000\",\"remaining\":\"4351\",\"reset\":\"1681746512\",\"used\":\"649\",\"timestamp\":\"2023-04-17T14:58:10.0000000Z\"},\"itemCount\":1,\"location\":\"\",\"user_AuthenticatedId\":\"\",\"appId\":\"4ad5a808-11f7-49d5-9713-f6ede83141e4\",\"user_Id\":\"\",\"resultCode\":\"\",\"type\":\"\",\"data\":\"\",\"target\":\"\",\"assembly\":\"\",\"outerType\":\"\",\"innermostAssembly\":\"\",\"innermostType\":\"\",\"method\":\"\",\"problemId\":\"\",\"handledAt\":\"\",\"outerMessage\":\"\",\"details\":null,\"innermostMethod\":\"\",\"innermostMessage\":\"\",\"outerAssembly\":\"\",\"outerMethod\":\"\",\"severityLevel\":1,\"url\":\"\",\"source\":\"\"}",
|
||||
"65863e6b-dd30-11ed-a808-002248268105",
|
||||
"trace"
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -0,0 +1,321 @@
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
//
|
||||
// Frame[0] {
|
||||
// "typeVersion": [
|
||||
// 0,
|
||||
// 0
|
||||
// ],
|
||||
// "custom": {
|
||||
// "azureColumnTypes": [
|
||||
// "string",
|
||||
// "string",
|
||||
// "string",
|
||||
// "real",
|
||||
// "string",
|
||||
// "string",
|
||||
// "datetime",
|
||||
// "dynamic",
|
||||
// "dynamic",
|
||||
// "string",
|
||||
// "string"
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
// Name:
|
||||
// Dimensions: 11 Fields by 1 Rows
|
||||
// +----------------------------------+--------------------------------------+------------------------------------+------------------+-------------------+-------------------------------------+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------+-----------------+
|
||||
// | Name: traceID | Name: spanID | Name: parentSpanID | Name: duration | Name: serviceName | Name: operationName | Name: startTime | Name: serviceTags | Name: tags | Name: itemId | Name: itemType |
|
||||
// | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: |
|
||||
// | Type: []*string | Type: []*string | Type: []*string | Type: []*float64 | Type: []*string | Type: []*string | Type: []*time.Time | Type: []*json.RawMessage | Type: []*json.RawMessage | Type: []*string | Type: []*string |
|
||||
// +----------------------------------+--------------------------------------+------------------------------------+------------------+-------------------+-------------------------------------+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------+-----------------+
|
||||
// | cfae497bfd7a44169f35643940820938 | b52403c5-5b27-43a8-9bc6-5938667a4470 | |cfae497bfd7a44169f35643940820938. | 0 | | GET /github/grafana/grafana/commits | 2023-04-17 14:58:10.176 +0000 UTC | [{"value":"5000","key":"limit"},{"value":"4351","key":"remaining"},{"value":"1681746512","key":"reset"},{"value":"github-test-data","key":"service"},{"value":"2023-04-17T14:58:10.0000000Z","key":"timestamp"},{"value":"649","key":"used"}] | [{"value":"4ad5a808-11f7-49d5-9713-f6ede83141e4","key":"appId"},{"value":"test-app","key":"appName"},{"value":"1.0.0","key":"application_Version"},{"value":"Dublin","key":"client_City"},{"value":"Ireland","key":"client_CountryOrRegion"},{"value":"0.0.0.0","key":"client_IP"},{"value":"Linux 5.4.0-1036-azure","key":"client_OS"},{"value":"Dublin","key":"client_StateOrProvince"},{"value":"PC","key":"client_Type"},{"value":"test-vm","key":"cloud_RoleInstance"},{"value":"Web","key":"cloud_RoleName"},{"value":{"limit":"5000","remaining":"4351","reset":"1681746512","service":"github-test-data","timestamp":"2023-04-17T14:58:10.0000000Z","used":"649"},"key":"customDimensions"},{"value":0,"key":"duration"},{"value":"195b4fe4-7b01-4814-abca-ffceb1f62c8f","key":"iKey"},{"value":1,"key":"itemCount"},{"value":"65863e6b-dd30-11ed-a808-002248268105","key":"itemId"},{"value":"trace","key":"itemType"},{"value":"github commits rate limiting info","key":"message"},{"value":"cfae497bfd7a44169f35643940820938","key":"operation_Id"},{"value":"GET /github/grafana/grafana/commits","key":"operation_Name"},{"value":"|cfae497bfd7a44169f35643940820938.","key":"operation_ParentId"},{"value":"node:1.8.9","key":"sdkVersion"},{"value":1,"key":"severityLevel"},{"value":"2023-04-17T14:58:10.1760000Z","key":"timestamp"}] | 65863e6b-dd30-11ed-a808-002248268105 | trace |
|
||||
// +----------------------------------+--------------------------------------+------------------------------------+------------------+-------------------+-------------------------------------+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------+-----------------+
|
||||
//
|
||||
//
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
{
|
||||
"status": 200,
|
||||
"frames": [
|
||||
{
|
||||
"schema": {
|
||||
"meta": {
|
||||
"typeVersion": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"custom": {
|
||||
"azureColumnTypes": [
|
||||
"string",
|
||||
"string",
|
||||
"string",
|
||||
"real",
|
||||
"string",
|
||||
"string",
|
||||
"datetime",
|
||||
"dynamic",
|
||||
"dynamic",
|
||||
"string",
|
||||
"string"
|
||||
]
|
||||
}
|
||||
},
|
||||
"fields": [
|
||||
{
|
||||
"name": "traceID",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "spanID",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "parentSpanID",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "duration",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "serviceName",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "operationName",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "startTime",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "serviceTags",
|
||||
"type": "other",
|
||||
"typeInfo": {
|
||||
"frame": "json.RawMessage",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tags",
|
||||
"type": "other",
|
||||
"typeInfo": {
|
||||
"frame": "json.RawMessage",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "itemId",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "itemType",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
"cfae497bfd7a44169f35643940820938"
|
||||
],
|
||||
[
|
||||
"b52403c5-5b27-43a8-9bc6-5938667a4470"
|
||||
],
|
||||
[
|
||||
"|cfae497bfd7a44169f35643940820938."
|
||||
],
|
||||
[
|
||||
0
|
||||
],
|
||||
[
|
||||
""
|
||||
],
|
||||
[
|
||||
"GET /github/grafana/grafana/commits"
|
||||
],
|
||||
[
|
||||
1681743490176
|
||||
],
|
||||
[
|
||||
[
|
||||
{
|
||||
"value": "5000",
|
||||
"key": "limit"
|
||||
},
|
||||
{
|
||||
"value": "4351",
|
||||
"key": "remaining"
|
||||
},
|
||||
{
|
||||
"value": "1681746512",
|
||||
"key": "reset"
|
||||
},
|
||||
{
|
||||
"value": "github-test-data",
|
||||
"key": "service"
|
||||
},
|
||||
{
|
||||
"value": "2023-04-17T14:58:10.0000000Z",
|
||||
"key": "timestamp"
|
||||
},
|
||||
{
|
||||
"value": "649",
|
||||
"key": "used"
|
||||
}
|
||||
]
|
||||
],
|
||||
[
|
||||
[
|
||||
{
|
||||
"value": "4ad5a808-11f7-49d5-9713-f6ede83141e4",
|
||||
"key": "appId"
|
||||
},
|
||||
{
|
||||
"value": "test-app",
|
||||
"key": "appName"
|
||||
},
|
||||
{
|
||||
"value": "1.0.0",
|
||||
"key": "application_Version"
|
||||
},
|
||||
{
|
||||
"value": "Dublin",
|
||||
"key": "client_City"
|
||||
},
|
||||
{
|
||||
"value": "Ireland",
|
||||
"key": "client_CountryOrRegion"
|
||||
},
|
||||
{
|
||||
"value": "0.0.0.0",
|
||||
"key": "client_IP"
|
||||
},
|
||||
{
|
||||
"value": "Linux 5.4.0-1036-azure",
|
||||
"key": "client_OS"
|
||||
},
|
||||
{
|
||||
"value": "Dublin",
|
||||
"key": "client_StateOrProvince"
|
||||
},
|
||||
{
|
||||
"value": "PC",
|
||||
"key": "client_Type"
|
||||
},
|
||||
{
|
||||
"value": "test-vm",
|
||||
"key": "cloud_RoleInstance"
|
||||
},
|
||||
{
|
||||
"value": "Web",
|
||||
"key": "cloud_RoleName"
|
||||
},
|
||||
{
|
||||
"value": {
|
||||
"limit": "5000",
|
||||
"remaining": "4351",
|
||||
"reset": "1681746512",
|
||||
"service": "github-test-data",
|
||||
"timestamp": "2023-04-17T14:58:10.0000000Z",
|
||||
"used": "649"
|
||||
},
|
||||
"key": "customDimensions"
|
||||
},
|
||||
{
|
||||
"value": 0,
|
||||
"key": "duration"
|
||||
},
|
||||
{
|
||||
"value": "195b4fe4-7b01-4814-abca-ffceb1f62c8f",
|
||||
"key": "iKey"
|
||||
},
|
||||
{
|
||||
"value": 1,
|
||||
"key": "itemCount"
|
||||
},
|
||||
{
|
||||
"value": "65863e6b-dd30-11ed-a808-002248268105",
|
||||
"key": "itemId"
|
||||
},
|
||||
{
|
||||
"value": "trace",
|
||||
"key": "itemType"
|
||||
},
|
||||
{
|
||||
"value": "github commits rate limiting info",
|
||||
"key": "message"
|
||||
},
|
||||
{
|
||||
"value": "cfae497bfd7a44169f35643940820938",
|
||||
"key": "operation_Id"
|
||||
},
|
||||
{
|
||||
"value": "GET /github/grafana/grafana/commits",
|
||||
"key": "operation_Name"
|
||||
},
|
||||
{
|
||||
"value": "|cfae497bfd7a44169f35643940820938.",
|
||||
"key": "operation_ParentId"
|
||||
},
|
||||
{
|
||||
"value": "node:1.8.9",
|
||||
"key": "sdkVersion"
|
||||
},
|
||||
{
|
||||
"value": 1,
|
||||
"key": "severityLevel"
|
||||
},
|
||||
{
|
||||
"value": "2023-04-17T14:58:10.1760000Z",
|
||||
"key": "timestamp"
|
||||
}
|
||||
]
|
||||
],
|
||||
[
|
||||
"65863e6b-dd30-11ed-a808-002248268105"
|
||||
],
|
||||
[
|
||||
"trace"
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
192
pkg/tsdb/azuremonitor/testdata/traces/2-traces-single-table.json.single-trace.golden.jsonc
vendored
Normal file
192
pkg/tsdb/azuremonitor/testdata/traces/2-traces-single-table.json.single-trace.golden.jsonc
vendored
Normal file
@ -0,0 +1,192 @@
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
//
|
||||
// Frame[0] {
|
||||
// "typeVersion": [
|
||||
// 0,
|
||||
// 0
|
||||
// ],
|
||||
// "custom": {
|
||||
// "azureColumnTypes": [
|
||||
// "string",
|
||||
// "string",
|
||||
// "string",
|
||||
// "real",
|
||||
// "string",
|
||||
// "string",
|
||||
// "datetime",
|
||||
// "dynamic",
|
||||
// "dynamic",
|
||||
// "string",
|
||||
// "string"
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
// Name:
|
||||
// Dimensions: 11 Fields by 1 Rows
|
||||
// +----------------------------------+--------------------------------------+------------------------------------+------------------+-------------------+-------------------------------------+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------+-----------------+
|
||||
// | Name: traceID | Name: spanID | Name: parentSpanID | Name: duration | Name: serviceName | Name: operationName | Name: startTime | Name: serviceTags | Name: tags | Name: itemId | Name: itemType |
|
||||
// | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: | Labels: |
|
||||
// | Type: []*string | Type: []*string | Type: []*string | Type: []*float64 | Type: []*string | Type: []*string | Type: []*time.Time | Type: []*string | Type: []*string | Type: []*string | Type: []*string |
|
||||
// +----------------------------------+--------------------------------------+------------------------------------+------------------+-------------------+-------------------------------------+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------+-----------------+
|
||||
// | cfae497bfd7a44169f35643940820938 | b52403c5-5b27-43a8-9bc6-5938667a4470 | |cfae497bfd7a44169f35643940820938. | 0 | | GET /github/grafana/grafana/commits | 2023-04-17 14:58:10.176 +0000 UTC | {"service":"github-test-data","limit":"5000","remaining":"4351","reset":"1681746512","used":"649","timestamp":"2023-04-17T14:58:10.0000000Z"} | {"client_IP":"0.0.0.0","operation_Id":"cfae497bfd7a44169f35643940820938","duration":0,"iKey":"195b4fe4-7b01-4814-abca-ffceb1f62c8f","size":null,"sdkVersion":"node:1.8.9","name":"","client_Model":"","cloud_RoleName":"Web","customMeasurements":null,"client_Browser":"","operation_Name":"GET /github/grafana/grafana/commits","performanceBucket":"","client_CountryOrRegion":"Ireland","cloud_RoleInstance":"test-vm","appName":"test-app","client_Type":"PC","operation_ParentId":"|cfae497bfd7a44169f35643940820938.","success":"","application_Version":"1.0.0","operation_SyntheticSource":"","itemType":"trace","user_AccountId":"","session_Id":"","timestamp":"2023-04-17T14:58:10.1760000Z","message":"github commits rate limiting info","client_City":"Dublin","client_StateOrProvince":"Dublin","itemId":"65863e6b-dd30-11ed-a808-002248268105","client_OS":"Linux 5.4.0-1036-azure","id":"","customDimensions":{"service":"github-test-data","limit":"5000","remaining":"4351","reset":"1681746512","used":"649","timestamp":"2023-04-17T14:58:10.0000000Z"},"itemCount":1,"location":"","user_AuthenticatedId":"","appId":"4ad5a808-11f7-49d5-9713-f6ede83141e4","user_Id":"","resultCode":"","type":"","data":"","target":"","assembly":"","outerType":"","innermostAssembly":"","innermostType":"","method":"","problemId":"","handledAt":"","outerMessage":"","details":null,"innermostMethod":"","innermostMessage":"","outerAssembly":"","outerMethod":"","severityLevel":1,"url":"","source":""} | 65863e6b-dd30-11ed-a808-002248268105 | trace |
|
||||
// +----------------------------------+--------------------------------------+------------------------------------+------------------+-------------------+-------------------------------------+-----------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------+-----------------+
|
||||
//
|
||||
//
|
||||
// 🌟 This was machine generated. Do not edit. 🌟
|
||||
{
|
||||
"status": 200,
|
||||
"frames": [
|
||||
{
|
||||
"schema": {
|
||||
"meta": {
|
||||
"typeVersion": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"custom": {
|
||||
"azureColumnTypes": [
|
||||
"string",
|
||||
"string",
|
||||
"string",
|
||||
"real",
|
||||
"string",
|
||||
"string",
|
||||
"datetime",
|
||||
"dynamic",
|
||||
"dynamic",
|
||||
"string",
|
||||
"string"
|
||||
]
|
||||
}
|
||||
},
|
||||
"fields": [
|
||||
{
|
||||
"name": "traceID",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "spanID",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "parentSpanID",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "duration",
|
||||
"type": "number",
|
||||
"typeInfo": {
|
||||
"frame": "float64",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "serviceName",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "operationName",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "startTime",
|
||||
"type": "time",
|
||||
"typeInfo": {
|
||||
"frame": "time.Time",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "serviceTags",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tags",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "itemId",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "itemType",
|
||||
"type": "string",
|
||||
"typeInfo": {
|
||||
"frame": "string",
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"values": [
|
||||
[
|
||||
"cfae497bfd7a44169f35643940820938"
|
||||
],
|
||||
[
|
||||
"b52403c5-5b27-43a8-9bc6-5938667a4470"
|
||||
],
|
||||
[
|
||||
"|cfae497bfd7a44169f35643940820938."
|
||||
],
|
||||
[
|
||||
0
|
||||
],
|
||||
[
|
||||
""
|
||||
],
|
||||
[
|
||||
"GET /github/grafana/grafana/commits"
|
||||
],
|
||||
[
|
||||
1681743490176
|
||||
],
|
||||
[
|
||||
"{\"service\":\"github-test-data\",\"limit\":\"5000\",\"remaining\":\"4351\",\"reset\":\"1681746512\",\"used\":\"649\",\"timestamp\":\"2023-04-17T14:58:10.0000000Z\"}"
|
||||
],
|
||||
[
|
||||
"{\"client_IP\":\"0.0.0.0\",\"operation_Id\":\"cfae497bfd7a44169f35643940820938\",\"duration\":0,\"iKey\":\"195b4fe4-7b01-4814-abca-ffceb1f62c8f\",\"size\":null,\"sdkVersion\":\"node:1.8.9\",\"name\":\"\",\"client_Model\":\"\",\"cloud_RoleName\":\"Web\",\"customMeasurements\":null,\"client_Browser\":\"\",\"operation_Name\":\"GET /github/grafana/grafana/commits\",\"performanceBucket\":\"\",\"client_CountryOrRegion\":\"Ireland\",\"cloud_RoleInstance\":\"test-vm\",\"appName\":\"test-app\",\"client_Type\":\"PC\",\"operation_ParentId\":\"|cfae497bfd7a44169f35643940820938.\",\"success\":\"\",\"application_Version\":\"1.0.0\",\"operation_SyntheticSource\":\"\",\"itemType\":\"trace\",\"user_AccountId\":\"\",\"session_Id\":\"\",\"timestamp\":\"2023-04-17T14:58:10.1760000Z\",\"message\":\"github commits rate limiting info\",\"client_City\":\"Dublin\",\"client_StateOrProvince\":\"Dublin\",\"itemId\":\"65863e6b-dd30-11ed-a808-002248268105\",\"client_OS\":\"Linux 5.4.0-1036-azure\",\"id\":\"\",\"customDimensions\":{\"service\":\"github-test-data\",\"limit\":\"5000\",\"remaining\":\"4351\",\"reset\":\"1681746512\",\"used\":\"649\",\"timestamp\":\"2023-04-17T14:58:10.0000000Z\"},\"itemCount\":1,\"location\":\"\",\"user_AuthenticatedId\":\"\",\"appId\":\"4ad5a808-11f7-49d5-9713-f6ede83141e4\",\"user_Id\":\"\",\"resultCode\":\"\",\"type\":\"\",\"data\":\"\",\"target\":\"\",\"assembly\":\"\",\"outerType\":\"\",\"innermostAssembly\":\"\",\"innermostType\":\"\",\"method\":\"\",\"problemId\":\"\",\"handledAt\":\"\",\"outerMessage\":\"\",\"details\":null,\"innermostMethod\":\"\",\"innermostMessage\":\"\",\"outerAssembly\":\"\",\"outerMethod\":\"\",\"severityLevel\":1,\"url\":\"\",\"source\":\"\"}"
|
||||
],
|
||||
[
|
||||
"65863e6b-dd30-11ed-a808-002248268105"
|
||||
],
|
||||
[
|
||||
"trace"
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
29
pkg/tsdb/azuremonitor/testdata/utils.go
vendored
Normal file
29
pkg/tsdb/azuremonitor/testdata/utils.go
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
package testdata
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/experimental"
|
||||
)
|
||||
|
||||
func CheckGoldenFrame(t *testing.T, path string, name string, f *data.Frame) {
|
||||
frames := data.Frames{f}
|
||||
if f == nil {
|
||||
frames = nil
|
||||
}
|
||||
dr := backend.DataResponse{
|
||||
Frames: frames,
|
||||
}
|
||||
experimental.CheckGoldenJSONResponse(t, filepath.Join(path), fmt.Sprintf("%s.golden", name), &dr, true)
|
||||
}
|
||||
|
||||
func CheckGoldenFrames(t *testing.T, path string, name string, f data.Frames) {
|
||||
dr := backend.DataResponse{
|
||||
Frames: f,
|
||||
}
|
||||
experimental.CheckGoldenJSONResponse(t, filepath.Join(path), fmt.Sprintf("%s.golden", name), &dr, true)
|
||||
}
|
@ -11,10 +11,13 @@ import (
|
||||
|
||||
"github.com/grafana/grafana-azure-sdk-go/azcredentials"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/kinds/dataquery"
|
||||
)
|
||||
|
||||
const (
|
||||
TimeSeries = "time_series"
|
||||
Table = "table"
|
||||
Trace = "trace"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -54,6 +57,9 @@ type DatasourceInfo struct {
|
||||
DecryptedSecureJSONData map[string]string
|
||||
DatasourceID int64
|
||||
OrgID int64
|
||||
|
||||
DatasourceName string
|
||||
DatasourceUID string
|
||||
}
|
||||
|
||||
// AzureMonitorQuery is the query for all the services as they have similar queries
|
||||
@ -183,6 +189,7 @@ type LogJSONQuery struct {
|
||||
Query string `json:"query"`
|
||||
ResultFormat string `json:"resultFormat"`
|
||||
Resources []string `json:"resources"`
|
||||
OperationId string `json:"operationId"`
|
||||
|
||||
// Deprecated: Queries should be migrated to use Resource instead
|
||||
Workspace string `json:"workspace"`
|
||||
@ -191,6 +198,39 @@ type LogJSONQuery struct {
|
||||
} `json:"azureLogAnalytics"`
|
||||
}
|
||||
|
||||
type TracesJSONQuery struct {
|
||||
AzureTraces struct {
|
||||
// Filters for property values.
|
||||
Filters []TracesFilters `json:"filters"`
|
||||
|
||||
// Operation ID. Used only for Traces queries.
|
||||
OperationId *string `json:"operationId"`
|
||||
|
||||
// KQL query to be executed.
|
||||
Query *string `json:"query"`
|
||||
|
||||
// Array of resource URIs to be queried.
|
||||
Resources []string `json:"resources"`
|
||||
|
||||
// Specifies the format results should be returned as.
|
||||
ResultFormat *dataquery.AzureMonitorQueryAzureTracesResultFormat `json:"resultFormat"`
|
||||
|
||||
// Types of events to filter by.
|
||||
TraceTypes []string `json:"traceTypes"`
|
||||
} `json:"azureTraces"`
|
||||
}
|
||||
|
||||
type TracesFilters struct {
|
||||
// Values to filter by.
|
||||
Filters []string `json:"filters"`
|
||||
|
||||
// Comparison operator to use. Either equals or not equals.
|
||||
Operation string `json:"operation"`
|
||||
|
||||
// Property name, auto-populated based on available traces.
|
||||
Property string `json:"property"`
|
||||
}
|
||||
|
||||
// MetricChartDefinition is the JSON model for a metrics chart definition
|
||||
type MetricChartDefinition struct {
|
||||
ResourceMetadata map[string]string `json:"resourceMetadata"`
|
||||
|
@ -1,8 +1,13 @@
|
||||
import { ContextSrv } from 'app/core/services/context_srv';
|
||||
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||
|
||||
import Datasource from '../datasource';
|
||||
|
||||
type DeepPartial<T> = {
|
||||
[P in keyof T]?: DeepPartial<T[P]>;
|
||||
};
|
||||
const contextSrv = new ContextSrv();
|
||||
const timeSrv = new TimeSrv(contextSrv);
|
||||
|
||||
export default function createMockDatasource(overrides?: DeepPartial<Datasource>) {
|
||||
// We make this a partial so we get _some_ kind of type safety when making this, rather than
|
||||
@ -46,6 +51,7 @@ export default function createMockDatasource(overrides?: DeepPartial<Datasource>
|
||||
azureLogAnalyticsDatasource: {
|
||||
getKustoSchema: () => Promise.resolve(),
|
||||
getDeprecatedDefaultWorkSpace: () => 'defaultWorkspaceId',
|
||||
timeSrv,
|
||||
},
|
||||
resourcePickerData: {
|
||||
getSubscriptions: () => jest.fn().mockResolvedValue([]),
|
||||
|
@ -27,6 +27,16 @@ export default function createMockQuery(overrides?: Partial<AzureMonitorQuery>):
|
||||
...overrides?.azureResourceGraph,
|
||||
},
|
||||
|
||||
azureTraces: {
|
||||
query: 'example traces query',
|
||||
resultFormat: ResultFormat.Trace,
|
||||
resources: ['test-resource'],
|
||||
operationId: 'operationId',
|
||||
traceTypes: ['traces'],
|
||||
filters: [{ filters: ['filter'], operation: 'eq', property: 'property' }],
|
||||
...overrides?.azureTraces,
|
||||
},
|
||||
|
||||
azureMonitor: {
|
||||
// aggOptions: [],
|
||||
aggregation: 'Average',
|
||||
|
@ -88,7 +88,6 @@ export const mockResourcesByResourceGroup = (): ResourceRowGroup => [
|
||||
type: ResourceRowType.Resource,
|
||||
location: 'northeurope',
|
||||
},
|
||||
|
||||
{
|
||||
id: 'db-server',
|
||||
uri: '/subscriptions/def-456/resourceGroups/dev-3/providers/Microsoft.Compute/virtualMachines/db-server',
|
||||
@ -106,6 +105,22 @@ export const mockResourcesByResourceGroup = (): ResourceRowGroup => [
|
||||
type: ResourceRowType.Resource,
|
||||
location: 'northeurope',
|
||||
},
|
||||
{
|
||||
id: 'app-insights-1',
|
||||
uri: '/subscriptions/def-456/resourceGroups/dev-3/providers/microsoft.insights/components/app-insights-1',
|
||||
name: 'app-insights-1',
|
||||
typeLabel: 'Microsoft.Insights/components',
|
||||
type: ResourceRowType.Resource,
|
||||
location: 'northeurope',
|
||||
},
|
||||
{
|
||||
id: 'app-insights-2',
|
||||
uri: '/subscriptions/def-456/resourceGroups/dev-3/providers/microsoft.insights/components/app-insights-2',
|
||||
name: 'app-insights-2',
|
||||
typeLabel: 'Microsoft.Insights/components',
|
||||
type: ResourceRowType.Resource,
|
||||
location: 'northeurope',
|
||||
},
|
||||
];
|
||||
|
||||
export const mockSearchResults = (): ResourceRowGroup => [
|
||||
|
@ -5,7 +5,7 @@ import createMockQuery from '../__mocks__/query';
|
||||
import { createTemplateVariables } from '../__mocks__/utils';
|
||||
import { singleVariable } from '../__mocks__/variables';
|
||||
import AzureMonitorDatasource from '../datasource';
|
||||
import { AzureMonitorQuery, AzureQueryType } from '../types';
|
||||
import { AzureLogsQuery, AzureMonitorQuery, AzureQueryType, AzureTracesQuery } from '../types';
|
||||
|
||||
import FakeSchemaData from './__mocks__/schema';
|
||||
import AzureLogAnalyticsDatasource from './azure_log_analytics_datasource';
|
||||
@ -330,6 +330,17 @@ describe('AzureLogAnalyticsDatasource', () => {
|
||||
|
||||
expect(laDatasource.filterQuery(query)).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should not run traces queries missing a resource', () => {
|
||||
const query: AzureMonitorQuery = {
|
||||
refId: 'A',
|
||||
azureTraces: {
|
||||
resources: [],
|
||||
},
|
||||
};
|
||||
|
||||
expect(laDatasource.filterQuery(query)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('When performing interpolateVariablesInQueries for azure_log_analytics', () => {
|
||||
@ -344,12 +355,12 @@ describe('AzureLogAnalyticsDatasource', () => {
|
||||
expect(templatedQuery[0]).toEqual(query);
|
||||
});
|
||||
|
||||
it('should return a query with any template variables replaced', () => {
|
||||
it('should return a logs query with any template variables replaced', () => {
|
||||
const templateableProps = ['resource', 'workspace', 'query'];
|
||||
const templateVariables = createTemplateVariables(templateableProps);
|
||||
templateSrv.init(Array.from(templateVariables.values()).map((item) => item.templateVariable));
|
||||
const query = createMockQuery();
|
||||
const azureLogAnalytics: { [index: string]: any } = {};
|
||||
const azureLogAnalytics: Partial<AzureLogsQuery> = {};
|
||||
azureLogAnalytics.query = '$query';
|
||||
azureLogAnalytics.workspace = '$workspace';
|
||||
azureLogAnalytics.resources = ['$resource'];
|
||||
@ -366,5 +377,39 @@ describe('AzureLogAnalyticsDatasource', () => {
|
||||
resources: [templateVariables.get('resource')?.templateVariable.current.value],
|
||||
});
|
||||
});
|
||||
|
||||
it('should return a traces query with any template variables replaced', () => {
|
||||
const templateableProps = ['resource', 'query', 'traceTypes', 'property', 'operation', 'filter', 'operationId'];
|
||||
const templateVariables = createTemplateVariables(templateableProps);
|
||||
templateSrv.init(Array.from(templateVariables.values()).map((item) => item.templateVariable));
|
||||
const query = createMockQuery();
|
||||
const azureTraces: Partial<AzureTracesQuery> = {};
|
||||
azureTraces.resources = ['$resource'];
|
||||
azureTraces.query = '$query';
|
||||
azureTraces.traceTypes = ['$traceTypes'];
|
||||
azureTraces.filters = [{ filters: ['$filter'], operation: 'eq', property: '$property' }];
|
||||
azureTraces.operationId = '$operationId';
|
||||
query.queryType = AzureQueryType.AzureTraces;
|
||||
query.azureTraces = {
|
||||
...query.azureTraces,
|
||||
...azureTraces,
|
||||
};
|
||||
|
||||
const templatedQuery = ctx.ds.interpolateVariablesInQueries([query], {});
|
||||
expect(templatedQuery[0]).toHaveProperty('datasource');
|
||||
expect(templatedQuery[0].azureTraces).toMatchObject({
|
||||
query: templateVariables.get('query')?.templateVariable.current.value,
|
||||
resources: [templateVariables.get('resource')?.templateVariable.current.value],
|
||||
operationId: templateVariables.get('operationId')?.templateVariable.current.value,
|
||||
traceTypes: [templateVariables.get('traceTypes')?.templateVariable.current.value],
|
||||
filters: [
|
||||
{
|
||||
filters: [templateVariables.get('filter')?.templateVariable.current.value],
|
||||
operation: 'eq',
|
||||
property: templateVariables.get('property')?.templateVariable.current.value,
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -2,6 +2,7 @@ import { map } from 'lodash';
|
||||
|
||||
import { DataSourceInstanceSettings, DataSourceRef, ScopedVars } from '@grafana/data';
|
||||
import { DataSourceWithBackend, getTemplateSrv } from '@grafana/runtime';
|
||||
import { TimeSrv, getTimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||
|
||||
import { isGUIDish } from '../components/ResourcePicker/utils';
|
||||
import { getAuthType, getAzureCloud, getAzurePortalUrl } from '../credentials';
|
||||
@ -36,6 +37,8 @@ export default class AzureLogAnalyticsDatasource extends DataSourceWithBackend<
|
||||
azureMonitorPath: string;
|
||||
firstWorkspace?: string;
|
||||
|
||||
readonly timeSrv: TimeSrv = getTimeSrv();
|
||||
|
||||
constructor(private instanceSettings: DataSourceInstanceSettings<AzureDataSourceJsonData>) {
|
||||
super(instanceSettings);
|
||||
|
||||
@ -55,8 +58,9 @@ export default class AzureLogAnalyticsDatasource extends DataSourceWithBackend<
|
||||
filterQuery(item: AzureMonitorQuery): boolean {
|
||||
return (
|
||||
item.hide !== true &&
|
||||
!!item.azureLogAnalytics?.query &&
|
||||
(!!item.azureLogAnalytics.resources?.length || !!item.azureLogAnalytics.workspace)
|
||||
((!!item.azureLogAnalytics?.query &&
|
||||
(!!item.azureLogAnalytics.resources?.length || !!item.azureLogAnalytics.workspace)) ||
|
||||
!!item.azureTraces?.resources?.length)
|
||||
);
|
||||
}
|
||||
|
||||
@ -108,34 +112,66 @@ export default class AzureLogAnalyticsDatasource extends DataSourceWithBackend<
|
||||
}
|
||||
|
||||
applyTemplateVariables(target: AzureMonitorQuery, scopedVars: ScopedVars): AzureMonitorQuery {
|
||||
const item = target.azureLogAnalytics;
|
||||
if (!item) {
|
||||
return target;
|
||||
let item;
|
||||
if (target.queryType === AzureQueryType.LogAnalytics && target.azureLogAnalytics) {
|
||||
item = target.azureLogAnalytics;
|
||||
const templateSrv = getTemplateSrv();
|
||||
const resources = item.resources?.map((r) => templateSrv.replace(r, scopedVars));
|
||||
let workspace = templateSrv.replace(item.workspace, scopedVars);
|
||||
|
||||
if (!workspace && !resources && this.firstWorkspace) {
|
||||
workspace = this.firstWorkspace;
|
||||
}
|
||||
|
||||
const query = templateSrv.replace(item.query, scopedVars, interpolateVariable);
|
||||
|
||||
return {
|
||||
...target,
|
||||
queryType: target.queryType || AzureQueryType.LogAnalytics,
|
||||
|
||||
azureLogAnalytics: {
|
||||
resultFormat: item.resultFormat,
|
||||
query,
|
||||
resources,
|
||||
// Workspace was removed in Grafana 8, but remains for backwards compat
|
||||
workspace,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const templateSrv = getTemplateSrv();
|
||||
const resources = item.resources?.map((r) => templateSrv.replace(r, scopedVars));
|
||||
let workspace = templateSrv.replace(item.workspace, scopedVars);
|
||||
if (target.queryType === AzureQueryType.AzureTraces && target.azureTraces) {
|
||||
item = target.azureTraces;
|
||||
const templateSrv = getTemplateSrv();
|
||||
const resources = item.resources?.map((r) => templateSrv.replace(r, scopedVars));
|
||||
const query = templateSrv.replace(item.query, scopedVars, interpolateVariable);
|
||||
const traceTypes = item.traceTypes?.map((t) => templateSrv.replace(t, scopedVars));
|
||||
const filters = (item.filters ?? [])
|
||||
.filter((f) => !!f.property)
|
||||
.map((f) => {
|
||||
const filtersReplaced = f.filters?.map((filter) => templateSrv.replace(filter ?? '', scopedVars));
|
||||
return {
|
||||
property: templateSrv.replace(f.property, scopedVars),
|
||||
operation: f.operation || 'eq',
|
||||
filters: filtersReplaced || [],
|
||||
};
|
||||
});
|
||||
|
||||
if (!workspace && !resources && this.firstWorkspace) {
|
||||
workspace = this.firstWorkspace;
|
||||
return {
|
||||
...target,
|
||||
queryType: target.queryType || AzureQueryType.AzureTraces,
|
||||
|
||||
azureTraces: {
|
||||
resultFormat: item.resultFormat,
|
||||
query,
|
||||
resources,
|
||||
operationId: templateSrv.replace(target.azureTraces?.operationId, scopedVars),
|
||||
filters,
|
||||
traceTypes,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const query = templateSrv.replace(item.query, scopedVars, interpolateVariable);
|
||||
|
||||
return {
|
||||
...target,
|
||||
queryType: AzureQueryType.LogAnalytics,
|
||||
|
||||
azureLogAnalytics: {
|
||||
resultFormat: item.resultFormat,
|
||||
query,
|
||||
resources,
|
||||
|
||||
// Workspace was removed in Grafana 8, but remains for backwards compat
|
||||
workspace,
|
||||
},
|
||||
};
|
||||
return target;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -0,0 +1,73 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
|
||||
import createMockDatasource from '../__mocks__/datasource';
|
||||
import createMockQuery from '../__mocks__/query';
|
||||
import { ResultFormat } from '../types';
|
||||
|
||||
import FormatAsField from './FormatAsField';
|
||||
import { setFormatAs } from './TracesQueryEditor/setQueryValue';
|
||||
|
||||
const options = [
|
||||
{ label: 'Table', value: ResultFormat.Table },
|
||||
{ label: 'Trace', value: ResultFormat.Trace },
|
||||
{ label: 'Time Series', value: ResultFormat.TimeSeries },
|
||||
];
|
||||
|
||||
const props = {
|
||||
query: createMockQuery(),
|
||||
datasource: createMockDatasource(),
|
||||
variableOptionGroup: { label: 'Templates', options: [] },
|
||||
onQueryChange: jest.fn(),
|
||||
setError: jest.fn(),
|
||||
isLoading: false,
|
||||
inputId: 'input-id',
|
||||
options,
|
||||
defaultValue: ResultFormat.Table,
|
||||
setFormatAs,
|
||||
resultFormat: undefined,
|
||||
};
|
||||
|
||||
describe('FormatAsField', () => {
|
||||
it('should render the current value', async () => {
|
||||
const query = {
|
||||
...props.query,
|
||||
azureTraces: {
|
||||
resultFormat: ResultFormat.Trace,
|
||||
},
|
||||
};
|
||||
render(<FormatAsField {...props} resultFormat={query.azureTraces.resultFormat} query={query} />);
|
||||
expect(screen.getByText('Trace')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render the default value if selected is not in list of options', async () => {
|
||||
const query = {
|
||||
...props.query,
|
||||
azureTraces: {
|
||||
resultFormat: ResultFormat.Trace,
|
||||
},
|
||||
};
|
||||
|
||||
const shortOptions = options.slice(0, 1);
|
||||
|
||||
const { rerender } = render(
|
||||
<FormatAsField {...props} resultFormat={query.azureTraces.resultFormat} options={shortOptions} query={query} />
|
||||
);
|
||||
|
||||
const newQuery = {
|
||||
...query,
|
||||
azureTraces: { ...query.azureTraces, resultFormat: props.defaultValue },
|
||||
};
|
||||
expect(props.onQueryChange).toHaveBeenCalledWith(newQuery);
|
||||
rerender(
|
||||
<FormatAsField
|
||||
{...props}
|
||||
resultFormat={newQuery.azureTraces.resultFormat}
|
||||
options={shortOptions}
|
||||
query={newQuery}
|
||||
/>
|
||||
);
|
||||
expect(screen.getByText('Table')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Trace')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
@ -0,0 +1,60 @@
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { useEffectOnce } from 'react-use';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { Select } from '@grafana/ui';
|
||||
|
||||
import { selectors } from '../e2e/selectors';
|
||||
import { FormatAsFieldProps, ResultFormat } from '../types';
|
||||
|
||||
import { Field } from './Field';
|
||||
|
||||
const FormatAsField = ({
|
||||
query,
|
||||
variableOptionGroup,
|
||||
onQueryChange,
|
||||
inputId,
|
||||
options: formatOptions,
|
||||
defaultValue,
|
||||
setFormatAs,
|
||||
resultFormat,
|
||||
}: FormatAsFieldProps) => {
|
||||
const options = useMemo(() => [...formatOptions, variableOptionGroup], [variableOptionGroup, formatOptions]);
|
||||
|
||||
const handleChange = useCallback(
|
||||
(change: SelectableValue<ResultFormat>) => {
|
||||
const { value } = change;
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
const newQuery = setFormatAs(query, value);
|
||||
onQueryChange(newQuery);
|
||||
},
|
||||
[onQueryChange, query, setFormatAs]
|
||||
);
|
||||
|
||||
useEffectOnce(() => {
|
||||
if (!resultFormat) {
|
||||
handleChange({ value: defaultValue });
|
||||
} else {
|
||||
if (!formatOptions.find((item) => item.value === resultFormat)) {
|
||||
handleChange({ value: defaultValue });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<Field label="Format as" data-testid={selectors.components.queryEditor.logsQueryEditor.formatSelection.input}>
|
||||
<Select
|
||||
inputId={`${inputId}-format-as-field`}
|
||||
value={resultFormat ?? defaultValue}
|
||||
onChange={handleChange}
|
||||
options={options}
|
||||
width={38}
|
||||
/>
|
||||
</Field>
|
||||
);
|
||||
};
|
||||
|
||||
export default FormatAsField;
|
@ -1,46 +0,0 @@
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { Select } from '@grafana/ui';
|
||||
|
||||
import { selectors } from '../../e2e/selectors';
|
||||
import { AzureQueryEditorFieldProps, ResultFormat } from '../../types';
|
||||
import { Field } from '../Field';
|
||||
|
||||
import { setFormatAs } from './setQueryValue';
|
||||
|
||||
const FORMAT_OPTIONS: Array<SelectableValue<ResultFormat>> = [
|
||||
{ label: 'Time series', value: ResultFormat.TimeSeries },
|
||||
{ label: 'Table', value: ResultFormat.Table },
|
||||
];
|
||||
|
||||
const FormatAsField = ({ query, variableOptionGroup, onQueryChange }: AzureQueryEditorFieldProps) => {
|
||||
const options = useMemo(() => [...FORMAT_OPTIONS, variableOptionGroup], [variableOptionGroup]);
|
||||
|
||||
const handleChange = useCallback(
|
||||
(change: SelectableValue<ResultFormat>) => {
|
||||
const { value } = change;
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
const newQuery = setFormatAs(query, value);
|
||||
onQueryChange(newQuery);
|
||||
},
|
||||
[onQueryChange, query]
|
||||
);
|
||||
|
||||
return (
|
||||
<Field label="Format as" data-testid={selectors.components.queryEditor.logsQueryEditor.formatSelection.input}>
|
||||
<Select
|
||||
inputId="azure-monitor-logs-workspaces-field"
|
||||
value={query.azureLogAnalytics?.resultFormat}
|
||||
onChange={handleChange}
|
||||
options={options}
|
||||
width={38}
|
||||
/>
|
||||
</Field>
|
||||
);
|
||||
};
|
||||
|
||||
export default FormatAsField;
|
@ -170,7 +170,7 @@ describe('LogsQueryEditor', () => {
|
||||
await userEvent.click(advancedSection);
|
||||
|
||||
const advancedInput = await screen.findByTestId('input-advanced-resource-picker-1');
|
||||
// const advancedInput = await screen.findByLabelText('Resource URI(s)');
|
||||
|
||||
await userEvent.type(advancedInput, '/subscriptions/def-123');
|
||||
|
||||
const applyButton = screen.getByRole('button', { name: 'Apply' });
|
||||
|
@ -4,14 +4,16 @@ import { EditorFieldGroup, EditorRow, EditorRows } from '@grafana/experimental';
|
||||
import { Alert } from '@grafana/ui';
|
||||
|
||||
import Datasource from '../../datasource';
|
||||
import { AzureMonitorErrorish, AzureMonitorOption, AzureMonitorQuery } from '../../types';
|
||||
import { selectors } from '../../e2e/selectors';
|
||||
import { AzureMonitorErrorish, AzureMonitorOption, AzureMonitorQuery, ResultFormat } from '../../types';
|
||||
import FormatAsField from '../FormatAsField';
|
||||
import ResourceField from '../ResourceField';
|
||||
import { ResourceRow, ResourceRowGroup, ResourceRowType } from '../ResourcePicker/types';
|
||||
import { parseResourceDetails } from '../ResourcePicker/utils';
|
||||
|
||||
import AdvancedResourcePicker from './AdvancedResourcePicker';
|
||||
import FormatAsField from './FormatAsField';
|
||||
import QueryField from './QueryField';
|
||||
import { setFormatAs } from './setQueryValue';
|
||||
import useMigrations from './useMigrations';
|
||||
|
||||
interface LogsQueryEditorProps {
|
||||
@ -49,7 +51,7 @@ const LogsQueryEditor = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<span data-testid="azure-monitor-logs-query-editor-with-experimental-ui">
|
||||
<span data-testid={selectors.components.queryEditor.logsQueryEditor.container.input}>
|
||||
<EditorRows>
|
||||
<EditorRow>
|
||||
<EditorFieldGroup>
|
||||
@ -99,6 +101,14 @@ const LogsQueryEditor = ({
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
onQueryChange={onChange}
|
||||
setError={setError}
|
||||
inputId={'azure-monitor-logs'}
|
||||
options={[
|
||||
{ label: 'Time series', value: ResultFormat.TimeSeries },
|
||||
{ label: 'Table', value: ResultFormat.Table },
|
||||
]}
|
||||
defaultValue={ResultFormat.Table}
|
||||
setFormatAs={setFormatAs}
|
||||
resultFormat={query.azureLogAnalytics?.resultFormat}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
@ -13,6 +13,7 @@ import {
|
||||
mockGetValidLocations,
|
||||
mockResourcesByResourceGroup,
|
||||
} from '../../__mocks__/resourcePickerRows';
|
||||
import { selectors } from '../../e2e/selectors';
|
||||
import ResourcePickerData from '../../resourcePicker/resourcePickerData';
|
||||
|
||||
import MetricsQueryEditor from './MetricsQueryEditor';
|
||||
@ -74,7 +75,9 @@ describe('MetricsQueryEditor', () => {
|
||||
/>
|
||||
);
|
||||
|
||||
expect(await screen.findByTestId('azure-monitor-metrics-query-editor-with-experimental-ui')).toBeInTheDocument();
|
||||
expect(
|
||||
await screen.findByTestId(selectors.components.queryEditor.metricsQueryEditor.container.input)
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should show the current resource in the ResourcePicker', async () => {
|
||||
|
@ -5,6 +5,7 @@ import { EditorRows, EditorRow, EditorFieldGroup } from '@grafana/experimental';
|
||||
|
||||
import { multiResourceCompatibleTypes } from '../../azureMetadata';
|
||||
import type Datasource from '../../datasource';
|
||||
import { selectors } from '../../e2e/selectors';
|
||||
import type { AzureMonitorQuery, AzureMonitorOption, AzureMonitorErrorish, AzureMonitorResource } from '../../types';
|
||||
import ResourceField from '../ResourceField';
|
||||
import { ResourceRow, ResourceRowGroup, ResourceRowType } from '../ResourcePicker/types';
|
||||
@ -85,7 +86,7 @@ const MetricsQueryEditor = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<span data-testid="azure-monitor-metrics-query-editor-with-experimental-ui">
|
||||
<span data-testid={selectors.components.queryEditor.metricsQueryEditor.container.input}>
|
||||
<EditorRows>
|
||||
<EditorRow>
|
||||
<EditorFieldGroup>
|
||||
|
@ -7,6 +7,7 @@ import * as ui from '@grafana/ui';
|
||||
import createMockDatasource from '../../__mocks__/datasource';
|
||||
import { invalidNamespaceError } from '../../__mocks__/errors';
|
||||
import createMockQuery from '../../__mocks__/query';
|
||||
import { selectors } from '../../e2e/selectors';
|
||||
import { AzureQueryType } from '../../types';
|
||||
|
||||
import QueryEditor from './QueryEditor';
|
||||
@ -29,7 +30,9 @@ describe('Azure Monitor QueryEditor', () => {
|
||||
|
||||
render(<QueryEditor query={mockQuery} datasource={mockDatasource} onChange={() => {}} onRunQuery={() => {}} />);
|
||||
await waitFor(() =>
|
||||
expect(screen.getByTestId('azure-monitor-metrics-query-editor-with-experimental-ui')).toBeInTheDocument()
|
||||
expect(
|
||||
screen.getByTestId(selectors.components.queryEditor.metricsQueryEditor.container.input)
|
||||
).toBeInTheDocument()
|
||||
);
|
||||
});
|
||||
|
||||
@ -42,7 +45,35 @@ describe('Azure Monitor QueryEditor', () => {
|
||||
|
||||
render(<QueryEditor query={mockQuery} datasource={mockDatasource} onChange={() => {}} onRunQuery={() => {}} />);
|
||||
await waitFor(() =>
|
||||
expect(screen.queryByTestId('azure-monitor-logs-query-editor-with-experimental-ui')).toBeInTheDocument()
|
||||
expect(screen.queryByTestId(selectors.components.queryEditor.logsQueryEditor.container.input)).toBeInTheDocument()
|
||||
);
|
||||
});
|
||||
|
||||
it('renders the ARG query editor when the query type is ARG', async () => {
|
||||
const mockDatasource = createMockDatasource();
|
||||
const mockQuery = {
|
||||
...createMockQuery(),
|
||||
queryType: AzureQueryType.AzureResourceGraph,
|
||||
};
|
||||
|
||||
render(<QueryEditor query={mockQuery} datasource={mockDatasource} onChange={() => {}} onRunQuery={() => {}} />);
|
||||
await waitFor(() =>
|
||||
expect(screen.queryByTestId(selectors.components.queryEditor.argsQueryEditor.container.input)).toBeInTheDocument()
|
||||
);
|
||||
});
|
||||
|
||||
it('renders the Traces query editor when the query type is Traces', async () => {
|
||||
const mockDatasource = createMockDatasource();
|
||||
const mockQuery = {
|
||||
...createMockQuery(),
|
||||
queryType: AzureQueryType.AzureTraces,
|
||||
};
|
||||
|
||||
render(<QueryEditor query={mockQuery} datasource={mockDatasource} onChange={() => {}} onRunQuery={() => {}} />);
|
||||
await waitFor(() =>
|
||||
expect(
|
||||
screen.queryByTestId(selectors.components.queryEditor.tracesQueryEditor.container.input)
|
||||
).toBeInTheDocument()
|
||||
);
|
||||
});
|
||||
|
||||
@ -69,7 +100,9 @@ describe('Azure Monitor QueryEditor', () => {
|
||||
<QueryEditor query={createMockQuery()} datasource={mockDatasource} onChange={() => {}} onRunQuery={() => {}} />
|
||||
);
|
||||
await waitFor(() =>
|
||||
expect(screen.getByTestId('azure-monitor-metrics-query-editor-with-experimental-ui')).toBeInTheDocument()
|
||||
expect(
|
||||
screen.getByTestId(selectors.components.queryEditor.metricsQueryEditor.container.input)
|
||||
).toBeInTheDocument()
|
||||
);
|
||||
expect(screen.getByText('An error occurred while requesting metadata from Azure Monitor')).toBeInTheDocument();
|
||||
});
|
||||
|
@ -18,6 +18,7 @@ import LogsQueryEditor from '../LogsQueryEditor';
|
||||
import NewMetricsQueryEditor from '../MetricsQueryEditor/MetricsQueryEditor';
|
||||
import { QueryHeader } from '../QueryHeader';
|
||||
import { Space } from '../Space';
|
||||
import TracesQueryEditor from '../TracesQueryEditor';
|
||||
|
||||
import usePreparedQuery from './usePreparedQuery';
|
||||
|
||||
@ -131,6 +132,18 @@ const EditorForQueryType = ({
|
||||
/>
|
||||
);
|
||||
|
||||
case AzureQueryType.AzureTraces:
|
||||
return (
|
||||
<TracesQueryEditor
|
||||
subscriptionId={subscriptionId}
|
||||
query={query}
|
||||
datasource={datasource}
|
||||
onChange={onChange}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
setError={setError}
|
||||
/>
|
||||
);
|
||||
|
||||
default:
|
||||
const type = query.queryType as unknown;
|
||||
return (
|
||||
|
@ -15,6 +15,7 @@ export const QueryHeader = ({ query, onQueryChange }: QueryTypeFieldProps) => {
|
||||
const queryTypes: Array<{ value: AzureQueryType; label: string }> = [
|
||||
{ value: AzureQueryType.AzureMonitor, label: 'Metrics' },
|
||||
{ value: AzureQueryType.LogAnalytics, label: 'Logs' },
|
||||
{ value: AzureQueryType.AzureTraces, label: 'Traces' },
|
||||
{ value: AzureQueryType.AzureResourceGraph, label: 'Azure Resource Graph' },
|
||||
];
|
||||
|
||||
|
@ -198,12 +198,24 @@ describe('AzureMonitor ResourcePicker utils', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('ignores an empty resource URI', () => {
|
||||
it('updates a resource with a resource URI for Traces', () => {
|
||||
expect(setResources(createMockQuery(), 'traces', ['/subscription/sub'])).toMatchObject({
|
||||
azureTraces: { resources: ['/subscription/sub'] },
|
||||
});
|
||||
});
|
||||
|
||||
it('ignores an empty logs resource URI', () => {
|
||||
expect(setResources(createMockQuery(), 'logs', ['/subscription/sub', ''])).toMatchObject({
|
||||
azureLogAnalytics: { resources: ['/subscription/sub'] },
|
||||
});
|
||||
});
|
||||
|
||||
it('ignores an empty traces resource URI', () => {
|
||||
expect(setResources(createMockQuery(), 'traces', ['/subscription/sub', ''])).toMatchObject({
|
||||
azureTraces: { resources: ['/subscription/sub'] },
|
||||
});
|
||||
});
|
||||
|
||||
it('updates a resource with a resource parameters for Metrics', () => {
|
||||
expect(
|
||||
setResources(createMockQuery(), 'metrics', [
|
||||
|
@ -169,6 +169,17 @@ export function setResources(
|
||||
},
|
||||
};
|
||||
}
|
||||
if (type === 'traces') {
|
||||
// Resource URI for Traces
|
||||
return {
|
||||
...query,
|
||||
azureTraces: {
|
||||
...query.azureTraces,
|
||||
resources: resourcesToStrings(resources).filter((resource) => resource !== ''),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// Resource object for metrics
|
||||
const parsedResource = resources.length ? parseResourceDetails(resources[0]) : {};
|
||||
return {
|
||||
|
@ -0,0 +1,278 @@
|
||||
import { cx } from '@emotion/css';
|
||||
import React, { RefCallback, SyntheticEvent, useState } from 'react';
|
||||
import { lastValueFrom } from 'rxjs';
|
||||
|
||||
import { CoreApp, DataFrame, SelectableValue, TimeRange } from '@grafana/data';
|
||||
import { AccessoryButton } from '@grafana/experimental';
|
||||
import {
|
||||
HorizontalGroup,
|
||||
Select,
|
||||
ButtonSelect,
|
||||
AsyncMultiSelect,
|
||||
getSelectStyles,
|
||||
useTheme2,
|
||||
Checkbox,
|
||||
} from '@grafana/ui';
|
||||
|
||||
import { AzureMonitorQuery, AzureQueryType, AzureTracesFilter } from '../../dataquery.gen';
|
||||
import Datasource from '../../datasource';
|
||||
import { VariableOptionGroup } from '../../types';
|
||||
import { addValueToOptions } from '../../utils/common';
|
||||
|
||||
export interface FilterProps {
|
||||
query: AzureMonitorQuery;
|
||||
datasource: Datasource;
|
||||
propertyMap: Map<string, SelectableValue[]>;
|
||||
setPropertyMap: React.Dispatch<React.SetStateAction<Map<string, Array<SelectableValue<string>>>>>;
|
||||
timeRange: TimeRange;
|
||||
queryTraceTypes: string[];
|
||||
properties: string[];
|
||||
variableOptionGroup: VariableOptionGroup;
|
||||
}
|
||||
|
||||
const onFieldChange = <Key extends keyof AzureTracesFilter>(
|
||||
fieldName: Key,
|
||||
item: Partial<AzureTracesFilter>,
|
||||
selected: SelectableValue<AzureTracesFilter[Key]>,
|
||||
onChange: (item: Partial<AzureTracesFilter>) => void
|
||||
) => {
|
||||
if (fieldName === 'filters') {
|
||||
item[fieldName] = selected.map((item: SelectableValue<string>) => item.value);
|
||||
} else {
|
||||
item[fieldName] = selected.value;
|
||||
if (fieldName === 'property') {
|
||||
item.filters = [];
|
||||
}
|
||||
}
|
||||
onChange(item);
|
||||
};
|
||||
|
||||
const getTraceProperties = async (
|
||||
query: AzureMonitorQuery,
|
||||
datasource: Datasource,
|
||||
timeRange: TimeRange,
|
||||
traceTypes: string[],
|
||||
propertyMap: Map<string, SelectableValue[]>,
|
||||
setPropertyMap: React.Dispatch<React.SetStateAction<Map<string, Array<SelectableValue<string>>>>>,
|
||||
filter?: Partial<AzureTracesFilter>
|
||||
): Promise<SelectableValue[]> => {
|
||||
const { azureTraces } = query;
|
||||
if (!azureTraces) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const { resources } = azureTraces;
|
||||
|
||||
if (!resources || !filter) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const property = filter.property;
|
||||
if (!property) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const queryString = `let ${property} = toscalar(union isfuzzy=true ${traceTypes.join(',')}
|
||||
| where $__timeFilter(timestamp)
|
||||
| summarize count=count() by ${property}
|
||||
| summarize make_list(pack_all()));
|
||||
print properties = bag_pack("${property}", ${property});`;
|
||||
|
||||
const results = await lastValueFrom(
|
||||
datasource.azureLogAnalyticsDatasource.query({
|
||||
requestId: 'azure-traces-properties-req',
|
||||
interval: '',
|
||||
intervalMs: 0,
|
||||
scopedVars: {},
|
||||
timezone: '',
|
||||
startTime: 0,
|
||||
app: CoreApp.Unknown,
|
||||
targets: [
|
||||
{
|
||||
...query,
|
||||
azureLogAnalytics: {
|
||||
resources,
|
||||
query: queryString,
|
||||
},
|
||||
queryType: AzureQueryType.LogAnalytics,
|
||||
},
|
||||
],
|
||||
range: timeRange,
|
||||
})
|
||||
);
|
||||
if (results.data.length > 0) {
|
||||
const result: DataFrame = results.data[0];
|
||||
if (result.fields.length > 0) {
|
||||
const properties: { [key: string]: Array<{ [key: string]: string | number; count: number }> } = JSON.parse(
|
||||
result.fields[0].values.toArray()[0]
|
||||
);
|
||||
const values = properties[property].map((value) => {
|
||||
let label = value[property];
|
||||
if (value[property] === '') {
|
||||
label = '<Empty>';
|
||||
}
|
||||
return { label: label.toString(), value: value[property].toString(), count: value.count };
|
||||
});
|
||||
propertyMap.set(property, values);
|
||||
setPropertyMap(propertyMap);
|
||||
return values;
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
};
|
||||
|
||||
export function makeRenderItem(props: FilterProps) {
|
||||
function renderItem(
|
||||
item: Partial<AzureTracesFilter>,
|
||||
onChange: (item: Partial<AzureTracesFilter>) => void,
|
||||
onDelete: () => void
|
||||
) {
|
||||
return <Filter {...props} item={item} onChange={onChange} onDelete={onDelete} />;
|
||||
}
|
||||
|
||||
return renderItem;
|
||||
}
|
||||
|
||||
interface OptionProps {
|
||||
isFocused: boolean;
|
||||
isSelected: boolean;
|
||||
innerProps: JSX.IntrinsicElements['div'];
|
||||
innerRef: RefCallback<HTMLDivElement>;
|
||||
data: SelectableValue<string>;
|
||||
selectOption: (data: SelectableValue<string>) => void;
|
||||
}
|
||||
|
||||
const Option = (props: React.PropsWithChildren<OptionProps>) => {
|
||||
const { data, innerProps, innerRef, isFocused, isSelected } = props;
|
||||
const theme = useTheme2();
|
||||
const styles = getSelectStyles(theme);
|
||||
|
||||
const onClickMultiOption = (e: SyntheticEvent) => {
|
||||
props.selectOption({ ...data });
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={innerRef}
|
||||
className={cx(
|
||||
styles.option,
|
||||
isFocused && styles.optionFocused,
|
||||
isSelected && styles.optionSelected,
|
||||
data.isDisabled && styles.optionDisabled
|
||||
)}
|
||||
{...innerProps}
|
||||
aria-label="Select option"
|
||||
title={data.title}
|
||||
onClick={onClickMultiOption}
|
||||
>
|
||||
<div className={styles.optionBody}>
|
||||
<Checkbox value={isSelected} label={data.label ? `${data.label} - (${data.count})` : ''} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const Filter = (
|
||||
props: FilterProps & {
|
||||
item: Partial<AzureTracesFilter>;
|
||||
onChange: (item: Partial<AzureTracesFilter>) => void;
|
||||
onDelete: () => void;
|
||||
}
|
||||
) => {
|
||||
const {
|
||||
query,
|
||||
datasource,
|
||||
propertyMap,
|
||||
setPropertyMap,
|
||||
timeRange,
|
||||
queryTraceTypes,
|
||||
properties,
|
||||
item,
|
||||
onChange,
|
||||
onDelete,
|
||||
variableOptionGroup,
|
||||
} = props;
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [values, setValues] = useState<Array<SelectableValue<string> | VariableOptionGroup>>(
|
||||
addValueToOptions(propertyMap.get(item.property ?? '') ?? [], variableOptionGroup)
|
||||
);
|
||||
const [selected, setSelected] = useState<SelectableValue[]>(
|
||||
item.filters ? item.filters.map((filter) => ({ value: filter, label: filter === '' ? '<Empty>' : filter })) : []
|
||||
);
|
||||
|
||||
const loadOptions = async () => {
|
||||
setLoading(true);
|
||||
if (item.property && item.property !== '') {
|
||||
const vals = propertyMap.get(item.property ?? '');
|
||||
if (!vals) {
|
||||
const promise = await getTraceProperties(
|
||||
query,
|
||||
datasource,
|
||||
timeRange,
|
||||
queryTraceTypes,
|
||||
propertyMap,
|
||||
setPropertyMap,
|
||||
item
|
||||
);
|
||||
setValues(addValueToOptions(promise, variableOptionGroup));
|
||||
setLoading(false);
|
||||
return promise;
|
||||
} else {
|
||||
setValues(addValueToOptions(vals, variableOptionGroup));
|
||||
setLoading(false);
|
||||
return Promise.resolve(vals);
|
||||
}
|
||||
}
|
||||
const empty: Array<SelectableValue<string>> = [];
|
||||
return Promise.resolve(empty);
|
||||
};
|
||||
|
||||
return (
|
||||
<HorizontalGroup spacing="none">
|
||||
<Select
|
||||
menuShouldPortal
|
||||
placeholder="Property"
|
||||
value={item.property ? { value: item.property, label: item.property } : null}
|
||||
options={addValueToOptions(
|
||||
properties.map((type) => ({ label: type, value: type })),
|
||||
variableOptionGroup
|
||||
)}
|
||||
onChange={(e) => onFieldChange('property', item, e, onChange)}
|
||||
width={25}
|
||||
/>
|
||||
<ButtonSelect<string>
|
||||
placeholder="Operator"
|
||||
value={item.operation ? { label: item.operation === 'eq' ? '=' : '!=', value: item.operation } : undefined}
|
||||
options={[
|
||||
{ label: '=', value: 'eq' },
|
||||
{ label: '!=', value: 'ne' },
|
||||
]}
|
||||
onChange={(e) => onFieldChange('operation', item, e, onChange)}
|
||||
defaultValue={'eq'}
|
||||
/>
|
||||
<AsyncMultiSelect
|
||||
blurInputOnSelect={false}
|
||||
menuShouldPortal
|
||||
placeholder="Value"
|
||||
value={selected}
|
||||
loadOptions={loadOptions}
|
||||
isLoading={loading}
|
||||
onOpenMenu={loadOptions}
|
||||
onChange={(e: Array<SelectableValue<string>>) => setSelected(e)}
|
||||
width={35}
|
||||
defaultOptions={values}
|
||||
isClearable
|
||||
components={{ Option }}
|
||||
closeMenuOnSelect={false}
|
||||
onCloseMenu={() => onFieldChange('filters', item, selected, onChange)}
|
||||
hideSelectedOptions={false}
|
||||
/>
|
||||
<AccessoryButton aria-label="Remove" icon="times" variant="secondary" onClick={onDelete} type="button" />
|
||||
</HorizontalGroup>
|
||||
);
|
||||
};
|
||||
|
||||
export default Filter;
|
@ -0,0 +1,411 @@
|
||||
import { act, render, screen, waitFor } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { UserEvent } from '@testing-library/user-event/dist/types/setup/setup';
|
||||
import React from 'react';
|
||||
import { of } from 'rxjs';
|
||||
import { selectOptionInTest } from 'test/helpers/selectOptionInTest';
|
||||
|
||||
import { ArrayVector, CoreApp } from '@grafana/data';
|
||||
|
||||
import createMockDatasource from '../../__mocks__/datasource';
|
||||
import createMockQuery from '../../__mocks__/query';
|
||||
import { AzureQueryType } from '../../dataquery.gen';
|
||||
import Datasource from '../../datasource';
|
||||
import { AzureMonitorQuery } from '../../types';
|
||||
|
||||
import Filters from './Filters';
|
||||
import { setFilters } from './setQueryValue';
|
||||
|
||||
const variableOptionGroup = {
|
||||
label: 'Template variables',
|
||||
options: [],
|
||||
};
|
||||
let user: UserEvent;
|
||||
let mockDatasource: Datasource;
|
||||
const onQueryChange = jest.fn();
|
||||
|
||||
const addFilter = async (
|
||||
mockQuery: AzureMonitorQuery,
|
||||
filter: {
|
||||
property: string;
|
||||
operation: string;
|
||||
index: number;
|
||||
filters: Array<{
|
||||
count: number;
|
||||
value: string;
|
||||
}>;
|
||||
},
|
||||
rerender: (ui: React.ReactElement) => void
|
||||
) => {
|
||||
const { property, operation, index } = filter;
|
||||
const resultVector = new ArrayVector([
|
||||
`{"${property}":[${filter.filters.map(({ count, value }) => `{"${property}":"${value}", "count":${count}}`)}]}`,
|
||||
]);
|
||||
mockDatasource.azureLogAnalyticsDatasource.query = jest.fn().mockReturnValue(
|
||||
of({
|
||||
data: [
|
||||
{
|
||||
refId: 'A',
|
||||
meta: {
|
||||
typeVersion: [0, 0],
|
||||
custom: {
|
||||
azureColumnTypes: ['dynamic'],
|
||||
},
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: 'properties',
|
||||
type: 'string',
|
||||
typeInfo: {
|
||||
frame: 'string',
|
||||
nullable: true,
|
||||
},
|
||||
config: {
|
||||
links: [
|
||||
{
|
||||
title: 'View in Azure Portal',
|
||||
targetBlank: true,
|
||||
url: 'https://portal.azure.com/#blade/Microsoft_OperationsManagementSuite_Workspace/AnalyticsBlade/initiator/AnalyticsShareLinkToQuery/isQueryEditorVisible/true/scope/%7B%22resources%22%3A%5B%7B%22resourceId%22%3A%22%2Fsubscriptions%2F44693801-6ee6-49de-9b2d-9106972f9572%2FresourceGroups%2Fcloud-datasources%2Fproviders%2Fmicrosoft.insights%2Fcomponents%2FAppInsightsTestData%22%7D%5D%7D/query/H4sIAAAAAAAA%2F3zPz0rDQBAG8HufYuglu2ChTQtqa3wIEQ+KhEk66tD9x86skuDDS+qthF7m8DG%2F+RhHCpiS4x6VY2hfKAvHAA1olB4dZlPCFLB8lHEcGs2FAL+RHXbsWIcnkuJUFgC%2F8PNFmeCtUvYkij5V7%2FDYwBGVpshU9brerta71aZ+3tztt%2FV+d%2F9aWcBwvFAPV9Ttvzo3SvEeM48EfSxBm%2FM0Frph7q0L4vFErWNRk7A%2FteicsdYeFgApc1BIOSbKyiTQQIef7bRmljOHlzdzdfbwFwAA%2F%2F8vPrTNXwEAAA==/isQueryBase64Compressed/true/timespanInIsoFormat/P1D',
|
||||
},
|
||||
],
|
||||
},
|
||||
values: resultVector,
|
||||
entities: {},
|
||||
},
|
||||
],
|
||||
length: 1,
|
||||
},
|
||||
],
|
||||
state: 'Done',
|
||||
})
|
||||
);
|
||||
|
||||
const operationLabel = operation === 'eq' ? '=' : '!=';
|
||||
const addFilter = await screen.findByLabelText('Add');
|
||||
await act(() => {
|
||||
userEvent.click(addFilter);
|
||||
if (mockQuery.azureTraces?.filters && mockQuery.azureTraces.filters.length < 1) {
|
||||
expect(onQueryChange).not.toHaveBeenCalled();
|
||||
}
|
||||
});
|
||||
|
||||
await waitFor(() => expect(screen.getByText('Property')).toBeInTheDocument());
|
||||
const propertySelect = await screen.findByText('Property');
|
||||
selectOptionInTest(propertySelect, property);
|
||||
await waitFor(() => expect(screen.getByText(property)).toBeInTheDocument());
|
||||
|
||||
await waitFor(() => expect(screen.getByText('Property')).toBeInTheDocument());
|
||||
const operationSelect = await screen.getAllByText('=');
|
||||
selectOptionInTest(operationSelect[index], operationLabel);
|
||||
await waitFor(() => expect(screen.getByText(operationLabel)).toBeInTheDocument());
|
||||
|
||||
const valueSelect = await screen.findByText('Value');
|
||||
await waitFor(() => user.click(valueSelect));
|
||||
|
||||
const query = `let ${property} = toscalar(union isfuzzy=true ${mockQuery.azureTraces?.traceTypes?.join(',')}
|
||||
| where $__timeFilter(timestamp)
|
||||
| summarize count=count() by ${property}
|
||||
| summarize make_list(pack_all()));
|
||||
print properties = bag_pack("${property}", ${property});`;
|
||||
|
||||
expect(mockDatasource.azureLogAnalyticsDatasource.query).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
requestId: 'azure-traces-properties-req',
|
||||
interval: '',
|
||||
intervalMs: 0,
|
||||
scopedVars: {},
|
||||
timezone: '',
|
||||
startTime: 0,
|
||||
app: CoreApp.Unknown,
|
||||
targets: [
|
||||
{
|
||||
...mockQuery,
|
||||
azureLogAnalytics: {
|
||||
resources: mockQuery.azureTraces?.resources,
|
||||
query,
|
||||
},
|
||||
queryType: AzureQueryType.LogAnalytics,
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
const values = [];
|
||||
for (const currFilter of filter.filters) {
|
||||
const label = `${currFilter.value} - (${currFilter.count})`;
|
||||
await waitFor(() => expect(screen.getByText(label)).toBeInTheDocument());
|
||||
selectOptionInTest(valueSelect, label);
|
||||
await waitFor(() => expect(screen.getByText(currFilter.value)).toBeInTheDocument());
|
||||
values.push(currFilter.value);
|
||||
}
|
||||
|
||||
if (mockQuery.azureTraces?.filters && mockQuery.azureTraces.filters.length === 0) {
|
||||
expect(onQueryChange).not.toHaveBeenCalled();
|
||||
}
|
||||
|
||||
const newQuery = setFilters(mockQuery, [
|
||||
...(mockQuery.azureTraces?.filters ?? []),
|
||||
{ property, operation, filters: values },
|
||||
]);
|
||||
await waitFor(() => {
|
||||
userEvent.type(valueSelect, '{Escape}');
|
||||
expect(onQueryChange).toHaveBeenCalledWith(newQuery);
|
||||
});
|
||||
|
||||
rerender(
|
||||
<Filters
|
||||
datasource={mockDatasource}
|
||||
onQueryChange={onQueryChange}
|
||||
query={newQuery}
|
||||
setError={jest.fn()}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
/>
|
||||
);
|
||||
|
||||
return newQuery;
|
||||
};
|
||||
|
||||
describe(`Traces Filters`, () => {
|
||||
beforeEach(() => {
|
||||
mockDatasource = createMockDatasource();
|
||||
user = userEvent.setup();
|
||||
});
|
||||
|
||||
it('should render a trace filter', async () => {
|
||||
let mockQuery = createMockQuery();
|
||||
mockQuery.azureTraces = {
|
||||
...mockQuery.azureTraces,
|
||||
filters: [
|
||||
{
|
||||
filters: ['test-filter'],
|
||||
operation: 'eq',
|
||||
property: 'test-property',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
render(
|
||||
<Filters
|
||||
subscriptionId="123"
|
||||
query={mockQuery}
|
||||
onQueryChange={onQueryChange}
|
||||
datasource={mockDatasource}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
setError={jest.fn()}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(screen.getByText('test-property')).toBeInTheDocument();
|
||||
expect(screen.getByText('=')).toBeInTheDocument();
|
||||
expect(screen.getByText('test-filter')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should add a trace filter', async () => {
|
||||
let mockQuery = createMockQuery({ azureTraces: { traceTypes: ['customEvents'] } });
|
||||
mockQuery.azureTraces = {
|
||||
...mockQuery.azureTraces,
|
||||
filters: undefined,
|
||||
};
|
||||
|
||||
const { rerender } = render(
|
||||
<Filters
|
||||
datasource={mockDatasource}
|
||||
onQueryChange={onQueryChange}
|
||||
query={mockQuery}
|
||||
setError={jest.fn()}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
/>
|
||||
);
|
||||
|
||||
await addFilter(
|
||||
mockQuery,
|
||||
{ property: 'appId', filters: [{ count: 10, value: 'test-app-id' }], operation: 'eq', index: 0 },
|
||||
rerender
|
||||
);
|
||||
});
|
||||
|
||||
it('should add multiple trace filters', async () => {
|
||||
let mockQuery = createMockQuery({ azureTraces: { traceTypes: ['customEvents'] } });
|
||||
mockQuery.azureTraces = {
|
||||
...mockQuery.azureTraces,
|
||||
filters: undefined,
|
||||
};
|
||||
|
||||
const { rerender } = render(
|
||||
<Filters
|
||||
datasource={mockDatasource}
|
||||
onQueryChange={onQueryChange}
|
||||
query={mockQuery}
|
||||
setError={jest.fn()}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
/>
|
||||
);
|
||||
|
||||
mockQuery = await addFilter(
|
||||
mockQuery,
|
||||
{ property: 'appId', filters: [{ count: 10, value: 'test-app-id' }], operation: 'eq', index: 0 },
|
||||
rerender
|
||||
);
|
||||
mockQuery = await addFilter(
|
||||
mockQuery,
|
||||
{ property: 'client_Browser', filters: [{ count: 100, value: 'test-client' }], operation: 'ne', index: 1 },
|
||||
rerender
|
||||
);
|
||||
});
|
||||
|
||||
it('should delete a trace filter', async () => {
|
||||
let mockQuery = createMockQuery({ azureTraces: { traceTypes: ['customEvents'] } });
|
||||
mockQuery.azureTraces = {
|
||||
...mockQuery.azureTraces,
|
||||
filters: undefined,
|
||||
};
|
||||
|
||||
const { rerender } = render(
|
||||
<Filters
|
||||
datasource={mockDatasource}
|
||||
onQueryChange={onQueryChange}
|
||||
query={mockQuery}
|
||||
setError={jest.fn()}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
/>
|
||||
);
|
||||
|
||||
mockQuery = await addFilter(
|
||||
mockQuery,
|
||||
{ property: 'appId', filters: [{ count: 10, value: 'test-app-id' }], operation: 'eq', index: 0 },
|
||||
rerender
|
||||
);
|
||||
mockQuery = await addFilter(
|
||||
mockQuery,
|
||||
{ property: 'client_Browser', filters: [{ count: 100, value: 'test-client' }], operation: 'ne', index: 1 },
|
||||
rerender
|
||||
);
|
||||
|
||||
const removeButtons = screen.getAllByLabelText('Remove');
|
||||
|
||||
mockQuery = {
|
||||
...mockQuery,
|
||||
azureTraces: {
|
||||
...mockQuery.azureTraces,
|
||||
filters: mockQuery.azureTraces?.filters?.slice(0, 1),
|
||||
},
|
||||
};
|
||||
|
||||
await act(async () => {
|
||||
await userEvent.click(removeButtons[1]);
|
||||
});
|
||||
rerender(
|
||||
<Filters
|
||||
datasource={mockDatasource}
|
||||
onQueryChange={onQueryChange}
|
||||
query={mockQuery}
|
||||
setError={jest.fn()}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(screen.getByText('appId')).toBeInTheDocument();
|
||||
expect(screen.getByText('=')).toBeInTheDocument();
|
||||
expect(screen.getByText('test-app-id')).toBeInTheDocument();
|
||||
expect(screen.queryByText('client_Browser')).not.toBeInTheDocument();
|
||||
expect(screen.queryByText('!=')).not.toBeInTheDocument();
|
||||
expect(screen.queryByText('test-client')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should add a trace filter and select multiple values', async () => {
|
||||
let mockQuery = createMockQuery({ azureTraces: { traceTypes: ['customEvents'] } });
|
||||
mockQuery.azureTraces = {
|
||||
...mockQuery.azureTraces,
|
||||
filters: undefined,
|
||||
};
|
||||
|
||||
const { rerender } = render(
|
||||
<Filters
|
||||
datasource={mockDatasource}
|
||||
onQueryChange={onQueryChange}
|
||||
query={mockQuery}
|
||||
setError={jest.fn()}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
/>
|
||||
);
|
||||
|
||||
await addFilter(
|
||||
mockQuery,
|
||||
{
|
||||
property: 'appId',
|
||||
filters: [
|
||||
{ count: 10, value: 'test-app-id' },
|
||||
{ count: 20, value: 'test-app-id-2' },
|
||||
],
|
||||
operation: 'eq',
|
||||
index: 0,
|
||||
},
|
||||
rerender
|
||||
);
|
||||
});
|
||||
|
||||
it('should remove a value from a trace filter with multiple values', async () => {
|
||||
let mockQuery = createMockQuery({ azureTraces: { traceTypes: ['customEvents'] } });
|
||||
mockQuery.azureTraces = {
|
||||
...mockQuery.azureTraces,
|
||||
filters: undefined,
|
||||
};
|
||||
|
||||
const { rerender } = render(
|
||||
<Filters
|
||||
datasource={mockDatasource}
|
||||
onQueryChange={onQueryChange}
|
||||
query={mockQuery}
|
||||
setError={jest.fn()}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
/>
|
||||
);
|
||||
|
||||
mockQuery = await addFilter(
|
||||
mockQuery,
|
||||
{
|
||||
property: 'appId',
|
||||
filters: [
|
||||
{ count: 10, value: 'test-app-id' },
|
||||
{ count: 20, value: 'test-app-id-2' },
|
||||
],
|
||||
operation: 'eq',
|
||||
index: 0,
|
||||
},
|
||||
rerender
|
||||
);
|
||||
|
||||
const currFilter = mockQuery.azureTraces?.filters![0]!;
|
||||
mockQuery = {
|
||||
...mockQuery,
|
||||
azureTraces: {
|
||||
...mockQuery.azureTraces,
|
||||
filters: [
|
||||
{
|
||||
...currFilter,
|
||||
filters: currFilter.filters.slice(0, 1),
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
const removeLabel = screen.getByLabelText(`Remove test-app-id-2`);
|
||||
await act(async () => {
|
||||
await userEvent.click(removeLabel);
|
||||
});
|
||||
|
||||
rerender(
|
||||
<Filters
|
||||
datasource={mockDatasource}
|
||||
onQueryChange={onQueryChange}
|
||||
query={mockQuery}
|
||||
setError={jest.fn()}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(screen.getByText('appId')).toBeInTheDocument();
|
||||
expect(screen.getByText('=')).toBeInTheDocument();
|
||||
expect(screen.getByText('test-app-id')).toBeInTheDocument();
|
||||
expect(screen.queryByText('test-app-id-2')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
@ -0,0 +1,95 @@
|
||||
import { uniq } from 'lodash';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
|
||||
import { SelectableValue, TimeRange } from '@grafana/data';
|
||||
import { EditorList } from '@grafana/experimental';
|
||||
import { Field } from '@grafana/ui';
|
||||
|
||||
import { AzureQueryEditorFieldProps, AzureTracesFilter } from '../../types';
|
||||
|
||||
import { makeRenderItem } from './Filter';
|
||||
import { tablesSchema } from './consts';
|
||||
import { setFilters } from './setQueryValue';
|
||||
|
||||
const Filters = ({ query, datasource, onQueryChange, variableOptionGroup }: AzureQueryEditorFieldProps) => {
|
||||
const { azureTraces } = query;
|
||||
const queryTraceTypes = azureTraces?.traceTypes ? azureTraces.traceTypes : Object.keys(tablesSchema);
|
||||
|
||||
const excludedProperties = new Set([
|
||||
'customDimensions',
|
||||
'customMeasurements',
|
||||
'details',
|
||||
'duration',
|
||||
'id',
|
||||
'itemId',
|
||||
'operation_Id',
|
||||
'operation_ParentId',
|
||||
'timestamp',
|
||||
]);
|
||||
const properties = uniq(queryTraceTypes.map((type) => Object.keys(tablesSchema[type])).flat()).filter(
|
||||
(item) => !excludedProperties.has(item)
|
||||
);
|
||||
|
||||
const [propertyMap, setPropertyMap] = useState(new Map<string, Array<SelectableValue<string>>>());
|
||||
const queryFilters = useMemo(() => query.azureTraces?.filters ?? [], [query.azureTraces?.filters]);
|
||||
const [filters, updateFilters] = useState(queryFilters);
|
||||
|
||||
const timeSrv = datasource.azureLogAnalyticsDatasource.timeSrv;
|
||||
const [timeRange, setTimeRange] = useState(timeSrv.timeRange());
|
||||
|
||||
const useTime = (time: TimeRange) => {
|
||||
if (
|
||||
timeRange !== null &&
|
||||
(timeRange.raw.from.toString() !== time.raw.from.toString() ||
|
||||
timeRange.raw.to.toString() !== time.raw.to.toString())
|
||||
) {
|
||||
setTimeRange({ ...time });
|
||||
}
|
||||
};
|
||||
useTime(timeSrv.timeRange());
|
||||
|
||||
useEffect(() => {
|
||||
setPropertyMap(new Map<string, Array<SelectableValue<string>>>());
|
||||
}, [timeRange, query.azureTraces?.resources, query.azureTraces?.traceTypes, query.azureTraces?.operationId]);
|
||||
|
||||
const changedFunc = (changed: Array<Partial<AzureTracesFilter>>) => {
|
||||
let updateQuery = false;
|
||||
const properData: AzureTracesFilter[] = changed.map((x) => {
|
||||
if (x.property !== '' && x.filters && x.filters.length > 0 && x.operation !== '') {
|
||||
updateQuery = true;
|
||||
} else {
|
||||
updateQuery = false;
|
||||
}
|
||||
return {
|
||||
property: x.property ?? '',
|
||||
filters: x.filters ?? [],
|
||||
operation: x.operation ?? 'eq',
|
||||
};
|
||||
});
|
||||
updateFilters(properData);
|
||||
if (updateQuery || (queryFilters.length > 0 && properData.length === 0)) {
|
||||
onQueryChange(setFilters(query, properData));
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Field label="Filters">
|
||||
<EditorList
|
||||
items={filters}
|
||||
onChange={changedFunc}
|
||||
renderItem={makeRenderItem({
|
||||
query,
|
||||
datasource,
|
||||
propertyMap,
|
||||
setPropertyMap,
|
||||
timeRange,
|
||||
queryTraceTypes,
|
||||
properties,
|
||||
variableOptionGroup,
|
||||
})}
|
||||
/>
|
||||
</Field>
|
||||
);
|
||||
};
|
||||
|
||||
export default Filters;
|
@ -0,0 +1,64 @@
|
||||
import { render, screen, act } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { openMenu } from 'react-select-event';
|
||||
|
||||
import createMockDatasource from '../../__mocks__/datasource';
|
||||
import createMockQuery from '../../__mocks__/query';
|
||||
import { selectors } from '../../e2e/selectors';
|
||||
|
||||
import TraceTypeField from './TraceTypeField';
|
||||
import { Tables } from './consts';
|
||||
import { setTraceTypes } from './setQueryValue';
|
||||
|
||||
const props = {
|
||||
query: createMockQuery(),
|
||||
datasource: createMockDatasource(),
|
||||
variableOptionGroup: { label: 'Templates', options: [] },
|
||||
onQueryChange: jest.fn(),
|
||||
setError: jest.fn(),
|
||||
};
|
||||
|
||||
describe('TraceTypeField', () => {
|
||||
it('should render with default types', async () => {
|
||||
const query = {
|
||||
...props.query,
|
||||
azureTraces: {
|
||||
...props.query.azureTraces,
|
||||
traceTypes: [],
|
||||
},
|
||||
};
|
||||
render(<TraceTypeField {...props} query={query} />);
|
||||
expect(screen.getByText('Choose event types')).toBeInTheDocument();
|
||||
|
||||
const menu = screen.getByLabelText(selectors.components.queryEditor.tracesQueryEditor.traceTypes.select);
|
||||
openMenu(menu);
|
||||
|
||||
Object.values(Tables).forEach((table) => {
|
||||
expect(screen.getByText(table.label)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it('should render the value defined in the query', async () => {
|
||||
render(<TraceTypeField {...props} />);
|
||||
expect(screen.getByText('Traces')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should update the query', async () => {
|
||||
const { rerender } = render(<TraceTypeField {...props} />);
|
||||
|
||||
expect(screen.getByText('Traces')).toBeInTheDocument();
|
||||
|
||||
const menu = screen.getByLabelText(selectors.components.queryEditor.tracesQueryEditor.traceTypes.select);
|
||||
|
||||
openMenu(menu);
|
||||
act(() => {
|
||||
screen.getByText('Dependencies').click();
|
||||
});
|
||||
|
||||
const newQuery = setTraceTypes(props.query, [...props.query.azureTraces?.traceTypes!, 'dependencies']);
|
||||
|
||||
expect(props.onQueryChange).toHaveBeenCalledWith(newQuery);
|
||||
rerender(<TraceTypeField {...props} query={newQuery} />);
|
||||
expect(screen.getByText('Dependencies')).toBeInTheDocument();
|
||||
});
|
||||
});
|
@ -0,0 +1,49 @@
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { MultiSelect } from '@grafana/ui';
|
||||
|
||||
import { selectors } from '../../e2e/selectors';
|
||||
import { AzureQueryEditorFieldProps, AzureMonitorOption } from '../../types';
|
||||
import { findOptions } from '../../utils/common';
|
||||
import { Field } from '../Field';
|
||||
|
||||
import { Tables } from './consts';
|
||||
import { setTraceTypes } from './setQueryValue';
|
||||
|
||||
const TraceTypeField = ({ query, variableOptionGroup, onQueryChange }: AzureQueryEditorFieldProps) => {
|
||||
const tables: AzureMonitorOption[] = Object.entries(Tables).map(([key, value]) => ({
|
||||
label: value.label,
|
||||
description: value.description,
|
||||
value: key,
|
||||
}));
|
||||
const handleChange = useCallback(
|
||||
(change: Array<SelectableValue<string>>) => {
|
||||
const newQuery = setTraceTypes(
|
||||
query,
|
||||
change.map((type) => type.value ?? '')
|
||||
);
|
||||
onQueryChange(newQuery);
|
||||
},
|
||||
[onQueryChange, query]
|
||||
);
|
||||
|
||||
const options = useMemo(() => [...tables, variableOptionGroup], [tables, variableOptionGroup]);
|
||||
|
||||
return (
|
||||
<Field label="Event Type">
|
||||
<MultiSelect
|
||||
placeholder="Choose event types"
|
||||
inputId="azure-monitor-traces-type-field"
|
||||
value={findOptions([...tables, ...variableOptionGroup.options], query.azureTraces?.traceTypes ?? [])}
|
||||
onChange={handleChange}
|
||||
options={options}
|
||||
allowCustomValue
|
||||
isClearable
|
||||
aria-label={selectors.components.queryEditor.tracesQueryEditor.traceTypes.select}
|
||||
/>
|
||||
</Field>
|
||||
);
|
||||
};
|
||||
|
||||
export default TraceTypeField;
|
@ -0,0 +1,187 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import React from 'react';
|
||||
|
||||
import createMockDatasource from '../../__mocks__/datasource';
|
||||
import createMockQuery from '../../__mocks__/query';
|
||||
import { createMockResourcePickerData } from '../MetricsQueryEditor/MetricsQueryEditor.test';
|
||||
|
||||
import TracesQueryEditor from './TracesQueryEditor';
|
||||
|
||||
jest.mock('@grafana/runtime', () => ({
|
||||
...jest.requireActual('@grafana/runtime'),
|
||||
getTemplateSrv: () => ({
|
||||
replace: (val: string) => {
|
||||
return val;
|
||||
},
|
||||
}),
|
||||
}));
|
||||
|
||||
const variableOptionGroup = {
|
||||
label: 'Template variables',
|
||||
options: [],
|
||||
};
|
||||
|
||||
describe('TracesQueryEditor', () => {
|
||||
const originalScrollIntoView = window.HTMLElement.prototype.scrollIntoView;
|
||||
|
||||
beforeEach(() => {
|
||||
window.HTMLElement.prototype.scrollIntoView = function () {};
|
||||
});
|
||||
afterEach(() => {
|
||||
window.HTMLElement.prototype.scrollIntoView = originalScrollIntoView;
|
||||
});
|
||||
|
||||
it('should select multiple resources', async () => {
|
||||
const mockDatasource = createMockDatasource({ resourcePickerData: createMockResourcePickerData() });
|
||||
const query = createMockQuery();
|
||||
delete query?.subscription;
|
||||
delete query?.azureTraces?.resources;
|
||||
const onChange = jest.fn();
|
||||
|
||||
render(
|
||||
<TracesQueryEditor
|
||||
query={query}
|
||||
datasource={mockDatasource}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
onChange={onChange}
|
||||
setError={() => {}}
|
||||
/>
|
||||
);
|
||||
|
||||
const resourcePickerButton = await screen.findByRole('button', { name: 'Select a resource' });
|
||||
await userEvent.click(resourcePickerButton);
|
||||
|
||||
const subscriptionButton = await screen.findByRole('button', { name: 'Expand Primary Subscription' });
|
||||
await userEvent.click(subscriptionButton);
|
||||
|
||||
const resourceGroupButton = await screen.findByRole('button', { name: 'Expand A Great Resource Group' });
|
||||
await userEvent.click(resourceGroupButton);
|
||||
|
||||
const checkbox = await screen.findByLabelText('app-insights-1');
|
||||
await userEvent.click(checkbox);
|
||||
expect(checkbox).toBeChecked();
|
||||
|
||||
const checkbox2 = await screen.findByLabelText('app-insights-2');
|
||||
await userEvent.click(checkbox2);
|
||||
expect(checkbox2).toBeChecked();
|
||||
|
||||
await userEvent.click(await screen.findByRole('button', { name: 'Apply' }));
|
||||
|
||||
expect(onChange).toBeCalledWith(
|
||||
expect.objectContaining({
|
||||
azureTraces: expect.objectContaining({
|
||||
resources: [
|
||||
'/subscriptions/def-456/resourceGroups/dev-3/providers/microsoft.insights/components/app-insights-1',
|
||||
'/subscriptions/def-456/resourceGroups/dev-3/providers/microsoft.insights/components/app-insights-2',
|
||||
],
|
||||
}),
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('should disable other resource types when selecting multiple resources', async () => {
|
||||
const mockDatasource = createMockDatasource({ resourcePickerData: createMockResourcePickerData() });
|
||||
const query = createMockQuery();
|
||||
delete query?.subscription;
|
||||
delete query?.azureTraces?.resources;
|
||||
const onChange = jest.fn();
|
||||
|
||||
render(
|
||||
<TracesQueryEditor
|
||||
query={query}
|
||||
datasource={mockDatasource}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
onChange={onChange}
|
||||
setError={() => {}}
|
||||
/>
|
||||
);
|
||||
|
||||
const resourcePickerButton = await screen.findByRole('button', { name: 'Select a resource' });
|
||||
await userEvent.click(resourcePickerButton);
|
||||
|
||||
const subscriptionButton = await screen.findByRole('button', { name: 'Expand Primary Subscription' });
|
||||
await userEvent.click(subscriptionButton);
|
||||
|
||||
const resourceGroupButton = await screen.findByRole('button', { name: 'Expand A Great Resource Group' });
|
||||
await userEvent.click(resourceGroupButton);
|
||||
|
||||
const checkbox = await screen.findByLabelText('app-insights-1');
|
||||
await userEvent.click(checkbox);
|
||||
expect(checkbox).toBeChecked();
|
||||
|
||||
expect(await screen.findByLabelText('web-server_DataDisk')).toBeDisabled();
|
||||
});
|
||||
|
||||
it('should show info about multiple selection', async () => {
|
||||
const mockDatasource = createMockDatasource({ resourcePickerData: createMockResourcePickerData() });
|
||||
const query = createMockQuery();
|
||||
delete query?.subscription;
|
||||
delete query?.azureTraces?.resources;
|
||||
const onChange = jest.fn();
|
||||
|
||||
render(
|
||||
<TracesQueryEditor
|
||||
query={query}
|
||||
datasource={mockDatasource}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
onChange={onChange}
|
||||
setError={() => {}}
|
||||
/>
|
||||
);
|
||||
|
||||
const resourcePickerButton = await screen.findByRole('button', { name: 'Select a resource' });
|
||||
await userEvent.click(resourcePickerButton);
|
||||
|
||||
const subscriptionButton = await screen.findByRole('button', { name: 'Expand Primary Subscription' });
|
||||
await userEvent.click(subscriptionButton);
|
||||
|
||||
const resourceGroupButton = await screen.findByRole('button', { name: 'Expand A Great Resource Group' });
|
||||
await userEvent.click(resourceGroupButton);
|
||||
|
||||
const checkbox = await screen.findByLabelText('app-insights-1');
|
||||
await userEvent.click(checkbox);
|
||||
expect(checkbox).toBeChecked();
|
||||
|
||||
expect(await screen.findByText('You may only choose items of the same resource type.')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should call onApply with a new subscription uri when a user types it in the selection box', async () => {
|
||||
const mockDatasource = createMockDatasource({ resourcePickerData: createMockResourcePickerData() });
|
||||
const query = createMockQuery();
|
||||
delete query?.subscription;
|
||||
delete query?.azureTraces?.resources;
|
||||
const onChange = jest.fn();
|
||||
|
||||
render(
|
||||
<TracesQueryEditor
|
||||
query={query}
|
||||
datasource={mockDatasource}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
onChange={onChange}
|
||||
setError={() => {}}
|
||||
/>
|
||||
);
|
||||
|
||||
const resourcePickerButton = await screen.findByRole('button', { name: 'Select a resource' });
|
||||
await userEvent.click(resourcePickerButton);
|
||||
|
||||
const advancedSection = screen.getByText('Advanced');
|
||||
await userEvent.click(advancedSection);
|
||||
|
||||
const advancedInput = await screen.findByTestId('input-advanced-resource-picker-1');
|
||||
|
||||
await userEvent.type(advancedInput, '/subscriptions/def-123');
|
||||
|
||||
const applyButton = screen.getByRole('button', { name: 'Apply' });
|
||||
await userEvent.click(applyButton);
|
||||
|
||||
expect(onChange).toBeCalledWith(
|
||||
expect.objectContaining({
|
||||
azureTraces: expect.objectContaining({
|
||||
resources: ['/subscriptions/def-123'],
|
||||
}),
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
@ -0,0 +1,163 @@
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { usePrevious } from 'react-use';
|
||||
|
||||
import { EditorFieldGroup, EditorRow, EditorRows } from '@grafana/experimental';
|
||||
import { Input } from '@grafana/ui';
|
||||
|
||||
import Datasource from '../../datasource';
|
||||
import { selectors } from '../../e2e/selectors';
|
||||
import { AzureMonitorErrorish, AzureMonitorOption, AzureMonitorQuery, ResultFormat } from '../../types';
|
||||
import { Field } from '../Field';
|
||||
import FormatAsField from '../FormatAsField';
|
||||
import AdvancedResourcePicker from '../LogsQueryEditor/AdvancedResourcePicker';
|
||||
import ResourceField from '../ResourceField';
|
||||
import { ResourceRow, ResourceRowGroup, ResourceRowType } from '../ResourcePicker/types';
|
||||
import { parseResourceDetails } from '../ResourcePicker/utils';
|
||||
|
||||
import Filters from './Filters';
|
||||
import TraceTypeField from './TraceTypeField';
|
||||
import { setFormatAs, setQueryOperationId } from './setQueryValue';
|
||||
|
||||
interface TracesQueryEditorProps {
|
||||
query: AzureMonitorQuery;
|
||||
datasource: Datasource;
|
||||
subscriptionId?: string;
|
||||
onChange: (newQuery: AzureMonitorQuery) => void;
|
||||
variableOptionGroup: { label: string; options: AzureMonitorOption[] };
|
||||
setError: (source: string, error: AzureMonitorErrorish | undefined) => void;
|
||||
}
|
||||
|
||||
const TracesQueryEditor = ({
|
||||
query,
|
||||
datasource,
|
||||
subscriptionId,
|
||||
variableOptionGroup,
|
||||
onChange,
|
||||
setError,
|
||||
}: TracesQueryEditorProps) => {
|
||||
const disableRow = (row: ResourceRow, selectedRows: ResourceRowGroup) => {
|
||||
if (selectedRows.length === 0) {
|
||||
// Only if there is some resource(s) selected we should disable rows
|
||||
return false;
|
||||
}
|
||||
const rowResourceNS = parseResourceDetails(row.uri, row.location).metricNamespace?.toLowerCase();
|
||||
const selectedRowSampleNs = parseResourceDetails(
|
||||
selectedRows[0].uri,
|
||||
selectedRows[0].location
|
||||
).metricNamespace?.toLowerCase();
|
||||
// Only resources with the same metricNamespace can be selected
|
||||
return rowResourceNS !== selectedRowSampleNs;
|
||||
};
|
||||
|
||||
const [operationId, setOperationId] = useState<string>(query.azureTraces?.operationId ?? '');
|
||||
const previousOperationId = usePrevious(query.azureTraces?.operationId);
|
||||
|
||||
useEffect(() => {
|
||||
if (query.azureTraces?.operationId) {
|
||||
if (previousOperationId !== query.azureTraces.operationId) {
|
||||
setOperationId(query.azureTraces.operationId);
|
||||
}
|
||||
}
|
||||
}, [setOperationId, previousOperationId, query, operationId]);
|
||||
|
||||
const handleChange = useCallback((ev: React.FormEvent) => {
|
||||
if (ev.target instanceof HTMLInputElement) {
|
||||
setOperationId(ev.target.value);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleBlur = useCallback(
|
||||
(ev: React.FormEvent) => {
|
||||
const newQuery = setQueryOperationId(query, operationId);
|
||||
onChange(newQuery);
|
||||
},
|
||||
[onChange, operationId, query]
|
||||
);
|
||||
|
||||
return (
|
||||
<span data-testid={selectors.components.queryEditor.tracesQueryEditor.container.input}>
|
||||
<EditorRows>
|
||||
<EditorRow>
|
||||
<EditorFieldGroup>
|
||||
<ResourceField
|
||||
query={query}
|
||||
datasource={datasource}
|
||||
subscriptionId={subscriptionId}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
onQueryChange={onChange}
|
||||
setError={setError}
|
||||
selectableEntryTypes={[
|
||||
ResourceRowType.Subscription,
|
||||
ResourceRowType.ResourceGroup,
|
||||
ResourceRowType.Resource,
|
||||
ResourceRowType.Variable,
|
||||
]}
|
||||
resources={query.azureTraces?.resources ?? []}
|
||||
queryType="traces"
|
||||
disableRow={disableRow}
|
||||
renderAdvanced={(resources, onChange) => (
|
||||
// It's required to cast resources because the resource picker
|
||||
// specifies the type to string | AzureMonitorResource.
|
||||
// eslint-disable-next-line
|
||||
<AdvancedResourcePicker resources={resources as string[]} onChange={onChange} />
|
||||
)}
|
||||
selectionNotice={() => 'You may only choose items of the same resource type.'}
|
||||
/>
|
||||
</EditorFieldGroup>
|
||||
</EditorRow>
|
||||
<EditorRow>
|
||||
<EditorFieldGroup>
|
||||
<TraceTypeField
|
||||
datasource={datasource}
|
||||
onQueryChange={onChange}
|
||||
query={query}
|
||||
setError={setError}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
/>
|
||||
<Field label="Operation ID">
|
||||
<Input
|
||||
id="azure-monitor-traces-operation-id-field"
|
||||
value={operationId}
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
width={40}
|
||||
/>
|
||||
</Field>
|
||||
</EditorFieldGroup>
|
||||
</EditorRow>
|
||||
<EditorRow>
|
||||
<EditorFieldGroup>
|
||||
<Filters
|
||||
datasource={datasource}
|
||||
onQueryChange={onChange}
|
||||
query={query}
|
||||
setError={setError}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
/>
|
||||
</EditorFieldGroup>
|
||||
</EditorRow>
|
||||
<EditorRow>
|
||||
<EditorFieldGroup>
|
||||
<FormatAsField
|
||||
datasource={datasource}
|
||||
setError={setError}
|
||||
query={query}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
onQueryChange={onChange}
|
||||
inputId="azure-monitor-traces"
|
||||
options={[
|
||||
{ label: 'Table', value: ResultFormat.Table },
|
||||
{ label: 'Trace', value: ResultFormat.Trace },
|
||||
]}
|
||||
defaultValue={ResultFormat.Table}
|
||||
setFormatAs={setFormatAs}
|
||||
resultFormat={query.azureTraces?.resultFormat}
|
||||
/>
|
||||
</EditorFieldGroup>
|
||||
</EditorRow>
|
||||
</EditorRows>
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
export default TracesQueryEditor;
|
@ -0,0 +1,167 @@
|
||||
import { omit } from 'lodash';
|
||||
|
||||
export const Tables = {
|
||||
availabilityResults: { label: 'Availablity Results', description: 'Availability test results.' },
|
||||
dependencies: {
|
||||
label: 'Dependencies',
|
||||
description: 'Calls your application makes to other services such as databases or REST APIs.',
|
||||
},
|
||||
customEvents: { label: 'Custom Events', description: 'Calls to TrackEvent that are inserted to monitor usage.' },
|
||||
exceptions: {
|
||||
label: 'Exceptions',
|
||||
description: 'Exceptions that are logged via TrackException, or uncaught exceptions.',
|
||||
},
|
||||
pageViews: { label: 'Page Views', description: 'Web client telemetry to create page view reports.' },
|
||||
requests: { label: 'Requests', description: 'HTTP requests received by the application.' },
|
||||
traces: {
|
||||
label: 'Traces',
|
||||
description:
|
||||
'Diagnostic logs emitted using TrackTrace and similar methods. Note: Traces are not visualised if the result format is set to Trace',
|
||||
},
|
||||
};
|
||||
|
||||
// Resource centric tables mapped to legacy tables
|
||||
export const tables = {
|
||||
AppAvailabilityResults: 'availabilityResults',
|
||||
AppDependencies: 'dependencies',
|
||||
AppEvents: 'events',
|
||||
AppExceptions: 'exceptions',
|
||||
AppPageViews: 'pageViews',
|
||||
AppRequests: 'requests',
|
||||
AppTraces: 'traces',
|
||||
};
|
||||
|
||||
// Properties to omit when generating the attributes bag
|
||||
export const attributesOmit = [
|
||||
'operationId',
|
||||
'duration',
|
||||
'id',
|
||||
'name',
|
||||
'problemId',
|
||||
'operation_ParentId',
|
||||
'timestamp',
|
||||
'customDimensions',
|
||||
'operation_Name',
|
||||
];
|
||||
|
||||
// Common resource centric properties mapped to legacy property names
|
||||
export const common = {
|
||||
appId: 'ResourceGUID',
|
||||
application_Version: 'AppVersion',
|
||||
appName: '_ResourceId',
|
||||
client_Browser: 'ClientBrowser',
|
||||
client_City: 'ClientCity',
|
||||
client_CountryOrRegion: 'ClientCountryOrRegion',
|
||||
client_IP: 'ClientIP',
|
||||
client_Model: 'ClientModel',
|
||||
client_OS: 'ClientOS',
|
||||
client_StateOrProvince: 'ClientStateOrProvince',
|
||||
client_Type: 'ClientType',
|
||||
cloud_RoleInstance: 'AppRoleInstance',
|
||||
cloud_RoleName: 'AppRoleName',
|
||||
customDimensions: 'Properties',
|
||||
customMeasurements: 'Measurements',
|
||||
duration: 'DurationMs',
|
||||
id: 'Id',
|
||||
iKey: 'IKey',
|
||||
itemCount: 'ItemCount',
|
||||
itemId: '_ItemId',
|
||||
itemType: 'Type',
|
||||
name: 'Name',
|
||||
operation_Id: 'OperationId',
|
||||
operation_Name: 'OperationName',
|
||||
operation_ParentId: 'OperationParentId',
|
||||
operation_SyntheticSource: 'OperationSyntheticSource',
|
||||
performanceBucket: 'PerformanceBucket',
|
||||
sdkVersion: 'SDKVersion',
|
||||
session_Id: 'SessionId',
|
||||
success: 'Success',
|
||||
timestamp: 'TimeGenerated',
|
||||
user_AccountId: 'UserAccountId',
|
||||
user_AuthenticatedId: 'UserAuthenticatedId',
|
||||
user_Id: 'UserId',
|
||||
};
|
||||
|
||||
// Additional properties for availabilityResults
|
||||
export const availabilityResultsSchema = {
|
||||
...common,
|
||||
location: 'Location',
|
||||
message: 'Message',
|
||||
size: 'Size',
|
||||
};
|
||||
|
||||
// Additional properties for dependencies
|
||||
export const dependenciesSchema = {
|
||||
...common,
|
||||
data: 'Data',
|
||||
resultCode: 'ResultCode',
|
||||
target: 'Target',
|
||||
type: 'DependencyType',
|
||||
};
|
||||
|
||||
// Additional properties for events
|
||||
export const eventsSchema = omit(common, ['duration', 'id', 'success', 'performanceBucket']);
|
||||
|
||||
// Additional properties for pageVies
|
||||
export const pageViewsSchema = omit(
|
||||
{
|
||||
...common,
|
||||
url: 'Url',
|
||||
},
|
||||
['success']
|
||||
);
|
||||
|
||||
// Additional properties for requests
|
||||
export const requestsSchema = {
|
||||
resultCode: 'ResultCode',
|
||||
source: 'Source',
|
||||
url: 'Url',
|
||||
};
|
||||
|
||||
// Additional properties for exceptions
|
||||
export const exceptionsSchema = omit(
|
||||
{
|
||||
...common,
|
||||
assembly: 'Assembly',
|
||||
details: 'Details',
|
||||
handledAt: 'HandledAt',
|
||||
innermostAssembly: 'InnermostAssembly',
|
||||
innermostMessage: 'InnermostMessage',
|
||||
innermostMethod: 'InnermostMethod',
|
||||
innermostType: 'InnermostType',
|
||||
message: 'Message',
|
||||
method: 'Method',
|
||||
outerAssembly: 'OuterAssembly',
|
||||
outerMessage: 'OuterMessage',
|
||||
outerMethod: 'OuterMethod',
|
||||
outerType: 'OuterType',
|
||||
problemId: 'ProblemId',
|
||||
severityLevel: 'SeverityLevel',
|
||||
type: 'ExceptionType',
|
||||
},
|
||||
['duration', 'id', 'name', 'performanceBucket', 'success']
|
||||
);
|
||||
|
||||
// Additional properties for traces
|
||||
export const tracesSchema = omit(
|
||||
{
|
||||
message: 'Message',
|
||||
severityLevel: 'SeverityLevel',
|
||||
},
|
||||
['duration', 'id', 'name', 'performanceBucket', 'success']
|
||||
);
|
||||
|
||||
export const tablesSchema: { [key: string]: { [key: string]: string } } = {
|
||||
availabilityResults: availabilityResultsSchema,
|
||||
dependencies: dependenciesSchema,
|
||||
customEvents: eventsSchema,
|
||||
exceptions: exceptionsSchema,
|
||||
pageViews: pageViewsSchema,
|
||||
requests: requestsSchema,
|
||||
traces: tracesSchema,
|
||||
};
|
||||
|
||||
export const tableTags = Object.entries(tablesSchema).reduce(
|
||||
(val, [k, v]) => ({ ...val, [k]: Object.keys(omit(v, attributesOmit)).join(',') }),
|
||||
{}
|
||||
);
|
@ -0,0 +1 @@
|
||||
export { default } from './TracesQueryEditor';
|
@ -0,0 +1,41 @@
|
||||
import { AzureMonitorQuery, AzureTracesFilter, ResultFormat } from '../../types';
|
||||
|
||||
export function setQueryOperationId(query: AzureMonitorQuery, operationId?: string): AzureMonitorQuery {
|
||||
return {
|
||||
...query,
|
||||
azureTraces: {
|
||||
...query.azureTraces,
|
||||
operationId,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function setFormatAs(query: AzureMonitorQuery, formatAs: ResultFormat): AzureMonitorQuery {
|
||||
return {
|
||||
...query,
|
||||
azureTraces: {
|
||||
...query.azureTraces,
|
||||
resultFormat: formatAs,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function setTraceTypes(query: AzureMonitorQuery, traceTypes: string[]): AzureMonitorQuery {
|
||||
return {
|
||||
...query,
|
||||
azureTraces: {
|
||||
...query.azureTraces,
|
||||
traceTypes,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function setFilters(query: AzureMonitorQuery, filters: AzureTracesFilter[]): AzureMonitorQuery {
|
||||
return {
|
||||
...query,
|
||||
azureTraces: {
|
||||
...query.azureTraces,
|
||||
filters,
|
||||
},
|
||||
};
|
||||
}
|
@ -43,6 +43,8 @@ composableKinds: DataQuery: {
|
||||
azureLogAnalytics?: #AzureLogsQuery
|
||||
// Azure Resource Graph sub-query properties.
|
||||
azureResourceGraph?: #AzureResourceGraphQuery
|
||||
// Application Insights Traces sub-query properties.
|
||||
azureTraces?: #AzureTracesQuery
|
||||
// @deprecated Legacy template variable support.
|
||||
grafanaTemplateVariableFn?: #GrafanaTemplateVariableQuery
|
||||
|
||||
@ -56,7 +58,7 @@ composableKinds: DataQuery: {
|
||||
} @cuetsy(kind="interface") @grafana(TSVeneer="type")
|
||||
|
||||
// Defines the supported queryTypes. GrafanaTemplateVariableFn is deprecated
|
||||
#AzureQueryType: "Azure Monitor" | "Azure Log Analytics" | "Azure Resource Graph" | "Azure Subscriptions" | "Azure Resource Groups" | "Azure Namespaces" | "Azure Resource Names" | "Azure Metric Names" | "Azure Workspaces" | "Azure Regions" | "Grafana Template Variable Function" @cuetsy(kind="enum", memberNames="AzureMonitor|LogAnalytics|AzureResourceGraph|SubscriptionsQuery|ResourceGroupsQuery|NamespacesQuery|ResourceNamesQuery|MetricNamesQuery|WorkspacesQuery|LocationsQuery|GrafanaTemplateVariableFn")
|
||||
#AzureQueryType: "Azure Monitor" | "Azure Log Analytics" | "Azure Resource Graph" | "Azure Traces" | "Azure Subscriptions" | "Azure Resource Groups" | "Azure Namespaces" | "Azure Resource Names" | "Azure Metric Names" | "Azure Workspaces" | "Azure Regions" | "Grafana Template Variable Function" @cuetsy(kind="enum", memberNames="AzureMonitor|LogAnalytics|AzureResourceGraph|AzureTraces|SubscriptionsQuery|ResourceGroupsQuery|NamespacesQuery|ResourceNamesQuery|MetricNamesQuery|WorkspacesQuery|LocationsQuery|GrafanaTemplateVariableFn")
|
||||
|
||||
#AzureMetricQuery: {
|
||||
// Array of resource URIs to be queried.
|
||||
@ -121,7 +123,32 @@ composableKinds: DataQuery: {
|
||||
resource?: string
|
||||
} @cuetsy(kind="interface")
|
||||
|
||||
#ResultFormat: "table" | "time_series" @cuetsy(kind="enum", memberNames="Table|TimeSeries")
|
||||
// Application Insights Traces sub-query properties
|
||||
#AzureTracesQuery: {
|
||||
// Specifies the format results should be returned as.
|
||||
resultFormat?: #ResultFormat
|
||||
// Array of resource URIs to be queried.
|
||||
resources?: [...string]
|
||||
// Operation ID. Used only for Traces queries.
|
||||
operationId?: string
|
||||
// Types of events to filter by.
|
||||
traceTypes?: [...string]
|
||||
// Filters for property values.
|
||||
filters?: [...#AzureTracesFilter]
|
||||
// KQL query to be executed.
|
||||
query?: string
|
||||
} @cuetsy(kind="interface")
|
||||
|
||||
#AzureTracesFilter: {
|
||||
// Property name, auto-populated based on available traces.
|
||||
property: string
|
||||
// Comparison operator to use. Either equals or not equals.
|
||||
operation: string
|
||||
// Values to filter by.
|
||||
filters: [...string]
|
||||
} @cuetsy(kind="interface")
|
||||
|
||||
#ResultFormat: "table" | "time_series" | "trace" @cuetsy(kind="enum", memberNames="Table|TimeSeries|Trace")
|
||||
|
||||
#AzureResourceGraphQuery: {
|
||||
// Azure Resource Graph KQL query to be executed.
|
||||
|
@ -25,6 +25,10 @@ export interface AzureMonitorQuery extends common.DataQuery {
|
||||
* Azure Resource Graph sub-query properties.
|
||||
*/
|
||||
azureResourceGraph?: AzureResourceGraphQuery;
|
||||
/**
|
||||
* Application Insights Traces sub-query properties.
|
||||
*/
|
||||
azureTraces?: AzureTracesQuery;
|
||||
/**
|
||||
* @deprecated Legacy template variable support.
|
||||
*/
|
||||
@ -60,6 +64,7 @@ export const defaultAzureMonitorQuery: Partial<AzureMonitorQuery> = {
|
||||
export enum AzureQueryType {
|
||||
AzureMonitor = 'Azure Monitor',
|
||||
AzureResourceGraph = 'Azure Resource Graph',
|
||||
AzureTraces = 'Azure Traces',
|
||||
GrafanaTemplateVariableFn = 'Grafana Template Variable Function',
|
||||
LocationsQuery = 'Azure Regions',
|
||||
LogAnalytics = 'Azure Log Analytics',
|
||||
@ -184,9 +189,65 @@ export const defaultAzureLogsQuery: Partial<AzureLogsQuery> = {
|
||||
resources: [],
|
||||
};
|
||||
|
||||
/**
|
||||
* Application Insights Traces sub-query properties
|
||||
*/
|
||||
export interface AzureTracesQuery {
|
||||
/**
|
||||
* Filters for property values.
|
||||
*/
|
||||
filters?: Array<AzureTracesFilter>;
|
||||
/**
|
||||
* Operation ID. Used only for Traces queries.
|
||||
*/
|
||||
operationId?: string;
|
||||
/**
|
||||
* KQL query to be executed.
|
||||
*/
|
||||
query?: string;
|
||||
/**
|
||||
* Array of resource URIs to be queried.
|
||||
*/
|
||||
resources?: Array<string>;
|
||||
/**
|
||||
* Specifies the format results should be returned as.
|
||||
*/
|
||||
resultFormat?: ResultFormat;
|
||||
/**
|
||||
* Types of events to filter by.
|
||||
*/
|
||||
traceTypes?: Array<string>;
|
||||
}
|
||||
|
||||
export const defaultAzureTracesQuery: Partial<AzureTracesQuery> = {
|
||||
filters: [],
|
||||
resources: [],
|
||||
traceTypes: [],
|
||||
};
|
||||
|
||||
export interface AzureTracesFilter {
|
||||
/**
|
||||
* Values to filter by.
|
||||
*/
|
||||
filters: Array<string>;
|
||||
/**
|
||||
* Comparison operator to use. Either equals or not equals.
|
||||
*/
|
||||
operation: string;
|
||||
/**
|
||||
* Property name, auto-populated based on available traces.
|
||||
*/
|
||||
property: string;
|
||||
}
|
||||
|
||||
export const defaultAzureTracesFilter: Partial<AzureTracesFilter> = {
|
||||
filters: [],
|
||||
};
|
||||
|
||||
export enum ResultFormat {
|
||||
Table = 'table',
|
||||
TimeSeries = 'time_series',
|
||||
Trace = 'trace',
|
||||
}
|
||||
|
||||
export interface AzureResourceGraphQuery {
|
||||
|
@ -90,7 +90,8 @@ export default class Datasource extends DataSourceWithBackend<AzureMonitorQuery,
|
||||
}
|
||||
|
||||
const observables: Array<Observable<DataQueryResponse>> = Array.from(byType.entries()).map(([queryType, req]) => {
|
||||
const ds = this.pseudoDatasource[queryType];
|
||||
const mappedQueryType = queryType === AzureQueryType.AzureTraces ? AzureQueryType.LogAnalytics : queryType;
|
||||
const ds = this.pseudoDatasource[mappedQueryType];
|
||||
if (!ds) {
|
||||
throw new Error('Data source not created for query type ' + queryType);
|
||||
}
|
||||
@ -183,7 +184,8 @@ export default class Datasource extends DataSourceWithBackend<AzureMonitorQuery,
|
||||
return query;
|
||||
}
|
||||
|
||||
const ds = this.pseudoDatasource[query.queryType];
|
||||
const queryType = query.queryType === AzureQueryType.AzureTraces ? AzureQueryType.LogAnalytics : query.queryType;
|
||||
const ds = this.pseudoDatasource[queryType];
|
||||
return {
|
||||
datasource: ds?.getRef(),
|
||||
...(ds?.applyTemplateVariables(query, scopedVars) ?? query),
|
||||
@ -213,6 +215,9 @@ function hasQueryForType(query: AzureMonitorQuery): boolean {
|
||||
case AzureQueryType.AzureResourceGraph:
|
||||
return !!query.azureResourceGraph;
|
||||
|
||||
case AzureQueryType.AzureTraces:
|
||||
return !!query.azureTraces;
|
||||
|
||||
case AzureQueryType.GrafanaTemplateVariableFn:
|
||||
return !!query.grafanaTemplateVariableFn;
|
||||
|
||||
|
@ -61,11 +61,13 @@ export const components = {
|
||||
},
|
||||
},
|
||||
metricsQueryEditor: {
|
||||
container: { input: 'data-testid azure-monitor-metrics-query-editor-with-experimental-ui' },
|
||||
metricName: {
|
||||
input: 'data-testid metric-name',
|
||||
},
|
||||
},
|
||||
logsQueryEditor: {
|
||||
container: { input: 'data-testid azure-monitor-logs-query-editor-with-experimental-ui' },
|
||||
formatSelection: {
|
||||
input: 'data-testid format-selection',
|
||||
},
|
||||
@ -78,6 +80,14 @@ export const components = {
|
||||
input: 'data-testid azure-monitor-args-subscription',
|
||||
},
|
||||
},
|
||||
tracesQueryEditor: {
|
||||
container: {
|
||||
input: 'data-testid azure-monitor-traces-query-editor-with-experimental-ui',
|
||||
},
|
||||
traceTypes: {
|
||||
select: 'data-testid azure-monitor-traces-query-editor-trace-types',
|
||||
},
|
||||
},
|
||||
},
|
||||
variableEditor: {
|
||||
queryType: {
|
||||
|
@ -32,7 +32,7 @@ const RESOURCE_GRAPH_URL = '/providers/Microsoft.ResourceGraph/resources?api-ver
|
||||
|
||||
const logsSupportedResourceTypesKusto = logsResourceTypes.map((v) => `"${v}"`).join(',');
|
||||
|
||||
export type ResourcePickerQueryType = 'logs' | 'metrics';
|
||||
export type ResourcePickerQueryType = 'logs' | 'metrics' | 'traces';
|
||||
|
||||
export default class ResourcePickerData extends DataSourceWithBackend<AzureMonitorQuery, AzureDataSourceJsonData> {
|
||||
private resourcePath: string;
|
||||
|
@ -5,8 +5,10 @@ export {
|
||||
AzureMetricQuery,
|
||||
AzureLogsQuery,
|
||||
AzureResourceGraphQuery,
|
||||
AzureTracesQuery,
|
||||
AzureMonitorResource,
|
||||
AzureMetricDimension,
|
||||
AzureTracesFilter,
|
||||
ResultFormat,
|
||||
} from '../dataquery.gen';
|
||||
|
||||
|
@ -3,12 +3,13 @@ import {
|
||||
DataSourceJsonData,
|
||||
DataSourceSettings,
|
||||
PanelData,
|
||||
SelectableValue,
|
||||
TableData,
|
||||
} from '@grafana/data';
|
||||
|
||||
import Datasource from '../datasource';
|
||||
|
||||
import { AzureMonitorQuery } from './query';
|
||||
import { AzureMonitorQuery, ResultFormat } from './query';
|
||||
|
||||
export type AzureDataSourceSettings = DataSourceSettings<AzureDataSourceJsonData, AzureDataSourceSecureJsonData>;
|
||||
export type AzureDataSourceInstanceSettings = DataSourceInstanceSettings<AzureDataSourceJsonData>;
|
||||
@ -170,6 +171,14 @@ export interface AzureQueryEditorFieldProps {
|
||||
setError: (source: string, error: AzureMonitorErrorish | undefined) => void;
|
||||
}
|
||||
|
||||
export interface FormatAsFieldProps extends AzureQueryEditorFieldProps {
|
||||
inputId: string;
|
||||
options: Array<SelectableValue<ResultFormat>>;
|
||||
defaultValue: ResultFormat;
|
||||
setFormatAs: (query: AzureMonitorQuery, formatAs: ResultFormat) => AzureMonitorQuery;
|
||||
resultFormat?: ResultFormat;
|
||||
}
|
||||
|
||||
export interface AzureResourceSummaryItem {
|
||||
subscriptionName: string;
|
||||
resourceGroupName: string | undefined;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { map } from 'lodash';
|
||||
|
||||
import { rangeUtil } from '@grafana/data';
|
||||
import { rangeUtil, SelectableValue } from '@grafana/data';
|
||||
import { VariableWithMultiSupport } from 'app/features/variables/types';
|
||||
|
||||
import TimegrainConverter from '../time_grain_converter';
|
||||
@ -23,7 +23,7 @@ export const findOptions = (options: AzureMonitorOption[], values: string[] = []
|
||||
export const toOption = (v: { text: string; value: string }) => ({ value: v.value, label: v.text });
|
||||
|
||||
export const addValueToOptions = (
|
||||
values: AzureMonitorOption[],
|
||||
values: Array<AzureMonitorOption | SelectableValue>,
|
||||
variableOptionGroup: VariableOptionGroup,
|
||||
value?: string
|
||||
) => {
|
||||
|
Loading…
Reference in New Issue
Block a user