mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
CloudWatch Logs: Add Monaco-based query field editor behind feature flag (#71799)
This commit is contained in:
parent
142cbc2ec6
commit
4c42632ab8
@ -3638,9 +3638,6 @@ exports[`better eslint`] = {
|
||||
"public/app/plugins/datasource/cloudwatch/components/ConfigEditor.test.tsx:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
],
|
||||
"public/app/plugins/datasource/cloudwatch/components/LogsQueryEditor.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
"public/app/plugins/datasource/cloudwatch/components/LogsQueryField.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
|
@ -3,6 +3,7 @@ import { css } from '@emotion/css';
|
||||
import React, { memo } from 'react';
|
||||
|
||||
import { AbsoluteTimeRange, QueryEditorProps } from '@grafana/data';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { InlineFormLabel } from '@grafana/ui';
|
||||
|
||||
import { CloudWatchDatasource } from '../datasource';
|
||||
@ -10,6 +11,7 @@ import { CloudWatchJsonData, CloudWatchLogsQuery, CloudWatchQuery } from '../typ
|
||||
|
||||
import { CloudWatchLink } from './CloudWatchLink';
|
||||
import CloudWatchLogsQueryField from './LogsQueryField';
|
||||
import CloudWatchLogsQueryFieldMonaco from './LogsQueryField/LogsQueryField';
|
||||
|
||||
type Props = QueryEditorProps<CloudWatchDatasource, CloudWatchQuery, CloudWatchJsonData> & {
|
||||
query: CloudWatchLogsQuery;
|
||||
@ -37,7 +39,16 @@ export const CloudWatchLogsQueryEditor = memo(function CloudWatchLogsQueryEditor
|
||||
};
|
||||
}
|
||||
|
||||
return (
|
||||
return config.featureToggles.cloudWatchLogsMonacoEditor ? (
|
||||
<CloudWatchLogsQueryFieldMonaco
|
||||
{...props}
|
||||
ExtraFieldElement={
|
||||
<InlineFormLabel className={`gf-form-label--btn ${labelClass}`} width="auto" tooltip="Link to Graph in AWS">
|
||||
<CloudWatchLink query={query} panelData={data} datasource={datasource} />
|
||||
</InlineFormLabel>
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<CloudWatchLogsQueryField
|
||||
{...props}
|
||||
exploreId={exploreId}
|
||||
@ -45,7 +56,7 @@ export const CloudWatchLogsQueryEditor = memo(function CloudWatchLogsQueryEditor
|
||||
absoluteRange={absolute}
|
||||
ExtraFieldElement={
|
||||
<InlineFormLabel className={`gf-form-label--btn ${labelClass}`} width="auto" tooltip="Link to Graph in AWS">
|
||||
<CloudWatchLink query={query as CloudWatchLogsQuery} panelData={data} datasource={datasource} />
|
||||
<CloudWatchLink query={query} panelData={data} datasource={datasource} />
|
||||
</InlineFormLabel>
|
||||
}
|
||||
/>
|
||||
|
@ -0,0 +1,108 @@
|
||||
import type * as monacoType from 'monaco-editor/esm/vs/editor/editor.api';
|
||||
import React, { ReactNode, useCallback } from 'react';
|
||||
|
||||
import { QueryEditorProps } from '@grafana/data';
|
||||
import { CodeEditor, Monaco, Themeable2, withTheme2 } from '@grafana/ui';
|
||||
|
||||
import { CloudWatchDatasource } from '../../datasource';
|
||||
import language from '../../language/logs/definition';
|
||||
import { TRIGGER_SUGGEST } from '../../language/monarch/commands';
|
||||
import { registerLanguage } from '../../language/monarch/register';
|
||||
import { CloudWatchJsonData, CloudWatchLogsQuery, CloudWatchQuery } from '../../types';
|
||||
import { getStatsGroups } from '../../utils/query/getStatsGroups';
|
||||
|
||||
import { LogGroupsField } from './../LogGroups/LogGroupsField';
|
||||
|
||||
export interface CloudWatchLogsQueryFieldProps
|
||||
extends QueryEditorProps<CloudWatchDatasource, CloudWatchQuery, CloudWatchJsonData>,
|
||||
Themeable2 {
|
||||
ExtraFieldElement?: ReactNode;
|
||||
query: CloudWatchLogsQuery;
|
||||
}
|
||||
export const CloudWatchLogsQueryFieldMonaco = (props: CloudWatchLogsQueryFieldProps) => {
|
||||
const { query, datasource, onChange, ExtraFieldElement, data } = props;
|
||||
|
||||
const showError = data?.error?.refId === query.refId;
|
||||
|
||||
const onChangeQuery = useCallback(
|
||||
(value: string) => {
|
||||
const nextQuery = {
|
||||
...query,
|
||||
expression: value,
|
||||
statsGroups: getStatsGroups(value),
|
||||
};
|
||||
onChange(nextQuery);
|
||||
},
|
||||
[onChange, query]
|
||||
);
|
||||
const onEditorMount = useCallback(
|
||||
(editor: monacoType.editor.IStandaloneCodeEditor, monaco: Monaco) => {
|
||||
editor.onDidFocusEditorText(() => editor.trigger(TRIGGER_SUGGEST.id, TRIGGER_SUGGEST.id, {}));
|
||||
editor.addCommand(monaco.KeyMod.Shift | monaco.KeyCode.Enter, () => {
|
||||
const text = editor.getValue();
|
||||
onChangeQuery(text);
|
||||
});
|
||||
},
|
||||
[onChangeQuery]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<LogGroupsField
|
||||
region={query.region}
|
||||
datasource={datasource}
|
||||
legacyLogGroupNames={query.logGroupNames}
|
||||
logGroups={query.logGroups}
|
||||
onChange={(logGroups) => {
|
||||
onChange({ ...query, logGroups, logGroupNames: undefined });
|
||||
}}
|
||||
/>
|
||||
<div className="gf-form-inline gf-form-inline--nowrap flex-grow-1">
|
||||
<div className="gf-form--grow flex-shrink-1">
|
||||
<CodeEditor
|
||||
height="150px"
|
||||
width="100%"
|
||||
showMiniMap={false}
|
||||
monacoOptions={{
|
||||
// without this setting, the auto-resize functionality causes an infinite loop, don't remove it!
|
||||
scrollBeyondLastLine: false,
|
||||
|
||||
// These additional options are style focused and are a subset of those in the query editor in Prometheus
|
||||
fontSize: 14,
|
||||
lineNumbers: 'off',
|
||||
renderLineHighlight: 'none',
|
||||
scrollbar: {
|
||||
vertical: 'hidden',
|
||||
horizontal: 'hidden',
|
||||
},
|
||||
suggestFontSize: 12,
|
||||
wordWrap: 'on',
|
||||
padding: {
|
||||
top: 6,
|
||||
},
|
||||
}}
|
||||
language={language.id}
|
||||
value={query.expression ?? ''}
|
||||
onBlur={(value) => {
|
||||
if (value !== query.expression) {
|
||||
onChangeQuery(value);
|
||||
}
|
||||
}}
|
||||
onBeforeEditorMount={(monaco: Monaco) =>
|
||||
registerLanguage(monaco, language, datasource.logsCompletionItemProvider)
|
||||
}
|
||||
onEditorDidMount={onEditorMount}
|
||||
/>
|
||||
</div>
|
||||
{ExtraFieldElement}
|
||||
</div>
|
||||
{showError ? (
|
||||
<div className="query-row-break">
|
||||
<div className="prom-query-field-info text-error">{data?.error?.message}</div>
|
||||
</div>
|
||||
) : null}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default withTheme2(CloudWatchLogsQueryFieldMonaco);
|
@ -22,6 +22,7 @@ import { DEFAULT_METRICS_QUERY, getDefaultLogsQuery } from './defaultQueries';
|
||||
import { isCloudWatchAnnotationQuery, isCloudWatchLogsQuery, isCloudWatchMetricsQuery } from './guards';
|
||||
import { CloudWatchLogsLanguageProvider } from './language/cloudwatch-logs/CloudWatchLogsLanguageProvider';
|
||||
import { SQLCompletionItemProvider } from './language/cloudwatch-sql/completion/CompletionItemProvider';
|
||||
import { LogsCompletionItemProvider } from './language/logs/completion/CompletionItemProvider';
|
||||
import { MetricMathCompletionItemProvider } from './language/metric-math/completion/CompletionItemProvider';
|
||||
import { CloudWatchAnnotationQueryRunner } from './query-runner/CloudWatchAnnotationQueryRunner';
|
||||
import { CloudWatchLogsQueryRunner } from './query-runner/CloudWatchLogsQueryRunner';
|
||||
@ -44,6 +45,7 @@ export class CloudWatchDatasource
|
||||
languageProvider: CloudWatchLogsLanguageProvider;
|
||||
sqlCompletionItemProvider: SQLCompletionItemProvider;
|
||||
metricMathCompletionItemProvider: MetricMathCompletionItemProvider;
|
||||
logsCompletionItemProvider: LogsCompletionItemProvider;
|
||||
defaultLogGroups?: string[];
|
||||
|
||||
type = 'cloudwatch';
|
||||
@ -65,6 +67,7 @@ export class CloudWatchDatasource
|
||||
this.sqlCompletionItemProvider = new SQLCompletionItemProvider(this.resources, this.templateSrv);
|
||||
this.metricMathCompletionItemProvider = new MetricMathCompletionItemProvider(this.resources, this.templateSrv);
|
||||
this.metricsQueryRunner = new CloudWatchMetricsQueryRunner(instanceSettings, templateSrv);
|
||||
this.logsCompletionItemProvider = new LogsCompletionItemProvider(this.resources, this.templateSrv);
|
||||
this.logsQueryRunner = new CloudWatchLogsQueryRunner(instanceSettings, templateSrv, timeSrv);
|
||||
this.annotationQueryRunner = new CloudWatchAnnotationQueryRunner(instanceSettings, templateSrv);
|
||||
this.variables = new CloudWatchVariableSupport(this.resources);
|
||||
|
Loading…
Reference in New Issue
Block a user