@parca/profile 0.16.226 → 0.16.227

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,10 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [0.16.227](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.225...@parca/profile@0.16.227) (2023-08-21)
7
+
8
+ **Note:** Version bump only for package @parca/profile
9
+
6
10
  ## [0.16.226](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.225...@parca/profile@0.16.226) (2023-08-16)
7
11
 
8
12
  **Note:** Version bump only for package @parca/profile
@@ -14,7 +14,7 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
14
14
  import { useState } from 'react';
15
15
  import { CopyToClipboard } from 'react-copy-to-clipboard';
16
16
  import { divide, getLastItem, valueFormatter } from '@parca/utilities';
17
- import { FIELD_CUMULATIVE, FIELD_DIFF, FIELD_FUNCTION_FILE_NAME, FIELD_FUNCTION_START_LINE, FIELD_LABELS, FIELD_LOCATION_ADDRESS, FIELD_LOCATION_LINE, FIELD_MAPPING_BUILD_ID, FIELD_MAPPING_FILE, } from '../ProfileIcicleGraph/IcicleGraphArrow';
17
+ import { FIELD_CUMULATIVE, FIELD_DIFF, FIELD_FUNCTION_FILE_NAME, FIELD_FUNCTION_START_LINE, FIELD_LOCATION_ADDRESS, FIELD_LOCATION_LINE, FIELD_MAPPING_BUILD_ID, FIELD_MAPPING_FILE, } from '../ProfileIcicleGraph/IcicleGraphArrow';
18
18
  import { nodeLabel } from '../ProfileIcicleGraph/IcicleGraphArrow/utils';
19
19
  import { hexifyAddress, truncateString, truncateStringReverse } from '../utils';
20
20
  import { ExpandOnHover } from './ExpandOnHoverValue';
