azuremonitor: use kusto editor for App Insights

This commit is contained in:
Alexander Zobnin 2019-02-04 18:51:56 +03:00
parent ad821cf629
commit dd8ca70151
No known key found for this signature in database
GPG Key ID: E17E9ABACEFA59EB
6 changed files with 91 additions and 9 deletions

View File

@ -224,4 +224,13 @@ export default class AppInsightsDatasource {
return new ResponseParser(result).parseGroupBys();
});
}
getQuerySchema() {
const url = `${this.baseUrl}/query/schema`;
return this.doRequest(url).then(result => {
const schema = new ResponseParser(result).parseQuerySchema();
// console.log(schema);
return schema;
});
}
}

View File

@ -199,6 +199,32 @@ export default class ResponseParser {
return ResponseParser.toTextValueList(this.results.supportedGroupBy);
}
parseQuerySchema() {
const result = {
Type: 'AppInsights',
Tables: {}
};
if (this.results && this.results.data && this.results.data.Tables) {
for (let i = 0; i < this.results.data.Tables[0].Rows.length; i++) {
const column = this.results.data.Tables[0].Rows[i];
const columnTable = column[0];
const columnName = column[1];
const columnType = column[2];
if (result.Tables[columnTable]) {
result.Tables[columnTable].OrderedColumns.push({ Name: columnName, Type: columnType });
} else {
result.Tables[columnTable] = {
Name: columnTable,
OrderedColumns: [
{ Name: columnName, Type: columnType }
]
};
}
}
}
return result;
}
static toTextValueList(values) {
const list: any[] = [];
for (let i = 0; i < values.length; i++) {

View File

@ -402,8 +402,11 @@ export default class KustoQueryField extends QueryField {
}
private async fetchSchema() {
const schema = await this.props.getSchema();
let schema = await this.props.getSchema();
if (schema) {
if (schema.Type === 'AppInsights') {
schema = castSchema(schema);
}
this.schema = schema;
} else {
this.schema = defaultSchema();
@ -411,6 +414,15 @@ export default class KustoQueryField extends QueryField {
}
}
/**
* Cast schema from App Insights to default Kusto schema
*/
function castSchema(schema) {
const defaultSchemaTemplate = defaultSchema();
defaultSchemaTemplate.Databases.Default = schema;
return defaultSchemaTemplate;
}
function normalizeQuery(query: string): string {
const commentPattern = /\/\/.*$/gm;
let normalizedQuery = query.replace(commentPattern, '');

View File

@ -4,7 +4,20 @@ import Kusto from './kusto/kusto';
import React, { Component } from 'react';
import coreModule from 'app/core/core_module';
class Editor extends Component<any, any> {
interface EditorProps {
index: number;
placeholder?: string;
change: (value: string, index: number) => void;
variables: () => string[] | string[];
getSchema?: () => Promise<any>;
execute?: () => void;
}
class Editor extends Component<EditorProps, any> {
static defaultProps = {
placeholder: 'Enter a query'
};
constructor(props) {
super(props);
this.state = {
@ -31,7 +44,7 @@ class Editor extends Component<any, any> {
};
render() {
const { request, variables, getSchema } = this.props;
const { variables, getSchema, placeholder } = this.props;
const { edited, query } = this.state;
return (
@ -42,8 +55,7 @@ class Editor extends Component<any, any> {
onQueryChange={this.onChangeQuery}
prismLanguage="kusto"
prismDefinition={Kusto}
placeholder="Enter a query"
request={request}
placeholder={placeholder}
templateVariables={variables}
getSchema={getSchema}
/>
@ -56,7 +68,7 @@ coreModule.directive('kustoEditor', [
'reactDirective',
reactDirective => {
return reactDirective(Editor, [
'change', 'database', 'execute', 'query', 'request', 'variables',
'change', 'database', 'execute', 'query', 'variables', 'placeholder',
['getSchema', { watchDepth: 'reference' }]
]);
},

View File

@ -124,8 +124,6 @@
<div class="gf-form gf-form--grow">
<kusto-editor
class="gf-form gf-form--grow"
request="ctrl.requestMetadata"
style="border: none"
query="ctrl.target.azureLogAnalytics.query"
change="ctrl.onLogAnalyticsQueryChange"
execute="ctrl.onLogAnalyticsQueryExecute"
@ -286,9 +284,20 @@
</div>
</div>
<div ng-show="ctrl.target.appInsights.rawQuery">
<div class="gf-form">
<!-- <div class="gf-form">
<textarea rows="3" class="gf-form-input" ng-model="ctrl.target.appInsights.rawQueryString" spellcheck="false"
placeholder="Application Insights Query" ng-model-onblur ng-change="ctrl.refresh()"></textarea>
</div> -->
<div class="gf-form gf-form--grow">
<kusto-editor
class="gf-form gf-form--grow"
query="ctrl.target.appInsights.rawQueryString"
placeholder="'Application Insights Query'"
change="ctrl.onAppInsightsQueryChange"
execute="ctrl.onAppInsightsQueryExecute"
variables="ctrl.templateVariables"
getSchema="ctrl.getAppInsightsQuerySchema"
/>
</div>
<div class="gf-form-inline">
<div class="gf-form">

View File

@ -345,6 +345,7 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
}
return interval;
}
getAppInsightsMetricNames() {
if (!this.datasource.appInsightsDatasource.isConfigured()) {
return;
@ -377,6 +378,19 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
.catch(this.handleQueryCtrlError.bind(this));
}
onAppInsightsQueryChange = (nextQuery: string) => {
this.target.appInsights.rawQueryString = nextQuery;
}
onAppInsightsQueryExecute = () => {
return this.refresh();
}
getAppInsightsQuerySchema = () => {
return this.datasource.appInsightsDatasource.getQuerySchema()
.catch(this.handleQueryCtrlError.bind(this));
}
getAppInsightsGroupBySegments(query) {
return _.map(this.target.appInsights.groupByOptions, option => {
return { text: option, value: option };