javascript - A metric with the name has already been registered | prometheus custom metric in nodejs app - Stack Overflow

Getting metric has already been registered when trying to publish metrics from service. To avoid that I

Getting metric has already been registered when trying to publish metrics from service. To avoid that I used register.removeSingleMetric("newMetric"); but problem is that it clear register and past records every time a new call es in. Wondering what to address this problem:

export function workController(req: Request, res: Response) {


    resolveFeaturePromises(featurePromises).then(featureAggregate => {
        return rulesService.runWorkingRulesForHook(featureAggregate, hook.name, headers)
            .then(([shouldLog, result]) => {
                ...

// publish metric
                publishHookMetrics(result);
 // publish metric
                sendResponse(res, new CoreResponse(result.isWorking, result.responseData), req, featureAggregate, hook);
            });
    }).catch(err => {
        sendResponse(res, new CoreResponse(Action.ALLOW, null), req, null, hook);
        console.error(err);
    });
}

function publishCustomMetrics(customInfoObject: CustomInfoObject) {
    const counter =  new promClient.Counter({
        name: "newMetric",
        help: "metric for custom detail",
        labelNames: ["name", "isWorking"]
    });
    counter.inc({
        name: customInfoObject.hook,
        isWorking: customInfoObject.isWorking
    });
}

stack trace

[Node] [2020-07-30T17:40:09+0500] [ERROR]  Error: A metric with the name newMetric has already been registered.

application.ts


export async function startWebServer(): Promise<Server> {
    if (!isGlobalsInitilized) {
        throw new Error("Globals are noit initilized. Run initGlobals() first.");
    }
    // Setup prom express middleware
    const metricsMiddleware = promBundle({
        includeMethod: true,
        includePath: true,
        metricsPath: "/prometheus",
        promClient: {
            collectDefaultMetrics: {
            }
        }
    });
    // start http server
    const app = require("express")();
    app.use(bodyParser.json());
    app.use(metricsMiddleware);
    const routeConfig = require("./config/route-config");
    routeConfig.configure(app);
    const port = process.env.PORT || 3000;
    return app.listen(port, function () {
        console.log("service listening on port", port);
    });
}

versions:

express-prom-bundle: 6.0.0 prom-client: 12.0.0

Getting metric has already been registered when trying to publish metrics from service. To avoid that I used register.removeSingleMetric("newMetric"); but problem is that it clear register and past records every time a new call es in. Wondering what to address this problem:

export function workController(req: Request, res: Response) {


    resolveFeaturePromises(featurePromises).then(featureAggregate => {
        return rulesService.runWorkingRulesForHook(featureAggregate, hook.name, headers)
            .then(([shouldLog, result]) => {
                ...

// publish metric
                publishHookMetrics(result);
 // publish metric
                sendResponse(res, new CoreResponse(result.isWorking, result.responseData), req, featureAggregate, hook);
            });
    }).catch(err => {
        sendResponse(res, new CoreResponse(Action.ALLOW, null), req, null, hook);
        console.error(err);
    });
}

function publishCustomMetrics(customInfoObject: CustomInfoObject) {
    const counter =  new promClient.Counter({
        name: "newMetric",
        help: "metric for custom detail",
        labelNames: ["name", "isWorking"]
    });
    counter.inc({
        name: customInfoObject.hook,
        isWorking: customInfoObject.isWorking
    });
}

stack trace

[Node] [2020-07-30T17:40:09+0500] [ERROR]  Error: A metric with the name newMetric has already been registered.

application.ts


export async function startWebServer(): Promise<Server> {
    if (!isGlobalsInitilized) {
        throw new Error("Globals are noit initilized. Run initGlobals() first.");
    }
    // Setup prom express middleware
    const metricsMiddleware = promBundle({
        includeMethod: true,
        includePath: true,
        metricsPath: "/prometheus",
        promClient: {
            collectDefaultMetrics: {
            }
        }
    });
    // start http server
    const app = require("express")();
    app.use(bodyParser.json());
    app.use(metricsMiddleware);
    const routeConfig = require("./config/route-config");
    routeConfig.configure(app);
    const port = process.env.PORT || 3000;
    return app.listen(port, function () {
        console.log("service listening on port", port);
    });
}

versions:

express-prom-bundle: 6.0.0 prom-client: 12.0.0

Share Improve this question asked Jul 30, 2020 at 13:10 Ahsan NaseemAhsan Naseem 1,1063 gold badges19 silver badges39 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 5

The counter should be initialize only once, then used for each call. Simplest modification from code you gave would be something like this.

const counter =  new promClient.Counter({
    name: "newMetric",
    help: "metric for custom detail",
    labelNames: ["name", "isWorking"]
});
export function publishCustomMetrics(customInfoObject: CustomInfoObject) {
    counter.inc({
        name: customInfoObject.hook,
        isWorking: customInfoObject.isWorking
    });
}

BTW, I found this thread while searching a way to avoid the "already been registered" error in unit tests. Many tests was instantiating the same class (from a library) that was initializing a counter in the constructor. As it is in tests, and I didn't need consistency over the metrics, I found an easy solution is to clear metrics registers at the beginning of each test.

import { register } from "prom-client";
// ...
register.clear();

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744710288a4589303.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信