Skip to content
This repository was archived by the owner on Jul 19, 2023. It is now read-only.

Commit a512ee3

Browse files
petethepigeh-am
andauthored
feat(ui): explore page (#704)
* feat: implements explore page * text change * type fixes * one fix * adds types * types fix * fix logo * pull latest version --------- Co-authored-by: Eduardo Aleixo <eduardo@pyroscope.io>
1 parent 982a19f commit a512ee3

File tree

8 files changed

+127
-18
lines changed

8 files changed

+127
-18
lines changed

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,15 @@
3030
"@types/jest": "^29.5.0",
3131
"@types/jquery": "^3.5.13",
3232
"@types/lodash.debounce": "^4.0.6",
33+
"@types/lodash.groupby": "^4.6.7",
34+
"@types/lodash.map": "^4.6.13",
3335
"@types/prismjs": "^1.26.0",
34-
"@types/react": "^18.0.0",
3536
"@types/react-datepicker": "^4.3.4",
3637
"@types/react-dom": "^18.0.11",
3738
"@types/react-helmet": "^6.1.5",
3839
"@types/react-outside-click-handler": "^1.3.1",
3940
"@types/react-router-dom": "5.3.0",
41+
"@types/react": "^18.0.0",
4042
"@typescript-eslint/eslint-plugin": "^5.59.5",
4143
"@typescript-eslint/parser": "^5.59.5",
4244
"copy-webpack-plugin": "^11.0.0",
@@ -74,7 +76,7 @@
7476
"@szhsin/react-menu": "3.5.2",
7577
"graphviz-react": "^1.2.5",
7678
"jquery": "^3.6.4",
77-
"pyroscope-oss": "git+https://github.com/pyroscope-io/pyroscope.git#b63a15e",
79+
"pyroscope-oss": "git+https://github.com/pyroscope-io/pyroscope.git#72e54cc",
7880
"react": "^18.2.0",
7981
"react-datepicker": "^4.7.0",
8082
"react-debounce-input": "^3.2.5",

pkg/querier/http.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/prometheus/common/model"
1313
"github.com/prometheus/prometheus/model/labels"
1414
"github.com/prometheus/prometheus/promql/parser"
15+
"github.com/pyroscope-io/pyroscope/pkg/structs/flamebearer"
1516
"github.com/pyroscope-io/pyroscope/pkg/util/attime"
1617
"golang.org/x/sync/errgroup"
1718
"google.golang.org/grpc/codes"
@@ -126,6 +127,8 @@ func (q *QueryHandlers) Render(w http.ResponseWriter, req *http.Request) {
126127
return
127128
}
128129

130+
groupBy := req.URL.Query()["groupBy"]
131+
129132
var resFlame *connect.Response[querierv1.SelectMergeStacktracesResponse]
130133
g, ctx := errgroup.WithContext(req.Context())
131134
g.Go(func() error {
@@ -143,6 +146,7 @@ func (q *QueryHandlers) Render(w http.ResponseWriter, req *http.Request) {
143146
Start: selectParams.Start,
144147
End: selectParams.End,
145148
Step: timelineStep,
149+
GroupBy: groupBy,
146150
}))
147151

148152
return err
@@ -162,6 +166,21 @@ func (q *QueryHandlers) Render(w http.ResponseWriter, req *http.Request) {
162166
fb := ExportToFlamebearer(resFlame.Msg.Flamegraph, profileType)
163167
fb.Timeline = timeline.New(seriesVal, selectParams.Start, selectParams.End, int64(timelineStep))
164168

169+
if len(groupBy) > 0 {
170+
fb.Groups = make(map[string]*flamebearer.FlamebearerTimelineV1)
171+
for _, s := range resSeries.Msg.Series {
172+
key := "*"
173+
for _, l := range s.Labels {
174+
// right now we only support one group by
175+
if l.Name == groupBy[0] {
176+
key = l.Value
177+
break
178+
}
179+
}
180+
fb.Groups[key] = timeline.New(s, selectParams.Start, selectParams.End, int64(timelineStep))
181+
}
182+
}
183+
165184
w.Header().Add("Content-Type", "application/json")
166185
if err := json.NewEncoder(w).Encode(fb); err != nil {
167186
http.Error(w, err.Error(), http.StatusInternalServerError)

public/app/app.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { createBrowserHistory } from 'history';
1212
import { ROUTES } from '@phlare/pages/routes';
1313
import { SingleView } from '@phlare/pages/SingleView';
1414
import { ComparisonView } from '@phlare/pages/ComparisonView';
15+
import { ExploreView } from '@phlare/pages/ExploreView';
1516
import { DiffView } from '@phlare/pages/DiffView';
1617
import { LoadAppNames } from '@phlare/components/LoadAppNames';
1718
import { Sidebar } from '@phlare/components/Sidebar';
@@ -32,6 +33,9 @@ function App() {
3233
<TenantWall>
3334
<LoadAppNames>
3435
<Switch>
36+
<Route exact path={ROUTES.EXPLORE_VIEW}>
37+
<ExploreView />
38+
</Route>
3539
<Route exact path={ROUTES.SINGLE_VIEW}>
3640
<SingleView />
3741
</Route>

public/app/components/Sidebar.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
2-
import { faWindowMaximize } from '@fortawesome/free-regular-svg-icons';
2+
import { faWindowMaximize } from '@fortawesome/free-regular-svg-icons/faWindowMaximize';
3+
import { faSearch } from '@fortawesome/free-solid-svg-icons/faSearch';
34
import { faChartBar } from '@fortawesome/free-solid-svg-icons/faChartBar';
45
import { faColumns } from '@fortawesome/free-solid-svg-icons/faColumns';
56
import { faChevronLeft } from '@fortawesome/free-solid-svg-icons/faChevronLeft';
@@ -24,7 +25,7 @@ import clsx from 'clsx';
2425
import { useWindowWidth } from '@react-hook/window-size';
2526
import { isRouteActive, ROUTES } from '@phlare/pages/routes';
2627
import Logo from '@phlare/static/logo.svg';
27-
import styles from '@webapp/components/Sidebar.module.css';
28+
import styles from '@phlare/components/Sidebar.module.css';
2829
import { SidebarTenant } from '@phlare/components/SidebarTenant';
2930

3031
export function Sidebar() {
@@ -59,6 +60,17 @@ export function Sidebar() {
5960
</SidebarHeader>
6061
<SidebarContent>
6162
<Menu iconShape="square" popperArrow>
63+
<MenuItem
64+
active={isRouteActive(pathname, ROUTES.EXPLORE_VIEW)}
65+
icon={<Icon icon={faSearch} />}
66+
>
67+
Tag Explorer
68+
<NavLink
69+
activeClassName="active-route"
70+
to={{ pathname: ROUTES.EXPLORE_VIEW, search }}
71+
exact
72+
/>
73+
</MenuItem>
6274
<MenuItem
6375
active={isRouteActive(pathname, ROUTES.SINGLE_VIEW)}
6476
icon={<Icon icon={faWindowMaximize} />}

public/app/overrides/services/render.ts

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
Profile,
44
Groups,
55
FlamebearerProfileSchema,
6+
GroupsSchema,
67
} from '@pyroscope/models/src';
78
import { z } from 'zod';
89
import type { ZodError } from 'zod';
@@ -112,17 +113,44 @@ export async function renderDiff(
112113
);
113114
}
114115

115-
export interface RenderExploreOutput {
116-
profile: Profile;
117-
groups: Groups;
116+
const RenderExploreSchema = FlamebearerProfileSchema.extend({
117+
groups: z.preprocess((groups) => {
118+
const groupNames = Object.keys(groups as Groups);
119+
return groupNames.length
120+
? groupNames
121+
.filter((g) => !!g.trim())
122+
.reduce(
123+
(acc, current) => ({
124+
...acc,
125+
[current]: (groups as Groups)[current],
126+
}),
127+
{}
128+
)
129+
: groups;
130+
}, GroupsSchema),
131+
}).transform((values) => {
132+
return {
133+
profile: values,
134+
groups: values.groups,
135+
};
136+
});
137+
138+
interface RenderExploreProps extends Omit<RenderSingleProps, 'maxNodes'> {
139+
groupBy: string;
140+
grouByTagValue: string;
118141
}
142+
143+
export type RenderExploreOutput = z.infer<typeof RenderExploreSchema>;
144+
119145
export async function renderExplore(
120-
props: unknown,
146+
props: RenderExploreProps,
121147
controller?: {
122148
signal?: AbortSignal;
123149
}
124-
) {
125-
return Result.err<RenderExploreOutput, { message: string }>({
126-
message: 'TODO: implement ',
150+
): Promise<Result<RenderExploreOutput, RequestError | ZodError>> {
151+
const url = buildRenderURL(props);
152+
const response = await requestWithOrgID(`/pyroscope/${url}&format=json`, {
153+
signal: controller?.signal,
127154
});
155+
return parseResponse<RenderExploreOutput>(response, RenderExploreSchema);
128156
}

public/app/pages/ExploreView.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import React from 'react';
2+
3+
import TagExplorerView from '@webapp/pages/TagExplorerView';
4+
5+
export function ExploreView() {
6+
return <TagExplorerView />;
7+
}

public/app/pages/routes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export enum ROUTES {
22
SINGLE_VIEW = '/',
3+
EXPLORE_VIEW = '/explore',
34
COMPARISON_VIEW = '/comparison',
45
COMPARISON_DIFF_VIEW = '/comparison-diff',
56
}

yarn.lock

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3148,9 +3148,9 @@
31483148
integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==
31493149

31503150
"@pyroscope/nodejs@^0.2.5":
3151-
version "0.2.5"
3152-
resolved "https://registry.yarnpkg.com/@pyroscope/nodejs/-/nodejs-0.2.5.tgz#cbfbf3421a12193555d1dbc23107c6f3e7869856"
3153-
integrity sha512-R36ZooJwSZ+K35RNjBvUDpGyH+ZkkspLNeHVuMl2Nh8HyEKi44IZFksCIGNvThUg8lKQlLKaZKrgYlLG660oEw==
3151+
version "0.2.6"
3152+
resolved "https://registry.yarnpkg.com/@pyroscope/nodejs/-/nodejs-0.2.6.tgz#edc91bb230f36dbddaf854fa5b31257cf7f1ada5"
3153+
integrity sha512-F37ROH//HzO7zKm2S7CtNG8OAp+i4ADg4erQR9D57BrSgi8+3Jjp5s5PWqyJABC6IzsABgGrentPobBDr8QdsA==
31543154
dependencies:
31553155
axios "^0.26.1"
31563156
debug "^4.3.3"
@@ -3652,6 +3652,20 @@
36523652
dependencies:
36533653
"@types/lodash" "*"
36543654

3655+
"@types/lodash.groupby@^4.6.7":
3656+
version "4.6.7"
3657+
resolved "https://registry.yarnpkg.com/@types/lodash.groupby/-/lodash.groupby-4.6.7.tgz#35fdb9647f100450d1004f65f74cbd964cdb567a"
3658+
integrity sha512-dFUR1pqdMgjIBbgPJ/8axJX6M1C7zsL+HF4qdYMQeJ7XOp0Qbf37I3zh9gpXr/ks6tgEYPDRqyZRAnFYvewYHQ==
3659+
dependencies:
3660+
"@types/lodash" "*"
3661+
3662+
"@types/lodash.map@^4.6.13":
3663+
version "4.6.13"
3664+
resolved "https://registry.yarnpkg.com/@types/lodash.map/-/lodash.map-4.6.13.tgz#7d776611d4c0345e48cfdfe466d7b291b31d1d13"
3665+
integrity sha512-kppRBzlpuvQQsr7R2nv/DDDZds8fglRFNAK70WUOkOC18KOcuQ22oQF9Kgy5Z2v/eDNkBm0ltrT6FThSkuWwow==
3666+
dependencies:
3667+
"@types/lodash" "*"
3668+
36553669
"@types/lodash@*":
36563670
version "4.14.192"
36573671
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.192.tgz#5790406361a2852d332d41635d927f1600811285"
@@ -3677,11 +3691,16 @@
36773691
resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c"
36783692
integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==
36793693

3680-
"@types/node@*", "@types/node@>=13.7.0":
3694+
"@types/node@*":
36813695
version "18.15.11"
36823696
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.11.tgz#b3b790f09cb1696cffcec605de025b088fa4225f"
36833697
integrity sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==
36843698

3699+
"@types/node@>=13.7.0":
3700+
version "20.2.3"
3701+
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.2.3.tgz#b31eb300610c3835ac008d690de6f87e28f9b878"
3702+
integrity sha512-pg9d0yC4rVNWQzX8U7xb4olIOFuuVL9za3bzMT2pu2SU0SNEi66i2qrvhE2qt0HvkhuCaWJu7pLNOt/Pj8BIrw==
3703+
36853704
"@types/node@^14.14.31":
36863705
version "14.18.43"
36873706
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.43.tgz#679e000d9f1d914132ea295b4a1ffdf20370ec49"
@@ -10498,6 +10517,11 @@ minipass@^4.0.0:
1049810517
resolved "https://registry.yarnpkg.com/minipass/-/minipass-4.2.5.tgz#9e0e5256f1e3513f8c34691dd68549e85b2c8ceb"
1049910518
integrity sha512-+yQl7SX3bIT83Lhb4BVorMAHVuqsskxRdlmO9kTpyukp8vsm2Sn/fUOV9xlnG8/a5JsypJzap21lz/y3FBMJ8Q==
1050010519

10520+
minipass@^5.0.0:
10521+
version "5.0.0"
10522+
resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d"
10523+
integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==
10524+
1050110525
minizlib@^1.3.3:
1050210526
version "1.3.3"
1050310527
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d"
@@ -11974,9 +11998,9 @@ pure-rand@^6.0.0:
1197411998
resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.0.1.tgz#31207dddd15d43f299fdcdb2f572df65030c19af"
1197511999
integrity sha512-t+x1zEHDjBwkDGY5v5ApnZ/utcd4XYDiJsaQQoptTXgUXX95sDg1elCdJghzicm7n2mbCBJ3uYWr6M22SO19rg==
1197612000

11977-
"pyroscope-oss@git+https://github.com/pyroscope-io/pyroscope.git#b63a15e":
12001+
"pyroscope-oss@git+https://github.com/pyroscope-io/pyroscope.git#72e54cc":
1197812002
version "0.37.2"
11979-
resolved "git+https://github.com/pyroscope-io/pyroscope.git#b63a15ec7d8a515229666ed32c5be8f9132e1794"
12003+
resolved "git+https://github.com/pyroscope-io/pyroscope.git#72e54ccfcbb4812f87f8fc6840545079096c5462"
1198012004
dependencies:
1198112005
"@babel/plugin-transform-runtime" "^7.16.4"
1198212006
"@babel/preset-env" "^7.10.4"
@@ -13814,7 +13838,7 @@ tar@^4.4.12:
1381413838
safe-buffer "^5.2.1"
1381513839
yallist "^3.1.1"
1381613840

13817-
tar@^6.0.2, tar@^6.1.0, tar@^6.1.11:
13841+
tar@^6.0.2, tar@^6.1.0:
1381813842
version "6.1.13"
1381913843
resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.13.tgz#46e22529000f612180601a6fe0680e7da508847b"
1382013844
integrity sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==
@@ -13826,6 +13850,18 @@ tar@^6.0.2, tar@^6.1.0, tar@^6.1.11:
1382613850
mkdirp "^1.0.3"
1382713851
yallist "^4.0.0"
1382813852

13853+
tar@^6.1.11:
13854+
version "6.1.15"
13855+
resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.15.tgz#c9738b0b98845a3b344d334b8fa3041aaba53a69"
13856+
integrity sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==
13857+
dependencies:
13858+
chownr "^2.0.0"
13859+
fs-minipass "^2.0.0"
13860+
minipass "^5.0.0"
13861+
minizlib "^2.1.1"
13862+
mkdirp "^1.0.3"
13863+
yallist "^4.0.0"
13864+
1382913865
temp-dir@^1.0.0:
1383013866
version "1.0.0"
1383113867
resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d"

0 commit comments

Comments
 (0)