node-sleuth
v1.0.2
Published
A zipkin sleuth impelement for general node.
Downloads
5
Readme
node-sleuth
A zipkin sleuth impelement for general node.
Usage
init node-sleuth at startup
import { Tracing, ProxyInjector } from 'node-sleuth';
Tracing.init({
localServiceName: 'systemname',
endpointHost: 'localhost',
endpointPort: 9411,
injector: new ProxyInjector(),
});
create a koa middleware for eject traceId from http headers
import { Tracing } from 'node-sleuth';
app.use(async (ctx: Context, next: () => Promise<any>) => {
const traceIdEjected = Tracing.ejector.eject(ctx);
/**
* if there isnot a traceId then generate a new TraceId
*/
const rootTraceId = traceIdEjected.getOrElse(() => Tracing.tracer.createRootId());
// set traceId into tracer for inject create children traceId
Tracing.tracer.setId(rootTraceId);
const span = new Span(rootTraceId);
// put some thing into trace span
span.setKind('SERVER');
span.setName(`${app.config.name}${ctx.path}`);
span.putTag('method', ctx.method);
span.putTag('protocol', ctx.protocol);
span.putTag('query', JSON.stringify(removeTFromQuery(ctx.queries)));
span.putTag('body', JSON.stringify(ctx.request.body));
span.setTimestamp(ctx.starttime * 1000);
span.setRemoteEndpoint(new Endpoint({ ipv4: ctx.ip }));
span.setLocalEndpoint(new Endpoint({ serviceName: app.config.name, ipv4: Tracing.ip, port: ctx.protocol === 'http' ? 80 : 443 })); // maybe is arbitrary
try {
await next();
span.setDuration((Date.now() - ctx.starttime) * 1000);
if (!ctx.body) {
span.putTag('error', '1');
span.putTag('NotFound', '1');
} else {
if (ctx.body.success === false || ctx.body.err || ctx.body.error || ctx.body.code !== 0) {
span.putTag('error', '1');
}
span.putTag('result', JSON.stringify(ctx.body));
}
Tracing.logger.logSpan(span);
} catch (error) {
span.putTag('error', '1');
if (error.code) {
span.putTag('error_code', error.code);
}
if (error.message) {
span.putTag('error_msg', error.message);
}
if (error.stack) {
span.putTag('error_stack', error.stack);
}
Tracing.logger.logSpan(span);
throw error;
}
})
inject traceId into proxy headers
import { Tracing } from 'node-sleuth';
export default class ProxyController extends Controller {
index() {
const proxyHeaders = {
...request.headers,
host,
'bff-proxy': true,
};
const traceId = Tracing.tracer.createChildId();
Tracing.injector.inject(proxyHeaders, traceId);
span.setKind('CLIENT');
span.putTag('PROXY', '1');
span.setTimestamp(ctx.starttime * 1000);
try {
// @ts-ignore
res = await this.ctx.curl(`http://${backendHost(this.ctx, request.path)}${request.originalUrl}`, {
method: method as RequestOptions['method'],
stream: this.ctx.request.req,
headers: proxyHeaders,
streaming: true,
gzip: !!this.ctx.request.acceptsEncodings('gzip'),
beforeRequest: writeTracingHeaders(this.ctx),
});
span.setDuration((Date.now() - ctx.starttime) * 1000);
Tracing.logger.logSpan(span);
} catch (error) {
span.putTag('error', '1');
if (error.code) {
span.putTag('error_code', error.code);
}
if (error.message) {
span.putTag('error_msg', error.message);
}
if (error.stack) {
span.putTag('error_stack', error.stack);
}
Tracing.logger.logSpan(span);
this.app.emit('error', error);
throw new BackendError(500, '连接失败');
}
}
}