Skip to content

[HEIHEI-147] add TraceManagerDebugger #30

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Apr 18, 2025
1 change: 0 additions & 1 deletion .storybook/main.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { StorybookConfig } from '@storybook/react-webpack5'
import remarkGfm from 'remark-gfm'
// import { mergeConfig } from 'vite'

const config: StorybookConfig = {
Expand Down
67 changes: 35 additions & 32 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,24 +102,24 @@
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/modifiers": "^9.0.0",
"@mdx-js/react": "^3.1.0",
"@niieani/scaffold": "^1.7.45",
"@storybook/addon-actions": "^8.6.11",
"@storybook/addon-backgrounds": "^8.6.11",
"@storybook/addon-controls": "^8.6.11",
"@storybook/addon-docs": "^8.6.11",
"@storybook/addon-essentials": "^8.6.11",
"@storybook/addon-interactions": "^8.6.11",
"@storybook/addon-links": "^8.6.11",
"@storybook/addon-measure": "^8.6.11",
"@storybook/addon-outline": "^8.6.11",
"@storybook/addon-toolbars": "^8.6.11",
"@storybook/addon-viewport": "^8.6.11",
"@niieani/scaffold": "^1.7.46",
"@storybook/addon-actions": "^8.6.12",
"@storybook/addon-backgrounds": "^8.6.12",
"@storybook/addon-controls": "^8.6.12",
"@storybook/addon-docs": "^8.6.12",
"@storybook/addon-essentials": "^8.6.12",
"@storybook/addon-interactions": "^8.6.12",
"@storybook/addon-links": "^8.6.12",
"@storybook/addon-measure": "^8.6.12",
"@storybook/addon-outline": "^8.6.12",
"@storybook/addon-toolbars": "^8.6.12",
"@storybook/addon-viewport": "^8.6.12",
"@storybook/addon-webpack5-compiler-swc": "^3.0.0",
"@storybook/react": "^8.6.11",
"@storybook/react-webpack5": "^8.6.11",
"@storybook/react": "^8.6.12",
"@storybook/react-webpack5": "^8.6.12",
"@svgr/core": "^8.1.0",
"@svgr/webpack": "^8.1.0",
"@swc/core": "1.11.16",
"@swc/core": "1.11.21",
"@swc/types": "0.1.21",
"@types/lodash.debounce": "^4.0.9",
"@types/react": "^18.0.0",
Expand All @@ -144,36 +144,36 @@
"@visx/vendor": "^3.12.0",
"@visx/visx": "^3.12.0",
"@zendeskgarden/css-bedrock": "^10.0.1",
"@zendeskgarden/react-accordions": "^9.5.3",
"@zendeskgarden/react-avatars": "^9.5.3",
"@zendeskgarden/react-buttons": "^9.5.3",
"@zendeskgarden/react-chrome": "^9.5.3",
"@zendeskgarden/react-dropdowns": "^9.5.3",
"@zendeskgarden/react-grid": "^9.5.3",
"@zendeskgarden/react-loaders": "^9.5.3",
"@zendeskgarden/react-notifications": "^9.5.3",
"@zendeskgarden/react-tables": "^9.5.3",
"@zendeskgarden/react-theming": "^9.5.3",
"@zendeskgarden/react-typography": "^9.5.3",
"@zendeskgarden/react-accordions": "^9.5.4",
"@zendeskgarden/react-avatars": "^9.5.4",
"@zendeskgarden/react-buttons": "^9.5.4",
"@zendeskgarden/react-chrome": "^9.5.4",
"@zendeskgarden/react-dropdowns": "^9.5.4",
"@zendeskgarden/react-grid": "^9.5.4",
"@zendeskgarden/react-loaders": "^9.5.4",
"@zendeskgarden/react-notifications": "^9.5.4",
"@zendeskgarden/react-tables": "^9.5.4",
"@zendeskgarden/react-theming": "^9.5.4",
"@zendeskgarden/react-typography": "^9.5.4",
"@zendeskgarden/svg-icons": "^7.6.0",
"css-loader": "^7.1.2",
"eslint": "8.57.1",
"eslint-config-niieani": "^1.2.7",
"eslint-config-niieani": "^1.2.8",
"eslint-plugin-eslint-comments": "^3.2.0",
"husky": "^9.1.7",
"lodash.debounce": "^4.0.8",
"prettier-2": "npm:prettier@^2",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react-test-renderer": "^18.0.0",
"storybook": "^8.6.11",
"storybook": "^8.6.12",
"style-loader": "^4.0.0",
"styled-components": "^6.1.16",
"styled-components": "^6.1.17",
"ts-loader": "^9.5.2",
"typescript": "^5.8.2",
"typescript": "^5.8.3",
"url-loader": "^4.1.1",
"vitest": "^3.1.1",
"webpack": "5.98.0",
"webpack": "5.99.5",
"webpack-cli": "^6.0.1",
"webpack-sources": "^3.2.3"
},
Expand All @@ -200,5 +200,8 @@
"cjs",
"esm",
"docs"
]
],
"dependencies": {
"rxjs": "^7.8.2"
}
}
19 changes: 3 additions & 16 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,6 @@ export { performanceMark, performanceMeasure } from './performanceMark'
export { switchFn } from './switchFn'
export { getCurrentBrowserSupportForNonResponsiveStateDetection } from './utilities'

