pandora-metrics
Version:
## Overview
163 lines • 5.82 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const index_1 = require("./common/index");
const MetricsConstants_1 = require("./MetricsConstants");
const pandora_env_1 = require("pandora-env");
const MessengerUtil_1 = require("./util/MessengerUtil");
const index_2 = require("./client/index");
const AbstractIndicator_1 = require("./indicator/AbstractIndicator");
const common_1 = require("./common");
class MetricsClient extends AbstractIndicator_1.AbstractIndicator {
constructor() {
super();
this.environment = pandora_env_1.EnvironmentUtil.getInstance().getCurrentEnvironment();
this.appName = this.getAppName();
this.allMetricsRegistry = this.getNewMetricRegistry();
this.messengerClient = new MessengerUtil_1.MetricsMessengerClient(MetricsConstants_1.MetricsConstants.METRICS_PANDORA_KEY);
this.clientId = Math.random().toString(35).substr(2, 10);
this.group = 'metrics';
this.debug = require('debug')('pandora:metrics:client:' + this.clientId);
this.registerClient();
this.registerDownlink();
}
static getInstance() {
if (!this.instance) {
this.instance = new MetricsClient();
}
return this.instance;
}
/**
* 注册 Client
*/
registerClient() {
this.messengerClient.register({
appName: this.appName,
clientId: this.clientId,
});
}
/**
* 注册一个 Metric
*
* @example
* let counter = new BaseCounter();
* MetricsClient.register('eagleeye', 'eagleeye.hsf.qps', counter);
* counter.inc(2);
*
* @param {string} group
* @param {} name
* @param {Proxiable} metric
*/
register(group, name, metric) {
this.debug(`Register: wait register a metrics name = ${name}`);
let newName = this.buildName(name);
// 把应用名加上
newName = newName.tagged('appName', this.getAppName());
if (!metric.type) {
metric.type = index_1.MetricType.GAUGE;
}
// 这边暂时不做去重
this.allMetricsRegistry.register(newName, metric);
// Gauge 比较特殊,是实际的类,而服务端才是一个代理,和其他 metric 都不同,不需要 proxy
if (metric.proxyMethod && metric.proxyMethod.length) {
for (let method of metric.proxyMethod) {
metric[method] = (...args) => {
this.debug(`Invoke: invoke name = ${newName.getNameKey()}, type = ${metric.type}, method = ${method}, value = ${args}`);
this.report({
action: MetricsConstants_1.MetricsConstants.EVT_METRIC_UPDATE,
name: newName.getNameKey(),
method: method,
value: args,
type: metric.type,
clientId: this.clientId
});
};
}
}
if (metric instanceof common_1.MetricSet) {
// report metricSet
// TODO 暂时忽略 metricSet 套 metricSet 的情况
for (let subMetric of metric.getMetrics()) {
this.reportMetric(index_1.MetricName.join(newName, subMetric.name), subMetric.metric, group);
}
}
else {
this.reportMetric(newName, metric, group);
}
}
reportMetric(name, metric, group) {
this.report({
action: MetricsConstants_1.MetricsConstants.EVT_METRIC_CREATE,
name: name.getNameKey(),
type: metric.type,
group: group,
clientId: this.clientId
});
}
/**
* 发送上行消息
* @param data
*/
report(data) {
this.messengerClient.report(this.getClientUplinkKey(), data);
}
async invoke(args) {
this.debug(`Invoke: invoked, key = ${args.metricKey} `);
let metric = this.allMetricsRegistry.getMetric(index_1.MetricName.parseKey(args.metricKey));
if (metric && metric.type === args.type) {
return await Promise.resolve(metric.getValue());
}
else {
this.debug(`Invoke: can not find metric(${args.metricKey}) or type different`);
}
}
/**
* 注册下行链路
*/
registerDownlink() {
this.debug(`Register: down link eventKey = ${this.getClientDownlinkKey()}`);
this.messengerClient.query(this.getClientDownlinkKey(), async (message, reply) => {
try {
reply && reply(await this.invoke(message));
}
catch (err) {
// error
this.debug(`Error: err = ${err}`);
reply && reply();
}
});
}
getAppName() {
return this.environment.get('appName');
}
getCounter(group, name) {
const counter = new index_2.Counter();
this.register(group, name, counter);
return counter;
}
getTimer(group, name) {
const timer = new index_2.Timer();
this.register(group, name, timer);
return timer;
}
getMeter(group, name) {
const meter = new index_2.Meter();
this.register(group, name, meter);
return meter;
}
getHistogram(group, name) {
const histogram = new index_2.Histogram();
this.register(group, name, histogram);
return histogram;
}
buildName(name) {
if (typeof name === 'string') {
name = index_1.MetricName.build(name);
}
return name;
}
getNewMetricRegistry() {
return new index_1.MetricsRegistry();
}
}
exports.MetricsClient = MetricsClient;
//# sourceMappingURL=MetricsClient.js.map