UNPKG

skywalking-backend-js-netease

Version:

The NodeJS agent for Apache SkyWalking

141 lines 5.98 kB
"use strict"; /*! * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const AgentConfig_1 = tslib_1.__importDefault(require("../config/AgentConfig")); const http_grpc_pb_1 = require("../proto/tunnel/http_grpc_pb"); const AuthInterceptor_1 = tslib_1.__importDefault(require("../agent/protocol/grpc/AuthInterceptor")); const http_pb_1 = require("../proto/tunnel/http_pb"); const logging_1 = require("../logging"); const grpc_js_1 = require("@grpc/grpc-js"); const prom_client_1 = tslib_1.__importDefault(require("prom-client")); const os_1 = tslib_1.__importDefault(require("os")); const logger = logging_1.createLogger(__filename); /** * use grpc tunnel to send http request */ class GrpcPushgateway extends prom_client_1.default.Pushgateway { constructor(url, options, registry) { super(`http://${url}`, {}, registry); this.registry = registry || new prom_client_1.default.Registry(); this.options = options; this.httpReportServiceClient = new http_grpc_pb_1.HttpReportServiceClient(url, AgentConfig_1.default.secure ? grpc_js_1.credentials.createSsl() : grpc_js_1.credentials.createInsecure()); this.lastCpu = this.cpu(); const _that = this; this.cpuPercGuage = new prom_client_1.default.Gauge({ name: 'process_cpu_percentage', help: 'current process cpu usage percentage.', registers: [this.registry], labelNames: [], collect: function () { const current = _that.cpu(); const [all, cur] = [current.total - _that.lastCpu.total, current.current - _that.lastCpu.current]; if (all > 0) { _that.cpuPercGuage.set(cur / all * 100); } else { _that.cpuPercGuage.set(0); } _that.lastCpu = current; }, }); } cpu() { const cpus = os_1.default.cpus(); // Accumulate every CPU times values, miliseconds const total = cpus.map(x => x.times) .reduce((acc, tv) => acc + tv.idle + tv.irq + tv.nice + tv.sys + tv.user, 0); // Normalize the one returned by process.cpuUsage() microseconds // (microseconds VS miliseconds) const usage = process.cpuUsage(); const current = usage.user + usage.system; return { total, current: current / 1e3 }; } push(params) { if (!params || !params.jobName) { throw new Error('Missing jobName parameter'); } return this.useGateway('PUT', params.jobName, params.groupings); } useGateway(method, job, groupings) { const path = `http://127.0.0.1:11800/metrics/job/${encodeURIComponent(job)}${this.generateGroupings(groupings)}`; return new Promise((resolve, reject) => { const stream = this.httpReportServiceClient.invoke(AuthInterceptor_1.default(), this.options(), (err, resp) => { if (err) { reject(err); return; } resolve({ code: resp.getCode(), body: resp.getBody() }); }); if (method !== 'DELETE') { this.registry.metrics() .then(metrics => { stream.write(new http_pb_1.HttpReqObject().setMethod(method).setUrl(path).setBody(new TextEncoder().encode(metrics))); stream.end(); }) .catch(err => { reject(err); }); } else { resolve(null); } }); } generateGroupings(groupings) { if (!groupings) { return ''; } return Object.keys(groupings) .map(key => `/${encodeURIComponent(key)}/${encodeURIComponent(groupings[key])}`) .join(''); } } class PrometheusPlugin { constructor() { this.module = 'prom-client'; // nodejs prom client this.versions = '*'; } install() { const register = new prom_client_1.default.Registry(); prom_client_1.default.collectDefaultMetrics({ register, gcDurationBuckets: [0.001, 0.01, 0.1, 1, 2, 5], }); const gateway = new GrpcPushgateway(AgentConfig_1.default.collectorAddress, () => { return { deadline: Date.now() + 30000 }; }, // Set the request timeout to 30000ms register); setInterval(() => { gateway.push({ jobName: 'nodejs_metrics', groupings: { product: AgentConfig_1.default.authorization, instance: AgentConfig_1.default.serviceInstance, service: AgentConfig_1.default.serviceName, }, }).then(() => { logger.debug(`Success sended Node.js VM Metrics`); }).catch(err => { logger.error('Failed to send Node.js VM Metrics', err); }); }, 60000); } } exports.default = new PrometheusPlugin(); //# sourceMappingURL=PrometheusPlugin.js.map