1.0.0 • Published 5 years ago

@fewlines/fwl-tracing v1.0.0

Weekly downloads
2
License
MIT
Repository
-
Last release
5 years ago

FWL Tracing

Disclaimer: this package is made for our internal usage and is only open source for convenience so we might not consider Pull Requests or Issues. Feel free to fork though.

This is part of the Fewlines Web Libraries packages. It provides a simple way to do tracing with OpenTelemetry.

Installation

yarn add @fewlines/fwl-tracing

Getting Started

As OpenTelemetry libraries need to monkey patch packages before them being called, the easiest way is to initialize tracing in a separate file that is required using node’s (or ts-node's) -r option before application code runs.

So for instance, have a tracing.ts file with that content:

// src/tracing.ts
import { startTracer } from "@fewlines/fwl-tracing";

startTracer({ serviceName: "serviceName" });

And start your server with ts-node -r src/tracing.ts src/index.ts.

Once you're done, your index.ts could get the Tracer with:

import { getTracer } from "@fewlines/fwl-tracing";

const tracer = getTracer();

Usage

Once you have a tracer (of type Tracer), you will have a span method:

import { Span, Tracer } from "@fewlines/fwl-tracing";

// ...
function(tracer: Tracer) {
  tracer.span("span name", async (span: Span) => {
    // If you want to add attributes to your span
    span.setAttribute(key, value);

    // any code there that return a Promise (in this example, the callback is an `async` function so any value should do
  });
}

This way is the recommended way as it will automatically end the span for you. However, if you ever are in need to more fine grain control (for instance, in a middleware), you can use createSpan:

Here is an example of a logging middleware:

import { NextFunction, Request, Response } from "express";
import { Logger } from "@fewlines/fwl-logging";
import { Tracer, Span } from "@fewlines/fwl-tracing";

export function loggingMiddleware(tracer: Tracer, logger: Logger) {
  function onCloseOrFinish(span: Span, startTime: bigint): () => void {
    return function () {
      const response = this as Response;
      response.removeListener("finish", onCloseOrFinish);
      const end = process.hrtime.bigint();
      logger.log(`${response.req.path}: ${response.statusCode} in ${end - startTime}`);
      span.end();
    };
  }
  return function (
    _request: Request,
    response: Response,
    next: NextFunction,
  ): void {
    const startTime = process.hrtime.bigint();
    const span = tracer.createSpan("logging middleware");
    response.once("finish", onCloseOrFinish(span, startTime));
    next();
  };
}

Keep in mind that this method is only required because we need to call next() and we want to start the span across the whole request. The recommended method is to use tracer.span.