Skip to content

Commit 4df639d

Browse files
authored
feat(ourlogs): Use new aliases, add byte renderer (#97725)
### Summary This adds units for the bytes in payload_size and updates the timestamp and observed aliases to not be prefixed by sentry
1 parent 7d3076e commit 4df639d

File tree

15 files changed

+123
-42
lines changed

15 files changed

+123
-42
lines changed

static/app/components/events/ourlogs/ourlogsSection.spec.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {ProjectFixture} from 'sentry-fixture/project';
66
import {render, screen, userEvent, within} from 'sentry-test/reactTestingLibrary';
77

88
import {OurlogsSection} from 'sentry/components/events/ourlogs/ourlogsSection';
9+
import {OurLogKnownFieldKey} from 'sentry/views/explore/logs/types';
910

1011
const TRACE_ID = '00000000000000000000000000000000';
1112

@@ -97,7 +98,7 @@ describe('OurlogsSection', function () {
9798
severity_number: 0,
9899
severity: 'info',
99100
timestamp: now.toISOString(),
100-
'tags[sentry.timestamp_precise,number]': now.getTime() * 1e6,
101+
[OurLogKnownFieldKey.TIMESTAMP_PRECISE]: now.getTime() * 1e6,
101102
message: 'i am a log',
102103
},
103104
],

static/app/utils/discover/fieldRenderers.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ export const SIZE_UNITS = {
191191
};
192192

193193
export const ABYTE_UNITS = [
194+
'byte',
194195
'kilobyte',
195196
'megabyte',
196197
'gigabyte',

static/app/views/dashboards/widgets/timeSeriesWidget/formatters/formatTooltipValue.spec.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ describe('formatTooltipValue', () => {
4646

4747
describe('size', () => {
4848
it.each([
49-
[0, 'byte', '0.0 B'],
49+
[0, 'byte', '0 B'],
5050
[0.712, 'megabyte', '712 KB'],
5151
[1231, 'kibibyte', '1.2 MiB'],
5252
])('Formats %s as %s', (value, unit, formattedValue) => {

static/app/views/explore/logs/fieldRenderers.spec.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ describe('Logs Field Renderers', function () {
4040
organization,
4141
location: {} as any,
4242
theme: ThemeFixture(),
43+
attributeTypes: {},
4344
attributes,
4445
highlightTerms: [],
4546
logColors: {
@@ -107,7 +108,7 @@ describe('Logs Field Renderers', function () {
107108
expect(TimestampRenderer).toBeDefined();
108109
const preciseTimestamp = '1705329045123456789';
109110
const props = makeRendererProps(timestamp, {
110-
'tags[sentry.timestamp_precise,number]': preciseTimestamp,
111+
[OurLogKnownFieldKey.TIMESTAMP_PRECISE]: preciseTimestamp,
111112
});
112113
const result = TimestampRenderer!(props);
113114

static/app/views/explore/logs/fieldRenderers.tsx

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,27 @@ import Version from 'sentry/components/version';
99
import {tct} from 'sentry/locale';
1010
import {defined} from 'sentry/utils';
1111
import {stripAnsi} from 'sentry/utils/ansiEscapeCodes';
12+
import type {EventsMetaType} from 'sentry/utils/discover/eventView';
1213
import {
1314
getFieldRenderer,
1415
type RenderFunctionBaggage,
1516
} from 'sentry/utils/discover/fieldRenderers';
16-
import {parseFunction} from 'sentry/utils/discover/fields';
17+
import {parseFunction, type ColumnValueType} from 'sentry/utils/discover/fields';
1718
import {NumberContainer, VersionContainer} from 'sentry/utils/discover/styles';
1819
import normalizeUrl from 'sentry/utils/url/normalizeUrl';
1920
import {useRelease} from 'sentry/utils/useRelease';
2021
import {QuickContextHoverWrapper} from 'sentry/views/discover/table/quickContext/quickContextWrapper';
2122
import {ContextType} from 'sentry/views/discover/table/quickContext/utils';
2223
import type {AttributesFieldRendererProps} from 'sentry/views/explore/components/traceItemAttributes/attributesTree';
2324
import {stripLogParamsFromLocation} from 'sentry/views/explore/contexts/logs/logsPageParams';
25+
import type {TraceItemResponseAttribute} from 'sentry/views/explore/hooks/useTraceItemDetails';
2426
import {LOG_ATTRIBUTE_LAZY_LOAD_HOVER_TIMEOUT} from 'sentry/views/explore/logs/constants';
2527
import LogsTimestampTooltip from 'sentry/views/explore/logs/logsTimeTooltip';
2628
import {
2729
AlignedCellContent,
2830
ColoredLogCircle,
2931
ColoredLogText,
32+
LogBasicRendererContainer,
3033
LogDate,
3134
LogsHighlight,
3235
WrappingText,
@@ -51,6 +54,10 @@ import {getTraceDetailsUrl} from 'sentry/views/performance/traceDetails/utils';
5154
interface LogFieldRendererProps extends AttributesFieldRendererProps<RendererExtra> {}
5255

5356
export interface RendererExtra extends RenderFunctionBaggage {
57+
attributeTypes: Record<
58+
string,
59+
TraceItemResponseAttribute['type'] | EventsMetaType['fields'][string]
60+
>;
5461
attributes: Record<string, string | number | boolean>;
5562
highlightTerms: string[];
5663
logColors: ReturnType<typeof getLogColors>;
@@ -120,8 +127,8 @@ export function SeverityCircleRenderer(props: Omit<LogFieldRendererProps, 'item'
120127
}
121128

122129
function TimestampRenderer(props: LogFieldRendererProps) {
123-
const preciseTimestamp =
124-
props.extra.attributes?.['tags[sentry.timestamp_precise,number]'];
130+
const preciseTimestamp = props.extra.attributes[OurLogKnownFieldKey.TIMESTAMP_PRECISE];
131+
125132
const timestampToUse = preciseTimestamp
126133
? new Date(Number(preciseTimestamp) / 1_000_000) // Convert nanoseconds to milliseconds
127134
: props.item.value;
@@ -402,6 +409,50 @@ export function LogFieldRenderer(props: LogFieldRendererProps) {
402409
);
403410
}
404411

412+
/**
413+
* Only formats the field the same as discover does, does not apply any additional rendering, but has a container to fix styling.
414+
*/
415+
function BasicDiscoverRenderer(props: LogFieldRendererProps) {
416+
const logMeta: EventsMetaType =
417+
Object.keys(props.meta ?? {}).length > 0 ? props.meta! : logFieldBasicMetas;
418+
const basicRenderer = getFieldRenderer(props.item.fieldKey, logMeta, false);
419+
const attributeType = props.extra.attributeTypes[props.item.fieldKey];
420+
const align = logsFieldAlignment(props.item.fieldKey, attributeType as ColumnValueType);
421+
let castValue: string | number | boolean | null = props.item.value;
422+
// TODO: Values being emitted by ProjectTraceItemDetails and Events should be the same type, and their type names should match (or be casted from rpc types to discover types).
423+
if (
424+
attributeType === 'int' ||
425+
attributeType === 'float' ||
426+
attributeType === 'size' ||
427+
attributeType === 'number' ||
428+
attributeType === 'integer' ||
429+
attributeType === 'duration' ||
430+
attributeType === 'percentage' ||
431+
attributeType === 'rate' ||
432+
attributeType === 'percent_change' ||
433+
attributeType === 'score'
434+
) {
435+
castValue = Number(props.item.value);
436+
}
437+
if (attributeType === 'bool' || attributeType === 'boolean') {
438+
castValue = Boolean(props.item.value);
439+
}
440+
return (
441+
<LogBasicRendererContainer align={align}>
442+
{basicRenderer(
443+
{
444+
[props.item.fieldKey]: castValue,
445+
},
446+
{
447+
unit: logMeta.units[props.item.fieldKey] ?? undefined,
448+
...props.extra,
449+
theme: props.extra.theme,
450+
}
451+
)}
452+
</LogBasicRendererContainer>
453+
);
454+
}
455+
405456
export const LogAttributesRendererMap: Record<
406457
OurLogFieldKey,
407458
(props: LogFieldRendererProps) => React.ReactNode
@@ -415,8 +466,19 @@ export const LogAttributesRendererMap: Record<
415466
[OurLogKnownFieldKey.CODE_FILE_PATH]: CodePathRenderer,
416467
[OurLogKnownFieldKey.RELEASE]: ReleaseRenderer,
417468
[OurLogKnownFieldKey.TEMPLATE]: LogTemplateRenderer,
469+
[OurLogKnownFieldKey.PAYLOAD_SIZE]: BasicDiscoverRenderer,
418470
};
419471

420472
const fullFieldToExistingField: Record<OurLogFieldKey, string> = {
421473
[OurLogKnownFieldKey.TRACE_ID]: 'trace',
422474
};
475+
476+
// Meta returned from TraceItemDetails is empty, in which case we can provide our own meta to map known fields to their types to get the basic rendering working.
477+
const logFieldBasicMetas: EventsMetaType = {
478+
fields: {
479+
[OurLogKnownFieldKey.PAYLOAD_SIZE]: 'size',
480+
},
481+
units: {
482+
[OurLogKnownFieldKey.PAYLOAD_SIZE]: 'byte', // SIZE_UNITS
483+
},
484+
};

static/app/views/explore/logs/logsTab.spec.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {TraceItemAttributeProvider} from 'sentry/views/explore/contexts/traceIte
1414
import {AlwaysPresentLogFields} from 'sentry/views/explore/logs/constants';
1515
import {LogsQueryParamsProvider} from 'sentry/views/explore/logs/logsQueryParamsProvider';
1616
import {LogsTabContent} from 'sentry/views/explore/logs/logsTab';
17+
import {OurLogKnownFieldKey} from 'sentry/views/explore/logs/types';
1718
import {TraceItemDataset} from 'sentry/views/explore/types';
1819
import type {PickableDays} from 'sentry/views/explore/utils';
1920

@@ -82,7 +83,7 @@ describe('LogsTabContent', function () {
8283
severity_text: 'info',
8384
timestamp: '2025-04-10T19:21:12+00:00',
8485
message: 'some log message1',
85-
'tags[sentry.timestamp_precise,number]': 1.7443128722090732e18,
86+
[OurLogKnownFieldKey.TIMESTAMP_PRECISE]: 1.7443128722090732e18,
8687
},
8788
{
8889
'sentry.item_id': '0196212624a17144aa392d01420256a2',
@@ -92,7 +93,7 @@ describe('LogsTabContent', function () {
9293
severity_text: 'info',
9394
timestamp: '2025-04-10T19:21:10+00:00',
9495
message: 'some log message2',
95-
'tags[sentry.timestamp_precise,number]': 1.744312870049196e18,
96+
[OurLogKnownFieldKey.TIMESTAMP_PRECISE]: 1.744312870049196e18,
9697
},
9798
],
9899
meta: {
@@ -104,7 +105,7 @@ describe('LogsTabContent', function () {
104105
severity_text: 'string',
105106
timestamp: 'string',
106107
message: 'string',
107-
'tags[sentry.timestamp_precise,number]': 'number',
108+
[OurLogKnownFieldKey.TIMESTAMP_PRECISE]: 'number',
108109
},
109110
units: {
110111
'sentry.item_id': null,
@@ -114,7 +115,7 @@ describe('LogsTabContent', function () {
114115
severity_text: null,
115116
timestamp: null,
116117
message: null,
117-
'tags[sentry.timestamp_precise,number]': null,
118+
[OurLogKnownFieldKey.TIMESTAMP_PRECISE]: null,
118119
},
119120
isMetricsData: false,
120121
isMetricsExtractedData: false,
@@ -192,8 +193,7 @@ describe('LogsTabContent', function () {
192193
dataset: 'ourlogs',
193194
yAxis: 'count(message)',
194195
interval: '1h',
195-
query:
196-
'severity:error tags[sentry.timestamp_precise,number]:<=1508208040000000000',
196+
query: 'severity:error timestamp_precise:<=1508208040000000000',
197197
}),
198198
})
199199
);

static/app/views/explore/logs/styles.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import PageFilterBar from 'sentry/components/organizations/pageFilterBar';
88
import Panel from 'sentry/components/panels/panel';
99
import {GRID_BODY_ROW_HEIGHT} from 'sentry/components/tables/gridEditable/styles';
1010
import {space} from 'sentry/styles/space';
11+
import {NumberContainer} from 'sentry/utils/discover/styles';
1112
import {chonkStyled} from 'sentry/utils/theme/theme.chonk';
1213
import {withChonk} from 'sentry/utils/theme/withChonk';
1314
import {unreachable} from 'sentry/utils/unreachable';
@@ -116,6 +117,12 @@ export const LogFirstCellContent = styled('div')`
116117
align-items: center;
117118
`;
118119

120+
export const LogBasicRendererContainer = styled('span')<{align?: 'left' | 'right'}>`
121+
${NumberContainer} {
122+
text-align: ${p => p.align || 'left'};
123+
}
124+
`;
125+
119126
export const DetailsBody = styled('div')`
120127
display: flex;
121128
border-bottom: 1px solid ${p => p.theme.innerBorder};

static/app/views/explore/logs/tables/logsAggregateTable.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ export function LogsAggregateTable() {
105105
: (row[column.key] as string | number);
106106
const extra: RendererExtra = {
107107
attributes: row,
108+
attributeTypes: data?.meta?.fields ?? {},
108109
highlightTerms: [],
109110
logColors: getLogColors(SeverityLevel.DEFAULT, theme),
110111
location,

static/app/views/explore/logs/tables/logsTable.spec.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ describe('LogsTable', function () {
8282
'10.5.55.212 - - [05/May/2025:18:36:15 +0000] "POST /v1/automation/autofix/state HTTP/1.1" 200 293642 "-" "python-requests/2.32.3"',
8383
'sentry.release': '985bae16edc2f3f8132e346a4f6c5a559f7c968b',
8484
'code.file.path': '/usr/local/lib/python3.11/dist-packages/gunicorn/glogging.py',
85-
'tags[sentry.timestamp_precise,number]': 1.7464701752771756e18,
85+
[OurLogKnownFieldKey.TIMESTAMP_PRECISE]: 1.7464701752771756e18,
8686
},
8787
{
8888
'sentry.item_id': '0196a1bc00e3720f8d47c84c53131891',
@@ -95,7 +95,7 @@ describe('LogsTable', function () {
9595
'10.5.58.189 - - [05/May/2025:18:36:14 +0000] "POST /v0/issues/similar-issues HTTP/1.1" 200 131 "-" "python-urllib3/2.2.2"',
9696
'sentry.release': '985bae16edc2f3f8132e346a4f6c5a559f7c968b',
9797
'code.file.path': '/usr/local/lib/python3.11/dist-packages/gunicorn/glogging.py',
98-
'tags[sentry.timestamp_precise,number]': 1.746470174947077e18,
98+
[OurLogKnownFieldKey.TIMESTAMP_PRECISE]: 1.746470174947077e18,
9999
},
100100
{
101101
'sentry.item_id': '0196a1bc007c7dfbbe099b6328e41d12',
@@ -108,7 +108,7 @@ describe('LogsTable', function () {
108108
'10.5.62.140 - - [05/May/2025:18:36:14 +0000] "POST /v0/issues/similar-issues HTTP/1.1" 200 586 "-" "python-urllib3/2.2.2"',
109109
'sentry.release': '985bae16edc2f3f8132e346a4f6c5a559f7c968b',
110110
'code.file.path': '/usr/local/lib/python3.11/dist-packages/gunicorn/glogging.py',
111-
'tags[sentry.timestamp_precise,number]': 1.7464701748443016e18,
111+
[OurLogKnownFieldKey.TIMESTAMP_PRECISE]: 1.7464701748443016e18,
112112
},
113113
],
114114
meta: {
@@ -122,7 +122,7 @@ describe('LogsTable', function () {
122122
message: 'string',
123123
'sentry.release': 'string',
124124
'code.file.path': 'string',
125-
'tags[sentry.timestamp_precise,number]': 'number',
125+
[OurLogKnownFieldKey.TIMESTAMP_PRECISE]: 'number',
126126
},
127127
},
128128
isLoading: false,

static/app/views/explore/logs/tables/logsTableRow.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ export const LogRowContent = memo(function LogRowContent({
234234
location,
235235
organization,
236236
attributes: dataRow,
237+
attributeTypes: meta?.fields ?? {},
237238
theme,
238239
projectSlug,
239240
};
@@ -406,6 +407,8 @@ function LogRowDetails({
406407
data?.attributes?.reduce((it, {name, value}) => ({...it, [name]: value}), {
407408
[OurLogKnownFieldKey.TIMESTAMP]: dataRow[OurLogKnownFieldKey.TIMESTAMP],
408409
}) ?? {};
410+
const attributeTypes =
411+
data?.attributes?.reduce((it, {name, type}) => ({...it, [name]: type}), {}) ?? {};
409412

410413
if (missingLogId || isError) {
411414
return (
@@ -437,6 +440,7 @@ function LogRowDetails({
437440
organization,
438441
projectSlug,
439442
attributes,
443+
attributeTypes,
440444
theme,
441445
},
442446
})}
@@ -456,6 +460,7 @@ function LogRowDetails({
456460
organization,
457461
projectSlug,
458462
attributes,
463+
attributeTypes,
459464
theme,
460465
disableLazyLoad: true, // We disable lazy loading in the log details view since a user has to open it first.
461466
}}

0 commit comments

Comments
 (0)