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

feat(apps/price_pusher): add prom metrics #2491

Merged
merged 18 commits into from
Mar 19, 2025
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
528aae2
add prom metrics
cctdaniel Mar 17, 2025
342ddbf
resolve lock
cctdaniel Mar 17, 2025
e55be6d
feat: add wallet balance metrics and alerts; update price feed metrics
cctdaniel Mar 18, 2025
b007d78
fix; revert pnpm lock
cctdaniel Mar 18, 2025
2da9377
feat: update README with new wallet balance metrics and monitoring in…
cctdaniel Mar 18, 2025
d1a180e
chore: add grafana-dashboard.json to .gitignore
cctdaniel Mar 18, 2025
cef1a9f
chore: remove commented-out example services from docker-compose.metr…
cctdaniel Mar 18, 2025
a478455
remove unused code
cctdaniel Mar 18, 2025
0b5f597
address readme comments
cctdaniel Mar 19, 2025
8ad268e
chore: update sample configuration files and README for Grafana and P…
cctdaniel Mar 19, 2025
1f7d073
refactor: simplify metrics handling and enhance README dashboard desc…
cctdaniel Mar 19, 2025
62cb38c
feat: add update conditions tracking and update related metrics in RE…
cctdaniel Mar 19, 2025
7cf6259
feat: implement EVM balance tracker and integrate with metrics
cctdaniel Mar 19, 2025
08ea7db
refactor: update Grafana dashboard expressions and simplify error tra…
cctdaniel Mar 19, 2025
48bfa09
feat: update metrics tracking for price updates and errors, enhancing…
cctdaniel Mar 19, 2025
8ca483b
feat: enhance README and alerts configuration with updated metrics an…
cctdaniel Mar 19, 2025
9210f30
refactor: reorganize balance tracker files and consolidate interfaces…
cctdaniel Mar 19, 2025
19ebf18
chore: bump version to 9.1.2 in price pusher package
cctdaniel Mar 19, 2025
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
148 changes: 148 additions & 0 deletions apps/price_pusher/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,3 +259,151 @@ pushed twice and you won't pay additional costs most of the time.** However, the
conditions in the RPCs because they are often behind a load balancer which can sometimes cause rejected
transactions to land on-chain. You can reduce the chances of additional cost overhead by reducing the
pushing frequency.

## Prometheus Metrics

The price_pusher now supports Prometheus metrics to monitor the health and performance of the price update service. Metrics are exposed via an HTTP endpoint that can be scraped by Prometheus.

### Available Metrics

The following metrics are available:

- **pyth_price_last_published_time** (Gauge): The last published time of a price feed in unix timestamp
- **pyth_price_updates_total** (Counter): Total number of price updates pushed to the chain
- **pyth_price_feeds_total** (Gauge): Total number of price feeds being monitored
- **pyth_price_update_errors_total** (Counter): Total number of errors encountered during price updates
- **pyth_update_conditions_total** (Counter): Count of update condition checks by status (YES/NO/EARLY)
- **pyth_wallet_balance** (Gauge): Current wallet balance of the price pusher in native token units

### Configuration

Metrics are enabled by default and can be configured using the following command-line options:

- `--enable-metrics`: Enable or disable the Prometheus metrics server (default: true)
- `--metrics-port`: Port for the Prometheus metrics server (default: 9090)

Example:

```bash
pnpm run dev evm --config config.evm.mainnet.json --metrics-port 9091
```

### Running Locally with Docker

You can run the monitoring stack (Prometheus and Grafana) using the provided docker-compose configuration:

1. Use the sample docker-compose file for metrics:

```bash
docker-compose -f docker-compose.metrics.sample.yaml up
```

This will start:
- Prometheus server on port 9090 with the alerts configured in alerts.sample.yml
- Grafana server on port 3000 with default credentials (admin/admin)

