[One Discover] Custom Service Name Cell (#192381)

closes https://github.com/elastic/kibana/issues/190456

## 📝  Summary

This PR adds the agent icon as a prefix to the service name if an agent
name is available.

## 🎥 Demo


https://github.com/user-attachments/assets/4fad743a-6806-4440-91eb-fdfa35785a19

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
mohamedhamed-ahmed 2024-09-15 18:28:04 +01:00 committed by GitHub
parent 4797dc4555
commit 7b3fa3ab10
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 622 additions and 224 deletions

View file

@ -8,6 +8,7 @@
*/
import { generateShortId } from '@kbn/apm-synthtrace-client';
import { ELASTIC_AGENT_NAMES } from '@kbn/elastic-agent-utils';
import { faker } from '@faker-js/faker';
import { randomInt } from 'crypto';
import moment from 'moment';
@ -65,6 +66,8 @@ export const getGeoCoordinate = (index?: number) => getAtIndexOrRandom(GEO_COORD
export const getCloudProvider = (index?: number) => getAtIndexOrRandom(CLOUD_PROVIDERS, index);
export const getCloudRegion = (index?: number) => getAtIndexOrRandom(CLOUD_REGION, index);
export const getServiceName = (index?: number) => getAtIndexOrRandom(SERVICE_NAMES, index);
export const getAgentName = (index?: number) => getAtIndexOrRandom(ELASTIC_AGENT_NAMES, index);
export const getJavaLog = () =>
`${moment().format('YYYY-MM-DD HH:mm:ss,SSS')} ${getAtIndexOrRandom(
LOG_LEVELS

View file

@ -19,6 +19,7 @@ import {
getCluster,
getCloudProvider,
getCloudRegion,
getAgentName,
} from './helpers/logs_mock_data';
import { parseLogsScenarioOpts } from './helpers/logs_scenario_opts_parser';
@ -44,7 +45,7 @@ const scenario: Scenario<LogDocument> = async (runOptions) => {
const commonLongEntryFields: LogDocument = {
'trace.id': generateShortId(),
'agent.name': 'nodejs',
'agent.name': getAgentName(),
'orchestrator.cluster.name': clusterName,
'orchestrator.cluster.id': clusterId,
'orchestrator.namespace': namespace,
@ -82,7 +83,6 @@ const scenario: Scenario<LogDocument> = async (runOptions) => {
.fill(0)
.map(() => {
const {
serviceName,
logMessage: { level, message },
commonLongEntryFields,
} = constructLogsCommonData();
@ -91,7 +91,6 @@ const scenario: Scenario<LogDocument> = async (runOptions) => {
.create({ isLogsDb })
.message(message.replace('<random>', generateShortId()))
.logLevel(level)
.service(serviceName)
.setGeoLocation(getGeoCoordinate())
.setHostIp(getIpAddress())
.defaults(commonLongEntryFields)

View file

@ -9,6 +9,7 @@
"@kbn/datemath",
"@kbn/apm-synthtrace-client",
"@kbn/dev-utils",
"@kbn/elastic-agent-utils",
],
"exclude": [
"target/**/*",

View file

@ -66,3 +66,5 @@ export const DEFAULT_ALLOWED_DATA_VIEWS = ['logs', 'auditbeat', 'filebeat', 'win
export const DEFAULT_ALLOWED_LOGS_DATA_VIEWS = ['logs', 'auditbeat', 'filebeat', 'winlogbeat'];
export const LOG_LEVEL_FIELDS = ['log.level', 'log_level'];
export const SERVICE_NAME_FIELDS = ['service.name', 'service_name'];
export const AGENT_NAME_FIELD = 'agent.name';

View file

@ -0,0 +1,61 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/
import { buildDataTableRecord, DataTableRecord } from '@kbn/discover-utils';
import { dataViewMock } from '@kbn/discover-utils/src/__mocks__';
import { fieldFormatsMock } from '@kbn/field-formats-plugin/common/mocks';
import { render, screen } from '@testing-library/react';
import React from 'react';
import { getServiceNameCell } from './service_name_cell';
const renderCell = (serviceNameField: string, record: DataTableRecord) => {
const ServiceNameCell = getServiceNameCell(serviceNameField);
render(
<ServiceNameCell
rowIndex={0}
colIndex={0}
columnId="service.name"
isExpandable={false}
isExpanded={false}
isDetails={false}
row={record}
dataView={dataViewMock}
fieldFormats={fieldFormatsMock}
setCellProps={() => {}}
closePopover={() => {}}
/>
);
};
describe('getServiceNameCell', () => {
it('renders icon if agent name is recognized', () => {
const record = buildDataTableRecord(
{ fields: { 'service.name': 'test-service', 'agent.name': 'nodejs' } },
dataViewMock
);
renderCell('service.name', record);
expect(screen.getByTestId('serviceNameCell-nodejs')).toBeInTheDocument();
});
it('renders default icon with unknwon test subject if agent name is missing', () => {
const record = buildDataTableRecord(
{ fields: { 'service.name': 'test-service' } },
dataViewMock
);
renderCell('service.name', record);
expect(screen.getByTestId('serviceNameCell-unknown')).toBeInTheDocument();
});
it('does not render if service name is missing', () => {
const record = buildDataTableRecord({ fields: { 'agent.name': 'nodejs' } }, dataViewMock);
renderCell('service.name', record);
expect(screen.queryByTestId('serviceNameCell-nodejs')).not.toBeInTheDocument();
expect(screen.queryByTestId('serviceNameCell-unknown')).not.toBeInTheDocument();
});
});

View file

@ -0,0 +1,45 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/
import { EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui';
import type { AgentName } from '@kbn/elastic-agent-utils';
import { dynamic } from '@kbn/shared-ux-utility';
import type { DataGridCellValueElementProps } from '@kbn/unified-data-table';
import React from 'react';
import { getFieldValue } from '@kbn/discover-utils';
import { AGENT_NAME_FIELD } from '../../../../common/data_types/logs/constants';
const dataTestSubj = 'serviceNameCell';
const AgentIcon = dynamic(() => import('@kbn/custom-icons/src/components/agent_icon'));
export const getServiceNameCell =
(serviceNameField: string) => (props: DataGridCellValueElementProps) => {
const serviceNameValue = getFieldValue(props.row, serviceNameField);
const agentName = getFieldValue(props.row, AGENT_NAME_FIELD) as AgentName;
if (!serviceNameValue) {
return <span data-test-subj={`${dataTestSubj}-empty`}>-</span>;
}
return (
<EuiFlexGroup
gutterSize="xs"
data-test-subj={`${dataTestSubj}-${agentName || 'unknown'}`}
responsive={false}
alignItems="center"
>
<EuiFlexItem grow={false}>
<EuiToolTip position="left" content={agentName} repositionOnScroll={true}>
<AgentIcon agentName={agentName} size="m" />
</EuiToolTip>
</EuiFlexItem>
<EuiFlexItem grow={false}>{serviceNameValue}</EuiFlexItem>
</EuiFlexGroup>
);
};

View file

@ -7,9 +7,13 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/
import { LOG_LEVEL_FIELDS } from '../../../../../../common/data_types/logs/constants';
import {
LOG_LEVEL_FIELDS,
SERVICE_NAME_FIELDS,
} from '../../../../../../common/data_types/logs/constants';
import { getLogLevelBadgeCell } from '../../../../../components/data_types/logs/log_level_badge_cell';
import type { DataSourceProfileProvider } from '../../../../profiles';
import { getServiceNameCell } from '../../../../../components/data_types/logs/service_name_cell';
import { DataSourceProfileProvider } from '../../../../profiles';
export const getCellRenderers: DataSourceProfileProvider['profile']['getCellRenderers'] =
(prev) => () => ({
@ -22,4 +26,12 @@ export const getCellRenderers: DataSourceProfileProvider['profile']['getCellRend
}),
{}
),
...SERVICE_NAME_FIELDS.reduce(
(acc, field) => ({
...acc,
[field]: getServiceNameCell(field),
[`${field}.keyword`]: getServiceNameCell(`${field}.keyword`),
}),
{}
),
});

View file

@ -37,135 +37,245 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
describe('ES|QL mode', () => {
it('should render log.level badge cell', async () => {
const state = kbnRison.encode({
dataSource: { type: 'esql' },
query: {
esql: 'from my-example-logs,logstash* | sort @timestamp desc | where `log.level` is not null',
},
});
await common.navigateToActualUrl('discover', `?_a=${state}`, {
ensureCurrentUrl: false,
});
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
await unifiedFieldList.clickFieldListItemAdd('log.level');
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
describe('Log Level Badge Cell', () => {
it('should render log.level badge cell', async () => {
const state = kbnRison.encode({
dataSource: { type: 'esql' },
query: {
esql: 'from my-example-logs,logstash* | sort @timestamp desc | where `log.level` is not null',
},
});
await common.navigateToActualUrl('discover', `?_a=${state}`, {
ensureCurrentUrl: false,
});
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
await unifiedFieldList.clickFieldListItemAdd('log.level');
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
const firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 0);
const logLevelBadge = await firstCell.findByTestSubject('*logLevelBadgeCell-');
expect(await logLevelBadge.getVisibleText()).to.be('debug');
expect(await logLevelBadge.getComputedStyle('background-color')).to.be(
'rgba(190, 207, 227, 1)'
);
});
it("should not render log.level badge cell if it's not a logs data source", async () => {
const state = kbnRison.encode({
dataSource: { type: 'esql' },
query: {
esql: 'from my-example* | sort @timestamp desc | where `log.level` is not null',
},
});
await common.navigateToActualUrl('discover', `?_a=${state}`, {
ensureCurrentUrl: false,
});
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
await unifiedFieldList.clickFieldListItemAdd('log.level');
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
await retry.try(async () => {
const firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 0);
expect(await firstCell.getVisibleText()).to.be('debug');
await testSubjects.missingOrFail('*logLevelBadgeCell-');
const logLevelBadge = await firstCell.findByTestSubject('*logLevelBadgeCell-');
expect(await logLevelBadge.getVisibleText()).to.be('debug');
expect(await logLevelBadge.getComputedStyle('background-color')).to.be(
'rgba(190, 207, 227, 1)'
);
});
it("should not render log.level badge cell if it's not a logs data source", async () => {
const state = kbnRison.encode({
dataSource: { type: 'esql' },
query: {
esql: 'from my-example* | sort @timestamp desc | where `log.level` is not null',
},
});
await common.navigateToActualUrl('discover', `?_a=${state}`, {
ensureCurrentUrl: false,
});
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
await unifiedFieldList.clickFieldListItemAdd('log.level');
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
await retry.try(async () => {
const firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 0);
expect(await firstCell.getVisibleText()).to.be('debug');
await testSubjects.missingOrFail('*logLevelBadgeCell-');
});
});
});
describe('Service Name Cell', () => {
it('should render service.name cell', async () => {
const state = kbnRison.encode({
dataSource: { type: 'esql' },
query: {
esql: 'from my-example-logs,logstash* | sort @timestamp desc | where `service.name` is not null',
},
});
await common.navigateToActualUrl('discover', `?_a=${state}`, {
ensureCurrentUrl: false,
});
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
await unifiedFieldList.clickFieldListItemAdd('service.name');
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
const firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 0);
const lastCell = await dataGrid.getCellElementExcludingControlColumns(2, 0);
const firstServiceNameCell = await firstCell.findByTestSubject('serviceNameCell-java');
const lastServiceNameCell = await lastCell.findByTestSubject('serviceNameCell-unknown');
expect(await firstServiceNameCell.getVisibleText()).to.be('product');
expect(await lastServiceNameCell.getVisibleText()).to.be('accounting');
});
it("should not render service.name cell if it's not a logs data source", async () => {
const state = kbnRison.encode({
dataSource: { type: 'esql' },
query: {
esql: 'from my-example* | sort @timestamp desc | where `service.name` is not null',
},
});
await common.navigateToActualUrl('discover', `?_a=${state}`, {
ensureCurrentUrl: false,
});
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
await unifiedFieldList.clickFieldListItemAdd('service.name');
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
await retry.try(async () => {
const firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 0);
expect(await firstCell.getVisibleText()).to.be('product');
await testSubjects.missingOrFail('*serviceNameCell*');
});
});
});
});
describe('data view mode', () => {
it('should render log.level badge cell', async () => {
await common.navigateToActualUrl('discover', undefined, {
ensureCurrentUrl: false,
});
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
await dataViews.switchToAndValidate('my-example-logs,logstash*');
await queryBar.setQuery('log.level:*');
await queryBar.submitQuery();
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
await unifiedFieldList.clickFieldListItemAdd('log.level');
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
describe('Log Level Badge Cell', () => {
it('should render log.level badge cell', async () => {
await common.navigateToActualUrl('discover', undefined, {
ensureCurrentUrl: false,
});
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
await dataViews.switchToAndValidate('my-example-logs,logstash*');
await queryBar.setQuery('log.level:*');
await queryBar.submitQuery();
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
await unifiedFieldList.clickFieldListItemAdd('log.level');
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
let firstCell: WebElementWrapper;
let logLevelBadge: WebElementWrapper;
let firstCell: WebElementWrapper;
let logLevelBadge: WebElementWrapper;
await retry.try(async () => {
firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1);
logLevelBadge = await firstCell.findByTestSubject('*logLevelBadgeCell-');
expect(await logLevelBadge.getVisibleText()).to.be('debug');
expect(await logLevelBadge.getComputedStyle('background-color')).to.be(
'rgba(190, 207, 227, 1)'
);
await retry.try(async () => {
firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1);
logLevelBadge = await firstCell.findByTestSubject('*logLevelBadgeCell-');
expect(await logLevelBadge.getVisibleText()).to.be('debug');
expect(await logLevelBadge.getComputedStyle('background-color')).to.be(
'rgba(190, 207, 227, 1)'
);
});
// check Surrounding docs page
await dataGrid.clickRowToggle();
const [, surroundingActionEl] = await dataGrid.getRowActions();
await surroundingActionEl.click();
await header.waitUntilLoadingHasFinished();
await browser.refresh();
await header.waitUntilLoadingHasFinished();
await retry.try(async () => {
firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1);
logLevelBadge = await firstCell.findByTestSubject('*logLevelBadgeCell-');
expect(await logLevelBadge.getVisibleText()).to.be('debug');
expect(await logLevelBadge.getComputedStyle('background-color')).to.be(
'rgba(190, 207, 227, 1)'
);
});
});
// check Surrounding docs page
await dataGrid.clickRowToggle();
const [, surroundingActionEl] = await dataGrid.getRowActions();
await surroundingActionEl.click();
await header.waitUntilLoadingHasFinished();
await browser.refresh();
await header.waitUntilLoadingHasFinished();
it("should not render log.level badge cell if it's not a logs data source", async () => {
await common.navigateToActualUrl('discover', undefined, {
ensureCurrentUrl: false,
});
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
await dataViews.switchToAndValidate('my-example-*');
await queryBar.setQuery('log.level:*');
await queryBar.submitQuery();
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
await unifiedFieldList.clickFieldListItemAdd('log.level');
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
await retry.try(async () => {
firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1);
logLevelBadge = await firstCell.findByTestSubject('*logLevelBadgeCell-');
expect(await logLevelBadge.getVisibleText()).to.be('debug');
expect(await logLevelBadge.getComputedStyle('background-color')).to.be(
'rgba(190, 207, 227, 1)'
);
let firstCell: WebElementWrapper;
await retry.try(async () => {
firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1);
expect(await firstCell.getVisibleText()).to.be('debug');
await testSubjects.missingOrFail('*logLevelBadgeCell-');
});
// check Surrounding docs page
await dataGrid.clickRowToggle();
const [, surroundingActionEl] = await dataGrid.getRowActions();
await surroundingActionEl.click();
await header.waitUntilLoadingHasFinished();
await browser.refresh();
await header.waitUntilLoadingHasFinished();
await retry.try(async () => {
firstCell = await dataGrid.getCellElementExcludingControlColumns(1, 1);
expect(await firstCell.getVisibleText()).to.be('debug');
await testSubjects.missingOrFail('*logLevelBadgeCell-');
});
});
});
it("should not render log.level badge cell if it's not a logs data source", async () => {
await common.navigateToActualUrl('discover', undefined, {
ensureCurrentUrl: false,
});
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
await dataViews.switchToAndValidate('my-example-*');
await queryBar.setQuery('log.level:*');
await queryBar.submitQuery();
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
await unifiedFieldList.clickFieldListItemAdd('log.level');
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
describe('Service Name Cell', () => {
it('should render service.name cell', async () => {
await common.navigateToActualUrl('discover', undefined, {
ensureCurrentUrl: false,
});
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
await dataViews.switchToAndValidate('my-example-logs,logstash*');
await queryBar.setQuery('service.name:*');
await queryBar.submitQuery();
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
await unifiedFieldList.clickFieldListItemAdd('service.name');
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
let firstCell: WebElementWrapper;
let firstCell: WebElementWrapper;
let lastCell: WebElementWrapper;
await retry.try(async () => {
firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1);
expect(await firstCell.getVisibleText()).to.be('debug');
await testSubjects.missingOrFail('*logLevelBadgeCell-');
await retry.try(async () => {
firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1);
lastCell = await dataGrid.getCellElementExcludingControlColumns(2, 1);
const firstServiceNameCell = await firstCell.findByTestSubject('serviceNameCell-java');
const lastServiceNameCell = await lastCell.findByTestSubject('serviceNameCell-unknown');
expect(await firstServiceNameCell.getVisibleText()).to.be('product');
expect(await lastServiceNameCell.getVisibleText()).to.be('accounting');
});
});
// check Surrounding docs page
await dataGrid.clickRowToggle();
const [, surroundingActionEl] = await dataGrid.getRowActions();
await surroundingActionEl.click();
await header.waitUntilLoadingHasFinished();
await browser.refresh();
await header.waitUntilLoadingHasFinished();
it("should not render service.name cell if it's not a logs data source", async () => {
await common.navigateToActualUrl('discover', undefined, {
ensureCurrentUrl: false,
});
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
await dataViews.switchToAndValidate('my-example-*');
await queryBar.setQuery('service.name:*');
await queryBar.submitQuery();
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
await unifiedFieldList.clickFieldListItemAdd('service.name');
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
await retry.try(async () => {
firstCell = await dataGrid.getCellElementExcludingControlColumns(1, 1);
expect(await firstCell.getVisibleText()).to.be('debug');
await testSubjects.missingOrFail('*logLevelBadgeCell-');
let firstCell: WebElementWrapper;
let lastCell: WebElementWrapper;
await retry.try(async () => {
firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1);
lastCell = await dataGrid.getCellElementExcludingControlColumns(2, 1);
expect(await firstCell.getVisibleText()).to.be('product');
expect(await lastCell.getVisibleText()).to.be('accounting');
await testSubjects.missingOrFail('*serviceNameCell*');
});
});
});
});

View file

@ -9,6 +9,22 @@
"@timestamp": {
"type": "date"
},
"agent": {
"properties": {
"name": {
"fields": {
"text": {
"type": "match_only_text"
}
},
"type": "keyword"
},
"version": {
"ignore_above": 1024,
"type": "keyword"
}
}
},
"data_stream": {
"properties": {
"type": {
@ -26,6 +42,18 @@
},
"message": {
"type": "match_only_text"
},
"service": {
"properties": {
"name": {
"fields": {
"text": {
"type": "match_only_text"
}
},
"type": "keyword"
}
}
}
}
},
@ -49,6 +77,22 @@
"@timestamp": {
"type": "date"
},
"agent": {
"properties": {
"name": {
"fields": {
"text": {
"type": "match_only_text"
}
},
"type": "keyword"
},
"version": {
"ignore_above": 1024,
"type": "keyword"
}
}
},
"data_stream": {
"properties": {
"type": {
@ -63,6 +107,18 @@
"type": "long"
}
}
},
"service": {
"properties": {
"name": {
"fields": {
"text": {
"type": "match_only_text"
}
},
"type": "keyword"
}
}
}
}
},

View file

@ -37,135 +37,244 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
describe('ES|QL mode', () => {
it('should render log.level badge cell', async () => {
const state = kbnRison.encode({
dataSource: { type: 'esql' },
query: {
esql: 'from my-example-logs,logstash* | sort @timestamp desc | where `log.level` is not null',
},
});
await PageObjects.common.navigateToActualUrl('discover', `?_a=${state}`, {
ensureCurrentUrl: false,
});
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
await PageObjects.unifiedFieldList.clickFieldListItemAdd('log.level');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
describe('Log Level Badge Cell', () => {
it('should render log.level badge cell', async () => {
const state = kbnRison.encode({
dataSource: { type: 'esql' },
query: {
esql: 'from my-example-logs,logstash* | sort @timestamp desc | where `log.level` is not null',
},
});
await PageObjects.common.navigateToActualUrl('discover', `?_a=${state}`, {
ensureCurrentUrl: false,
});
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
await PageObjects.unifiedFieldList.clickFieldListItemAdd('log.level');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
const firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 0);
const logLevelBadge = await firstCell.findByTestSubject('*logLevelBadgeCell-');
expect(await logLevelBadge.getVisibleText()).to.be('debug');
expect(await logLevelBadge.getComputedStyle('background-color')).to.be(
'rgba(190, 207, 227, 1)'
);
});
it("should not render log.level badge cell if it's not a logs data source", async () => {
const state = kbnRison.encode({
dataSource: { type: 'esql' },
query: {
esql: 'from my-example* | sort @timestamp desc | where `log.level` is not null',
},
});
await PageObjects.common.navigateToActualUrl('discover', `?_a=${state}`, {
ensureCurrentUrl: false,
});
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
await PageObjects.unifiedFieldList.clickFieldListItemAdd('log.level');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
await retry.try(async () => {
const firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 0);
expect(await firstCell.getVisibleText()).to.be('debug');
await testSubjects.missingOrFail('*logLevelBadgeCell-');
const logLevelBadge = await firstCell.findByTestSubject('*logLevelBadgeCell-');
expect(await logLevelBadge.getVisibleText()).to.be('debug');
expect(await logLevelBadge.getComputedStyle('background-color')).to.be(
'rgba(190, 207, 227, 1)'
);
});
it("should not render log.level badge cell if it's not a logs data source", async () => {
const state = kbnRison.encode({
dataSource: { type: 'esql' },
query: {
esql: 'from my-example* | sort @timestamp desc | where `log.level` is not null',
},
});
await PageObjects.common.navigateToActualUrl('discover', `?_a=${state}`, {
ensureCurrentUrl: false,
});
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
await PageObjects.unifiedFieldList.clickFieldListItemAdd('log.level');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
await retry.try(async () => {
const firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 0);
expect(await firstCell.getVisibleText()).to.be('debug');
await testSubjects.missingOrFail('*logLevelBadgeCell-');
});
});
});
describe('Service Name Cell', () => {
it('should render service.name cell', async () => {
const state = kbnRison.encode({
dataSource: { type: 'esql' },
query: {
esql: 'from my-example-logs,logstash* | sort @timestamp desc | where `service.name` is not null',
},
});
await PageObjects.common.navigateToActualUrl('discover', `?_a=${state}`, {
ensureCurrentUrl: false,
});
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
await PageObjects.unifiedFieldList.clickFieldListItemAdd('service.name');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
const firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 0);
const lastCell = await dataGrid.getCellElementExcludingControlColumns(2, 0);
const firstServiceNameCell = await firstCell.findByTestSubject('serviceNameCell-java');
const lastServiceNameCell = await lastCell.findByTestSubject('serviceNameCell-unknown');
expect(await firstServiceNameCell.getVisibleText()).to.be('product');
expect(await lastServiceNameCell.getVisibleText()).to.be('accounting');
});
it("should not render service.name cell if it's not a logs data source", async () => {
const state = kbnRison.encode({
dataSource: { type: 'esql' },
query: {
esql: 'from my-example* | sort @timestamp desc | where `service.name` is not null',
},
});
await PageObjects.common.navigateToActualUrl('discover', `?_a=${state}`, {
ensureCurrentUrl: false,
});
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
await PageObjects.unifiedFieldList.clickFieldListItemAdd('service.name');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
await retry.try(async () => {
const firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 0);
expect(await firstCell.getVisibleText()).to.be('product');
await testSubjects.missingOrFail('*serviceNameCell*');
});
});
});
});
describe('data view mode', () => {
it('should render log.level badge cell', async () => {
await PageObjects.common.navigateToActualUrl('discover', undefined, {
ensureCurrentUrl: false,
});
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
await dataViews.switchToAndValidate('my-example-logs,logstash*');
await queryBar.setQuery('log.level:*');
await queryBar.submitQuery();
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
await PageObjects.unifiedFieldList.clickFieldListItemAdd('log.level');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
describe('Log Level Badge Cell', () => {
it('should render log.level badge cell', async () => {
await PageObjects.common.navigateToActualUrl('discover', undefined, {
ensureCurrentUrl: false,
});
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
await dataViews.switchToAndValidate('my-example-logs,logstash*');
await queryBar.setQuery('log.level:*');
await queryBar.submitQuery();
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
await PageObjects.unifiedFieldList.clickFieldListItemAdd('log.level');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
let firstCell: WebElementWrapper;
let logLevelBadge: WebElementWrapper;
let firstCell: WebElementWrapper;
let logLevelBadge: WebElementWrapper;
await retry.try(async () => {
firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1);
logLevelBadge = await firstCell.findByTestSubject('*logLevelBadgeCell-');
expect(await logLevelBadge.getVisibleText()).to.be('debug');
expect(await logLevelBadge.getComputedStyle('background-color')).to.be(
'rgba(190, 207, 227, 1)'
);
await retry.try(async () => {
firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1);
logLevelBadge = await firstCell.findByTestSubject('*logLevelBadgeCell-');
expect(await logLevelBadge.getVisibleText()).to.be('debug');
expect(await logLevelBadge.getComputedStyle('background-color')).to.be(
'rgba(190, 207, 227, 1)'
);
});
// check Surrounding docs page
await dataGrid.clickRowToggle();
const [, surroundingActionEl] = await dataGrid.getRowActions();
await surroundingActionEl.click();
await PageObjects.header.waitUntilLoadingHasFinished();
await browser.refresh();
await PageObjects.header.waitUntilLoadingHasFinished();
await retry.try(async () => {
firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1);
logLevelBadge = await firstCell.findByTestSubject('*logLevelBadgeCell-');
expect(await logLevelBadge.getVisibleText()).to.be('debug');
expect(await logLevelBadge.getComputedStyle('background-color')).to.be(
'rgba(190, 207, 227, 1)'
);
});
});
// check Surrounding docs page
await dataGrid.clickRowToggle();
const [, surroundingActionEl] = await dataGrid.getRowActions();
await surroundingActionEl.click();
await PageObjects.header.waitUntilLoadingHasFinished();
await browser.refresh();
await PageObjects.header.waitUntilLoadingHasFinished();
it("should not render log.level badge cell if it's not a logs data source", async () => {
await PageObjects.common.navigateToActualUrl('discover', undefined, {
ensureCurrentUrl: false,
});
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
await dataViews.switchToAndValidate('my-example-*');
await queryBar.setQuery('log.level:*');
await queryBar.submitQuery();
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
await PageObjects.unifiedFieldList.clickFieldListItemAdd('log.level');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
await retry.try(async () => {
firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1);
logLevelBadge = await firstCell.findByTestSubject('*logLevelBadgeCell-');
expect(await logLevelBadge.getVisibleText()).to.be('debug');
expect(await logLevelBadge.getComputedStyle('background-color')).to.be(
'rgba(190, 207, 227, 1)'
);
let firstCell: WebElementWrapper;
await retry.try(async () => {
firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1);
expect(await firstCell.getVisibleText()).to.be('debug');
await testSubjects.missingOrFail('*logLevelBadgeCell-');
});
// check Surrounding docs page
await dataGrid.clickRowToggle();
const [, surroundingActionEl] = await dataGrid.getRowActions();
await surroundingActionEl.click();
await PageObjects.header.waitUntilLoadingHasFinished();
await browser.refresh();
await PageObjects.header.waitUntilLoadingHasFinished();
await retry.try(async () => {
firstCell = await dataGrid.getCellElementExcludingControlColumns(1, 1);
expect(await firstCell.getVisibleText()).to.be('debug');
await testSubjects.missingOrFail('*logLevelBadgeCell-');
});
});
});
describe('Service Name Cell', () => {
it('should render service.name cell', async () => {
await PageObjects.common.navigateToActualUrl('discover', undefined, {
ensureCurrentUrl: false,
});
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
await dataViews.switchToAndValidate('my-example-logs,logstash*');
await queryBar.setQuery('service.name:*');
await queryBar.submitQuery();
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
await PageObjects.unifiedFieldList.clickFieldListItemAdd('service.name');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
it("should not render log.level badge cell if it's not a logs data source", async () => {
await PageObjects.common.navigateToActualUrl('discover', undefined, {
ensureCurrentUrl: false,
});
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
await dataViews.switchToAndValidate('my-example-*');
await queryBar.setQuery('log.level:*');
await queryBar.submitQuery();
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
await PageObjects.unifiedFieldList.clickFieldListItemAdd('log.level');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
let firstCell: WebElementWrapper;
let lastCell: WebElementWrapper;
let firstCell: WebElementWrapper;
await retry.try(async () => {
firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1);
expect(await firstCell.getVisibleText()).to.be('debug');
await testSubjects.missingOrFail('*logLevelBadgeCell-');
await retry.try(async () => {
firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1);
lastCell = await dataGrid.getCellElementExcludingControlColumns(2, 1);
const firstServiceNameCell = await firstCell.findByTestSubject('serviceNameCell-java');
const lastServiceNameCell = await lastCell.findByTestSubject('serviceNameCell-unknown');
expect(await firstServiceNameCell.getVisibleText()).to.be('product');
expect(await lastServiceNameCell.getVisibleText()).to.be('accounting');
});
});
// check Surrounding docs page
await dataGrid.clickRowToggle();
const [, surroundingActionEl] = await dataGrid.getRowActions();
await surroundingActionEl.click();
await PageObjects.header.waitUntilLoadingHasFinished();
await browser.refresh();
await PageObjects.header.waitUntilLoadingHasFinished();
it("should not render service.name cell if it's not a logs data source", async () => {
await PageObjects.common.navigateToActualUrl('discover', undefined, {
ensureCurrentUrl: false,
});
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
await dataViews.switchToAndValidate('my-example-*');
await queryBar.setQuery('service.name:*');
await queryBar.submitQuery();
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
await PageObjects.unifiedFieldList.clickFieldListItemAdd('service.name');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.discover.waitUntilSearchingHasFinished();
await retry.try(async () => {
firstCell = await dataGrid.getCellElementExcludingControlColumns(1, 1);
expect(await firstCell.getVisibleText()).to.be('debug');
await testSubjects.missingOrFail('*logLevelBadgeCell-');
let firstCell: WebElementWrapper;
let lastCell: WebElementWrapper;
await retry.try(async () => {
firstCell = await dataGrid.getCellElementExcludingControlColumns(0, 1);
lastCell = await dataGrid.getCellElementExcludingControlColumns(2, 1);
expect(await firstCell.getVisibleText()).to.be('product');
expect(await lastCell.getVisibleText()).to.be('accounting');
await testSubjects.missingOrFail('*serviceNameCell*');
});
});
});
});