[8.x] [Discover] Add EBT events for next resolved contextual profiles (#203124) (#204209)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[Discover] Add EBT events for next resolved contextual profiles
(#203124)](https://github.com/elastic/kibana/pull/203124)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Julia
Rechkunova","email":"julia.rechkunova@elastic.co"},"sourceCommit":{"committedDate":"2024-12-13T12:31:42Z","message":"[Discover]
Add EBT events for next resolved contextual profiles (#203124)\n\n-
Closes https://github.com/elastic/kibana/issues/200257\r\n\r\n##
Summary\r\n\r\nThis PR adds `discover_profile_resolved` EBT events when
a new\r\ncontextual profile is resolved at any level (root, data source,
or\r\ndocument level).\r\n\r\nEvents will be triggered from Discover
pages and dashboards.\r\n\r\nPlease note that duplicate events will not
be sent in the current\r\nimplementation. Only when profile ID is
changing.\r\n\r\n<img width=\"1710\" alt=\"Screenshot 2024-12-06 at 17
39
23\"\r\nsrc=\"https://github.com/user-attachments/assets/54eef630-8bcc-4185-917f-d251c003df65\">\r\n\r\n<img
width=\"1699\" alt=\"Screenshot 2024-12-06 at 17 38
36\"\r\nsrc=\"https://github.com/user-attachments/assets/541522eb-9cc5-47b6-a51a-81186232b7e5\">\r\n\r\n\r\n##
Testing\r\n\r\nAdd logging to `trackContextualProfileResolvedEvent` or
do the\r\nfollowing:\r\n\r\nEnable \"Usage collection\" global
setting.\r\n\r\nNavigate to Discover and observe `kibana-browser`
requests in Network\r\ntab.\r\n\r\n\r\n### Checklist\r\n\r\n- [x] [Unit
or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios\r\n\r\n---------\r\n\r\nCo-authored-by: Davis McPhee
<davismcphee@hotmail.com>","sha":"f2f2a0a689c717435c61f2f8f8694b28776eed76","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","Team:DataDiscovery","backport:prev-minor","Project:OneDiscover"],"title":"[Discover]
Add EBT events for next resolved contextual
profiles","number":203124,"url":"https://github.com/elastic/kibana/pull/203124","mergeCommit":{"message":"[Discover]
Add EBT events for next resolved contextual profiles (#203124)\n\n-
Closes https://github.com/elastic/kibana/issues/200257\r\n\r\n##
Summary\r\n\r\nThis PR adds `discover_profile_resolved` EBT events when
a new\r\ncontextual profile is resolved at any level (root, data source,
or\r\ndocument level).\r\n\r\nEvents will be triggered from Discover
pages and dashboards.\r\n\r\nPlease note that duplicate events will not
be sent in the current\r\nimplementation. Only when profile ID is
changing.\r\n\r\n<img width=\"1710\" alt=\"Screenshot 2024-12-06 at 17
39
23\"\r\nsrc=\"https://github.com/user-attachments/assets/54eef630-8bcc-4185-917f-d251c003df65\">\r\n\r\n<img
width=\"1699\" alt=\"Screenshot 2024-12-06 at 17 38
36\"\r\nsrc=\"https://github.com/user-attachments/assets/541522eb-9cc5-47b6-a51a-81186232b7e5\">\r\n\r\n\r\n##
Testing\r\n\r\nAdd logging to `trackContextualProfileResolvedEvent` or
do the\r\nfollowing:\r\n\r\nEnable \"Usage collection\" global
setting.\r\n\r\nNavigate to Discover and observe `kibana-browser`
requests in Network\r\ntab.\r\n\r\n\r\n### Checklist\r\n\r\n- [x] [Unit
or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios\r\n\r\n---------\r\n\r\nCo-authored-by: Davis McPhee
<davismcphee@hotmail.com>","sha":"f2f2a0a689c717435c61f2f8f8694b28776eed76"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/203124","number":203124,"mergeCommit":{"message":"[Discover]
Add EBT events for next resolved contextual profiles (#203124)\n\n-
Closes https://github.com/elastic/kibana/issues/200257\r\n\r\n##
Summary\r\n\r\nThis PR adds `discover_profile_resolved` EBT events when
a new\r\ncontextual profile is resolved at any level (root, data source,
or\r\ndocument level).\r\n\r\nEvents will be triggered from Discover
pages and dashboards.\r\n\r\nPlease note that duplicate events will not
be sent in the current\r\nimplementation. Only when profile ID is
changing.\r\n\r\n<img width=\"1710\" alt=\"Screenshot 2024-12-06 at 17
39
23\"\r\nsrc=\"https://github.com/user-attachments/assets/54eef630-8bcc-4185-917f-d251c003df65\">\r\n\r\n<img
width=\"1699\" alt=\"Screenshot 2024-12-06 at 17 38
36\"\r\nsrc=\"https://github.com/user-attachments/assets/541522eb-9cc5-47b6-a51a-81186232b7e5\">\r\n\r\n\r\n##
Testing\r\n\r\nAdd logging to `trackContextualProfileResolvedEvent` or
do the\r\nfollowing:\r\n\r\nEnable \"Usage collection\" global
setting.\r\n\r\nNavigate to Discover and observe `kibana-browser`
requests in Network\r\ntab.\r\n\r\n\r\n### Checklist\r\n\r\n- [x] [Unit
or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios\r\n\r\n---------\r\n\r\nCo-authored-by: Davis McPhee
<davismcphee@hotmail.com>","sha":"f2f2a0a689c717435c61f2f8f8694b28776eed76"}}]}]
BACKPORT-->

Co-authored-by: Julia Rechkunova <julia.rechkunova@elastic.co>
This commit is contained in:
Kibana Machine 2024-12-14 01:28:32 +11:00 committed by GitHub
parent 6ac20e0373
commit e92ced1cd0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 446 additions and 25 deletions

View file

@ -26,6 +26,7 @@ describe('ProfilesManager', () => {
jest.clearAllMocks();
mocks = createContextAwarenessMocks();
jest.spyOn(mocks.ebtManagerMock, 'updateProfilesContextWith');
jest.spyOn(mocks.ebtManagerMock, 'trackContextualProfileResolvedEvent');
});
it('should return default profiles', () => {
@ -74,6 +75,15 @@ describe('ProfilesManager', () => {
'root-profile',
'data-source-profile',
]);
expect(mocks.ebtManagerMock.trackContextualProfileResolvedEvent).toHaveBeenNthCalledWith(1, {
profileId: 'root-profile',
contextLevel: 'rootLevel',
});
expect(mocks.ebtManagerMock.trackContextualProfileResolvedEvent).toHaveBeenNthCalledWith(2, {
profileId: 'data-source-profile',
contextLevel: 'dataSourceLevel',
});
});
it('should expose profiles as an observable', async () => {
@ -152,7 +162,7 @@ describe('ProfilesManager', () => {
resolveSpy.mockRejectedValue(new Error('Failed to resolve'));
await mocks.profilesManagerMock.resolveRootProfile({ solutionNavId: 'newSolutionNavId' });
expect(addLog).toHaveBeenCalledWith(
'[ProfilesManager] root context resolution failed with params: {\n "solutionNavId": "newSolutionNavId"\n}',
'[ProfilesManager] rootLevel context resolution failed with params: {\n "solutionNavId": "newSolutionNavId"\n}',
new Error('Failed to resolve')
);
profiles = mocks.profilesManagerMock.getProfiles();
@ -177,7 +187,7 @@ describe('ProfilesManager', () => {
query: { esql: 'from logs-*' },
});
expect(addLog).toHaveBeenCalledWith(
'[ProfilesManager] data source context resolution failed with params: {\n "esqlQuery": "from logs-*"\n}',
'[ProfilesManager] dataSourceLevel context resolution failed with params: {\n "esqlQuery": "from logs-*"\n}',
new Error('Failed to resolve')
);
profiles = mocks.profilesManagerMock.getProfiles();
@ -199,10 +209,14 @@ describe('ProfilesManager', () => {
});
profiles = mocks.profilesManagerMock.getProfiles({ record: record2 });
expect(addLog).toHaveBeenCalledWith(
'[ProfilesManager] document context resolution failed with params: {\n "recordId": "logstash-2014.09.09::388::"\n}',
'[ProfilesManager] documentLevel context resolution failed with params: {\n "recordId": "logstash-2014.09.09::388::"\n}',
new Error('Failed to resolve')
);
expect(profiles).toEqual([{}, {}, {}]);
expect(mocks.ebtManagerMock.trackContextualProfileResolvedEvent).toHaveBeenCalledWith({
profileId: 'document-profile',
contextLevel: 'documentLevel',
});
});
it('should cancel existing root profile resolution when another is triggered', async () => {

View file

@ -51,6 +51,12 @@ export interface GetProfilesOptions {
record?: DataTableRecord;
}
export enum ContextualProfileLevel {
rootLevel = 'rootLevel',
dataSourceLevel = 'dataSourceLevel',
documentLevel = 'documentLevel',
}
export class ProfilesManager {
private readonly rootContext$: BehaviorSubject<ContextWithProfileId<RootContext>>;
private readonly dataSourceContext$: BehaviorSubject<ContextWithProfileId<DataSourceContext>>;
@ -104,7 +110,7 @@ export class ProfilesManager {
try {
context = await this.rootProfileService.resolve(params);
} catch (e) {
logResolutionError(ContextType.Root, serializedParams, e);
logResolutionError(ContextualProfileLevel.rootLevel, serializedParams, e);
}
if (abortController.signal.aborted) {
@ -142,7 +148,7 @@ export class ProfilesManager {
rootContext: this.rootContext$.getValue(),
});
} catch (e) {
logResolutionError(ContextType.DataSource, serializedParams, e);
logResolutionError(ContextualProfileLevel.dataSourceLevel, serializedParams, e);
}
if (abortController.signal.aborted) {
@ -179,11 +185,20 @@ export class ProfilesManager {
dataSourceContext: this.dataSourceContext$.getValue(),
});
} catch (e) {
logResolutionError(ContextType.Document, { recordId: params.record.id }, e);
logResolutionError(
ContextualProfileLevel.documentLevel,
{ recordId: params.record.id },
e
);
context = this.documentProfileService.defaultContext;
}
}
this.ebtManager.trackContextualProfileResolvedEvent({
contextLevel: ContextualProfileLevel.documentLevel,
profileId: context.profileId,
});
return context;
},
});
@ -223,6 +238,15 @@ export class ProfilesManager {
private trackActiveProfiles(rootContextProfileId: string, dataSourceContextProfileId: string) {
const dscProfiles = [rootContextProfileId, dataSourceContextProfileId];
this.ebtManager.trackContextualProfileResolvedEvent({
contextLevel: ContextualProfileLevel.rootLevel,
profileId: rootContextProfileId,
});
this.ebtManager.trackContextualProfileResolvedEvent({
contextLevel: ContextualProfileLevel.dataSourceLevel,
profileId: dataSourceContextProfileId,
});
this.ebtManager.updateProfilesContextWith(dscProfiles);
}
}
@ -256,19 +280,13 @@ const recordHasContext = (
return Boolean(record && 'context' in record);
};
enum ContextType {
Root = 'root',
DataSource = 'data source',
Document = 'document',
}
const logResolutionError = <TParams, TError>(
profileType: ContextType,
profileLevel: ContextualProfileLevel,
params: TParams,
error: TError
) => {
addLog(
`[ProfilesManager] ${profileType} context resolution failed with params: ${JSON.stringify(
`[ProfilesManager] ${profileLevel} context resolution failed with params: ${JSON.stringify(
params,
null,
2

View file

@ -180,7 +180,7 @@ export class DiscoverPlugin
window.dispatchEvent(new HashChangeEvent('hashchange'));
});
ebtManager.enableContext();
ebtManager.onDiscoverAppMounted();
const services = buildServices({
core: coreStart,
@ -229,7 +229,7 @@ export class DiscoverPlugin
});
return () => {
ebtManager.disableAndResetContext();
ebtManager.onDiscoverAppUnmounted();
unlistenParentHistory();
unmount();
appUnMounted();

View file

@ -11,6 +11,7 @@ import { BehaviorSubject } from 'rxjs';
import { coreMock } from '@kbn/core/public/mocks';
import { DiscoverEBTManager } from './discover_ebt_manager';
import { FieldsMetadataPublicStart } from '@kbn/fields-metadata-plugin/public';
import { ContextualProfileLevel } from '../context_awareness/profiles_manager';
describe('DiscoverEBTManager', () => {
let discoverEBTContextManager: DiscoverEBTManager;
@ -31,6 +32,7 @@ describe('DiscoverEBTManager', () => {
beforeEach(() => {
discoverEBTContextManager = new DiscoverEBTManager();
(coreSetupMock.analytics.reportEvent as jest.Mock).mockClear();
});
describe('register', () => {
@ -95,7 +97,7 @@ describe('DiscoverEBTManager', () => {
shouldInitializeCustomContext: true,
shouldInitializeCustomEvents: false,
});
discoverEBTContextManager.enableContext();
discoverEBTContextManager.onDiscoverAppMounted();
discoverEBTContextManager.updateProfilesContextWith(dscProfiles);
expect(discoverEBTContextManager.getProfilesContext()).toBe(dscProfiles);
@ -112,7 +114,7 @@ describe('DiscoverEBTManager', () => {
shouldInitializeCustomContext: true,
shouldInitializeCustomEvents: false,
});
discoverEBTContextManager.enableContext();
discoverEBTContextManager.onDiscoverAppMounted();
discoverEBTContextManager.updateProfilesContextWith(dscProfiles);
expect(discoverEBTContextManager.getProfilesContext()).toBe(dscProfiles);
@ -140,14 +142,14 @@ describe('DiscoverEBTManager', () => {
shouldInitializeCustomContext: true,
shouldInitializeCustomEvents: false,
});
discoverEBTContextManager.enableContext();
discoverEBTContextManager.onDiscoverAppMounted();
discoverEBTContextManager.updateProfilesContextWith(dscProfiles);
expect(discoverEBTContextManager.getProfilesContext()).toBe(dscProfiles);
discoverEBTContextManager.disableAndResetContext();
discoverEBTContextManager.onDiscoverAppUnmounted();
expect(discoverEBTContextManager.getProfilesContext()).toEqual([]);
discoverEBTContextManager.updateProfilesContextWith(dscProfiles);
expect(discoverEBTContextManager.getProfilesContext()).toEqual([]);
discoverEBTContextManager.enableContext();
discoverEBTContextManager.onDiscoverAppMounted();
discoverEBTContextManager.updateProfilesContextWith(dscProfiles);
expect(discoverEBTContextManager.getProfilesContext()).toBe(dscProfiles);
});
@ -239,4 +241,117 @@ describe('DiscoverEBTManager', () => {
});
});
});
describe('trackContextualProfileResolvedEvent', () => {
it('should track the event when a next contextual profile is resolved', async () => {
discoverEBTContextManager.initialize({
core: coreSetupMock,
shouldInitializeCustomContext: false,
shouldInitializeCustomEvents: true,
});
discoverEBTContextManager.trackContextualProfileResolvedEvent({
contextLevel: ContextualProfileLevel.rootLevel,
profileId: 'test',
});
expect(coreSetupMock.analytics.reportEvent).toHaveBeenNthCalledWith(
1,
'discover_profile_resolved',
{
contextLevel: 'rootLevel',
profileId: 'test',
}
);
discoverEBTContextManager.trackContextualProfileResolvedEvent({
contextLevel: ContextualProfileLevel.dataSourceLevel,
profileId: 'data-source-test',
});
expect(coreSetupMock.analytics.reportEvent).toHaveBeenNthCalledWith(
2,
'discover_profile_resolved',
{
contextLevel: 'dataSourceLevel',
profileId: 'data-source-test',
}
);
discoverEBTContextManager.trackContextualProfileResolvedEvent({
contextLevel: ContextualProfileLevel.documentLevel,
profileId: 'document-test',
});
expect(coreSetupMock.analytics.reportEvent).toHaveBeenNthCalledWith(
3,
'discover_profile_resolved',
{
contextLevel: 'documentLevel',
profileId: 'document-test',
}
);
});
it('should not trigger duplicate requests', async () => {
discoverEBTContextManager.initialize({
core: coreSetupMock,
shouldInitializeCustomContext: false,
shouldInitializeCustomEvents: true,
});
discoverEBTContextManager.trackContextualProfileResolvedEvent({
contextLevel: ContextualProfileLevel.rootLevel,
profileId: 'test1',
});
expect(coreSetupMock.analytics.reportEvent).toHaveBeenCalledTimes(1);
discoverEBTContextManager.trackContextualProfileResolvedEvent({
contextLevel: ContextualProfileLevel.rootLevel,
profileId: 'test1',
});
expect(coreSetupMock.analytics.reportEvent).toHaveBeenCalledTimes(1);
discoverEBTContextManager.trackContextualProfileResolvedEvent({
contextLevel: ContextualProfileLevel.rootLevel,
profileId: 'test2',
});
expect(coreSetupMock.analytics.reportEvent).toHaveBeenCalledTimes(2);
});
it('should trigger similar requests after remount', async () => {
discoverEBTContextManager.initialize({
core: coreSetupMock,
shouldInitializeCustomContext: false,
shouldInitializeCustomEvents: true,
});
discoverEBTContextManager.trackContextualProfileResolvedEvent({
contextLevel: ContextualProfileLevel.rootLevel,
profileId: 'test1',
});
expect(coreSetupMock.analytics.reportEvent).toHaveBeenCalledTimes(1);
discoverEBTContextManager.trackContextualProfileResolvedEvent({
contextLevel: ContextualProfileLevel.rootLevel,
profileId: 'test1',
});
expect(coreSetupMock.analytics.reportEvent).toHaveBeenCalledTimes(1);
discoverEBTContextManager.onDiscoverAppUnmounted();
discoverEBTContextManager.onDiscoverAppMounted();
discoverEBTContextManager.trackContextualProfileResolvedEvent({
contextLevel: ContextualProfileLevel.rootLevel,
profileId: 'test1',
});
expect(coreSetupMock.analytics.reportEvent).toHaveBeenCalledTimes(2);
});
});
});

View file

@ -11,7 +11,11 @@ import { BehaviorSubject } from 'rxjs';
import { isEqual } from 'lodash';
import type { CoreSetup } from '@kbn/core-lifecycle-browser';
import type { FieldsMetadataPublicStart } from '@kbn/fields-metadata-plugin/public';
import { ContextualProfileLevel } from '../context_awareness/profiles_manager';
/**
* Field usage events i.e. when a field is selected in the data table, removed from the data table, or a filter is added
*/
const FIELD_USAGE_EVENT_TYPE = 'discover_field_usage';
const FIELD_USAGE_EVENT_NAME = 'eventName';
const FIELD_USAGE_FIELD_NAME = 'fieldName';
@ -30,6 +34,19 @@ interface FieldUsageEventData {
[FIELD_USAGE_FILTER_OPERATION]?: FilterOperation;
}
/**
* Contextual profile resolved event i.e. when a different contextual profile is resolved at root, data source, or document level
* Duplicated events for the same profile level will not be sent.
*/
const CONTEXTUAL_PROFILE_RESOLVED_EVENT_TYPE = 'discover_profile_resolved';
const CONTEXTUAL_PROFILE_LEVEL = 'contextLevel';
const CONTEXTUAL_PROFILE_ID = 'profileId';
interface ContextualProfileResolvedEventData {
[CONTEXTUAL_PROFILE_LEVEL]: ContextualProfileLevel;
[CONTEXTUAL_PROFILE_ID]: string;
}
export interface DiscoverEBTContextProps {
discoverProfiles: string[]; // Discover Context Awareness Profiles
}
@ -39,8 +56,19 @@ export class DiscoverEBTManager {
private isCustomContextEnabled: boolean = false;
private customContext$: DiscoverEBTContext | undefined;
private reportEvent: CoreSetup['analytics']['reportEvent'] | undefined;
private lastResolvedContextProfiles: {
[ContextualProfileLevel.rootLevel]: string | undefined;
[ContextualProfileLevel.dataSourceLevel]: string | undefined;
[ContextualProfileLevel.documentLevel]: string | undefined;
};
constructor() {}
constructor() {
this.lastResolvedContextProfiles = {
[ContextualProfileLevel.rootLevel]: undefined,
[ContextualProfileLevel.dataSourceLevel]: undefined,
[ContextualProfileLevel.documentLevel]: undefined,
};
}
// https://docs.elastic.dev/telemetry/collection/event-based-telemetry
public initialize({
@ -104,17 +132,40 @@ export class DiscoverEBTManager {
},
},
});
core.analytics.registerEventType({
eventType: CONTEXTUAL_PROFILE_RESOLVED_EVENT_TYPE,
schema: {
[CONTEXTUAL_PROFILE_LEVEL]: {
type: 'keyword',
_meta: {
description:
'The context level at which it was resolved i.e. rootLevel, dataSourceLevel, documentLevel',
},
},
[CONTEXTUAL_PROFILE_ID]: {
type: 'keyword',
_meta: {
description: 'The resolved name of the active profile',
},
},
},
});
this.reportEvent = core.analytics.reportEvent;
}
}
public enableContext() {
public onDiscoverAppMounted() {
this.isCustomContextEnabled = true;
}
public disableAndResetContext() {
public onDiscoverAppUnmounted() {
this.updateProfilesContextWith([]);
this.isCustomContextEnabled = false;
this.lastResolvedContextProfiles = {
[ContextualProfileLevel.rootLevel]: undefined,
[ContextualProfileLevel.dataSourceLevel]: undefined,
[ContextualProfileLevel.documentLevel]: undefined,
};
}
public updateProfilesContextWith(discoverProfiles: DiscoverEBTContextProps['discoverProfiles']) {
@ -216,4 +267,30 @@ export class DiscoverEBTManager {
filterOperation,
});
}
public trackContextualProfileResolvedEvent({
contextLevel,
profileId,
}: {
contextLevel: ContextualProfileLevel;
profileId: string;
}) {
if (!this.reportEvent) {
return;
}
if (this.lastResolvedContextProfiles[contextLevel] === profileId) {
// avoid sending duplicate events to EBT
return;
}
this.lastResolvedContextProfiles[contextLevel] = profileId;
const eventData: ContextualProfileResolvedEventData = {
[CONTEXTUAL_PROFILE_LEVEL]: contextLevel,
[CONTEXTUAL_PROFILE_ID]: profileId,
};
this.reportEvent(CONTEXTUAL_PROFILE_RESOLVED_EVENT_TYPE, eventData);
}
}

View file

@ -121,7 +121,99 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
});
});
describe('events', () => {
describe('contextual profiles', () => {
before(async () => {
await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional');
await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover');
});
after(async () => {
await kibanaServer.importExport.unload('test/functional/fixtures/kbn_archiver/discover');
});
it('should send EBT events when a different data source profile gets resolved', async () => {
await common.navigateToApp('discover');
await discover.selectTextBaseLang();
await discover.waitUntilSearchingHasFinished();
await monacoEditor.setCodeEditorValue('from my-example-logs | sort @timestamp desc');
await ebtUIHelper.setOptIn(true); // starts the recording of events from this moment
await testSubjects.click('querySubmitButton');
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
let events = await ebtUIHelper.getEvents(Number.MAX_SAFE_INTEGER, {
eventTypes: ['discover_profile_resolved'],
withTimeoutMs: 500,
});
// root profile stays the same as it's not changing after switching to ES|QL mode
// but the data source profile should change because of the different data source
expect(events[0].properties).to.eql({
contextLevel: 'dataSourceLevel',
profileId: 'example-data-source-profile',
});
// should not trigger any new events after a simple refresh
await testSubjects.click('querySubmitButton');
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
events = await ebtUIHelper.getEvents(Number.MAX_SAFE_INTEGER, {
eventTypes: ['discover_profile_resolved'],
withTimeoutMs: 500,
});
expect(events.length).to.be(1);
// should detect a new data source profile when switching to a different data source
await monacoEditor.setCodeEditorValue('from my-example-* | sort @timestamp desc');
await testSubjects.click('querySubmitButton');
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
events = await ebtUIHelper.getEvents(Number.MAX_SAFE_INTEGER, {
eventTypes: ['discover_profile_resolved'],
withTimeoutMs: 500,
});
expect(events[1].properties).to.eql({
contextLevel: 'dataSourceLevel',
profileId: 'default-data-source-profile',
});
expect(events.length).to.be(2);
});
it('should send EBT events when a different document profile gets resolved', async () => {
await common.navigateToApp('discover');
await discover.selectTextBaseLang();
await monacoEditor.setCodeEditorValue('from my-example-* | sort @timestamp desc');
await testSubjects.click('querySubmitButton');
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
await ebtUIHelper.setOptIn(true); // starts the recording of events from this moment
// should trigger a new event after opening the doc viewer
await dataGrid.clickRowToggle();
await discover.isShowingDocViewer();
const events = await ebtUIHelper.getEvents(Number.MAX_SAFE_INTEGER, {
eventTypes: ['discover_profile_resolved'],
withTimeoutMs: 500,
});
expect(events.length).to.be(1);
expect(events[0].properties).to.eql({
contextLevel: 'documentLevel',
profileId: 'default-document-profile',
});
});
});
describe('field usage events', () => {
beforeEach(async () => {
await common.navigateToApp('discover');
await header.waitUntilLoadingHasFinished();

View file

@ -123,6 +123,111 @@ export default function ({ getService, getPageObjects }: ObservabilityTelemetryF
});
});
describe('contextual profiles', () => {
before(async () => {
await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional');
await kibanaServer.importExport.load('test/functional/fixtures/kbn_archiver/discover');
});
after(async () => {
await kibanaServer.importExport.unload('test/functional/fixtures/kbn_archiver/discover');
});
it('should send EBT events when a different data source profile gets resolved', async () => {
await common.navigateToApp('discover');
await discover.selectTextBaseLang();
await discover.waitUntilSearchingHasFinished();
await monacoEditor.setCodeEditorValue('from my-example-logs | sort @timestamp desc');
await ebtUIHelper.setOptIn(true); // starts the recording of events from this moment
await testSubjects.click('querySubmitButton');
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
let events = await ebtUIHelper.getEvents(Number.MAX_SAFE_INTEGER, {
eventTypes: ['discover_profile_resolved'],
withTimeoutMs: 500,
});
expect(events[0].properties).to.eql({
contextLevel: 'rootLevel',
profileId: 'observability-root-profile',
});
expect(events[1].properties).to.eql({
contextLevel: 'dataSourceLevel',
profileId: 'default-data-source-profile',
});
expect(events[2].properties).to.eql({
contextLevel: 'dataSourceLevel',
profileId: 'observability-logs-data-source-profile',
});
// should not trigger any new events after a simple refresh
await testSubjects.click('querySubmitButton');
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
events = await ebtUIHelper.getEvents(Number.MAX_SAFE_INTEGER, {
eventTypes: ['discover_profile_resolved'],
withTimeoutMs: 500,
});
expect(events.length).to.be(3);
// should detect a new data source profile when switching to a different data source
await monacoEditor.setCodeEditorValue('from my-example-* | sort @timestamp desc');
await testSubjects.click('querySubmitButton');
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
events = await ebtUIHelper.getEvents(Number.MAX_SAFE_INTEGER, {
eventTypes: ['discover_profile_resolved'],
withTimeoutMs: 500,
});
expect(events[3].properties).to.eql({
contextLevel: 'dataSourceLevel',
profileId: 'default-data-source-profile',
});
expect(events.length).to.be(4);
});
it('should send EBT events when a different document profile gets resolved', async () => {
await common.navigateToApp('discover');
await discover.selectTextBaseLang();
await monacoEditor.setCodeEditorValue('from my-example-logs | sort @timestamp desc');
await ebtUIHelper.setOptIn(true); // starts the recording of events from this moment
await testSubjects.click('querySubmitButton');
await header.waitUntilLoadingHasFinished();
await discover.waitUntilSearchingHasFinished();
let events = await ebtUIHelper.getEvents(Number.MAX_SAFE_INTEGER, {
eventTypes: ['discover_profile_resolved'],
withTimeoutMs: 500,
});
expect(events.length).to.be(3);
// should trigger a new event after opening the doc viewer
await dataGrid.clickRowToggle();
await discover.isShowingDocViewer();
events = await ebtUIHelper.getEvents(Number.MAX_SAFE_INTEGER, {
eventTypes: ['discover_profile_resolved'],
withTimeoutMs: 500,
});
expect(events.length).to.be(4);
expect(events[events.length - 1].properties).to.eql({
contextLevel: 'documentLevel',
profileId: 'observability-log-document-profile',
});
});
});
describe('events', () => {
beforeEach(async () => {
await common.navigateToApp('discover');