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

Commit 0de11eb

Browse files
committed
connect to data source and readme
1 parent 0c41605 commit 0de11eb

File tree

8 files changed

+65
-104
lines changed

8 files changed

+65
-104
lines changed

README.md

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,43 @@
11
# Pyroscope Grafana Panel Plugin
2-
## Getting started
32

4-
1. Install dependencies
3+
## Getting started
54

6-
```bash
7-
yarn install
5+
1. Create `grafana-plugins` folder
6+
2. Open grafana config:
7+
* MacOS: `vim /usr/local/etc/grafana/grafana.ini`
8+
* Linux: `vim /etc/grafana/grafana.ini`
9+
3. Specify path to your `grafana-plugins` folder:
810
```
9-
10-
2. Build plugin in development mode or run in watch mode
11-
12-
```bash
13-
yarn dev
11+
# Directory where grafana will automatically scan and look for plugins
12+
plugins = /<path_to>/grafana-plugins
1413
```
14+
*Don't forget to remove semicolon at the beginning*
1515

16-
or
16+
4. Clone [pyroscope-panel-plugin]() and [pyroscope-datasource-plugin]() into `grafana-plugins` folder
1717

18-
```bash
19-
yarn watch
18+
5. Visit each plugin folder and build them:
2019
```
21-
22-
3. Build plugin in production mode
23-
24-
```bash
25-
yarn build
20+
yarn install
21+
yarn dev
2622
```
23+
6. Restart Grafana:
24+
* MacOS Homebrew: `brew services restart grafana`
25+
* Linux: `systemctl restart grafana-server`
26+
7. Open Grafana ang go to **Configuratin -> Plugins**
27+
8. Check that plugins are available:
28+
![plugins-list]()
29+
9. Set up data source plugin:
30+
* **Configuration -> Data Sources -> Add data source**
31+
* click on `pyroscope-datasource`
32+
* Specify Pyroscope host in `Endpoint` field:
33+
![endpoint]()
34+
10. Set up panel plugin:
35+
* Add an empty panel on your dashboard
36+
* Select `pyroscop-panel` from Visualization list
37+
* Under panel view in Query tab select `pyroscope-datasource`
38+
* In `Application name` input specify app name
39+
* Click `Apply`
40+
![settings]()
41+
42+
Congratulations! Now you can monitor application flamegraph on your Grafana dashboard!
43+
![]()

docs/assets/dashboard.jpg

193 KB
Loading

docs/assets/endpoint.jpg

26.5 KB
Loading

docs/assets/pluginslist.jpg

23.7 KB
Loading

docs/assets/settings.jpg

395 KB
Loading

src/SimplePanel.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,7 @@ export const SimplePanel: React.FC<Props> = ({ options, data }) => {
1515
<>
1616
<div className={styles.app}>
1717
<div className={`${styles.appContainer} flamegraph-wrapper`}>
18-
<FlameGraphRenderer
19-
viewType="single"
20-
renderURL="/render?name=pyroscope.server.alloc_objects%7B%7D"
21-
options={options}
22-
data={data}
23-
/>
18+
<FlameGraphRenderer options={options} data={data} />
2419
</div>
2520
</div>
2621
</>

src/components/FlameGraphRenderer.tsx

Lines changed: 26 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -77,20 +77,16 @@ class FlameGraphRenderer extends React.Component {
7777
"Reset Flamegraph View"
7878
);
7979
}
80-
81-
this.fetchFlameBearerData(this.props.renderURL)
80+
this.updateFlameBearerData()
8281
}
8382

