Created
May 21, 2019 00:28
-
-
Save heckj/00701e2971cb2f307326eede6cb7e058 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as opentracing from 'opentracing'; | |
import { DocumentQuery } from 'mongoose'; | |
// Notes and light documentation at <https://github.com/jaegertracing/jaeger-client-node> | |
// templates for running Jaeger pieces in Kubernetes at <https://github.com/jaegertracing/jaeger-kubernetes> | |
// If you're working in local development and want to see what's up here, you can run a local instance | |
// of Jaeger in a docker container to capture any generated traces locally. This works with running the | |
// unit tests and traces they generate. | |
// | |
// from <https://www.jaegertracing.io/docs/1.8/getting-started/> | |
// docker run -d --name jaeger \ | |
// -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 \ | |
// -p 5775:5775/udp \ | |
// -p 6831:6831/udp \ | |
// -p 6832:6832/udp \ | |
// -p 5778:5778 \ | |
// -p 16686:16686 \ | |
// -p 14268:14268 \ | |
// -p 9411:9411 \ | |
// jaegertracing/all-in-one:1.8 | |
// to clean up after: | |
// docker rm /jaeger | |
// the web UI for this is exposed on port 16686... | |
// open http://localhost:16686 | |
// once that's up and running, do something that will generate traces, such as running the tests: | |
// npm test -- --filter='API /sites/{site}/trackers' | |
// and after that, the trace's UI will have some data to poke through... | |
// If you're using this on a Mac, you might start seeing some EMSGERROR responses. MacOS constrains | |
// the size of the max UDP header below where Jaeger is happy. You can bump it up though: | |
// $ sysctl net.inet.udp.maxdgram | |
// net.inet.udp.maxdgram: 9216 | |
// $ sudo sysctl net.inet.udp.maxdgram=65536 | |
// net.inet.udp.maxdgram: 9216 -> 65536 | |
// $ sudo sysctl net.inet.udp.maxdgram | |
// net.inet.udp.maxdgram: 65536 | |
// If you're missing traces you expect to see, check this setting! | |
// When instrumenting code with trace Spans, you add tags to help identify the spans later. | |
// The semantic definitions from OpenTracing for common tag names and usages are detailed at | |
// <https://github.com/opentracing/specification/blob/master/semantic_conventions.md> | |
const initJaegerTracer = require('jaeger-client').initTracer; | |
function initTracer(serviceName: string) { | |
const config = { | |
serviceName: serviceName, | |
// sampler details: <https://www.jaegertracing.io/docs/1.7/sampling/#client-sampling-configuration> | |
sampler: { | |
type: 'probabilistic', | |
param: 0.5, // traces roughly half the calls | |
}, | |
reporter: { | |
logSpans: false, // this logs whenever we send a span | |
}, | |
}; | |
const options = { | |
logger: { | |
info: function logInfo(msg: string) { | |
console.log('INFO ', msg); | |
}, | |
error: function logError(msg: string) { | |
console.log('ERROR ', msg); | |
}, | |
}, | |
}; | |
return initJaegerTracer(config, options); | |
} | |
export const tracer = initTracer('vertex-api') as opentracing.Tracer; | |
export function createSchemaSpan(schemaName: string, operation: string, parentSpan?: opentracing.Span) { | |
if (parentSpan) { | |
return tracer.startSpan(operation, { | |
childOf: parentSpan, | |
tags: { | |
[opentracing.Tags.SPAN_KIND]: opentracing.Tags.SPAN_KIND_RPC_SERVER, | |
[opentracing.Tags.COMPONENT]: schemaName | |
} | |
}); | |
} else { | |
return tracer.startSpan(operation, { | |
tags: { | |
[opentracing.Tags.SPAN_KIND]: opentracing.Tags.SPAN_KIND_RPC_SERVER, | |
[opentracing.Tags.COMPONENT]: schemaName | |
} | |
}); | |
} | |
} | |
export function createControllerSpan(controller: string, operation: string, headers: any) { | |
let traceSpan: opentracing.Span; | |
// NOTE(heckj): OpenTracing type definitions at | |
// <https://github.com/opentracing/opentracing-javascript/blob/master/src/tracer.ts> | |
const parentSpanContext = tracer.extract(opentracing.FORMAT_HTTP_HEADERS, headers); | |
if (parentSpanContext) { | |
traceSpan = tracer.startSpan(operation, { | |
childOf: parentSpanContext, | |
tags: { | |
[opentracing.Tags.SPAN_KIND]: opentracing.Tags.SPAN_KIND_RPC_SERVER, | |
[opentracing.Tags.COMPONENT]: controller | |
} | |
}); | |
} else { | |
traceSpan = tracer.startSpan(operation, { | |
tags: { | |
[opentracing.Tags.SPAN_KIND]: opentracing.Tags.SPAN_KIND_RPC_SERVER, | |
[opentracing.Tags.COMPONENT]: controller | |
} | |
}); | |
} | |
return traceSpan; | |
} | |
export function finishSpanWithResult(span: opentracing.Span, status: Number, errorTag?: boolean) { | |
span.setTag(opentracing.Tags.HTTP_STATUS_CODE, status); | |
if (errorTag) { | |
span.setTag(opentracing.Tags.ERROR, true); | |
} | |
span.finish(); | |
} | |
export async function traceMongoQuery(parentSpan: opentracing.Span, traceName: string, documentQuery: DocumentQuery<any, any>) { | |
const traceSpan = tracer.startSpan(traceName, { | |
childOf: parentSpan, | |
tags: { | |
[opentracing.Tags.SPAN_KIND]: opentracing.Tags.SPAN_KIND_RPC_SERVER, | |
[opentracing.Tags.COMPONENT]: 'mongodb' | |
} | |
}); | |
const documentResult = await documentQuery; | |
traceSpan.finish(); | |
return documentResult; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment