Skip to content
7 changes: 7 additions & 0 deletions .changeset/honest-mice-applaud.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@hyperdx/common-utils": patch
"@hyperdx/api": patch
"@hyperdx/app": patch
---

feat: Add custom trace-level attributes above trace waterfall
3 changes: 3 additions & 0 deletions packages/api/src/models/source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ export const Source = mongoose.model<ISource>(
statusCodeExpression: String,
statusMessageExpression: String,
spanEventsValueExpression: String,
highlightedTraceAttributeExpressions: {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does the ordering matter here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ordering of elements in this array? No I don't think it matters - the Event Tags are sorted before they're displayed client-side. Why?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since it's an array type, it makes sense to sort them before deploying, or we can sort them during query time

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way we end up sorting them on the UI can depend on the values that are queried for each attribute and for each trace. There also should not be very many attributes (dozens at most, I would guess) so I don't think it should be any issue with sorting them on the client side when used.

type: mongoose.Schema.Types.Array,
},

metricTables: {
type: {
Expand Down
21 changes: 17 additions & 4 deletions packages/app/src/DBSearchPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
DisplayType,
Filter,
SourceKind,
TSource,
} from '@hyperdx/common-utils/dist/types';
import {
ActionIcon,
Expand Down Expand Up @@ -1091,21 +1092,32 @@ function DBSearchPage() {
({
where,
whereLanguage,
source,
}: {
where: SearchConfig['where'];
whereLanguage: SearchConfig['whereLanguage'];
source?: TSource;
}) => {
const qParams = new URLSearchParams({
where: where || searchedConfig.where || '',
whereLanguage: whereLanguage || 'sql',
from: searchedTimeRange[0].getTime().toString(),
to: searchedTimeRange[1].getTime().toString(),
select: searchedConfig.select || '',
source: searchedSource?.id || '',
filters: JSON.stringify(searchedConfig.filters ?? []),
isLive: 'false',
liveInterval: interval.toString(),
});

// When generating a search based on a different source,
// filters and select for the current source are not preserved.
if (source && source.id !== searchedSource?.id) {
qParams.append('where', where || '');
qParams.append('source', source.id);
} else {
qParams.append('select', searchedConfig.select || '');
qParams.append('where', where || searchedConfig.where || '');
qParams.append('filters', JSON.stringify(searchedConfig.filters ?? []));
qParams.append('source', searchedSource?.id || '');
}
Comment thread
pulpdrew marked this conversation as resolved.
Resolved

return `/search?${qParams.toString()}`;
},
[
Expand Down Expand Up @@ -1829,6 +1841,7 @@ function DBSearchPage() {
dbSqlRowTableConfig,
isChildModalOpen: isDrawerChildModalOpen,
setChildModalOpen: setDrawerChildModalOpen,
source: searchedSource,
}}
config={dbSqlRowTableConfig}
sourceId={searchedConfig.source}
Expand Down
67 changes: 67 additions & 0 deletions packages/app/src/components/DBHighlightedAttributesList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { useContext, useMemo } from 'react';
import { TSource } from '@hyperdx/common-utils/dist/types';
import { Flex } from '@mantine/core';

import { RowSidePanelContext } from './DBRowSidePanel';
import EventTag from './EventTag';

export type HighlightedAttribute = {
source: TSource;
displayedKey: string;
value: string;
sql: string;
lucene?: string;
};

export function DBHighlightedAttributesList({
attributes = [],
}: {
attributes: HighlightedAttribute[];
}) {
const {
onPropertyAddClick,
generateSearchUrl,
source: contextSource,
} = useContext(RowSidePanelContext);

const sortedAttributes = useMemo(() => {
return attributes.sort(
(a, b) =>
a.displayedKey.localeCompare(b.displayedKey) ||
a.value.localeCompare(b.value),
);
}, [attributes]);

return (
<Flex wrap="wrap" gap="2px" mb="md">
{sortedAttributes.map(({ displayedKey, value, sql, lucene, source }) => (
<EventTag
displayedKey={displayedKey}
name={lucene ? lucene : sql}
nameLanguage={lucene ? 'lucene' : 'sql'}
value={value as string}
key={`${displayedKey}-${value}-${source.id}`}
{...(onPropertyAddClick && contextSource?.id === source.id
? {
onPropertyAddClick,
sqlExpression: sql,
}
: {
onPropertyAddClick: undefined,
sqlExpression: undefined,
})}
generateSearchUrl={
generateSearchUrl
? (query, queryLanguage) =>
generateSearchUrl({
where: query || '',
whereLanguage: queryLanguage ?? 'lucene',
source,
})
: undefined
}
/>
))}
</Flex>
);
}
6 changes: 2 additions & 4 deletions packages/app/src/components/DBRowOverviewPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,11 @@ export function RowOverviewPanel({
: {};

const _generateSearchUrl = useCallback(
(query?: string, timeRange?: [Date, Date]) => {
(query?: string, queryLanguage?: 'sql' | 'lucene') => {
return (
generateSearchUrl?.({
where: query,
whereLanguage: 'lucene',
whereLanguage: queryLanguage,
}) ?? '/'
);
},
Expand Down Expand Up @@ -195,8 +195,6 @@ export function RowOverviewPanel({
<Box px="md">
<NetworkPropertySubpanel
eventAttributes={flattenedEventAttributes}
onPropertyAddClick={onPropertyAddClick}
generateSearchUrl={_generateSearchUrl}
/>
</Box>
</Accordion.Panel>
Expand Down
3 changes: 3 additions & 0 deletions packages/app/src/components/DBRowSidePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,11 @@ export type RowSidePanelContextProps = {
generateSearchUrl?: ({
where,
whereLanguage,
source,
}: {
where: SearchConfig['where'];
whereLanguage: SearchConfig['whereLanguage'];
source?: TSource;
}) => string;
generateChartUrl?: (config: {
aggFn: string;
Expand All @@ -61,6 +63,7 @@ export type RowSidePanelContextProps = {
dbSqlRowTableConfig?: ChartConfigWithDateRange;
isChildModalOpen?: boolean;
setChildModalOpen?: (open: boolean) => void;
source?: TSource;
};

export const RowSidePanelContext = createContext<RowSidePanelContextProps>({});
Expand Down
4 changes: 2 additions & 2 deletions packages/app/src/components/DBRowSidePanelHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,11 @@ export default function DBRowSidePanelHeader({
const maxBoxHeight = 120;

const _generateSearchUrl = useCallback(
(query?: string, timeRange?: [Date, Date]) => {
(query?: string, queryLanguage?: 'sql' | 'lucene') => {
return (
generateSearchUrl?.({
where: query,
whereLanguage: 'lucene',
whereLanguage: queryLanguage,
}) ?? '/'
);
},
Expand Down
Loading
Loading