UNPKG

@servant573/nest-jaeger

Version:

Jaeger middleware to request tracing for nest application

164 lines (163 loc) 6.75 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.JaegerInterceptor = void 0; const common_1 = require("@nestjs/common"); const core_1 = require("@nestjs/core"); const operators_1 = require("rxjs/operators"); const jaeger_client_1 = require("jaeger-client"); const opentracing_1 = require("opentracing"); const axios_1 = require("axios"); const TAGS = Object.assign(Object.assign({}, opentracing_1.Tags), { PROTOCAL: 'protocal', TRACING_TAG: 'tracing-tag' }); const UNKNOW = 'Unknow'; const DEFAULT_SAMPLER = { type: 'const', param: 1, }; const DEFAULT_REPORTER = { collectorEndpoint: 'http://localhost:14268/api/traces', }; const DEFAULT_LOGGER = { info: (msg) => { console.log('JAEGER INFO ', msg); }, error: (msg) => { console.log('JAEGER ERROR', msg); }, }; const DEFAULT_OPTION = { logger: DEFAULT_LOGGER }; const DEFAULT_CONFIG = { serviceName: UNKNOW, reporter: DEFAULT_REPORTER, sampler: DEFAULT_SAMPLER, }; let JaegerInterceptor = class JaegerInterceptor { constructor(cfg, opt, req_cb, res_cb) { this.tracer = undefined; this.span = undefined; this.tracing_tag = {}; this.req_cb = undefined; this.res_cb = undefined; if (!this.tracer) { try { const config = Object.assign(Object.assign({}, DEFAULT_CONFIG), cfg); const options = Object.assign(Object.assign({}, DEFAULT_OPTION), opt); this.tracer = (0, jaeger_client_1.initTracer)(config, options); this.req_cb = req_cb; this.res_cb = res_cb; console.log('[*]Init tracer ... [ DONE ] '); } catch (error) { console.error('[*]Init tracer ... [ FAILED ] '); } } else { console.log(`[*]Tracer already existed`); } } intercept(context, next) { const reflector = new core_1.Reflector(); const except = reflector.get('ExceptJaegerInterceptor', context.getHandler()); if (except) return next.handle(); if (!this.tracer) return next.handle(); const req = context.switchToHttp().getRequest(); const res = context.switchToHttp().getResponse(); const parent = this.tracer.extract(opentracing_1.FORMAT_HTTP_HEADERS, req.headers); const parentObj = parent ? { childOf: parent } : {}; this.span = this.tracer.startSpan(req.headers.host + req.path, parentObj); if (!this.span) return next.handle(); if (req.headers && req.headers[TAGS.TRACING_TAG]) { this.tracing_tag = JSON.parse(req.headers[TAGS.TRACING_TAG]); } for (const key in this.tracing_tag) { const val = this.tracing_tag[key]; this.span.setTag(key, val); } const createJaegerInstance = () => { return { span: this.span, tracer: this.tracer, tags: TAGS, axios: (opts = undefined) => { if (!opts) return; let options = {}; const headers = {}; headers[TAGS.TRACING_TAG] = JSON.stringify(this.tracing_tag); this.tracer.inject(this.span, opentracing_1.FORMAT_HTTP_HEADERS, headers); opts.headers = Object.assign(Object.assign({}, opts.headers), headers); options = Object.assign({}, opts); return (0, axios_1.default)(options); }, log: (name, content) => { if (!this.span) return; this.span.logEvent(name, content); }, setTag: (tag, val) => { if (!this.span) return; this.span.setTag(tag, val); }, addTags: (obj) => { if (!this.span && !obj) return; this.span.addTags(obj); }, setTracingTag: (tag, val) => { if (!this.span) return; this.span.setTag(tag, val); this.tracing_tag[tag] = val; }, finish: () => { if (!this.span) return; this.span.finish(); }, createSpan: (name, parent) => { const parentObj = parent ? { childOf: parent } : { childOf: this.span }; if (!this.tracer) return; return this.tracer.startSpan(name, parentObj); }, }; }; req.jaeger = createJaegerInstance(); req.jaeger.setTag('request.ip', req.ip || UNKNOW); req.jaeger.setTag('request.method', req.method || UNKNOW); req.jaeger.setTag('request.headers', req.headers || UNKNOW); req.jaeger.setTag('request.path', req.path || UNKNOW); req.jaeger.setTag('request.body', req.body || UNKNOW); req.jaeger.setTag('request.query', req.query || UNKNOW); if (this.req_cb) { this.req_cb(req, res); } return next.handle().pipe((0, operators_1.tap)(() => { if (this.res_cb) { this.res_cb(req, res); } req.jaeger.setTag('response.state', res.statusCode || UNKNOW); req.jaeger.setTag('response.result', res.statusMessage || UNKNOW); req.jaeger.finish(); })); } }; JaegerInterceptor = __decorate([ (0, common_1.Injectable)(), __metadata("design:paramtypes", [Object, Object, Object, Object]) ], JaegerInterceptor); exports.JaegerInterceptor = JaegerInterceptor;