Stream of Consciousness

Mark Eschbach's random writings on various topics.

Integrating Jaeger with Nodjes

Categories: programming

Tags: nodejs jaeger

I’ve been interested in using Jaeger for a bit now to get some visibility into my applications beyond they are alive. Especially as I keep creating more services for myself and my family. I setup a simple all-in-one deployment on my OSX device under k8s. Before I dedicate on my home k8s cluster I would like to prove this will be helpful.

My goal: get a simple NodeJS service to report what it’s doing. Yuri Shkuro’s tutorial looks interesting. It shows how to use the Jaeger Node binding. First up appears to be initializing a tracer.

const initJaegerTracer = require('jaeger-client').initTracer;

function initTracer(serviceName) {
	const config = {
		serviceName: serviceName,
		sampler: {
			type: "const",
			param: 1,
		},
		reporter: {
			logSpans: true,
		},
	};
	const options = {
		logger: {
			info(msg) {
				console.log("INFO ", msg);
			},
			error(msg) {
				console.log("ERROR", msg);
			},
		},
	};
	return initJaegerTracer(config, options);
}

const tracer = initTracer("jaeger-test");

const sayHello = helloTo => {
	const span = tracer.startSpan("say-hello");
	span.setTag("hello-to", helloTo);
	const helloStr = `Hello, ${helloTo}!`;
	span.log({
		event: "string-format",
		value: helloStr,
	});
	console.log(helloStr);
	span.log({ event: "print-string" });
	span.finish();
};

sayHello("test");

tracer.close();
$ npm install --save jaeger-client
$ node jager-test
stdout> INFO  Initializing Jaeger Tracer with CompositeReporter(LoggingReporter,RemoteReporter) and ConstSampler(always)
stdout> Hello, test!
stdout> INFO  Reporting span 2113121bde90b11c:2113121bde90b11c:0:1

Interesting it will log to the console. Althought this ran, which was awesome it did not connect to my Jaeger instance. Reading the manual the client by default sends the data to udp://localhost:6832. Fair enough. Now to figure out how to expose that via a service. Turns out kubectl port-forward does not yet support UDP port forwarding, so I will have to figure out the HTTP connection. According to the documentation this should be as easy as setting JAEGER_ENDPOINT and forwarding port tcp/14268.

Turns out the environment variables require a different initialization function initTracerFromEnv, totally reasonable from a functional decomposition perspective. Also helps for me to RTFM :-). Once this is set JAEGER_ENDPOINT will work as expected with kubectl port-forward svc/jaeger -n platform-jaeger 16686:16686 14268:14268 and the following deployment for Jager.

# https://www.jaegertracing.io/docs/1.8/getting-started/
apiVersion: apps/v1
kind: Deployment
metadata:
  name: jaeger-instance
  namespace: platform-jaeger
  labels:
    app: jaeger
spec:
  replicas: 1
  selector:
    matchLabels:
      app: jaeger
  template:
    metadata:
      labels:
        app: jaeger
    spec:
      containers:
        - name: all-in-one
          image: jaegertracing/all-in-one:1.8
          env:
            - name: COLLECTOR_ZIPKIN_HTTP_PORT
              value: "9411"
---
apiVersion: v1
kind: Service
metadata:
  name: jaeger
  namespace: platform-jaeger
  labels:
    app: jaeger
spec:
  ports:
    - port: 16686
      protocol: TCP
      name: "ui"
    - port: 14268
      protocol: TCP
      name: "collector"
  selector:
    app: jaeger

And that is a wrap.