mirror of
https://github.com/hyperdxio/hyperdx
synced 2026-04-21 13:37:15 +00:00
feat: misc improvements (#824)
- add top level attributes to overview panel: HDX-1715 - add connection name to sources list - introduce additional default aliases for otel (service, level, duration) - fix bug with being unable to save source after deselecting correlated log source - copy improvements - `dev:down` npm command to tear down dev docker compose
This commit is contained in:
parent
a36c2290df
commit
5ce694401b
8 changed files with 71 additions and 13 deletions
|
|
@ -32,6 +32,7 @@
|
|||
"app:dev": "npx concurrently -k -n 'API,APP,ALERTS-TASK,COMMON-UTILS' -c 'green.bold,blue.bold,yellow.bold,magenta' 'nx run @hyperdx/api:dev' 'nx run @hyperdx/app:dev' 'nx run @hyperdx/api:dev-task check-alerts' 'nx run @hyperdx/common-utils:dev'",
|
||||
"app:lint": "nx run @hyperdx/app:ci:lint",
|
||||
"dev": "docker compose -f docker-compose.dev.yml up -d && yarn app:dev && docker compose -f docker-compose.dev.yml down",
|
||||
"dev:down": "docker compose -f docker-compose.dev.yml down",
|
||||
"lint": "npx nx run-many -t ci:lint",
|
||||
"version": "make version",
|
||||
"release": "npx nx run-many --target=build --projects=@hyperdx/common-utils && npx changeset tag && npx changeset publish"
|
||||
|
|
|
|||
|
|
@ -779,7 +779,7 @@ export default function AppNav({ fixed = false }: { fixed?: boolean }) {
|
|||
pathname.startsWith('/clickhouse'),
|
||||
})}
|
||||
>
|
||||
Clickhouse
|
||||
ClickHouse
|
||||
</Link>
|
||||
<Link
|
||||
href={`/services`}
|
||||
|
|
|
|||
|
|
@ -201,7 +201,11 @@ export default function AuthPage({ action }: { action: 'register' | 'login' }) {
|
|||
loading={isSubmitting}
|
||||
data-test-id="submit"
|
||||
>
|
||||
{isRegister ? 'Register' : 'Login'}
|
||||
{config.IS_OSS && isRegister
|
||||
? 'Create'
|
||||
: isRegister
|
||||
? 'Register'
|
||||
: 'Login'}
|
||||
</Button>
|
||||
</Stack>
|
||||
</Paper>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { SubmitHandler, useForm } from 'react-hook-form';
|
|||
import { json, jsonParseLinter } from '@codemirror/lang-json';
|
||||
import { linter } from '@codemirror/lint';
|
||||
import { EditorView, ViewUpdate } from '@codemirror/view';
|
||||
import { WebhookService } from '@hyperdx/common-utils/dist/types';
|
||||
import { SourceKind, WebhookService } from '@hyperdx/common-utils/dist/types';
|
||||
import {
|
||||
Alert,
|
||||
Badge,
|
||||
|
|
@ -198,6 +198,7 @@ function ConnectionsSection() {
|
|||
}
|
||||
|
||||
function SourcesSection() {
|
||||
const { data: connections } = useConnections();
|
||||
const { data: sources } = useSources();
|
||||
|
||||
const [editedSourceId, setEditedSourceId] = useState<string | null>(null);
|
||||
|
|
@ -216,13 +217,22 @@ function SourcesSection() {
|
|||
<Flex key={s.id} justify="space-between" align="center">
|
||||
<div>
|
||||
<Text>{s.name}</Text>
|
||||
<Text size="xxs" c="dimmed">
|
||||
<Text size="xxs" c="dimmed" mt="xs">
|
||||
{capitalizeFirstLetter(s.kind)}
|
||||
<Text px="md" span>
|
||||
<span className="bi-hdd-stack me-1" />
|
||||
{connections?.find(c => c.id === s.connection)?.name}
|
||||
</Text>
|
||||
{s.from && (
|
||||
<>
|
||||
{' '}
|
||||
· <span className="bi-database me-1" />
|
||||
{s.from.databaseName}.{s.from.tableName}
|
||||
<span className="bi-database me-1" />
|
||||
{s.from.databaseName}
|
||||
{
|
||||
s.kind === SourceKind.Metric
|
||||
? ''
|
||||
: '.' /** Metrics dont have table names */
|
||||
}
|
||||
{s.from.tableName}
|
||||
</>
|
||||
)}
|
||||
</Text>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { useCallback, useContext, useMemo } from 'react';
|
||||
import { isString, pickBy } from 'lodash';
|
||||
import isString from 'lodash/isString';
|
||||
import pickBy from 'lodash/pickBy';
|
||||
import { SourceKind, TSource } from '@hyperdx/common-utils/dist/types';
|
||||
import { Accordion, Box, Divider, Flex, Text } from '@mantine/core';
|
||||
|
||||
|
|
@ -37,6 +38,32 @@ export function RowOverviewPanel({
|
|||
return firstRow;
|
||||
}, [data]);
|
||||
|
||||
// TODO: Use source config to select these in SQL, but we'll just
|
||||
// assume OTel column names for now
|
||||
const topLevelAttributeKeys = [
|
||||
'ServiceName',
|
||||
'SpanName',
|
||||
'Duration',
|
||||
'SeverityText',
|
||||
'StatusCode',
|
||||
'StatusMessage',
|
||||
'SpanKind',
|
||||
'TraceId',
|
||||
'SpanId',
|
||||
'ParentSpanId',
|
||||
'ScopeName',
|
||||
'ScopeVersion',
|
||||
];
|
||||
const topLevelAttributes = pickBy(firstRow, (value, key) => {
|
||||
if (value === '') {
|
||||
return false;
|
||||
}
|
||||
if (topLevelAttributeKeys.includes(key)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
const resourceAttributes = firstRow?.__hdx_resource_attributes ?? EMPTY_OBJ;
|
||||
const eventAttributes = firstRow?.__hdx_event_attributes ?? EMPTY_OBJ;
|
||||
const dataAttributes =
|
||||
|
|
@ -138,6 +165,7 @@ export function RowOverviewPanel({
|
|||
'network',
|
||||
'resourceAttributes',
|
||||
'eventAttributes',
|
||||
'topLevelAttributes',
|
||||
]}
|
||||
multiple
|
||||
>
|
||||
|
|
@ -181,6 +209,21 @@ export function RowOverviewPanel({
|
|||
</Accordion.Item>
|
||||
)}
|
||||
|
||||
{Object.keys(topLevelAttributes).length > 0 && (
|
||||
<Accordion.Item value="topLevelAttributes">
|
||||
<Accordion.Control>
|
||||
<Text size="sm" c="gray.2" ps="md">
|
||||
Top Level Attributes
|
||||
</Text>
|
||||
</Accordion.Control>
|
||||
<Accordion.Panel>
|
||||
<Box px="md">
|
||||
<DBRowJsonViewer data={topLevelAttributes} />
|
||||
</Box>
|
||||
</Accordion.Panel>
|
||||
</Accordion.Item>
|
||||
)}
|
||||
|
||||
<Accordion.Item value="eventAttributes">
|
||||
<Accordion.Control>
|
||||
<Text size="sm" c="gray.2" ps="md">
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ export default function DBTracePanel({
|
|||
focusDate,
|
||||
parentSourceId,
|
||||
}: {
|
||||
parentSourceId?: string;
|
||||
childSourceId?: string;
|
||||
parentSourceId?: string | null;
|
||||
childSourceId?: string | null;
|
||||
traceId: string;
|
||||
dateRange: [Date, Date];
|
||||
focusDate: Date;
|
||||
|
|
|
|||
|
|
@ -268,7 +268,7 @@ export async function inferTableSourceConfig({
|
|||
...(isOtelLogSchema
|
||||
? {
|
||||
defaultTableSelectExpression:
|
||||
'Timestamp, ServiceName, SeverityText, Body',
|
||||
'Timestamp, ServiceName as service, SeverityText as level, Body',
|
||||
serviceNameExpression: 'ServiceName',
|
||||
bodyExpression: 'Body',
|
||||
|
||||
|
|
@ -288,7 +288,7 @@ export async function inferTableSourceConfig({
|
|||
implicitColumnExpression: 'SpanName',
|
||||
bodyExpression: 'SpanName',
|
||||
defaultTableSelectExpression:
|
||||
'Timestamp, ServiceName, StatusCode, round(Duration / 1e6), SpanName',
|
||||
'Timestamp, ServiceName as service, StatusCode as level, round(Duration / 1e6) as duration, SpanName',
|
||||
eventAttributesExpression: 'SpanAttributes',
|
||||
serviceNameExpression: 'ServiceName',
|
||||
resourceAttributesExpression: 'ResourceAttributes',
|
||||
|
|
|
|||
|
|
@ -516,7 +516,7 @@ export const SourceSchema = z.object({
|
|||
spanKindExpression: z.string().optional(),
|
||||
statusCodeExpression: z.string().optional(),
|
||||
statusMessageExpression: z.string().optional(),
|
||||
logSourceId: z.string().optional(),
|
||||
logSourceId: z.string().optional().nullable(),
|
||||
|
||||
// OTEL Metrics
|
||||
metricTables: MetricTableSchema.optional(),
|
||||
|
|
|
|||
Loading…
Reference in a new issue