Skip to content

Commit 62cb38c

Browse files
committed
feat: add update conditions tracking and update related metrics in README and dashboard
1 parent 1f7d073 commit 62cb38c

File tree

4 files changed

+151
-23
lines changed

4 files changed

+151
-23
lines changed

apps/price_pusher/README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -270,10 +270,9 @@ The following metrics are available:
270270

271271
- **pyth_price_last_published_time** (Gauge): The last published time of a price feed in unix timestamp
272272
- **pyth_price_updates_total** (Counter): Total number of price updates pushed to the chain
273-
- **pyth_price_update_duration_seconds** (Histogram): Duration of price update operations in seconds
274273
- **pyth_price_feeds_total** (Gauge): Total number of price feeds being monitored
275274
- **pyth_price_update_errors_total** (Counter): Total number of errors encountered during price updates
276-
- **pyth_price_update_attempts_total** (Counter): Total number of price update attempts
275+
- **pyth_update_conditions_total** (Counter): Count of update condition checks by status (YES/NO/EARLY)
277276
- **pyth_wallet_balance** (Gauge): Current wallet balance of the price pusher in native token units
278277

279278
### Configuration
@@ -358,10 +357,10 @@ sum(increase(pyth_price_updates_total[1h]))
358357
time() - pyth_price_last_published_time > 3600
359358
```
360359

361-
4. Average update duration:
360+
4. Distribution of update conditions:
362361

363362
```
364-
rate(pyth_price_update_duration_seconds_sum[5m]) / rate(pyth_price_update_duration_seconds_count[5m])
363+
sum by (condition) (increase(pyth_update_conditions_total[$__range]))
365364
```
366365

367366
5. Monitor wallet balances:
@@ -378,13 +377,14 @@ pyth_wallet_balance < 0.1
378377

379378
### Dashboard
380379

381-
The docker-compose setup includes a pre-configured Grafana dashboard (`grafana-dashboard.sample.json`) that provides monitoring of your price pusher operations. Based on the screenshot, the dashboard includes the following panels:
380+
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:
382381

383382
- **Configured Price Feeds**: Shows the number of price feeds configured in your price-config file.
384383
- **Active Price Feeds**: Displays the number of price feeds currently being actively monitored.
385384
- **Time Since Last Update**: Shows how long it's been since the last successful price update was published on-chain.
386385
- **Price Feeds List**: A table listing all configured price feeds with their details.
387386
- **Price Updates (Last Hour)**: Graph showing the number of price updates over the last hour with timeline.
387+
- **Update Conditions Distribution**: Pie chart showing the distribution of update conditions (YES/NO/EARLY) over the selected time range.
388388
- **Wallet Balance**: Current balance of your wallet in native token units.
389389
- **Wallet Balance Over Time**: Graph tracking your wallet balance over time to monitor consumption.
390390
- **Update Errors**: Tracks errors encountered during price update operations.

apps/price_pusher/grafana-dashboard.sample.json

Lines changed: 123 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,126 @@
529529
"title": "Price Updates (Last Hour)",
530530
"type": "timeseries"
531531
},
532+
{
533+
"datasource": {
534+
"type": "prometheus",
535+
"uid": "prometheus"
536+
},
537+
"fieldConfig": {
538+
"defaults": {
539+
"color": {
540+
"mode": "palette-classic"
541+
},
542+
"custom": {
543+
"hideFrom": {
544+
"legend": false,
545+
"tooltip": false,
546+
"viz": false
547+
}
548+
},
549+
"mappings": []
550+
},
551+
"overrides": [
552+
{
553+
"matcher": {
554+
"id": "byName",
555+
"options": "YES"
556+
},
557+
"properties": [
558+
{
559+
"id": "color",
560+
"value": {
561+
"fixedColor": "green",
562+
"mode": "fixed"
563+
}
564+
}
565+
]
566+
},
567+
{
568+
"matcher": {
569+
"id": "byName",
570+
"options": "NO"
571+
},
572+
"properties": [
573+
{
574+
"id": "color",
575+
"value": {
576+
"fixedColor": "red",
577+
"mode": "fixed"
578+
}
579+
}
580+
]
581+
},
582+
{
583+
"matcher": {
584+
"id": "byName",
585+
"options": "EARLY"
586+
},
587+
"properties": [
588+
{
589+
"id": "color",
590+
"value": {
591+
"fixedColor": "yellow",
592+
"mode": "fixed"
593+
}
594+
}
595+
]
596+
}
597+
]
598+
},
599+
"gridPos": {
600+
"h": 8,
601+
"w": 6,
602+
"x": 0,
603+
"y": 16
604+
},
605+
"id": 13,
606+
"options": {
607+
"displayLabels": [
608+
"percent",
609+
"name"
610+
],
611+
"legend": {
612+
"displayMode": "list",
613+
"placement": "right",
614+
"showLegend": true,
615+
"values": [
616+
"value",
617+
"percent"
618+
]
619+
},
620+
"pieType": "pie",
621+
"reduceOptions": {
622+
"calcs": [
623+
"sum"
624+
],
625+
"fields": "",
626+
"values": false
627+
},
628+
"tooltip": {
629+
"hideZeros": false,
630+
"mode": "single",
631+
"sort": "none"
632+
}
633+
},
634+
"pluginVersion": "11.5.2",
635+
"targets": [
636+
{
637+
"datasource": {
638+
"type": "prometheus",
639+
"uid": "prometheus"
640+
},
641+
"editorMode": "code",
642+
"expr": "sum by (condition) (increase(pyth_update_conditions_total[$__range]))",
643+
"instant": false,
644+
"legendFormat": "{{condition}}",
645+
"range": true,
646+
"refId": "A"
647+
}
648+
],
649+
"title": "Update Conditions Distribution (Current Range)",
650+
"type": "piechart"
651+
},
532652
{
533653
"datasource": {
534654
"type": "prometheus",
@@ -563,8 +683,8 @@
563683
},
564684
"gridPos": {
565685
"h": 8,
566-
"w": 12,
567-
"x": 0,
686+
"w": 6,
687+
"x": 6,
568688
"y": 16
569689
},
570690
"id": 10,
@@ -808,6 +928,6 @@
808928
"timezone": "",
809929
"title": "Pyth Price Pusher Dashboard",
810930
"uid": "pyth-price-pusher",
811-
"version": 41,
931+
"version": 44,
812932
"weekStart": ""
813933
}

apps/price_pusher/src/controller.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { SuperWalletClient } from "./evm/super-wallet";
99
// Define the wallet balance info interface
1010
interface WalletBalanceInfo {
1111
client: SuperWalletClient;
12-
address: string;
12+
address: `0x${string}`;
1313
network: string;
1414
updateInterval: DurationInSeconds;
1515
}
@@ -36,9 +36,7 @@ export class Controller {
3636
this.walletBalanceInfo = config.walletBalanceInfo;
3737

3838
// Set the number of price feeds if metrics are enabled
39-
if (this.metrics) {
40-
this.metrics.setPriceFeedsTotal(this.priceConfigs.length);
41-
}
39+
this.metrics?.setPriceFeedsTotal(this.priceConfigs.length);
4240
}
4341

4442
// Get wallet balance and update metrics
@@ -48,7 +46,7 @@ export class Controller {
4846
try {
4947
const { client, address, network } = this.walletBalanceInfo;
5048
const balance = await client.getBalance({
51-
address: address as `0x${string}`,
49+
address: address,
5250
});
5351

5452
this.metrics.updateWalletBalance(address, network, balance);
@@ -112,9 +110,9 @@ export class Controller {
112110
this.logger,
113111
);
114112

115-
// Record price update attempt in metrics
113+
// Record update condition in metrics
116114
if (this.metrics) {
117-
this.metrics.recordPriceUpdateAttempt(priceId, alias);
115+
this.metrics.recordUpdateCondition(priceId, alias, priceShouldUpdate);
118116
}
119117

120118
if (priceShouldUpdate == UpdateCondition.YES) {

apps/price_pusher/src/metrics.ts

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Registry, Counter, Gauge } from "prom-client";
22
import express from "express";
33
import { PriceInfo } from "./interface";
44
import { Logger } from "pino";
5+
import { UpdateCondition } from "./price-config";
56

67
// Define the metrics we want to track
78
export class PricePusherMetrics {
@@ -14,7 +15,7 @@ export class PricePusherMetrics {
1415
public priceUpdatesTotal: Counter<string>;
1516
public priceFeedsTotal: Gauge<string>;
1617
public priceUpdateErrors: Counter<string>;
17-
public priceUpdateAttempts: Counter<string>;
18+
public updateConditionsTotal: Counter<string>;
1819
// Wallet metrics
1920
public walletBalance: Gauge<string>;
2021

@@ -54,10 +55,10 @@ export class PricePusherMetrics {
5455
registers: [this.registry],
5556
});
5657

57-
this.priceUpdateAttempts = new Counter({
58-
name: "pyth_price_update_attempts_total",
59-
help: "Total number of price update attempts",
60-
labelNames: ["price_id", "alias"],
58+
this.updateConditionsTotal = new Counter({
59+
name: "pyth_update_conditions_total",
60+
help: "Total number of price update condition checks by status (YES/NO/EARLY)",
61+
labelNames: ["price_id", "alias", "condition"],
6162
registers: [this.registry],
6263
});
6364

@@ -100,9 +101,18 @@ export class PricePusherMetrics {
100101
this.priceUpdatesTotal.inc({ price_id: priceId, alias });
101102
}
102103

103-
// Record a price update attempt
104-
public recordPriceUpdateAttempt(priceId: string, alias: string): void {
105-
this.priceUpdateAttempts.inc({ price_id: priceId, alias });
104+
// Record update condition status (YES/NO/EARLY)
105+
public recordUpdateCondition(
106+
priceId: string,
107+
alias: string,
108+
condition: UpdateCondition,
109+
): void {
110+
const conditionLabel = UpdateCondition[condition];
111+
this.updateConditionsTotal.inc({
112+
price_id: priceId,
113+
alias,
114+
condition: conditionLabel,
115+
});
106116
}
107117

108118
// Record a price update error

0 commit comments

Comments
 (0)