You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js prom-client指标重启丢失,Prometheus数据留存求助

解决Node.js项目重启后Prometheus指标重置的问题

问题根源

  1. 注册表使用错误:你创建了自定义的prom.Registry实例,但在/metrics接口中调用的是默认的prom.register,导致自定义注册表的指标根本没被正确暴露。
  2. 内存存储特性:prom-client默认将指标存在内存中,项目重启后内存清空,指标会被重置为初始状态,Prometheus无法获取历史数据。

修复步骤

第一步:修正注册表不一致问题

修改你的/metrics接口代码,确保使用自定义的register实例:

// 替换原来的/metrics接口代码
app.get('/metrics', async function (req, res) {
    res.set('Content-Type', register.contentType);
    const metrics = await register.metrics();
    res.end(metrics);
});

第二步:实现指标持久化(文件存储方案)

通过将指标定期保存到文件,重启时从文件加载,实现数据留存:

  1. 添加文件操作依赖:
const fs = require('fs').promises;
const path = require('path');
// 定义指标存储文件路径
const METRICS_STORE = path.join(__dirname, 'prometheus-metrics.json');
  1. 编写加载和保存指标的函数:
// 从文件加载历史指标
async function loadSavedMetrics(register) {
    try {
        const rawData = await fs.readFile(METRICS_STORE, 'utf8');
        const savedMetrics = JSON.parse(rawData);
        await register.setMetrics(savedMetrics);
        console.log('成功加载历史指标');
    } catch (err) {
        // 文件不存在或读取失败时,使用初始指标
        console.log('无历史指标可加载,使用默认配置');
    }
}

// 将当前指标保存到文件
async function persistMetrics(register) {
    try {
        const metricsData = await register.getMetricsAsJSON();
        await fs.writeFile(METRICS_STORE, JSON.stringify(metricsData, null, 2));
    } catch (err) {
        console.error('保存指标失败:', err);
    }
}
  1. 初始化时加载指标,定时保存并处理进程退出:
const register = new prom.Registry();
const collectDefaultMetrics = prom.collectDefaultMetrics;
const tags_default = [ "guild", "channel", "user" ];
const tags_names = [ "guild", "channel", "channelName", "user", "name" ];
const track_names = true;
const prefix = "author_"
collectDefaultMetrics({ register });

// 启动时加载历史指标
loadSavedMetrics(register);

// 每30秒保存一次指标(可根据需求调整间隔)
setInterval(() => {
    persistMetrics(register);
}, 30000);

// 进程退出前保存指标,避免异常退出丢失数据
process.on('SIGINT', async () => {
    await persistMetrics(register);
    process.exit(0);
});
process.on('SIGTERM', async () => {
    await persistMetrics(register);
    process.exit(0);
});

可选:Redis持久化方案(适合多实例/分布式场景)

如果你的项目是多实例部署或需要更可靠的存储,可以用Redis替代文件存储:

  1. 安装ioredis依赖:
npm install ioredis
  1. 实现Redis版的加载/保存逻辑:
const Redis = require('ioredis');
const redis = new Redis({ host: '你的Redis地址', port: 6379 });
const REDIS_METRICS_KEY = 'prometheus:metrics';

async function loadSavedMetrics(register) {
    try {
        const rawData = await redis.get(REDIS_METRICS_KEY);
        if (rawData) {
            const savedMetrics = JSON.parse(rawData);
            await register.setMetrics(savedMetrics);
            console.log('从Redis加载历史指标成功');
        }
    } catch (err) {
        console.error('加载Redis指标失败:', err);
    }
}

async function persistMetrics(register) {
    try {
        const metricsData = await register.getMetricsAsJSON();
        await redis.set(REDIS_METRICS_KEY, JSON.stringify(metricsData));
    } catch (err) {
        console.error('保存指标到Redis失败:', err);
    }
}

验证

  1. 重启项目后,检查指标存储文件(或Redis)是否有数据
  2. 访问/metrics接口,确认指标是重启前的延续值
  3. 查看Prometheus面板,确认历史数据已正常衔接

内容的提问来源于stack exchange,提问作者alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 00:40:28