// visualizer
// export {
// getTimingDisplayModule,
// onActionAddedCallback,
// useVisualizer,
// } from './lazyVisualizer'

// operation tracking (v2)
// export * from './v2/constants'
// export * from './v2/defaultEventProcessor'
// export * from './v2/element'
// export * from './v2/getCommonUrlForTracing'
// export * from './v2/hooks'
// export * from './v2/operation'
// export type * from './v2/types'

// v3
export * from './v3/constants'
export * from './v3/convertToRum'
Expand All @@ -60,6 +44,8 @@ export * from './v3/Tracer'
// eslint-disable-next-line import/first, import/newline-after-import
import * as match from './v3/matchSpan'
export { match }
export * from './v3/ConsoleTraceLogger'
export type * from './v3/debugTypes'
export type {
NameMatcher,
SpanMatch,
Expand All @@ -72,6 +58,7 @@ export * from './v3/recordingComputeUtils'
export type * from './v3/spanAnnotationTypes'
export type * from './v3/spanTypes'
export * from './v3/TraceManager'
export * from './v3/TraceManagerDebuggerLazy'
export type * from './v3/traceRecordingTypes'
export type * from './v3/types'
export type * from './v3/typeUtils'
53 changes: 52 additions & 1 deletion src/stories/mockComponentsv3/App.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import React from 'react'
/* eslint-disable no-console */
import React, { useEffect } from 'react'
import type { Meta, StoryObj } from '@storybook/react'
import { createConsoleTraceLogger } from '../../v3/ConsoleTraceLogger'
import TraceManagerDebugger from '../../v3/TraceManagerDebugger'
import { App } from './App'
import { traceManager } from './traceManager'

const meta: Meta<typeof App> = {
component: App,
Expand All @@ -13,3 +17,50 @@ type Story = StoryObj<typeof App>
export const Primary: Story = {
render: () => <App />,
}

export const WithDebugger: Story = {
render: () => (
<div>
<div style={{ marginBottom: '20px' }}>
<TraceManagerDebugger traceManager={traceManager} />
</div>
<App />
</div>
),
}

export const WithFloatingDebugger: Story = {
render: () => (
<div>
<App />
<TraceManagerDebugger traceManager={traceManager} float={true} />
</div>
),
}

export const WithConsoleTraceLogger: Story = {
render: () => {
// Initialize the console trace logger when the story renders
useEffect(() => {
const consoleLogger = createConsoleTraceLogger(traceManager, {
verbose: true,
})

// Log a message to explain how to use the console
console.info(
'ConsoleTraceLogger is active. Open your browser console to see trace events. ' +
'Try clicking on tickets to see trace events logged in real-time.',
)

// Clean up the logger when the component unmounts
return () => {
consoleLogger.cleanup()
console.info(
'ConsoleTraceLogger has been cleaned up and unsubscribed from all events.',
)
}
}, [])

return <App />
},
}
56 changes: 2 additions & 54 deletions src/stories/mockComponentsv3/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,40 +21,8 @@ import { ReactComponent as ZendeskIcon } from '@zendeskgarden/svg-icons/src/26/z
// CYN: NEED UPDATE
import { mockTickets } from './mockTickets'
import { TicketList } from './TicketList'
import { ticketOperationTracer } from './ticketOperationTracer'
import { TicketView } from './TicketView'
import { traceManager } from './traceManager'

const ticketOperationTracer = traceManager.createTracer({
name: `ticket-activation`,
type: 'operation',
requiredSpans: [
{
name: 'TicketView',
matchingRelations: ['ticketId'],
type: 'component-render',
isIdle: true,
},
],
relationSchemaName: 'ticket',
variants: {
click: { timeout: 45_000 },
},
// debounceWindow: 1_000,
debounceOnSpans: [
{
name: 'TicketView',
matchingRelations: ['ticketId'],
},
],
interruptOnSpans: [
{
name: 'TicketView',
matchingRelations: ['ticketId'],
type: 'component-unmount',
},
],
captureInteractive: true,
})

// simulate an event every 2 seconds
const simulateEventPeriodically = (ticketId: number | null) => {
Expand All @@ -74,29 +42,9 @@ export const App: React.FC = () => {
)

const handleTicketClick = (id: number) => {
// traceManager.startOperation({
// operationName: `ticket-activation`,
// track: [
// {
// match: { type: 'component-unmount', attributes: { ticketId: id } },
// interruptWhenSeen: true,
// },
// {
// match: { attributes: { ticketId: id } },
// debounceEndWhenSeen: { debounceBy: 1_000 },
// },
// {
// match: { attributes: { ticketId: id, visibleState: 'complete' } },
// requiredToEnd: true,
// },
// ],
// onTracked,
// onEnd: onTracked,
// waitUntilInteractive: true,
// interruptSelf: true,
// })
ticketOperationTracer.start({
relatedTo: { ticketId: id },
attributes: { exampleTraceAttribute: true },
variant: 'click',
})

Expand Down
1 change: 1 addition & 0 deletions src/stories/mockComponentsv3/TicketView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export const TicketView: React.FC<TicketViewProps> = ({
name: 'TicketView',
relatedTo: { ticketId },
renderedOutput: cached ? 'content' : 'loading',
attributes: { exampleBeaconAttribute: true },
isIdle: cached,
})

Expand Down
9 changes: 4 additions & 5 deletions src/stories/mockComponentsv3/simulateLongTasks.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable no-console */
export function triggerLongTasks({
minTime,
maxTime,
Expand All @@ -20,25 +19,25 @@ export function triggerLongTasks({
const endTime = Date.now()

if (controller.signal.aborted) {
console.log('Cluster aborted.')
// console.log('Cluster aborted.')
return
}

if (endTime - startTime < totalClusterDuration) {
console.log(`Starting long task for ${taskDuration} ms`)
// console.log(`Starting long task for ${taskDuration} ms`)
const taskEnd = Date.now() + taskDuration

// Simulating a blocking long task
while (Date.now() < taskEnd) {
if (controller.signal.aborted) {
console.log('Task aborted.')
// console.log('Task aborted.')
return
}
}

executeLongTask() // Trigger the next task
} else {
console.log('Completed all tasks within the cluster duration.')
// console.log('Completed all tasks within the cluster duration.')
}
}

Expand Down
33 changes: 33 additions & 0 deletions src/stories/mockComponentsv3/ticketOperationTracer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { traceManager } from './traceManager'

export const ticketOperationTracer = traceManager.createTracer({
name: `ticket-activation`,
type: 'operation',
requiredSpans: [
{
name: 'TicketView',
matchingRelations: true,
type: 'component-render',
isIdle: true,
},
],
relationSchemaName: 'ticket',
variants: {
click: { timeout: 45_000 },
},
// debounceWindow: 1_000,
debounceOnSpans: [
{
name: 'TicketView',
matchingRelations: true,
},
],
interruptOnSpans: [
{
name: 'TicketView',
matchingRelations: true,
type: 'component-unmount',
},
],
captureInteractive: true,
})
Loading