mirror of https://github.com/grafana/grafana.git
[release-12.0.5] Azure: Fix logs editor rendering (#109667)
* Azure: Fix logs editor rendering (#109491)
* Fix logs editor rendering
- Add test
* Type fixes
* Fix schema conditions and add test
* Fix lint
* Update public/app/plugins/datasource/azuremonitor/components/LogsQueryEditor/TimeManagement.tsx
Co-authored-by: Adam Yeats <16296989+adamyeats@users.noreply.github.com>
* Lint
---------
Co-authored-by: Adam Yeats <16296989+adamyeats@users.noreply.github.com>
(cherry picked from commit b34642b188
)
# Conflicts:
# public/app/plugins/datasource/azuremonitor/components/LogsQueryEditor/LogsQueryEditor.test.tsx
* Mock error and warn
This commit is contained in:
parent
560f875837
commit
ab1e43b8b9
|
@ -38,7 +38,7 @@ interface LogsQueryBuilderProps {
|
||||||
query: AzureMonitorQuery;
|
query: AzureMonitorQuery;
|
||||||
basicLogsEnabled: boolean;
|
basicLogsEnabled: boolean;
|
||||||
onQueryChange: (newQuery: AzureMonitorQuery) => void;
|
onQueryChange: (newQuery: AzureMonitorQuery) => void;
|
||||||
schema: EngineSchema;
|
schema?: EngineSchema;
|
||||||
templateVariableOptions: SelectableValue<string>;
|
templateVariableOptions: SelectableValue<string>;
|
||||||
datasource: Datasource;
|
datasource: Datasource;
|
||||||
timeRange?: TimeRange;
|
timeRange?: TimeRange;
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { dateTime, LoadingState } from '@grafana/data';
|
||||||
import createMockDatasource from '../../__mocks__/datasource';
|
import createMockDatasource from '../../__mocks__/datasource';
|
||||||
import createMockQuery from '../../__mocks__/query';
|
import createMockQuery from '../../__mocks__/query';
|
||||||
import { ResultFormat } from '../../dataquery.gen';
|
import { ResultFormat } from '../../dataquery.gen';
|
||||||
|
import { EngineSchema } from '../../types/types';
|
||||||
import { createMockResourcePickerData } from '../MetricsQueryEditor/MetricsQueryEditor.test';
|
import { createMockResourcePickerData } from '../MetricsQueryEditor/MetricsQueryEditor.test';
|
||||||
|
|
||||||
import LogsQueryEditor from './LogsQueryEditor';
|
import LogsQueryEditor from './LogsQueryEditor';
|
||||||
|
@ -628,4 +629,130 @@ describe('LogsQueryEditor', () => {
|
||||||
expect(onChange).toHaveBeenCalledWith(newQuery);
|
expect(onChange).toHaveBeenCalledWith(newQuery);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('schema loading and auto-completion', () => {
|
||||||
|
it('loads schema and table plans when resources change and builder mode is set', async () => {
|
||||||
|
// Mock these as we expect Kusto to complain about workers
|
||||||
|
jest.spyOn(console, 'warn').mockImplementation();
|
||||||
|
jest.spyOn(console, 'error').mockImplementation();
|
||||||
|
const mockSchema: EngineSchema = {
|
||||||
|
clusterType: 'Engine',
|
||||||
|
cluster: {
|
||||||
|
connectionString:
|
||||||
|
'/subscriptions/subscriptionId/resourceGroups/resourceGroup/providers/Microsoft.OperationalInsights/workspaces/la-workspace',
|
||||||
|
databases: [
|
||||||
|
{
|
||||||
|
name: '/subscriptions/subscriptionId/resourceGroups/resourceGroup/providers/Microsoft.OperationalInsights/workspaces/la-workspace',
|
||||||
|
tables: [
|
||||||
|
{
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
description: '',
|
||||||
|
isPreferredFacet: false,
|
||||||
|
name: 'TenantId',
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: 'Date and time when dependency call was recorded.',
|
||||||
|
isPreferredFacet: false,
|
||||||
|
name: 'TimeGenerated',
|
||||||
|
type: 'datetime',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: 'Application Insights dependencies.',
|
||||||
|
id: 'AppDependencies',
|
||||||
|
name: 'AppDependencies',
|
||||||
|
timespanColumn: 'TimeGenerated',
|
||||||
|
hasData: true,
|
||||||
|
related: {
|
||||||
|
solutions: [],
|
||||||
|
functions: [],
|
||||||
|
categories: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
functions: [],
|
||||||
|
majorVersion: 0,
|
||||||
|
minorVersion: 0,
|
||||||
|
entityGroups: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
database: {
|
||||||
|
name: '/subscriptions/subscriptionId/resourceGroups/resourceGroup/providers/Microsoft.OperationalInsights/workspaces/la-workspace',
|
||||||
|
tables: [
|
||||||
|
{
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
description: '',
|
||||||
|
isPreferredFacet: false,
|
||||||
|
name: 'TenantId',
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
description: 'Date and time when dependency call was recorded.',
|
||||||
|
isPreferredFacet: false,
|
||||||
|
name: 'TimeGenerated',
|
||||||
|
type: 'datetime',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: 'Application Insights dependencies.',
|
||||||
|
id: 'AppDependencies',
|
||||||
|
name: 'AppDependencies',
|
||||||
|
timespanColumn: 'TimeGenerated',
|
||||||
|
hasData: true,
|
||||||
|
related: {
|
||||||
|
solutions: [],
|
||||||
|
functions: [],
|
||||||
|
categories: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
functions: [],
|
||||||
|
majorVersion: 0,
|
||||||
|
minorVersion: 0,
|
||||||
|
entityGroups: [],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const mockDatasource = createMockDatasource();
|
||||||
|
mockDatasource.azureLogAnalyticsDatasource.getKustoSchema = jest.fn().mockResolvedValue(mockSchema);
|
||||||
|
// @ts-ignore: forcibly attach for test
|
||||||
|
mockDatasource.azureMonitorDatasource.getWorkspaceTablePlan = jest.fn().mockResolvedValue('plan');
|
||||||
|
const query = createMockQuery({
|
||||||
|
azureLogAnalytics: {
|
||||||
|
resources: [
|
||||||
|
'/subscriptions/def-456/resourceGroups/dev-3/providers/microsoft.operationalinsights/workspaces/la-workspace',
|
||||||
|
],
|
||||||
|
mode: require('../../dataquery.gen').LogsEditorMode.Builder,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const onChange = jest.fn();
|
||||||
|
const onQueryChange = jest.fn();
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
render(
|
||||||
|
<LogsQueryEditor
|
||||||
|
query={query}
|
||||||
|
datasource={mockDatasource}
|
||||||
|
variableOptionGroup={variableOptionGroup}
|
||||||
|
onChange={onChange}
|
||||||
|
onQueryChange={onQueryChange}
|
||||||
|
setError={() => {}}
|
||||||
|
basicLogsEnabled={true}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(mockDatasource.azureLogAnalyticsDatasource.getKustoSchema).toHaveBeenCalledWith(
|
||||||
|
query.azureLogAnalytics?.resources?.[0]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
expect(mockDatasource.azureMonitorDatasource.getWorkspaceTablePlan).toHaveBeenCalledTimes(1);
|
||||||
|
expect(mockDatasource.azureMonitorDatasource.getWorkspaceTablePlan).toHaveBeenCalledWith(
|
||||||
|
query.azureLogAnalytics?.resources,
|
||||||
|
'AppDependencies'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -112,11 +112,9 @@ const LogsQueryEditor = ({
|
||||||
if (schema.database?.tables) {
|
if (schema.database?.tables) {
|
||||||
schema.database.tables = t;
|
schema.database.tables = t;
|
||||||
}
|
}
|
||||||
setSchema(schema);
|
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
setSchema(schema);
|
|
||||||
}
|
}
|
||||||
|
setSchema(schema);
|
||||||
setIsLoadingSchema(false);
|
setIsLoadingSchema(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -285,7 +283,7 @@ const LogsQueryEditor = ({
|
||||||
!!config.featureToggles.azureMonitorLogsBuilderEditor ? (
|
!!config.featureToggles.azureMonitorLogsBuilderEditor ? (
|
||||||
<LogsQueryBuilder
|
<LogsQueryBuilder
|
||||||
query={query}
|
query={query}
|
||||||
schema={schema!}
|
schema={schema}
|
||||||
basicLogsEnabled={basicLogsEnabled}
|
basicLogsEnabled={basicLogsEnabled}
|
||||||
onQueryChange={onQueryChange}
|
onQueryChange={onQueryChange}
|
||||||
templateVariableOptions={templateVariableOptions}
|
templateVariableOptions={templateVariableOptions}
|
||||||
|
|
|
@ -60,6 +60,25 @@ describe('LogsQueryEditor.TimeManagement', () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should render correctly even if no tables are in the schema', async () => {
|
||||||
|
const mockDatasource = createMockDatasource();
|
||||||
|
const query = createMockQuery({ azureLogAnalytics: { timeColumn: undefined } });
|
||||||
|
const onChange = jest.fn();
|
||||||
|
|
||||||
|
render(
|
||||||
|
<TimeManagement
|
||||||
|
query={query}
|
||||||
|
datasource={mockDatasource}
|
||||||
|
variableOptionGroup={variableOptionGroup}
|
||||||
|
onQueryChange={onChange}
|
||||||
|
setError={() => {}}
|
||||||
|
schema={FakeSchemaData.getLogAnalyticsFakeEngineSchema([])}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(screen.getByText('Time-range')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
it('should render the default value if no time columns exist', async () => {
|
it('should render the default value if no time columns exist', async () => {
|
||||||
const mockDatasource = createMockDatasource();
|
const mockDatasource = createMockDatasource();
|
||||||
const query = createMockQuery();
|
const query = createMockQuery();
|
||||||
|
|
|
@ -20,7 +20,7 @@ export function TimeManagement({ query, onQueryChange: onChange, schema }: Azure
|
||||||
const timeColumnsSet: Set<string> = new Set();
|
const timeColumnsSet: Set<string> = new Set();
|
||||||
const defaultColumnsMap: Map<string, SelectableValue> = new Map();
|
const defaultColumnsMap: Map<string, SelectableValue> = new Map();
|
||||||
const db = schema.database;
|
const db = schema.database;
|
||||||
if (db) {
|
if (db && db?.tables?.length > 0) {
|
||||||
for (const table of db.tables) {
|
for (const table of db.tables) {
|
||||||
const cols = table.columns.reduce<SelectableValue[]>((prev, curr, i) => {
|
const cols = table.columns.reduce<SelectableValue[]>((prev, curr, i) => {
|
||||||
if (curr.type === 'datetime') {
|
if (curr.type === 'datetime') {
|
||||||
|
@ -39,11 +39,9 @@ export function TimeManagement({ query, onQueryChange: onChange, schema }: Azure
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
setTimeColumns(timeColumnOptions);
|
setTimeColumns(timeColumnOptions);
|
||||||
const defaultColumns = Array.from(defaultColumnsMap.values());
|
const defaultColumns = Array.from(defaultColumnsMap.values());
|
||||||
setDefaultTimeColumns(defaultColumns);
|
setDefaultTimeColumns(defaultColumns);
|
||||||
|
|
||||||
// Set default value
|
// Set default value
|
||||||
if (
|
if (
|
||||||
!query.azureLogAnalytics.timeColumn ||
|
!query.azureLogAnalytics.timeColumn ||
|
||||||
|
@ -64,6 +62,7 @@ export function TimeManagement({ query, onQueryChange: onChange, schema }: Azure
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}, [schema, query.azureLogAnalytics?.dashboardTime, query.azureLogAnalytics?.timeColumn, setDefaultColumn]);
|
}, [schema, query.azureLogAnalytics?.dashboardTime, query.azureLogAnalytics?.timeColumn, setDefaultColumn]);
|
||||||
|
|
||||||
const handleTimeColumnChange = useCallback(
|
const handleTimeColumnChange = useCallback(
|
||||||
|
|
Loading…
Reference in New Issue