Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update nodejs examples #3550

Closed
wants to merge 10 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 24 additions & 43 deletions docs/internal/contributing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,26 @@ Use `make lint` to ensure formatting is correct.

## Building Grafana Pyroscope

To build:
These are steps for building Pyroscope in single binary mode. See [development.md](./development.md) for more advanced methods building and running Pyroscope locally for development.

### Building a binary

To build a binary, run:

```
make go/bin
```

### Building tests

To run the unit test suite:

```
make go/test
```

### Building a docker image

To build the docker image use:

```
Expand Down Expand Up @@ -76,62 +84,34 @@ brew install pkg-config cairo pango libpng jpeg giflib librsvg

See https://github.com/Automattic/node-canvas/issues/1662

#### Running examples locally
replace `image: grafana/pyroscope` with the local tag name you got from docker-image/pyroscope/build (i.e):
## Running Grafana Pyroscope locally

```
pyroscope:
image: us.gcr.io/kubernetes-dev/pyroscope:main-470125e1-WIP
ports:
- '4040:4040'
```

#### Run with Pyroscope with embedded Grafana + Explore Profiles
### Running examples

In order to quickly test the whole stack it is possible to run an embedded Grafana by using target parameter:
First, find the example you want to run and move to that directory. For example:

```
go run ./cmd/pyroscope --target all,embedded-grafana
cd examples/language-sdk-instrumentation/golang-push/rideshare
```

This will start additional to Pyroscope on `:4040`, the embedded Grafana on port `:4041`.
Then in the `docker-compose.yml` file, replace the image for the `pyroscope` service with the image built in the [Building a docker image](###building-a-docker-image) section.

#### Front end development

**Versions for development tools**:
- Node v18
- Yarn v1.22

The front end code is all located in the `public/app` directory, although its `plugin.json`
file exists at the repository root.

To run the local front end source code:
```sh
yarn
yarn dev
```yaml
pyroscope:
image: us.gcr.io/kubernetes-dev/pyroscope:main-470125e1-WIP
```

This will install / update front end dependencies and launch a process that will build
the front end code, launch a pyroscope web app service at `http://localhost:4041`,
and keep that web app updated any time you save the front end source code.
The resulting web app will not initially be connected to a pyroscope server,
so all attempts to fetch data will fail.
### Run with embedded Grafana + Explore Profiles

To launch a pyroscope server for development purposes:
```sh
yarn backend:dev
```
In order to quickly test the whole stack it is possible to run an embedded Grafana by using target parameter:

This yarn script actually runs the following:
```sh
make build run 'PARAMS=--config.file ./cmd/pyroscope/pyroscope.yaml'
```
go run ./cmd/pyroscope --target all,embedded-grafana
```

It will take a while for this process to build and start serving pyroscope data, but
once it is fully active, the pyroscope web app service at `http://localhost:4041`
will be able to interact with it.
In addition to starting Pyroscope on `:4040`, this starts an embedded Grafana on port `:4041`.

### Dependency management
## Dependency management

