Skip to content

Latest commit

 

History

History
137 lines (113 loc) · 3.41 KB

open-telemetry.md

File metadata and controls

137 lines (113 loc) · 3.41 KB

mercurius

OpenTelemetry (Tracing)

Mercurius is compatible with open-telemetry (Note that, for now, jitted requests are not able to trace the graphql execution). Also make sure that registration of opentelemetry instrumentation happens before requiring mercurius.

Here is a simple example on how to enable tracing on Mercurius with OpenTelemetry:

tracer.js

'use strict'

const api = require('@opentelemetry/api')
const { NodeTracerProvider } = require('@opentelemetry/node')
const { SimpleSpanProcessor } = require('@opentelemetry/tracing')
const { JaegerExporter } = require('@opentelemetry/exporter-jaeger')
const { GraphQLInstrumentation } = require('@opentelemetry/instrumentation-graphql')
const { W3CTraceContextPropagator } = require('@opentelemetry/core')
const { ZipkinExporter } = require('@opentelemetry/exporter-zipkin')
// or
// const { JaegerExporter } = require('@opentelemetry/exporter-jaeger')

module.exports = serviceName => {
  const provider = new NodeTracerProvider()
  const graphQLInstrumentation = new GraphQLInstrumentation()
  graphQLInstrumentation.setTracerProvider(provider)
  graphQLInstrumentation.enable()

  api.propagation.setGlobalPropagator(new W3CTraceContextPropagator())
  api.trace.setGlobalTracerProvider(provider)

  provider.addSpanProcessor(
    new SimpleSpanProcessor(
      new ZipkinExporter({
        serviceName
      })
      // or 
      // new JaegerExporter({
      //   serviceName,
      // })
    )
  )
  provider.register()
  return provider
}

serviceAdd.js

'use strict'
// Register tracer
const serviceName = 'service-add'
const tracer = require('./tracer')
tracer(serviceName)

const service = require('fastify')({ logger: { level: 'debug' } })
const mercurius = require('mercurius')
const opentelemetry = require('@autotelic/fastify-opentelemetry')

service.register(opentelemetry, { serviceName })
service.register(mercurius, {
  schema: `
  extend type Query {
    add(x: Float, y: Float): Float
  }
  `,
  resolvers: {
    Query: {
      add: (_, { x, y }, { reply }) => {
        const { activeSpan, tracer } = reply.request.openTelemetry()

        activeSpan.setAttribute('arg.x', x)
        activeSpan.setAttribute('arg.y', y)

        const span = tracer.startSpan('compute-add', { parent: tracer.getCurrentSpan() })
        const result = x + y
        span.end()

        return result
      }
    }
  },
})

service.listen({ port: 4001, host: 'localhost' }, err => {
  if (err) {
    console.error(err)
    process.exit(1)
  }
})

gateway.js

'use strict'
const serviceName = 'gateway'
const tracer = require('./tracer')
// Register tracer
tracer(serviceName)

const gateway = require('fastify')({ logger: { level: 'debug' } })
const mercurius = require('mercurius')
const opentelemetry = require('@autotelic/fastify-opentelemetry')

// Register fastify opentelemetry
gateway.register(opentelemetry, { serviceName })
gateway.register(mercurius, {
  gateway: {
    services: [
      {
        name: 'add',
        url: 'http://localhost:4001/graphql'
      }
    ]
  }
})

gateway.listen({ port: 3000, host: 'localhost' }, err => {
  if (err) {
    process.exit(1)
  }
})

Start a zipkin service:

$ docker run -d -p 9411:9411 openzipkin/zipkin

Send some request to the gateway:

$ curl localhost:3000/graphql -H 'Content-Type: application/json' --data '{"query":"{ add(x: 1, y: 2) }"}'

You can now browse through mercurius tracing at http://localhost:9411