@pythnetwork/price-pusher
Version:
Pyth Price Pusher
114 lines (113 loc) • 4.58 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PricePusherMetrics = void 0;
const prom_client_1 = require("prom-client");
const express_1 = __importDefault(require("express"));
const price_config_1 = require("./price-config");
// Define the metrics we want to track
class PricePusherMetrics {
registry;
server;
logger;
// Metrics for price feed updates
lastPublishedTime;
priceUpdateAttempts;
priceFeedsTotal;
// Wallet metrics
walletBalance;
constructor(logger) {
this.logger = logger;
this.registry = new prom_client_1.Registry();
this.server = (0, express_1.default)();
// Register the default metrics (memory, CPU, etc.)
this.registry.setDefaultLabels({ app: "price_pusher" });
// Create metrics
this.lastPublishedTime = new prom_client_1.Gauge({
name: "pyth_price_last_published_time",
help: "The last published time of a price feed in unix timestamp",
labelNames: ["price_id", "alias"],
registers: [this.registry],
});
this.priceUpdateAttempts = new prom_client_1.Counter({
name: "pyth_price_update_attempts_total",
help: "Total number of price update attempts with their trigger condition and status",
labelNames: ["price_id", "alias", "trigger", "status"],
registers: [this.registry],
});
this.priceFeedsTotal = new prom_client_1.Gauge({
name: "pyth_price_feeds_total",
help: "Total number of price feeds being monitored",
registers: [this.registry],
});
// Wallet balance metric
this.walletBalance = new prom_client_1.Gauge({
name: "pyth_wallet_balance",
help: "Current wallet balance of the price pusher in native token units",
labelNames: ["wallet_address", "network"],
registers: [this.registry],
});
// Setup the metrics endpoint
this.server.get("/metrics", async (req, res) => {
res.set("Content-Type", this.registry.contentType);
res.end(await this.registry.metrics());
});
}
// Start the metrics server
start(port) {
this.server.listen(port, () => {
this.logger.info(`Metrics server started on port ${port}`);
});
}
// Update the last published time for a price feed
updateLastPublishedTime(priceId, alias, priceInfo) {
this.lastPublishedTime.set({ price_id: priceId, alias }, priceInfo.publishTime);
}
// Record a successful price update
recordPriceUpdate(priceId, alias, trigger = "yes") {
this.priceUpdateAttempts.inc({
price_id: priceId,
alias,
trigger: trigger.toLowerCase(),
status: "success",
});
}
// Record update condition status (YES/NO/EARLY)
recordUpdateCondition(priceId, alias, condition) {
const triggerLabel = price_config_1.UpdateCondition[condition].toLowerCase();
// Only record as 'skipped' when the condition is NO
if (condition === price_config_1.UpdateCondition.NO) {
this.priceUpdateAttempts.inc({
price_id: priceId,
alias,
trigger: triggerLabel,
status: "skipped",
});
}
// YES and EARLY don't increment the counter here - they'll be counted
// when recordPriceUpdate or recordPriceUpdateError is called
}
// Record a price update error
recordPriceUpdateError(priceId, alias, trigger = "yes") {
this.priceUpdateAttempts.inc({
price_id: priceId,
alias,
trigger: trigger.toLowerCase(),
status: "error",
});
}
// Set the number of price feeds
setPriceFeedsTotal(count) {
this.priceFeedsTotal.set(count);
}
// Update wallet balance
updateWalletBalance(walletAddress, network, balance) {
// Convert to number for compatibility with prometheus
const balanceNum = typeof balance === "bigint" ? Number(balance) / 1e18 : balance;
this.walletBalance.set({ wallet_address: walletAddress, network }, balanceNum);
this.logger.debug(`Updated wallet balance metric: ${walletAddress} = ${balanceNum}`);
}
}
exports.PricePusherMetrics = PricePusherMetrics;