8483
componentDidUpdate(prevProps, prevState) {
85-
if (this.getParamsFromRenderURL(this.props.renderURL).name != this.getParamsFromRenderURL(prevProps.renderURL).name ||
86-
prevProps.from != this.props.from ||
87-
prevProps.until != this.props.until ||
88-
prevProps.maxNodes != this.props.maxNodes ||
89-
prevProps.refreshToken != this.props.refreshToken ||
90-
prevProps[`${this.props.viewSide}From`] != this.props[`${this.props.viewSide}From`] ||
91-
prevProps[`${this.props.viewSide}Until`] != this.props[`${this.props.viewSide}Until`]
92-
) {
93-
this.fetchFlameBearerData(this.props.renderURL)
84+
const from = this.props.data?.timeRange?.raw.from.valueOf();
85+
const until = this.props.data?.timeRange?.raw.to.valueOf();
86+
const prevFrom = prevProps.data?.timeRange?.raw.from.valueOf();
87+
const prevUntil = prevProps.data?.timeRange?.raw.to.valueOf();
88+
if (from !== prevFrom || until !== prevUntil) {
89+
this.updateFlameBearerData()
9490
}
9591

9692
if (
@@ -101,7 +97,7 @@ class FlameGraphRenderer extends React.Component {
10197
}
10298
}
10399

104-
fetchFlameBearerData() {
100+
updateFlameBearerData() {
105101
const flamebearer = this.props.data.series[this.props.data.series.length - 1].fields[0].values.buffer[0];
106102
deltaDiff(flamebearer.levels);
107103
this.setState({ ...this.state, flamebearer },
@@ -110,15 +106,6 @@ class FlameGraphRenderer extends React.Component {
110106
})
111107
}
112108

113-
getParamsFromRenderURL(inputURL) {
114-
let urlParamsRegexp = /(.*render\?)(?<urlParams>(.*))/
115-
let paramsString = inputURL.match(urlParamsRegexp);
116-
let params = new URLSearchParams(paramsString.groups.urlParams);
117-
let paramsObj = this.paramsToObject(params);
118-
119-
return paramsObj
120-
}
121-
122109
paramsToObject(entries) {
123110
const result = {}
124111
for(const [key, value] of entries) { // each 'entry' is a [key, value] tupple
@@ -240,7 +227,8 @@ class FlameGraphRenderer extends React.Component {
240227
// this is here to debounce resize events (see: https://css-tricks.com/debouncing-throttling-explained-examples/)
241228
// because rendering is expensive
242229
clearTimeout(this.resizeFinish);
243-
this.pxPerLevel = (el[0].contentRect.height - 60) / this.state.flamebearer.levels.length;
230+
const responsiveHeight = (el[0].contentRect.height - 60) / this.state.flamebearer.levels.length;
231+
this.pxPerLevel = responsiveHeight > 20 ? 20 : responsiveHeight;
244232
this.resizeFinish = setTimeout(this.renderCanvas, 50);
245233
};
246234

@@ -464,64 +452,25 @@ class FlameGraphRenderer extends React.Component {
464452
};
465453

466454
render = () => {
467-
468-
let flameGraphPane = (
469-
<div
470-
key={'flamegraph-pane'}
471-
className={this.styles.flamegraphPane}
472-
>
473-
<div className='flamegraph-header'>
474-
<span></span>
475-
<span>Frame width represents {unitsToFlamegraphTitle[this.state.units]}</span>
476-
</div>
477-
<canvas
478-
height="0"
479-
ref={this.canvasRef}
480-
onClick={this.clickHandler}
481-
onMouseMove={this.mouseMoveHandler}
482-
onMouseOut={this.mouseOutHandler}
483-
/>
484-
</div>
485-
)
486-
487-
let panes = [flameGraphPane];
488-
489-
let instructionsText = this.props.viewType === "double" ? `Select ${this.props.viewSide} time range` : null;
490-
let instructionsClassName = this.props.viewType === "double" ? `${this.props.viewSide}-instructions` : null;
491-
492455
return (
493456
<div>
494-
495-
<div>
496-
{/* <ProfilerHeader
497-
view={this.state.view}
498-
handleSearchChange={this.handleSearchChange}
499-
reset={this.reset}
500-
updateView={this.updateView}
501-
resetStyle={this.state.resetStyle}
502-
/> */}
503-
<div className={`${instructionsClassName}-wrapper`}>
504-
<span className={`${instructionsClassName}-text`}>{instructionsText}</span>
505-
</div>
506-
<div className={clsx("flamegraph-container panes-wrapper", { "vertical-orientation": this.props.viewType === "double" })}>
507-
{
508-
panes.map((pane) => (
509-
pane
510-
))
511-
}
512-
{/* { tablePane }
513-
{ flameGraphPane } */}
514-
</div>
515-
{/* <div
516-
className={clsx("no-data-message", {
517-
visible:
518-
this.state.flamebearer && this.state.flamebearer.numTicks === 0,
519-
})}
457+
<div className={clsx("flamegraph-container panes-wrapper")}>
458+
<div
459+
key={'flamegraph-pane'}
460+
className={this.styles.flamegraphPane}
520461
>
521-
<span>
522-
No profiling data available for this application / time range.
523-
</span>
524-
</div> */}
462+
<div className='flamegraph-header'>
463+
<span></span>
464+
<span>Frame width represents {unitsToFlamegraphTitle[this.state.units]}</span>
465+
</div>
466+
<canvas
467+
height="0"
468+
ref={this.canvasRef}
469+
onClick={this.clickHandler}
470+
onMouseMove={this.mouseMoveHandler}
471+
onMouseOut={this.mouseOutHandler}
472+
/>
473+
</div>
525474
</div>
526475
<div className="flamegraph-highlight" style={this.state.highlightStyle} />
527476
<div

src/plugin.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
{
22
"$schema": "https://raw.githubusercontent.com/grafana/grafana/master/docs/sources/developers/plugins/plugin.schema.json",
33
"type": "panel",
4-
"name": "pyroscope-grafana",
5-
"id": "pyroscope-pyroscope-grafana",
4+
"name": "pyroscope-panel",
5+
"id": "pyroscope-panel",
66
"info": {
77
"description": "Pyroscope plugin for grafana",
88
"author": {
9-
"name": "Mike Egorov",
9+
"name": "Pyroscope",
1010
"url": "https://pyroscope.io/"
1111
},
1212
"keywords": [
@@ -35,4 +35,4 @@
3535
"grafanaDependency": ">=7.0.0",
3636
"plugins": []
3737
}
38-
}
38+
}

0 commit comments

Comments
 (0)