The docker-compose.metrics.sample.yaml file includes a pre-configured Grafana dashboard (see the [Dashboard](#dashboard) section below) that displays all the metrics mentioned above. This dashboard provides monitoring of your price pusher operations with panels for configured feeds, active feeds, wallet balance, update statistics, and error tracking. The dashboard is automatically provisioned when you start the stack with docker-compose.

Alternatively, if you prefer to set up the monitoring stack manually:

1. Create a `prometheus.sample.yml` file:

```yaml
global:
scrape_interval: 15s

scrape_configs:
- job_name: "price_pusher"
static_configs:
- targets: ["localhost:9090"]
```

2. Run Prometheus with Docker:

```bash
docker run -d --name prometheus -p 9090:9090 \
-v $(pwd)/prometheus.sample.yml:/etc/prometheus/prometheus.yml \
-v $(pwd)/alerts.sample.yml:/etc/prometheus/alerts.yml \
prom/prometheus
```

3. Run Grafana with Docker:

```bash
docker run -d --name grafana -p 3000:3000 grafana/grafana
```

4. Access Grafana at http://localhost:3000 (default credentials: admin/admin) and add Prometheus as a data source (URL: http://host.docker.internal:9090).

### Example Grafana Queries

Here are some example Grafana queries to monitor your price feeds:

1. Last published time for each price feed:

```
pyth_price_last_published_time
```

2. Number of price updates in the last hour:

```
sum(increase(pyth_price_updates_total[1h]))
```

3. Price feeds not updated in the last hour:

```
time() - pyth_price_last_published_time > 3600
```

4. Distribution of update conditions:

```
sum by (condition) (increase(pyth_update_conditions_total[$__range]))
```

5. Monitor wallet balances:

```
pyth_wallet_balance
```

6. Detect low wallet balances (below 0.1 tokens):

```
pyth_wallet_balance < 0.1
```

### Dashboard

The docker-compose setup includes a pre-configured Grafana dashboard (`grafana-dashboard.sample.json`) that provides monitoring of your price pusher operations. The dashboard includes the following panels:

- **Configured Price Feeds**: Shows the number of price feeds configured in your price-config file.
- **Active Price Feeds**: Displays the number of price feeds currently being actively monitored.
- **Time Since Last Update**: Shows how long it's been since the last successful price update was published on-chain.
- **Price Feeds List**: A table listing all configured price feeds with their details.
- **Successful Updates (Current Range)**: Graph showing the number of successful price updates over the current range with timeline.
- **Update Conditions Distribution**: Pie chart showing the distribution of update conditions (YES/NO/EARLY) over the selected time range.
- **Wallet Balance**: Current balance of your wallet in native token units.
- **Wallet Balance Over Time**: Graph tracking your wallet balance over time to monitor consumption.
- **Failed Updates (Current Range)**: Graph showing the number of failed price updates over the current range with timeline.

When you first start the monitoring stack, the dashboard may show "No data" in the panels until the price pusher has been running for some time and has collected sufficient metrics.

This dashboard is automatically provisioned when you start the docker-compose stack and provides visibility into the health and performance of your price pusher deployment.

### Alerting

The price pusher includes pre-configured Prometheus alerting rules in the `alerts.sample.yml` file. These rules monitor various aspects of the price pusher's operation, including:

- Price feeds not being updated for an extended period (>1 hour)
- High error rates in price updates
- No recent price updates across all feeds
- Service availability
- High update durations
- Low wallet balances with two severity levels:
- Warning: Balance below 0.1 native tokens
- Critical: Balance below 0.01 native tokens (transactions may fail soon)

When using the docker-compose setup, these alerts are automatically loaded into Prometheus and can be viewed in the Alerting section of Grafana after setting up the Prometheus data source.
65 changes: 65 additions & 0 deletions apps/price_pusher/alerts.sample.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
groups:
- name: price_pusher_alerts
rules:
- alert: PriceFeedNotUpdated
expr: time() - pyth_price_last_published_time > 3600
for: 5m
labels:
severity: warning
annotations:
summary: "Price feed not updated"
description: "Price feed {{ $labels.alias }} has not been updated for more than 1 hour"

- alert: HighErrorRate
expr: sum(increase(pyth_price_update_errors_total[15m])) > 5
for: 5m
labels:
severity: warning
annotations:
summary: "High error rate in price updates"
description: "There have been more than 5 errors in the last 15 minutes"

- alert: NoRecentPriceUpdates
expr: sum(increase(pyth_price_updates_total[30m])) == 0
for: 5m
labels:
severity: critical
annotations:
summary: "No recent price updates"
description: "No price updates have been pushed in the last 30 minutes"

- alert: PricePusherDown
expr: up{job=~"price_pusher.*"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Price pusher service is down"
description: "The price pusher service {{ $labels.instance }} is down"

- alert: HighUpdateDuration
expr: rate(pyth_price_update_duration_seconds_sum[5m]) / rate(pyth_price_update_duration_seconds_count[5m]) > 5
for: 5m
labels:
severity: warning
annotations:
summary: "High update duration"
description: "Price updates are taking longer than 5 seconds on average"

- alert: WalletBalanceLow
expr: pyth_wallet_balance < 0.1
for: 5m
labels:
severity: warning
annotations:
summary: "Wallet balance is getting low"
description: "Wallet {{ $labels.wallet_address }} on network {{ $labels.network }} has balance below 0.1 native tokens"

- alert: WalletBalanceCritical
expr: pyth_wallet_balance < 0.01
for: 2m
labels:
severity: critical
annotations:
summary: "Wallet balance critically low"
description: "Wallet {{ $labels.wallet_address }} on network {{ $labels.network }} has balance below 0.01 native tokens. Transactions may fail soon!"
11 changes: 11 additions & 0 deletions apps/price_pusher/dashboard.sample.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: 1

providers:
- name: 'Pyth Price Pusher'
orgId: 1
folder: ''
type: file
disableDeletion: false
editable: true
options:
path: /var/lib/grafana/dashboards
8 changes: 8 additions & 0 deletions apps/price_pusher/datasource.sample.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: 1

datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
44 changes: 44 additions & 0 deletions apps/price_pusher/docker-compose.metrics.sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
version: "3"

services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.sample.yml:/etc/prometheus/prometheus.yml
- ./alerts.sample.yml:/etc/prometheus/alerts.yml
command:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.path=/prometheus"
- "--web.console.libraries=/usr/share/prometheus/console_libraries"
- "--web.console.templates=/usr/share/prometheus/consoles"
networks:
- monitoring

grafana:
image: grafana/grafana:latest
container_name: grafana
ports:
- "3000:3000"
volumes:
- grafana-storage:/var/lib/grafana
- ./grafana-dashboard.sample.json:/var/lib/grafana/dashboards/pyth-price-pusher-dashboard.json
- ./dashboard.sample.yml:/etc/grafana/provisioning/dashboards/dashboard.yml
- ./datasource.sample.yml:/etc/grafana/provisioning/datasources/datasource.yml
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin
- GF_USERS_ALLOW_SIGN_UP=false
depends_on:
- prometheus
networks:
- monitoring

networks:
monitoring:
driver: bridge

volumes:
grafana-storage:
Loading
Loading