blob: ab24dd76b9c5cdfd68ad27032389597259db79dc [file] [log] [blame] [view]
# SkiaPerf Server
The Performance Dashboard reads performance data from databases and serves
interactive dashboards to highlight how a commit impacts performance, allowing
for easy exploration and annotation.
The product is particularly useful for:
- **Chrome Developers** who are interested in performance regressions.
- **Marketing Teams** who need to track, visualize, and communicate product's
performance enhancements.
# Table of Contents
- [Developing](#developing)
- [First Time Setup](#first-time-setup)
- [Build](#build)
- [Test](#test)
- [Running locally](#running-locally)
- [Troubleshooting](#troubleshooting)
- [Creating a CL](#creating-a-cl)
- [Debugging and Profiling](#debugging-and-profiling)
- [About](#about)
- [Production Instances](#production-instances)
- [Terminology](#terminology)
- [History](#history)
- [Other Documentation](#other-documentation)
# Developing
## First Time Setup
First check out this repo and get all the dependencies as described in the
[top-level README.md](../README.md), including the Cloud SDK, which is needed to
run tests locally.
## Build
All building and testing is done by Bazel (optionally wrapped with Bazelisk),
but there is a Makefile that records regularly used commands.
To build the full project:
```
bazelisk build --config=mayberemote //perf/...
```
## Test
To run all the tests:
```
bazelisk test --config=mayberemote //perf/...
```
Note the first time you run this it will fail and inform you of the gcloud
simulators that need to be running in the background and how to start them.
### Test parameters
- `--test_output=streamed`: A blaze flag forcing tests to run locally and display logs directly to your terminal as they happen.
- `--test_arg=--no-single-run`: Passes --no-single-run to the Karma test runner. It keeps the Karma server running after the initial test execution, useful for debugging in a browser.
- `--test_arg=--auto-watch`: Passes --auto-watch to Karma. Makes Karma watch for file changes and automatically re-run tests when changes are detected.
### Debug Karma tests
1. Run a test with the debug arguments
`bazelisk test //perf/modules/regressions-page-sk:regressions-page-sk_test --test_output=streamed --test_arg=--no-single-run --test_arg=--auto-watch`
2. Open the application in your browser on port `9876`. [Screenshot 1](https://screenshot.googleplex.com/7K5Jr4PBz5hCB3d.png).
3. See assertion errors in the console if any. Find your sources, add a debug breakpoint. Rerun the test by refreshing the page. [Screenshot 2](https://screenshot.googleplex.com/Bq4QfPLMrBdAbyT.png).
## Running locally
There are several ways to run Perf locally depending on your needs.
### Running with a local demo database
This is the most common way to run Perf for frontend development. It uses a
local database with pre-populated demo data.
- To run with a fresh database (demo data is re-ingested on every run):
```
make run-demo-instance
```
- To run without tearing down the database between runs:
```
make run-demo-instance-db-persist
```
After the server starts, navigate to http://localhost:8002.
### Running against a production database
For backend changes, you may want to run your local instance against a copy of a
production database.
```
./run_with_spanner.sh p=<project> i=<instance> d=<database> config=<config_path>
```
For example, to run against the internal Chrome perf instance:
```
./run_with_spanner.sh p=skia-infra-corp i=tfgen-spanid-20241205020733610 d=chrome_int config=./configs/spanner/chrome-internal.json
```
**Parameters:**
- `p`: The GCP project. `skia-infra-corp` for internal instances,
`skia-infra-public` for public ones.
- `i`: The Spanner instance ID.
- `d`: The Spanner database name.
- `config`: Path to the instance configuration file. See `perf/configs/` for
examples.
### Running with authentication
If you are working on features that require login, you can run a local
authentication proxy. This proxy will sit in front of the Perf server and handle
authentication before forwarding requests to it. To start this setup:
```
make run-auth-proxy-before-demo-instance
```
Then run the server
[as described above](#running-against-a-production-database).
After the server starts, navigate to http://localhost:8003.
### Running individual component demos
You can view demo/test pages of a web components by running `demopage.sh` from
the root of the repo and passing in the relative path of the web component you
want to view, for example:
```
./demopage.sh perf/modules/day-range-sk
```
Additionally, the remote backend can be reverse-proxied such that the demo page
server will forward APIs under `/_/` to the remote backend
(`ENV_REMOTE_ENDPOINT`)
```
ENV_REMOTE_ENDPOINT='https://v8-perf.skia.org' ./demopage.sh perf/modules/day-range-sk
```
or
```
ENV_REMOTE_ENDPOINT='https://v8-perf.skia.org' bazelisk run //perf/modules/plot-summary-sk:demo_page_server
```
This will allow the demo page to fetch the real data.
Note you need to have `entr` installed for this to work:
```
sudo apt install entr
```
### Troubleshooting
- If you see errors related to ptrace scope, you may need to run:
```
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
```
- If you get `INVALID_ARGUMENT: Invalid credentials path specified:
/acct_credentials.json`, check your gcloud configuration and make sure you
are logged in:
```
gcloud auth application-default login
```
- If you see a `PermissionDenied` error related to the issue tracker API key
when running locally (e.g., `failed to access secret version: rpc error:
code = PermissionDenied desc = Permission 'secretmanager.versions.access'
denied for resource
'projects/skia-infra-public/secrets/perf-issue-tracker-apikey/versions/latest'`),
you can disable issue tracker integration in your local configuration file.
For example, if you are using `perf/configs/spanner/chrome-internal.json`:
1. Change `"notifications": "anomalygroup"` to `"notifications": "none"`.
2. Delete the entire `issue_tracker_config` section from the file.
## Creating a CL
To create a new CL (Change List) in Gerrit, follow these steps. For more
detailed information and best practices, please refer to the
[Skia Gerrit documentation](https://skia.org/docs/dev/contrib/submit/).
1. Create a new branch from `origin/main`:
```
git checkout -b <your-branch-name> -t origin/main
```
2. Make your changes and commit them.
3. Upload for review:
```
git cl upload
```
### Pulling changes from the CL
Instead of a `git pull`, you need to `cherry-pick` the patch from the remote to your local branch.
Command example:
```
git fetch https://skia.googlesource.com/buildbot refs/changes/96/1052696/5 \
&& git cherry-pick FETCH_HEAD
```
- `96`: This is the last two digits of the change number.
- `1052696`: This is the full change number in Gerrit.
- `5`: This is the patch set number. Gerrit creates a new patch set for each revision uploaded
to the same change. So, this fetches the state of the 5th version of change 1052696.
You can check how many patch sets you have in the
[Gerrit UI](https://screenshot.googleplex.com/8ZhhcoqmWku8xoF.png).
# Debugging and Profiling
When running the application locally, a debug server is also started on port 9000. This server exposes Go's standard `pprof` profiling data, which is useful
for debugging performance issues and memory leaks.
To get meaningful profiles, you may want to generate some load on the server
first, for example by loading several different graphs in the UI.
### Profiling with pprof
You can connect to the profiling endpoints using `go tool pprof`. For example,
to inspect the heap profile:
```
go tool pprof "http://localhost:9000/debug/pprof/heap"
```
Once in the `pprof` interactive console, you can use commands like `top` to see
the top memory consumers or `web` to visualize the call graph.
For internal use, you can also use `pprof` to visualize the profile as a flame
graph and compare it with another profile:
```
pprof -flame -symbolize=none (profile)
```
### Checking for Goroutine Leaks
To get a full stack dump of all running goroutines, which can help identify
leaks, visit the following URL in your browser or use `curl`:
```
http://localhost:9000/debug/pprof/goroutine?debug=2
```
# About
## Production Instances
The following are some example production instances. For the complete list,
refer to the configurations in the `perf/configs/` directory.
- **Chrome Perf**: https://chrome-perf.corp.goog/m/
- **Skia Perf**: https://skia-perf.luci.app/
- **V8 Perf**: https://v8-perf.skia.org/
- ...
## Terminology
- **Benchmark**: A top-level test name.
- **Test**: A specific test case within a benchmark.
- **Subtest**: A further breakdown of a test.
- **Bot**: The device or machine that runs the tests.
- **Trace**: A single line on a graph, representing measurements for a single
test over time. A trace has a unique key, which is a combination of its
properties (e.g., benchmark, test, subtest, bot, etc.).
- **Traceset**: The set of key-value pairs that uniquely identifies a trace.
- **X-axis**: Always represents commit position or timestamp.
- **Anomaly**: A statistically significant change in a trace, which could be a
regression or an improvement.
- **Frame**: A chunk of trace data stored in the database.
- **Sheriff**: A person or tool responsible for monitoring a set of tests for
regressions.
- **ChromePerf**: The legacy implementation of Perf.
- **Catapult**: The repository for the legacy Perf implementation.
See also
[Chromium Infra Glossary](https://chromium.googlesource.com/chromium/src/+/HEAD/docs/infra/glossary.md).
## History
The current Perf infrastructure in this repo was originally developed for Skia.
In 2023, a project began to unify it with Chrome's performance tooling,
replacing a legacy Python-based system. This unification effort involves
consolidating features from both platforms onto this modern Go and TypeScript
stack, with the goal of eventually deprecating the older system.
# Other Documentation
| File | Description |
| --------------------------------------------------- | ---------------------------------------------------------------- |
| [`ai_generated_doc.md`](./docs/ai_generated_doc.md) | Overview of the system by Gemini |
| [`API.md`](./API.md) | How to use the HTTP/JSON API for alerts. |
| [`BACKUPS.md`](./BACKUPS.md) | Instructions for backing up regression and alert data. |
| [`CHECKLIST.md`](./CHECKLIST.md) | A checklist for launching a new Perf instance. |
| [`DESIGN.md`](./DESIGN.md) | The design documentation for Perf. |
| [`FORMAT.md`](./FORMAT.md) | Details on the Skia Perf JSON data format. |
| [`PERFSERVER.md`](./PERFSERVER.md) | Documentation for the `perfserver` command-line tool. |
| [`PERFTOOL.md`](./PERFTOOL.md) | Documentation for the `perf-tool` command-line tool. |
| [`PROD.md`](./PROD.md) | A manual for operating Perf in a production environment. |
| [`Spanner.md`](./Spanner.md) | Information on the Spanner integration and running the emulator. |
| [`TRIAGE.md`](./TRIAGE.md) | Design for the regression triage page. |