kibana/test/analytics/plugins/analytics_plugin_a/server/plugin.ts
Kibana Machine 5419984424
[9.0] Add trace.id to EBT events (#222366) (#223517)
# Backport

This will backport the following commits from `main` to `9.0`:
- [Add trace.id to EBT events
(#222366)](https://github.com/elastic/kibana/pull/222366)

<!--- Backport version: 9.6.6 -->

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

<!--BACKPORT [{"author":{"name":"Maryam
Saeidi","email":"maryam.saeidi@elastic.co"},"sourceCommit":{"committedDate":"2025-06-11T20:11:41Z","message":"Add
trace.id to EBT events (#222366)\n\nCloses
https://github.com/elastic/observability-dev/issues/4445\n\nEBT
implementation: https://github.com/elastic/ebt/pull/57\n\n##
Summary\n\nIn this PR, we are adding `getTraceContext` to the
`createAnalytics` in\norder to include `trace.id` in the EBT
events.\n\n\n![image](https://github.com/user-attachments/assets/6aa19400-0e38-477a-b5de-74defea7652a)\n\n###
⚠️ Note\n\nSome events might not have a `trace.id` due to not having an
active\ntransaction at the moment of reporting the event. For those, we
can\nimplement more sophisticated logic to keep track of transactions
and use\nthe `trace.id` of the last one for the event (in a follow-up
ticket, if\nnecessary).\n\n### How to test\n- Add
`telemetry.localShipper: true` to the kibana config and create a\ndata
view for `ebt-kibana-browser` index\n- Check the `trace.id` in the
events that are passed\n\n---------\n\nCo-authored-by: Alejandro
Fernández Haro
<alejandro.haro@elastic.co>","sha":"cfc7f0ed0e84e486b9757756334f61153bae2037","branchLabelMapping":{"^v9.1.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","backport:version","v9.1.0","v8.19.0","author:obs-ux-management","v9.0.3"],"title":"Add
trace.id to EBT
events","number":222366,"url":"https://github.com/elastic/kibana/pull/222366","mergeCommit":{"message":"Add
trace.id to EBT events (#222366)\n\nCloses
https://github.com/elastic/observability-dev/issues/4445\n\nEBT
implementation: https://github.com/elastic/ebt/pull/57\n\n##
Summary\n\nIn this PR, we are adding `getTraceContext` to the
`createAnalytics` in\norder to include `trace.id` in the EBT
events.\n\n\n![image](https://github.com/user-attachments/assets/6aa19400-0e38-477a-b5de-74defea7652a)\n\n###
⚠️ Note\n\nSome events might not have a `trace.id` due to not having an
active\ntransaction at the moment of reporting the event. For those, we
can\nimplement more sophisticated logic to keep track of transactions
and use\nthe `trace.id` of the last one for the event (in a follow-up
ticket, if\nnecessary).\n\n### How to test\n- Add
`telemetry.localShipper: true` to the kibana config and create a\ndata
view for `ebt-kibana-browser` index\n- Check the `trace.id` in the
events that are passed\n\n---------\n\nCo-authored-by: Alejandro
Fernández Haro
<alejandro.haro@elastic.co>","sha":"cfc7f0ed0e84e486b9757756334f61153bae2037"}},"sourceBranch":"main","suggestedTargetBranches":["9.0"],"targetPullRequestStates":[{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/222366","number":222366,"mergeCommit":{"message":"Add
trace.id to EBT events (#222366)\n\nCloses
https://github.com/elastic/observability-dev/issues/4445\n\nEBT
implementation: https://github.com/elastic/ebt/pull/57\n\n##
Summary\n\nIn this PR, we are adding `getTraceContext` to the
`createAnalytics` in\norder to include `trace.id` in the EBT
events.\n\n\n![image](https://github.com/user-attachments/assets/6aa19400-0e38-477a-b5de-74defea7652a)\n\n###
⚠️ Note\n\nSome events might not have a `trace.id` due to not having an
active\ntransaction at the moment of reporting the event. For those, we
can\nimplement more sophisticated logic to keep track of transactions
and use\nthe `trace.id` of the last one for the event (in a follow-up
ticket, if\nnecessary).\n\n### How to test\n- Add
`telemetry.localShipper: true` to the kibana config and create a\ndata
view for `ebt-kibana-browser` index\n- Check the `trace.id` in the
events that are passed\n\n---------\n\nCo-authored-by: Alejandro
Fernández Haro
<alejandro.haro@elastic.co>","sha":"cfc7f0ed0e84e486b9757756334f61153bae2037"}},{"branch":"8.19","label":"v8.19.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"url":"https://github.com/elastic/kibana/pull/223464","number":223464,"state":"MERGED","mergeCommit":{"sha":"71b79af9b7c44566118e65b2e6d9341c5c39898d","message":"[8.19]
Add trace.id to EBT events (#222366) (#223464)\n\n# Backport\n\nThis
will backport the following commits from `main` to `8.19`:\n- [Add
trace.id to EBT
events\n(#222366)](https://github.com/elastic/kibana/pull/222366)\n\n\n\n###
Questions ?\nPlease refer to the [Backport
tool\ndocumentation](https://github.com/sorenlouv/backport)\n\n\n\nCo-authored-by:
Maryam Saeidi <maryam.saeidi@elastic.co>\nCo-authored-by: Alejandro
Fernández Haro
<alejandro.haro@elastic.co>"}},{"branch":"9.0","label":"v9.0.3","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

Co-authored-by: Maryam Saeidi <maryam.saeidi@elastic.co>
Co-authored-by: Alejandro Fernández Haro <alejandro.haro@elastic.co>
2025-06-12 13:46:11 +02:00

149 lines
4.3 KiB
TypeScript

/*
* 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 apm from 'elastic-apm-node';
import { BehaviorSubject, filter, firstValueFrom, ReplaySubject } from 'rxjs';
import { takeWhile, tap, toArray } from 'rxjs';
import { schema } from '@kbn/config-schema';
import type { Plugin, CoreSetup, CoreStart, TelemetryCounter, Event } from '@kbn/core/server';
import type { Action } from './custom_shipper';
import { CustomShipper } from './custom_shipper';
export class AnalyticsPluginAPlugin implements Plugin {
public setup({ analytics, http }: CoreSetup, deps: {}) {
const {
registerContextProvider,
registerEventType,
registerShipper,
reportEvent,
telemetryCounter$,
} = analytics;
const stats: TelemetryCounter[] = [];
telemetryCounter$.subscribe((event) => stats.push(event));
registerEventType({
eventType: 'test-plugin-lifecycle',
schema: {
plugin: {
type: 'keyword',
_meta: {
description: 'The ID of the plugin',
},
},
step: {
type: 'keyword',
_meta: {
description: 'The lifecycle step in which the plugin is',
},
},
traceId: {
type: 'keyword',
_meta: {
description: 'The trace ID of the APM transaction',
optional: true,
},
},
},
});
// Report an event before the shipper is registered
reportEvent('test-plugin-lifecycle', {
plugin: 'analyticsPluginA',
step: 'setup',
traceId: apm.currentTraceIds?.['trace.id'],
});
const actions$ = new ReplaySubject<Action>();
registerShipper(CustomShipper, actions$);
const router = http.createRouter();
router.get(
{
path: '/internal/analytics_plugin_a/stats',
validate: {
query: schema.object({
takeNumberOfCounters: schema.number({ min: 1 }),
eventType: schema.string(),
}),
},
},
async (context, req, res) => {
const { takeNumberOfCounters, eventType } = req.query;
return res.ok({
body: stats
.filter(
(counter) =>
counter.event_type === eventType &&
['client', 'FTR-shipper'].includes(counter.source)
)
.slice(-takeNumberOfCounters),
});
}
);
router.get(
{
path: '/internal/analytics_plugin_a/actions',
validate: false,
},
async (context, req, res) => {
let found = false;
const actions = await firstValueFrom(
actions$.pipe(
takeWhile(() => !found),
tap((action) => {
found = isTestPluginLifecycleReportEventAction(action);
}),
// Filter only the actions that are relevant to this plugin
filter(
({ action, meta }) =>
['optIn', 'extendContext'].includes(action) ||
isTestPluginLifecycleReportEventAction({ action, meta })
),
toArray()
)
);
return res.ok({ body: actions });
}
);
registerContextProvider({
name: 'analyticsPluginA',
context$: new BehaviorSubject({ pid: process.pid }),
schema: {
pid: {
type: 'short',
_meta: {
description: 'The Kibana process ID',
},
},
},
});
}
public start({ analytics }: CoreStart) {
analytics.reportEvent('test-plugin-lifecycle', {
plugin: 'analyticsPluginA',
step: 'start',
traceId: apm.currentTraceIds?.['trace.id'],
});
}
public stop() {}
}
function isTestPluginLifecycleReportEventAction({ action, meta }: Action): boolean {
return (
action === 'reportEvents' &&
meta.find((event: Event) => event.event_type === 'test-plugin-lifecycle')
);
}