fastify-jaeger
Advanced tools
Comparing version 0.1.0 to 1.0.0
117
index.js
@@ -1,34 +0,101 @@ | ||
const { opentracing, initTracer } = require('jaeger-client') | ||
'use strict' | ||
const assert = require('assert') | ||
const fp = require('fastify-plugin') | ||
const { Validator } = require('jsonschema') | ||
const jaegerSchema = require('./jaeger-schema') | ||
const logger = require('simple-json-logger') | ||
const { initTracer, opentracing } = require('jaeger-client') | ||
const url = require('url') | ||
function fastifyJaeger (fastify, params, next) { | ||
try { | ||
const baseConfig = { | ||
reporter: { logSpans: true } | ||
const { Tags, FORMAT_HTTP_HEADERS } = opentracing | ||
function jaegerPlugin (fastify, opts, next) { | ||
assert(opts.serviceName, 'Jaeger Plugin requires serviceName option') | ||
const exposeAPI = opts.exposeAPI !== false | ||
const { state } = opts | ||
const tracerConfig = { | ||
serviceName: opts.serviceName, | ||
sampler: { | ||
type: 'const', | ||
param: 1 | ||
}, | ||
reporter: { | ||
logSpans: false | ||
} | ||
const baseOptions = { logger } | ||
const { config, options } = params | ||
const v = new Validator() | ||
v.validate(config, jaegerSchema, { | ||
throwError: true | ||
} | ||
const tracerOptions = { | ||
logger: fastify.log | ||
} | ||
const tracerDefaults = { state, ...opts } | ||
const tracer = initTracer({ ...tracerConfig, ...tracerDefaults }, { ...tracerOptions, ...tracerDefaults }) | ||
const tracerMap = new WeakMap() | ||
function api () { | ||
const req = this | ||
return { | ||
get span () { | ||
return tracerMap.get(req) | ||
}, | ||
tags: Tags | ||
} | ||
} | ||
if (exposeAPI) { | ||
fastify.decorateRequest('jaeger', api) | ||
} | ||
function filterObject (obj) { | ||
const ret = {} | ||
Object.keys(obj) | ||
.filter((key) => obj[key] != null) | ||
.forEach((key) => { ret[key] = obj[key] }) | ||
return ret | ||
} | ||
function setContext (headers) { | ||
return filterObject({ ...headers, ...state }) | ||
} | ||
function onRequest (req, res, done) { | ||
const parentSpanContext = tracer.extract(FORMAT_HTTP_HEADERS, setContext(req.raw.headers)) | ||
const span = tracer.startSpan(`${req.raw.method} - ${url.format(req.raw.url)}`, { | ||
childOf: parentSpanContext, | ||
tags: { [Tags.SPAN_KIND]: Tags.SPAN_KIND_RPC_SERVER, [Tags.HTTP_METHOD]: req.raw.method, [Tags.HTTP_URL]: url.format(req.raw.url) } | ||
}) | ||
const tracer = initTracer({ ...baseConfig, ...config }, { ...baseOptions, ...options }) | ||
fastify.decorate('tracer', tracer) | ||
fastify.decorate('opentracing', opentracing) | ||
fastify.addHook('onClose', (_, done) => { | ||
tracer.close(done) | ||
tracerMap.set(req, span) | ||
done() | ||
} | ||
function onResponse (req, reply, done) { | ||
const span = tracerMap.get(req) | ||
span.setTag(Tags.HTTP_STATUS_CODE, reply.res.statusCode) | ||
done() | ||
} | ||
function onError (req, reply, error, done) { | ||
const span = tracerMap.get(req) | ||
span.setTag(Tags.ERROR, { | ||
'error.object': error, | ||
message: error.message, | ||
stack: error.stack | ||
}) | ||
next() | ||
} catch (e) { | ||
next(new Error(e.message)) | ||
done() | ||
} | ||
function onClose (instance, done) { | ||
tracer.close(done) | ||
} | ||
fastify.addHook('onRequest', onRequest) | ||
fastify.addHook('onResponse', onResponse) | ||
fastify.addHook('onError', onError) | ||
fastify.addHook('onClose', onClose) | ||
next() | ||
} | ||
module.exports = fp(fastifyJaeger, { | ||
name: 'fastify-jaeger', | ||
fastify: '1.x' | ||
}) | ||
module.exports = fp(jaegerPlugin, { name: 'fastify-jaeger' }) |
{ | ||
"name": "fastify-jaeger", | ||
"version": "0.1.0", | ||
"description": "", | ||
"version": "1.0.0", | ||
"description": "Fastify plugin for Jaeger distributed tracing system", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "tap test.js --cov" | ||
"jaeger": "docker container run -d -p 6831:6831/udp -p 6832:6832/udp -p 16686:16686 jaegertracing/all-in-one:1.17", | ||
"test": "tap **/*.test.js", | ||
"lint": "standard | snazzy", | ||
"fix": "standard --fix" | ||
}, | ||
"author": "", | ||
"files": [ | ||
"test", | ||
"example.js", | ||
"README.md" | ||
], | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/maumercado/fastify-jaeger.git" | ||
}, | ||
"keywords": [ | ||
"tracing", | ||
"jaeger", | ||
"trace", | ||
"fastify", | ||
"distributed", | ||
"timing" | ||
], | ||
"author": "Mauricio Mercado - @maumercado (https://codigo.sh)", | ||
"license": "ISC", | ||
"dependencies": { | ||
"fastify-plugin": "^1.2.1", | ||
"jaeger-client": "^3.13.0", | ||
"jsonschema": "^1.2.4", | ||
"simple-json-logger": "^3.1.1" | ||
"bugs": { | ||
"url": "https://github.com/maumercado/fastify-jaeger/issues" | ||
}, | ||
"homepage": "https://github.com/maumercado/fastify-jaeger#readme", | ||
"devDependencies": { | ||
"fastify": "^1.13.0", | ||
"tap": "^12.1.0" | ||
"fastify": "^2.13.0", | ||
"snazzy": "^8.0.0", | ||
"standard": "^14.3.3", | ||
"tap": "^14.10.7" | ||
}, | ||
"dependencies": { | ||
"fastify-plugin": "^1.6.1", | ||
"jaeger-client": "^3.17.2" | ||
} | ||
} |
# fastify-jaeger | ||
Fastify Jaeger tracing plugin, with this you can share the same Jaeger tracer | ||
in your server. | ||
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](http://standardjs.com/) | ||
[![Lint, Test](https://github.com/maumercado/fastify-jaeger/workflows/Lint,%20Test/badge.svg?branch=master)](https://github.com/maumercado/fastify-jaeger/actions?query=workflow%3A%22Lint%2C+Test%22) | ||
Fastify plugin for Jaeger distributed tracing system. | ||
## Install | ||
> npm i fastify-jaeger --save | ||
```sh | ||
npm install fastify-jaeger | ||
``` | ||
## Usage | ||
Require the plugin and register it within Fastify, the pass the following options: `{ serviceName [, exposeAPI] }` | ||
Add this by `register`. | ||
*exposeAPI: (true by default)* Exposes the Span API, binded to the current request, which allows the user to setTags, and log the current span. | ||
```javascript | ||
This plugins supports all other options and configurations of the official [jaeger-client-node](https://github.com/jaegertracing/jaeger-client-node) throught the options object of the plugin. | ||
It uses the logger set to the fastify instance as the tracer logger. | ||
```js | ||
const fastify = require('fastify')() | ||
fastify.register(require('fastify-jaeger'), { | ||
config: { | ||
serviceName: 'ping-server', | ||
sampler: { | ||
type: 'const', | ||
param: 1 | ||
}, | ||
reporter: { | ||
logSpans: true | ||
} | ||
}, | ||
options: { | ||
// using npm package `simple-json-logger` by default | ||
// change with whatever you prefer | ||
logger: { | ||
info (msg) { | ||
console.log('INFO ', msg) | ||
}, | ||
error (msg) { | ||
console.log('ERROR', msg) | ||
} | ||
} | ||
} | ||
serviceName: 'my-service-name' | ||
}) | ||
fastify.get('/ping', async function (req, reply) { | ||
const { Tags, FORMAT_HTTP_HEADERS } = this.opentracing | ||
const parentSpanContext = this.tracer.extract(FORMAT_HTTP_HEADERS, req.headers) | ||
const span = this.tracer.startSpan('ping', { | ||
childOf: parentSpanContext, | ||
tags: {[Tags.SPAN_KIND]: Tags.SPAN_KIND_RPC_SERVER} | ||
}) | ||
const msg = 'pong' | ||
span.log({event: 'ping', value: msg}) | ||
span.finish() | ||
return msg | ||
fastify.get('/', (req, reply) => { | ||
reply.send({ hello: 'world' }) | ||
}) | ||
@@ -57,19 +36,8 @@ | ||
if (err) throw err | ||
console.log('Server listenting on localhost:', fastify.server.address().port) | ||
}) | ||
``` | ||
see [examples](./examples) for more. | ||
## Reference | ||
This plugin decorates the `fastify` instance with `tracer` and `opentracing`. | ||
`tracer` is the instance created by `initTracer` of `jaeger-client`. `opentracing` | ||
is the `opentracing` which `jaeger-client` using. | ||
`fastify-jaeger` takes an object as parameter, which has `config` and `options` | ||
property. They are passed into `initTracer`, so for more infomation, see | ||
[jaeger-client](https://github.com/jaegertracing/jaeger-client-node). | ||
## License | ||
MIT | ||
Licensed under [MIT](./LICENSE). |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
No contributors or author data
MaintenancePackage does not specify a list of contributors or an author in package.json.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
2
0
0
11195
4
7
1
238
43
2
2
- Removedjsonschema@^1.2.4
- Removedsimple-json-logger@^3.1.1
- Removedfast-safe-stringify@2.1.1(transitive)
- Removedjsonschema@1.5.0(transitive)
- Removedlodash.defaultsdeep@4.6.1(transitive)
- Removedsimple-json-logger@3.1.2(transitive)
Updatedfastify-plugin@^1.6.1
Updatedjaeger-client@^3.17.2