diff --git a/x-pack/plugins/apm/kibana.json b/x-pack/plugins/apm/kibana.json
index f134b4eebddf8..80a52debd9773 100644
--- a/x-pack/plugins/apm/kibana.json
+++ b/x-pack/plugins/apm/kibana.json
@@ -8,7 +8,8 @@
"data",
"licensing",
"triggersActionsUi",
- "embeddable"
+ "embeddable",
+ "infra"
],
"optionalPlugins": [
"cloud",
diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TransactionTabs.tsx b/x-pack/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TransactionTabs.tsx
index 43732c23aea64..331fa17ba8bf8 100644
--- a/x-pack/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TransactionTabs.tsx
+++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/TransactionTabs.tsx
@@ -9,6 +9,7 @@ import { i18n } from '@kbn/i18n';
import { Location } from 'history';
import React from 'react';
import { useHistory } from 'react-router-dom';
+import { LogStream } from '../../../../../../infra/public';
import { Transaction } from '../../../../../typings/es_schemas/ui/transaction';
import type { IUrlParams } from '../../../../context/url_params_context/types';
import { fromQuery, toQuery } from '../../../shared/Links/url_helpers';
@@ -16,20 +17,6 @@ import { TransactionMetadata } from '../../../shared/MetadataTable/TransactionMe
import { WaterfallContainer } from './WaterfallContainer';
import { IWaterfall } from './WaterfallContainer/Waterfall/waterfall_helpers/waterfall_helpers';
-const timelineTab = {
- key: 'timeline',
- label: i18n.translate('xpack.apm.propertiesTable.tabs.timelineLabel', {
- defaultMessage: 'Timeline',
- }),
-};
-
-const metadataTab = {
- key: 'metadata',
- label: i18n.translate('xpack.apm.propertiesTable.tabs.metadataLabel', {
- defaultMessage: 'Metadata',
- }),
-};
-
interface Props {
location: Location;
transaction: Transaction;
@@ -46,9 +33,10 @@ export function TransactionTabs({
exceedsMax,
}: Props) {
const history = useHistory();
- const tabs = [timelineTab, metadataTab];
+ const tabs = [timelineTab, metadataTab, logsTab];
const currentTab =
- urlParams.detailTab === metadataTab.key ? metadataTab : timelineTab;
+ tabs.find(({ key }) => key === urlParams.detailTab) ?? timelineTab;
+ const TabContent = currentTab.component;
return (
@@ -76,16 +64,77 @@ export function TransactionTabs({
- {currentTab.key === timelineTab.key ? (
-
- ) : (
-
- )}
+
);
}
+
+const timelineTab = {
+ key: 'timeline',
+ label: i18n.translate('xpack.apm.propertiesTable.tabs.timelineLabel', {
+ defaultMessage: 'Timeline',
+ }),
+ component: TimelineTabContent,
+};
+
+const metadataTab = {
+ key: 'metadata',
+ label: i18n.translate('xpack.apm.propertiesTable.tabs.metadataLabel', {
+ defaultMessage: 'Metadata',
+ }),
+ component: MetadataTabContent,
+};
+
+const logsTab = {
+ key: 'logs',
+ label: i18n.translate('xpack.apm.propertiesTable.tabs.logsLabel', {
+ defaultMessage: 'Logs',
+ }),
+ component: LogsTabContent,
+};
+
+function TimelineTabContent({
+ location,
+ urlParams,
+ waterfall,
+ exceedsMax,
+}: {
+ location: Location;
+ urlParams: IUrlParams;
+ waterfall: IWaterfall;
+ exceedsMax: boolean;
+}) {
+ return (
+
+ );
+}
+
+function MetadataTabContent({ transaction }: { transaction: Transaction }) {
+ return ;
+}
+
+function LogsTabContent({ transaction }: { transaction: Transaction }) {
+ const startTimestamp = Math.floor(transaction.timestamp.us / 1000);
+ const endTimestamp = Math.ceil(
+ startTimestamp + transaction.transaction.duration.us / 1000
+ );
+ const framePaddingMs = 1000 * 60 * 60 * 24; // 24 hours
+ return (
+
+ );
+}