@@ -64,7 +64,8 @@ onCopy, row, }) => {
64
64
  const locationLine = table.getChild(FIELD_LOCATION_LINE)?.get(row) ?? 0n;
65
65
  const functionFilename = table.getChild(FIELD_FUNCTION_FILE_NAME)?.get(row) ?? '';
66
66
  const functionStartLine = table.getChild(FIELD_FUNCTION_START_LINE)?.get(row) ?? 0n;
67
- const labelsString = table.getChild(FIELD_LABELS)?.get(row) ?? '{}';
67
+ const pprofLabelPrefix = 'pprof_labels.';
68
+ const labelColumnNames = table.schema.fields.filter(field => field.name.startsWith(pprofLabelPrefix));
68
69
  const getTextForFile = () => {
69
70
  if (functionFilename === '')
70
71
  return '<unknown>';
@@ -73,11 +74,13 @@ onCopy, row, }) => {
73
74
  : `${functionStartLine !== 0n ? ` +${functionStartLine}` : ''}`}`;
74
75
  };
75
76
  const file = getTextForFile();
76
- const labels = Object.entries(JSON.parse(labelsString))
77
- .sort((a, b) => {
78
- return a[0].localeCompare(b[0]);
79
- })
80
- .map((l) => (_jsx("span", { className: "mr-3 inline-block rounded-lg bg-gray-200 px-2 py-1 text-xs font-bold text-gray-700 dark:bg-gray-700 dark:text-gray-400", children: `${l[0]}="${l[1]}"` }, l[0])));
81
- return (_jsxs(_Fragment, { children: [_jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "File" }), _jsx("td", { className: "w-3/4 break-all", children: functionFilename === '' ? (_jsx(NoData, {})) : (_jsx(CopyToClipboard, { onCopy: onCopy, text: file, children: _jsx("button", { className: "cursor-pointer whitespace-nowrap text-left", children: _jsx(ExpandOnHover, { value: file, displayValue: truncateStringReverse(file, 40) }) }) })) })] }), _jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "Address" }), _jsx("td", { className: "w-3/4 break-all", children: locationAddress === 0n ? (_jsx(NoData, {})) : (_jsx(CopyToClipboard, { onCopy: onCopy, text: hexifyAddress(locationAddress), children: _jsx("button", { className: "cursor-pointer", children: hexifyAddress(locationAddress) }) })) })] }), _jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "Binary" }), _jsx("td", { className: "w-3/4 break-all", children: mappingFile === '' ? (_jsx(NoData, {})) : (_jsx(CopyToClipboard, { onCopy: onCopy, text: mappingFile, children: _jsx("button", { className: "cursor-pointer", children: getLastItem(mappingFile) }) })) })] }), _jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "Build Id" }), _jsx("td", { className: "w-3/4 break-all", children: mappingBuildID === '' ? (_jsx(NoData, {})) : (_jsx(CopyToClipboard, { onCopy: onCopy, text: mappingBuildID, children: _jsx("button", { className: "cursor-pointer", children: truncateString(getLastItem(mappingBuildID), 28) }) })) })] }), labelsString !== '{}' && (_jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "Labels" }), _jsx("td", { className: "w-3/4 break-all", children: labels })] }))] }));
77
+ const labelPairs = labelColumnNames
78
+ .map((field, i) => [
79
+ labelColumnNames[i].name.slice(pprofLabelPrefix.length),
80
+ table.getChild(field.name)?.get(row) ?? '',
81
+ ])
82
+ .filter(value => value[1] !== '');
83
+ const labels = labelPairs.map((l) => (_jsx("span", { className: "mr-3 inline-block rounded-lg bg-gray-200 px-2 py-1 text-xs font-bold text-gray-700 dark:bg-gray-700 dark:text-gray-400", children: `${l[0]}="${l[1]}"` }, l[0])));
84
+ return (_jsxs(_Fragment, { children: [_jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "File" }), _jsx("td", { className: "w-3/4 break-all", children: functionFilename === '' ? (_jsx(NoData, {})) : (_jsx(CopyToClipboard, { onCopy: onCopy, text: file, children: _jsx("button", { className: "cursor-pointer whitespace-nowrap text-left", children: _jsx(ExpandOnHover, { value: file, displayValue: truncateStringReverse(file, 40) }) }) })) })] }), _jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "Address" }), _jsx("td", { className: "w-3/4 break-all", children: locationAddress === 0n ? (_jsx(NoData, {})) : (_jsx(CopyToClipboard, { onCopy: onCopy, text: hexifyAddress(locationAddress), children: _jsx("button", { className: "cursor-pointer", children: hexifyAddress(locationAddress) }) })) })] }), _jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "Binary" }), _jsx("td", { className: "w-3/4 break-all", children: mappingFile === '' ? (_jsx(NoData, {})) : (_jsx(CopyToClipboard, { onCopy: onCopy, text: mappingFile, children: _jsx("button", { className: "cursor-pointer", children: getLastItem(mappingFile) }) })) })] }), _jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "Build Id" }), _jsx("td", { className: "w-3/4 break-all", children: mappingBuildID === '' ? (_jsx(NoData, {})) : (_jsx(CopyToClipboard, { onCopy: onCopy, text: mappingBuildID, children: _jsx("button", { className: "cursor-pointer", children: truncateString(getLastItem(mappingBuildID), 28) }) })) })] }), labelPairs.length > 0 && (_jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "Labels" }), _jsx("td", { className: "w-3/4 break-all", children: labels })] }))] }));
82
85
  };
83
86
  export default GraphTooltipArrowContent;
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import { Table } from 'apache-arrow';
3
3
  import { type NavigateFunction } from '@parca/utilities';
4
+ export declare const FIELD_LABELS_ONLY = "labels_only";
4
5
  export declare const FIELD_MAPPING_FILE = "mapping_file";
5
6
  export declare const FIELD_MAPPING_BUILD_ID = "mapping_build_id";
6
7
  export declare const FIELD_LOCATION_ADDRESS = "location_address";
@@ -20,6 +20,7 @@ import GraphTooltipArrowContent from '../../GraphTooltipArrow/Content';
20
20
  import ColorStackLegend from './ColorStackLegend';
21
21
  import { IcicleNode, RowHeight } from './IcicleGraphNodes';
22
22
  import { extractFeature } from './utils';
23
+ export const FIELD_LABELS_ONLY = 'labels_only';
23
24
  export const FIELD_MAPPING_FILE = 'mapping_file';
24
25
  export const FIELD_MAPPING_BUILD_ID = 'mapping_build_id';
25
26
  export const FIELD_LOCATION_ADDRESS = 'location_address';
@@ -13,18 +13,25 @@
13
13
  import { EVERYTHING_ELSE, FEATURE_TYPES } from '@parca/store';
14
14
  import { getLastItem } from '@parca/utilities';
15
15
  import { hexifyAddress } from '../../utils';
16
- import { FIELD_FUNCTION_NAME, FIELD_LOCATION_ADDRESS, FIELD_MAPPING_FILE } from './index';
16
+ import { FIELD_FUNCTION_NAME, FIELD_LABELS_ONLY, FIELD_LOCATION_ADDRESS, FIELD_MAPPING_FILE, } from './index';
17
17
  export function nodeLabel(table, row, level, showBinaryName) {
18
18
  const functionName = table.getChild(FIELD_FUNCTION_NAME)?.get(row);
19
+ const labelsOnly = table.getChild(FIELD_LABELS_ONLY)?.get(row);
20
+ const pprofLabelPrefix = 'pprof_labels.';
21
+ const labelColumnNames = table.schema.fields.filter(field => field.name.startsWith(pprofLabelPrefix));
19
22
  if (functionName !== null && functionName !== '') {
20
- if (level === 1 && functionName.startsWith('{') && functionName.endsWith('}')) {
21
- return Object.entries(JSON.parse(functionName))
22
- .sort(([a], [b]) => a.localeCompare(b))
23
- .map(([k, v]) => `${k}="${v}"`)
24
- .join(', ');
25
- }
26
23
  return functionName;
27
24
  }
25
+ if (level === 1 && labelsOnly !== null && labelsOnly) {
26
+ return labelColumnNames
27
+ .map((field, i) => [
28
+ labelColumnNames[i].name.slice(pprofLabelPrefix.length),
29
+ table.getChild(field.name)?.get(row) ?? '',
30
+ ])
31
+ .filter(value => value[1] !== '')
32
+ .map(([k, v]) => `${k}="${v}"`)
33
+ .join(', ');
34
+ }
28
35
  let mappingString = '';
29
36
  if (showBinaryName) {
30
37
  const mappingFile = table.getChild(FIELD_MAPPING_FILE)?.get(row) ?? '';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parca/profile",
3
- "version": "0.16.226",
3
+ "version": "0.16.227",
4
4
  "description": "Profile viewing libraries",
5
5
  "dependencies": {
6
6
  "@parca/client": "^0.16.84",
@@ -47,5 +47,5 @@
47
47
  "access": "public",
48
48
  "registry": "https://registry.npmjs.org/"
49
49
  },
50
- "gitHead": "059cb869a7c59f1eeff510c2a52de47d223c1132"
50
+ "gitHead": "f1693104879d96c4291e3b96c5e37d8e11e3e356"
51
51
  }
@@ -181,7 +181,10 @@ const TooltipMetaInfo = ({
181
181
  const locationLine: bigint = table.getChild(FIELD_LOCATION_LINE)?.get(row) ?? 0n;
182
182
  const functionFilename: string = table.getChild(FIELD_FUNCTION_FILE_NAME)?.get(row) ?? '';
183
183
  const functionStartLine: bigint = table.getChild(FIELD_FUNCTION_START_LINE)?.get(row) ?? 0n;
184
- const labelsString: string = table.getChild(FIELD_LABELS)?.get(row) ?? '{}';
184
+ const pprofLabelPrefix = 'pprof_labels.';
185
+ const labelColumnNames = table.schema.fields.filter(field =>
186
+ field.name.startsWith(pprofLabelPrefix)
187
+ );
185
188
 
186
189
  const getTextForFile = (): string => {
187
190
  if (functionFilename === '') return '<unknown>';
@@ -194,20 +197,22 @@ const TooltipMetaInfo = ({
194
197
  };
195
198
  const file = getTextForFile();
196
199
 
197
- const labels = Object.entries(JSON.parse(labelsString))
198
- .sort((a, b) => {
199
- return a[0].localeCompare(b[0]);
200
- })
201
- .map(
202
- (l): React.JSX.Element => (
203
- <span
204
- key={l[0]}
205
- className="mr-3 inline-block rounded-lg bg-gray-200 px-2 py-1 text-xs font-bold text-gray-700 dark:bg-gray-700 dark:text-gray-400"
206
- >
207
- {`${l[0]}="${l[1] as string}"`}
208
- </span>
209
- )
210
- );
200
+ const labelPairs = labelColumnNames
201
+ .map((field, i) => [
202
+ labelColumnNames[i].name.slice(pprofLabelPrefix.length),
203
+ table.getChild(field.name)?.get(row) ?? '',
204
+ ])
205
+ .filter(value => value[1] !== '');
206
+ const labels = labelPairs.map(
207
+ (l): React.JSX.Element => (
208
+ <span
209
+ key={l[0]}
210
+ className="mr-3 inline-block rounded-lg bg-gray-200 px-2 py-1 text-xs font-bold text-gray-700 dark:bg-gray-700 dark:text-gray-400"
211
+ >
212
+ {`${l[0] as string}="${l[1] as string}"`}
213
+ </span>
214
+ )
215
+ );
211
216
 
212
217
  return (
213
218
  <>
@@ -263,7 +268,7 @@ const TooltipMetaInfo = ({
263
268
  )}
264
269
  </td>
265
270
  </tr>
266
- {labelsString !== '{}' && (
271
+ {labelPairs.length > 0 && (
267
272
  <tr>
268
273
  <td className="w-1/4">Labels</td>
269
274
  <td className="w-3/4 break-all">{labels}</td>
@@ -37,6 +37,7 @@ import ColorStackLegend from './ColorStackLegend';
37
37
  import {IcicleNode, RowHeight, mappingColors} from './IcicleGraphNodes';
38
38
  import {extractFeature} from './utils';
39
39
 
40
+ export const FIELD_LABELS_ONLY = 'labels_only';
40
41
  export const FIELD_MAPPING_FILE = 'mapping_file';
41
42
  export const FIELD_MAPPING_BUILD_ID = 'mapping_build_id';
42
43
  export const FIELD_LOCATION_ADDRESS = 'location_address';
@@ -17,7 +17,13 @@ import {EVERYTHING_ELSE, FEATURE_TYPES, type Feature} from '@parca/store';
17
17
  import {getLastItem} from '@parca/utilities';
18
18
 
19
19
  import {hexifyAddress} from '../../utils';
20
- import {FIELD_FUNCTION_NAME, FIELD_LOCATION_ADDRESS, FIELD_MAPPING_FILE} from './index';
20
+ import {
21
+ FIELD_FUNCTION_NAME,
22
+ FIELD_LABELS,
23
+ FIELD_LABELS_ONLY,
24
+ FIELD_LOCATION_ADDRESS,
25
+ FIELD_MAPPING_FILE,
26
+ } from './index';
21
27
 
22
28
  export function nodeLabel(
23
29
  table: Table<any>,
@@ -26,16 +32,26 @@ export function nodeLabel(
26
32
  showBinaryName: boolean
27
33
  ): string {
28
34
  const functionName: string | null = table.getChild(FIELD_FUNCTION_NAME)?.get(row);
35
+ const labelsOnly: boolean | null = table.getChild(FIELD_LABELS_ONLY)?.get(row);
36
+ const pprofLabelPrefix = 'pprof_labels.';
37
+ const labelColumnNames = table.schema.fields.filter(field =>
38
+ field.name.startsWith(pprofLabelPrefix)
39
+ );
29
40
  if (functionName !== null && functionName !== '') {
30
- if (level === 1 && functionName.startsWith('{') && functionName.endsWith('}')) {
31
- return Object.entries(JSON.parse(functionName))
32
- .sort(([a], [b]) => a.localeCompare(b))
33
- .map(([k, v]) => `${k}="${v as string}"`)
34
- .join(', ');
35
- }
36
41
  return functionName;
37
42
  }
38
43
 
44
+ if (level === 1 && labelsOnly !== null && labelsOnly) {
45
+ return labelColumnNames
46
+ .map((field, i) => [
47
+ labelColumnNames[i].name.slice(pprofLabelPrefix.length),
48
+ table.getChild(field.name)?.get(row) ?? '',
49
+ ])
50
+ .filter(value => value[1] !== '')
51
+ .map(([k, v]) => `${k as string}="${v as string}"`)
52
+ .join(', ');
53
+ }
54
+
39
55
  let mappingString = '';
40
56
  if (showBinaryName) {
41
57
  const mappingFile: string | null = table.getChild(FIELD_MAPPING_FILE)?.get(row) ?? '';