import _ from 'lodash' ; import { QueryCtrl } from 'grafana/app/plugins/sdk' ; import './css/query_editor.css' ; import TimegrainConverter from './time_grain_converter' ; import './monaco/kusto_monaco_editor' ; export interface ResultFormat { text : string ; value : string ; } export class AzureMonitorQueryCtrl extends QueryCtrl { static templateUrl = 'partials/query.editor.html' ; defaultDropdownValue = 'select' ; defaults = { queryType : 'Azure Monitor' , azureMonitor : { resourceGroup : this . defaultDropdownValue , metricDefinition : this . defaultDropdownValue , resourceName : this . defaultDropdownValue , metricName : this . defaultDropdownValue , dimensionFilter : '*' , timeGrain : 'auto' , } , azureLogAnalytics : { query : [ '//change this example to create your own time series query' , '<table name>                                                              ' + '//the table to query (e.g. Usage, Heartbeat, Perf)' , '| where $__timeFilter(TimeGenerated)                                      ' + '//this is a macro used to show the full chart’s time range, choose the datetime column here' , '| summarize count() by <group by column>, bin(TimeGenerated, $__interval) ' + '//change “group by column” to a column in your table, such as “Computer”. ' + 'The $__interval macro is used to auto-select the time grain. Can also use 1h, 5m etc.' , '| order by TimeGenerated asc' , ] . join ( '\n' ) , resultFormat : 'time_series' , workspace : this . datasource && this . datasource . azureLogAnalyticsDatasource ? this . datasource . azureLogAnalyticsDatasource . defaultOrFirstWorkspace : '' , } , appInsights : { metricName : this . defaultDropdownValue , rawQuery : false , rawQueryString : '' , groupBy : 'none' , timeGrainType : 'auto' , xaxis : 'timestamp' , yaxis : '' , spliton : '' , } , } ; resultFormats : ResultFormat [ ] ; workspaces : any [ ] ; showHelp : boolean ; showLastQuery : boolean ; lastQuery : string ; lastQueryError ? : string ; ngInject constructor ( $scope , $injector , private templateSrv ) { super ( $scope , $injector ) ; _ . defaultsDeep ( this . target , this . defaults ) ; this . migrateTimeGrains ( ) ; this . panelCtrl . events . on ( 'data-received' , this . onDataReceived . bind ( this ) , $scope ) ; this . panelCtrl . events . on ( 'data-error' , this . onDataError . bind ( this ) , $scope ) ; this . resultFormats = [ { text : 'Time series' , value : 'time_series' } , { text : 'Table' , value : 'table' } ] ; if ( this . target . queryType === 'Azure Log Analytics' ) { this . getWorkspaces ( ) ; } } onDataReceived ( dataList ) { this . lastQueryError = undefined ; this . lastQuery = '' ; const anySeriesFromQuery = _ . find ( dataList , { refId : this . target . refId } ) ; if ( anySeriesFromQuery ) { this . lastQuery = anySeriesFromQuery . query ; } } onDataError ( err ) { this . handleQueryCtrlError ( err ) ; } handleQueryCtrlError ( err ) { if ( err . query && err . query . refId && err . query . refId !== this . target . refId ) { return ; } if ( err . error && err . error . data && err . error . data . error && err . error . data . error . innererror ) { if ( err . error . data . error . innererror . innererror ) { this . lastQueryError = err . error . data . error . innererror . innererror . message ; } else { this . lastQueryError = err . error . data . error . innererror . message ; } } else if ( err . error && err . error . data && err . error . data . error ) { this . lastQueryError = err . error . data . error . message ; } else if ( err . error && err . error . data ) { this . lastQueryError = err . error . data . message ; } else if ( err . data && err . data . error ) { this . lastQueryError = err . data . error . message ; } else if ( err . data && err . data . message ) { this . lastQueryError = err . data . message ; } else { this . lastQueryError = err ; } } migrateTimeGrains ( ) { if ( this . target . azureMonitor . timeGrainUnit ) { if ( this . target . azureMonitor . timeGrain !== 'auto' ) { this . target . azureMonitor . timeGrain = TimegrainConverter . createISO8601Duration ( this . target . azureMonitor . timeGrain , this . target . azureMonitor . timeGrainUnit ) ; } delete this . target . azureMonitor . timeGrainUnit ; this . onMetricNameChange ( ) ; } } replace ( variable ) { return this . templateSrv . replace ( variable , this . panelCtrl . panel . scopedVars ) ; } onQueryTypeChange ( ) { if ( this . target . queryType === 'Azure Log Analytics' ) { return this . getWorkspaces ( ) ; } } getResourceGroups ( query ) { if ( this . target . queryType !== 'Azure Monitor' || ! this . datasource . azureMonitorDatasource . isConfigured ( ) ) { return ; } return this . datasource . getResourceGroups ( ) . catch ( this . handleQueryCtrlError . bind ( this ) ) ; } getMetricDefinitions ( query ) { if ( this . target . queryType !== 'Azure Monitor' || ! this . target . azureMonitor . resourceGroup || this . target . azureMonitor . resourceGroup === this . defaultDropdownValue ) { return ; } return this . datasource . getMetricDefinitions ( this . replace ( this . target . azureMonitor . resourceGroup ) ) . catch ( this . handleQueryCtrlError . bind ( this ) ) ; } getResourceNames ( query ) { if ( this . target . queryType !== 'Azure Monitor' || ! this . target . azureMonitor . resourceGroup || this . target . azureMonitor . resourceGroup === this . defaultDropdownValue || ! this . target . azureMonitor . metricDefinition || this . target . azureMonitor . metricDefinition === this . defaultDropdownValue ) { return ; } return this . datasource . getResourceNames ( this . replace ( this . target . azureMonitor . resourceGroup ) , this . replace ( this . target . azureMonitor . metricDefinition ) ) . catch ( this . handleQueryCtrlError . bind ( this ) ) ; } getMetricNames ( query ) { if ( this . target . queryType !== 'Azure Monitor' || ! this . target . azureMonitor . resourceGroup || this . target . azureMonitor . resourceGroup === this . defaultDropdownValue || ! this . target . azureMonitor . metricDefinition || this . target . azureMonitor . metricDefinition === this . defaultDropdownValue || ! this . target . azureMonitor . resourceName || this . target . azureMonitor . resourceName === this . defaultDropdownValue ) { return ; } return this . datasource . getMetricNames ( this . replace ( this . target . azureMonitor . resourceGroup ) , this . replace ( this . target . azureMonitor . metricDefinition ) , this . replace ( this . target . azureMonitor . resourceName ) ) . catch ( this . handleQueryCtrlError . bind ( this ) ) ; } onResourceGroupChange ( ) { this . target . azureMonitor . metricDefinition = this . defaultDropdownValue ; this . target . azureMonitor . resourceName = this . defaultDropdownValue ; this . target . azureMonitor . metricName = this . defaultDropdownValue ; this . target . azureMonitor . dimensions = [ ] ; this . target . azureMonitor . dimension = '' ; } onMetricDefinitionChange ( ) { this . target . azureMonitor . resourceName = this . defaultDropdownValue ; this . target . azureMonitor . metricName = this . defaultDropdownValue ; this . target . azureMonitor . dimensions = [ ] ; this . target . azureMonitor . dimension = '' ; } onResourceNameChange ( ) { this . target . azureMonitor . metricName = this . defaultDropdownValue ; this . target . azureMonitor . dimensions = [ ] ; this . target . azureMonitor . dimension = '' ; } onMetricNameChange ( ) { if ( ! this . target . azureMonitor . metricName || this . target . azureMonitor . metricName === this . defaultDropdownValue ) { return ; } return this . datasource . getMetricMetadata ( this . replace ( this . target . azureMonitor . resourceGroup ) , this . replace ( this . target . azureMonitor . metricDefinition ) , this . replace ( this . target . azureMonitor . resourceName ) , this . replace ( this . target . azureMonitor . metricName ) ) . then ( metadata => { this . target . azureMonitor . aggOptions = metadata . supportedAggTypes || [ metadata . primaryAggType ] ; this . target . azureMonitor . aggregation = metadata . primaryAggType ; this . target . azureMonitor . timeGrains = [ { text : 'auto' , value : 'auto' } ] . concat ( metadata . supportedTimeGrains ) ; this . target . azureMonitor . dimensions = metadata . dimensions ; if ( metadata . dimensions . length > 0 ) { this . target . azureMonitor . dimension = metadata . dimensions [ 0 ] . value ; } return this . refresh ( ) ; } ) . catch ( this . handleQueryCtrlError . bind ( this ) ) ; } getAutoInterval ( ) { if ( this . target . azureMonitor . timeGrain === 'auto' ) { return TimegrainConverter . findClosestTimeGrain ( this . panelCtrl . interval , _ . map ( this . target . azureMonitor . timeGrains , o => TimegrainConverter . createKbnUnitFromISO8601Duration ( o . value ) ) || [ '1m' , '5m' , '15m' , '30m' , '1h' , '6h' , '12h' , '1d' ] ) ; } return '' ; } getWorkspaces ( ) { return this . datasource . azureLogAnalyticsDatasource . getWorkspaces ( ) . then ( list => { this . workspaces = list ; if ( list . length > 0 && ! this . target . azureLogAnalytics . workspace ) { this . target . azureLogAnalytics . workspace = list [ 0 ] . value ; } } ) . catch ( this . handleQueryCtrlError . bind ( this ) ) ; } getAzureLogAnalyticsSchema ( ) { return this . getWorkspaces ( ) . then ( ( ) => { return this . datasource . azureLogAnalyticsDatasource . getSchema ( this . target . azureLogAnalytics . workspace ) ; } ) . catch ( this . handleQueryCtrlError . bind ( this ) ) ; } getAppInsightsAutoInterval ( ) { if ( this . panelCtrl . interval [ this . panelCtrl . interval . length - 1 ] === 's' ) { return '1m' ; } return this . panelCtrl . interval ; } getAppInsightsMetricNames ( ) { if ( ! this . datasource . appInsightsDatasource . isConfigured ( ) ) { return ; } return this . datasource . getAppInsightsMetricNames ( ) . catch ( this . handleQueryCtrlError . bind ( this ) ) ; } getAppInsightsColumns ( ) { return this . datasource . getAppInsightsColumns ( this . target . refId ) ; } onAppInsightsColumnChange ( ) { return this . refresh ( ) ; } onAppInsightsMetricNameChange ( ) { if ( ! this . target . appInsights . metricName || this . target . appInsights . metricName === this . defaultDropdownValue ) { return ; } return this . datasource . getAppInsightsMetricMetadata ( this . replace ( this . target . appInsights . metricName ) ) . then ( aggData => { this . target . appInsights . aggOptions = aggData . supportedAggTypes ; this . target . appInsights . groupByOptions = aggData . supportedGroupBy ; this . target . appInsights . aggregation = aggData . primaryAggType ; return this . refresh ( ) ; } ) . catch ( this . handleQueryCtrlError . bind ( this ) ) ; } getAppInsightsGroupBySegments ( query ) { return _ . map ( this . target . appInsights . groupByOptions , option => { return { text : option , value : option } ; } ) ; } resetAppInsightsGroupBy ( ) { this . target . appInsights . groupBy = 'none' ; this . refresh ( ) ; } updateTimeGrainType ( ) { if ( this . target . appInsights . timeGrainType === 'specific' ) { this . target . appInsights . timeGrain = '1' ; this . target . appInsights . timeGrainUnit = 'minute' ; } else { this . target . appInsights . timeGrain = '' ; } this . refresh ( ) ; } toggleEditorMode ( ) { this . target . appInsights . rawQuery = ! this . target . appInsights . rawQuery ; } }