We use [Go modules](https://golang.org/cmd/go/#hdr-Modules__module_versions__and_more) to manage dependencies on external packages.
However, we don't commit the `vendor/` folder.
Expand All @@ -154,6 +134,7 @@ make go/mod

Commit the changes to `go.mod` and `go.sum` before submitting your pull request.


## Documentation

The Grafana Pyroscope documentation is compiled into a website published at [grafana.com](https://grafana.com/).
Expand Down
116 changes: 116 additions & 0 deletions docs/internal/contributing/development.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Developing Grafana Pyroscope

This document contains helpful tips and tricks when developing Pyroscope.

## Run Pyroscope using a debugger

A debugger allows you to step through the code and inspect variables and understand control flow as the program is running.

### VSCode debugger

To attach a debugger to Pyroscope from VSCode, perform the following steps in the root of the Pyroscope project:

1. `mkdir .vscode`
1. `touch .vscode/tasks.json`
1. Add the following configuration. This creates a build task in VSCode which will build the Pyroscope binary with debug symbols.
```jsonc
{
"version": "2.0.0",
"tasks": [
{
"type": "shell",
// Name this whatever you like.
"label": "pyroscope: build debug",
"command": "make",
"args": [
"EMBEDASSETS=\"\"",
"go/bin-pyroscope-debug"
],
"group": "build",
"detail": "Build debug Pyroscope server"
}
]
}
```
1. `touch .vscode/launch.json`
1. Add the following configuration. This will add a launch task which will launch the debug Pyroscope binary and attach a debugger.
```jsonc
{
"version": "0.2.0",
"configurations": [
{
// Name this whatever you like.
"name": "Launch debug Pyroscope server",
"type": "go",
"request": "launch",
"mode": "exec",
"program": "./pyroscope",
"args": [
"-config.file",
// Point this to a Pyroscope configuration file.
"./.vscode/config.yaml",
],
"env": {
// env vars go here. For example:
// "GITHUB_CLIENT_ID": "my_client_id"
},
// This must match the name of the build task.
"preLaunchTask": "pyroscope: build debug",
}
]
}
```
1. `touch .vscode/config.yaml`
1. Add the following configuration. These are the settings your Pyroscope instance will use.
```yaml
server:
http_listen_port: 4040

# Not necessary, but this can help avoid some system limits when making
# certain queries.
limits:
max_query_length: 0
max_query_lookback: 0
```
1. You should be able to open the "Run and Debug" menu and select "Launch debug Pyroscope server" from the drop down.
<img src="../images/pyroscope-launch-debugger.png">
1. Now when you set breakpoints in the gutter, the debugger will break appropriately and logs will be emitted in the "DEBUG CONSOLE" terminal tab.
<img src="../images/pyroscope-debugger-running.png">

## Run a local Pyroscope frontend

Pyroscope ships with an embedded UI. This is UI is stable and largely in maintenance mode. If you find a need to develop the UI, follow these steps to run it without embedding it into the Pyroscope binary.

You will need these tools:

- Node v18
- Yarn v1.22

The frontend code is all located in the `public/app` directory, although its `plugin.json`
file exists at the repository root.

To run the local frontend source code:
```sh
yarn
yarn dev
```

This will install/update the frontend dependencies and launch a process that will build the frontend code, launch a pyroscope web app service at `http://localhost:4041`, and keep that web app updated any time you save the frontend source code. The resulting web app will not initially be connected to a Pyroscope server,
so all attempts to fetch data will fail.

To launch a Pyroscope server for development purposes:
```sh
yarn backend:dev
```

This yarn script actually runs the following:
```sh
make build run 'PARAMS=--config.file ./cmd/pyroscope/pyroscope.yaml'
```

> ![NOTE]
> Alternatively, you can connect to any Pyroscope instance as long as it is running on `:4040`. If you need to connect to a Pyroscope instance running on a different port, please modify the [webpack config](https://github.com/grafana/pyroscope/blob/main/scripts/webpack/webpack.dev.js#L14-L15) accordingly.

It will take a while for this process to build and start serving pyroscope data, but
once it is fully active, the pyroscope web app service at `http://localhost:4041`
will be able to interact with it.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Choose a language folder to select an example for your language of choice.

# How Pyroscope works

Pyroscope identifies performance issues in your application by continuously profiling the code.

If you've never used a profiler before, then welcome!
Expand Down
18 changes: 18 additions & 0 deletions examples/language-sdk-instrumentation/load.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { check } from 'k6';
import http from 'k6/http';

export const options = {
duration: '5m',
vus: 3,
};

const URL = __ENV.TARGET_URL || 'http://localhost:5000';

export default function() {
for (const endpoint of ['car', 'scooter', 'bike']) {
const res = http.get(`${URL}/${endpoint}`);
check(res, {
'status is 200': (r) => r.status === 200,
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/node_modules
/build
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/node_modules
/build
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ FROM node:latest
WORKDIR /app

COPY package.json yarn.lock .
RUN yarn

COPY tsconfig.json .
RUN yarn
COPY *.ts .
RUN yarn build
ENV DEBUG=pyroscope
CMD ["yarn", "run", "run"]

ENV DEBUG=pyroscope
CMD ["yarn", "start"]
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@ const Pyroscope = require('@pyroscope/nodejs');
const SourceMapper = Pyroscope.default.SourceMapper;

const port = process.env['PORT'] || 5000;

const region = process.env['REGION'] || 'default';
const appName = process.env['APP_NAME'] || 'express-ts-inline';
const pyroscopeUrl = process.env['PYROSCOPE_URL'] || 'http://pyroscope:4040';

const app = express();
app.use(morgan('dev'));

app.get('/', (req, res) => {
app.get('/', (_, res) => {
res.send('Available routes are: /bike, /car, /scooter');
});

const genericSearchHandler = (p: number) => (req: any, res: any) => {
const genericSearchHandler = (p: number) => (_: any, res: any) => {
const time = +new Date() + p * 1000;
let i = 0;
while (+new Date() < time) {
Expand All @@ -30,11 +31,13 @@ app.get('/bike', function bikeSearchHandler(req, res) {
genericSearchHandler(0.2)(req, res)
);
});

app.get('/car', function carSearchHandler(req, res) {
Pyroscope.wrapWithLabels({ vehicle: 'car' }, () =>
genericSearchHandler(1)(req, res)
);
});

app.get('/scooter', function scooterSearchHandler(req, res) {
Pyroscope.wrapWithLabels({ vehicle: 'scooter' }, () =>
genericSearchHandler(0.5)(req, res)
Expand All @@ -44,14 +47,14 @@ app.get('/scooter', function scooterSearchHandler(req, res) {
SourceMapper.create(['.'])
.then((sourceMapper) => {
Pyroscope.init({
appName: 'nodejs',
serverAddress: 'http://pyroscope:4040',
appName: appName,
serverAddress: pyroscopeUrl,
sourceMapper: sourceMapper,
tags: { region },
});
Pyroscope.start();
})
.catch((e) => {
.catch((e: any) => {
console.error(e);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
"scripts": {
"build": "tsc",
"test": "echo \"Error: no test specified\" && exit 1",
"run": "node build/index.js"
"start": "node build/index.js",
"start:local": "yarn build && PYROSCOPE_URL=http://localhost:4040 yarn start",
"up": "yarn down && docker compose up --build --force-recreate --no-deps",
"down": "docker compose down"
},
"author": "",
"license": "Apache-2.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/node_modules
/build
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ FROM node:latest
WORKDIR /app

COPY package.json yarn.lock .
RUN yarn

COPY tsconfig.json .
RUN yarn
COPY *.ts .
RUN yarn build
ENV DEBUG=pyroscope
CMD ["yarn", "run", "run"]

ENV DEBUG=pyroscope
CMD ["yarn", "start"]
Loading
Loading