mirror of
https://github.com/hyperdxio/hyperdx
synced 2026-04-21 21:37:41 +00:00
## Summary Adds a pattern mining feature to the CLI, accessible via `Shift+P`. This mirrors the web app's Pattern Table functionality but runs entirely in TypeScript — no Pyodide/Python WASM needed. **Linear:** https://linear.app/hyperdx/issue/HDX-3964 ## What changed ### 1. Drain library in common-utils (`packages/common-utils/src/drain/`) Ported the [browser-drain](https://github.com/DeploySentinel/browser-drain) TypeScript library into `@hyperdx/common-utils`. This is a pure TypeScript implementation of the Drain3 log template mining algorithm, including: - `TemplateMiner` / `TemplateMinerConfig` — main API - `Drain` — core algorithm with prefix tree and LRU cluster cache - `LogMasker` — regex-based token masking (IPs, numbers, etc.) - `LruCache` — custom LRU cache matching Python Drain3's eviction semantics - 11 Jest tests ported from the original `node:test` suite ### 2. CLI pattern view (`packages/cli/src/components/EventViewer/`) **Keybinding:** `Shift+P` toggles pattern view (pauses follow mode, restores on exit) **Data flow (mirrors web app's `useGroupedPatterns`):** - Issues `SELECT ... ORDER BY rand() LIMIT 100000` to randomly sample up to 100K events - Issues parallel `SELECT count()` to get true total event count - Feeds sampled log bodies through the TypeScript `TemplateMiner` - Estimates pattern counts via `sampleMultiplier = totalCount / sampledRowCount` - Computes time-bucketed trend data per pattern **UI:** - Pattern list with columns: Est. Count (with `~` prefix), Pattern - `l`/`Enter` expands a pattern to show its sample events (full table columns) - `h`/`Esc` returns to pattern list - `j/k/G/g/Ctrl+D/Ctrl+U` navigation throughout - Loading spinner while sampling query runs **Alias fix:** Pattern and count queries compute `WITH` clauses from the source's `defaultTableSelectExpression` so Lucene searches using aliases (e.g. `level:error` where `level` is an alias for `SeverityText`) resolve correctly. ### New files - `packages/common-utils/src/drain/` — 7 source files + barrel index - `packages/common-utils/src/__tests__/drain.test.ts` - `packages/cli/src/components/EventViewer/usePatternData.ts` - `packages/cli/src/components/EventViewer/PatternView.tsx` - `packages/cli/src/components/EventViewer/PatternSamplesView.tsx` ### Modified files - `packages/cli/src/api/eventQuery.ts` — added `buildPatternSampleQuery`, `buildTotalCountQuery`, `buildAliasWithClauses` - `packages/cli/src/components/EventViewer/EventViewer.tsx` — wired in pattern state + rendering - `packages/cli/src/components/EventViewer/useKeybindings.ts` — added P, l, h keybindings + pattern/sample navigation - `packages/cli/src/components/EventViewer/SubComponents.tsx` — added P to help screen ### Demo https://github.com/user-attachments/assets/50a2edfc-8891-43ae-ab86-b96fca778c66
85 lines
4 KiB
JSON
85 lines
4 KiB
JSON
{
|
|
"name": "hyperdx",
|
|
"private": true,
|
|
"version": "2.0.0",
|
|
"license": "MIT",
|
|
"workspaces": [
|
|
"packages/*"
|
|
],
|
|
"devDependencies": {
|
|
"@changesets/cli": "^2.26.2",
|
|
"@dotenvx/dotenvx": "^1.51.1",
|
|
"@eslint/js": "^9.39.1",
|
|
"@types/ungap__structured-clone": "^1.2.0",
|
|
"@ungap/structured-clone": "^1.3.0",
|
|
"babel-plugin-react-compiler": "^1.0.0",
|
|
"concurrently": "^9.1.2",
|
|
"dotenv": "^16.4.7",
|
|
"dotenv-cli": "^8.0.0",
|
|
"dotenv-expand": "^12.0.1",
|
|
"eslint": "^9.39.1",
|
|
"eslint-config-prettier": "^9.1.0",
|
|
"eslint-plugin-n": "^16.4.0",
|
|
"eslint-plugin-prettier": "^5.2.1",
|
|
"eslint-plugin-security": "^3.0.1",
|
|
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
"husky": "^8.0.3",
|
|
"knip": "^6.0.1",
|
|
"lint-staged": "^13.1.2",
|
|
"nx": "21.3.11",
|
|
"prettier": "3.3.3",
|
|
"tslib": "^2.6.0",
|
|
"typescript-eslint": "^8.46.0"
|
|
},
|
|
"scripts": {
|
|
"setup": "yarn install && husky install",
|
|
"build:common-utils": "nx run @hyperdx/common-utils:dev:build",
|
|
"app:dev": "concurrently -k -n 'API,APP,ALERTS-TASK,COMMON-UTILS' -c 'green.bold,blue.bold,yellow.bold,magenta' 'nx run @hyperdx/api:dev 2>&1 | tee ${HDX_DEV_LOGS_DIR:+\"$HDX_DEV_LOGS_DIR/api.log\"}' 'nx run @hyperdx/app:dev 2>&1 | tee ${HDX_DEV_LOGS_DIR:+\"$HDX_DEV_LOGS_DIR/app.log\"}' 'nx run @hyperdx/api:dev-task check-alerts 2>&1 | tee ${HDX_DEV_LOGS_DIR:+\"$HDX_DEV_LOGS_DIR/alerts.log\"}' 'nx run @hyperdx/common-utils:dev 2>&1 | tee ${HDX_DEV_LOGS_DIR:+\"$HDX_DEV_LOGS_DIR/common-utils.log\"}'",
|
|
"app:dev:local": "sh -c '. ./scripts/dev-env.sh && yarn build:common-utils && concurrently -k -n \"APP,COMMON-UTILS\" -c \"blue.bold,magenta\" \"nx run @hyperdx/app:dev:local 2>&1 | tee ${HDX_DEV_LOGS_DIR:+\\\"$HDX_DEV_LOGS_DIR/app.log\\\"}\" \"nx run @hyperdx/common-utils:dev 2>&1 | tee ${HDX_DEV_LOGS_DIR:+\\\"$HDX_DEV_LOGS_DIR/common-utils.log\\\"}\"'",
|
|
"app:lint": "nx run @hyperdx/app:ci:lint",
|
|
"app:storybook": "nx run @hyperdx/app:storybook",
|
|
"build:clickhouse": "nx run @hyperdx/common-utils:build && nx run @hyperdx/app:build:clickhouse",
|
|
"run:clickhouse": "nx run @hyperdx/app:run:clickhouse",
|
|
"dev": "sh -c '. ./scripts/dev-env.sh && yarn build:common-utils && dotenvx run --convention=nextjs -- docker compose -p \"$HDX_DEV_PROJECT\" -f docker-compose.dev.yml up -d && yarn app:dev; dotenvx run --convention=nextjs -- docker compose -p \"$HDX_DEV_PROJECT\" -f docker-compose.dev.yml down'",
|
|
"dev:local": "IS_LOCAL_APP_MODE='DANGEROUSLY_is_local_app_mode💀' yarn dev",
|
|
"cli:dev": "yarn workspace @hyperdx/cli dev",
|
|
"dev:down": "sh -c '. ./scripts/dev-env.sh && docker compose -p \"$HDX_DEV_PROJECT\" -f docker-compose.dev.yml down && sh ./scripts/dev-kill-ports.sh'",
|
|
"dev:compose": "sh -c '. ./scripts/dev-env.sh && docker compose -p \"$HDX_DEV_PROJECT\" -f docker-compose.dev.yml'",
|
|
"knip": "knip",
|
|
"knip:ci": "knip --reporter json",
|
|
"lint": "npx nx run-many -t ci:lint",
|
|
"lint:fix": "npx nx run-many -t lint:fix",
|
|
"version": "make version",
|
|
"release": "npx changeset tag && npx changeset publish"
|
|
},
|
|
"lint-staged": {
|
|
"packages/api/src/routers/external-api/**/*.ts": [
|
|
"prettier --write --ignore-unknown",
|
|
"eslint --flag v10_config_lookup_from_file --fix --quiet",
|
|
"sh -c 'cd packages/api && yarn run lint:openapi && git add openapi.json'"
|
|
],
|
|
"**/*.{ts,tsx}": [
|
|
"prettier --write --ignore-unknown",
|
|
"eslint --flag v10_config_lookup_from_file --fix --quiet"
|
|
],
|
|
"**/*.{mdx,json,yml}": [
|
|
"prettier --write --ignore-unknown"
|
|
]
|
|
},
|
|
"packageManager": "yarn@4.13.0",
|
|
"resolutions": {
|
|
"@types/react": "19.0.7",
|
|
"@types/react-dom": "19.0.3",
|
|
"@types/express": "4.17.21",
|
|
"@types/express-serve-static-core": "4.17.43",
|
|
"express": "^4.20.0",
|
|
"send": "^0.19.0",
|
|
"serve-static": "^1.16.0",
|
|
"cookie": "^0.7.0",
|
|
"brace-expansion": "^2.0.2",
|
|
"diff": "^5.2.2",
|
|
"on-headers": "^1.1.0",
|
|
"fast-xml-parser": "^4.5.4",
|
|
"systeminformation": "^5.24.0"
|
|
}
|
|
}
|