Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update for Middy v2 async API #6

Merged
merged 5 commits into from
Aug 4, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:

strategy:
matrix:
node-version: [10.x, 12.x, 14.x]
node-version: [12.x, 14.x]

steps:
- uses: actions/checkout@v2
Expand Down
19 changes: 15 additions & 4 deletions README.MD
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
middy-beeline
===
[![GitHub release](https://img.shields.io/github/release/resistbot/middy-beeline?include_prereleases=&sort=semver)](https://github.com/resistbot/middy-beeline/releases/) [![Tests](https://github.com/resistbot/middy-beeline/workflows/Tests/badge.svg)](https://github.com/resistbot/middy-beeline/actions?query=workflow:"Tests")

Middy middleware for instrumenting with [Honeycomb](https://honeycomb.io).
[![NPM](https://nodei.co/npm/@resistbot/middy-beeline.png?compact=true)](https://npmjs.org/package/@resistbot/middy-beeline)

# middy-beeline

Middy middleware for instrumenting with [Honeycomb](https://honeycomb.io).

## Getting Started

Expand All @@ -13,6 +16,7 @@ npm install --save @resistbot/middy-beeline
```

Running the tests

```bash
npm test
```
Expand Down Expand Up @@ -47,15 +51,22 @@ module.exports = { handler }
```

## How it works
The middleware will startup [Beeline for Nodejs](https://docs.honeycomb.io/getting-data-in/javascript/beeline-nodejs) with the options you configure before your handler runs, create a trace, and add any of the header context you supplied. It adds the `beeline` instance to the handler.event so you can use it in your function- add spans, more context, etc.

The middleware will startup [Beeline for Nodejs](https://docs.honeycomb.io/getting-data-in/javascript/beeline-nodejs) with the options you configure before your handler runs, create a trace, and add any of the header context you supplied. It adds the `beeline` instance to the handler.event so you can use it in your function- add spans, more context, etc.

Once your handler is done, the middleware will close the trace and run a `beeline.flush()` to make sure all the events are sent.

## Options

Some are obvious from the beeline for nodejs documentation (writeKey, dataset, serviceName, sampleRate) but there are a few extras. Just like the beeline docs say, you can substitute `sampleRate` with `samplerHook: fn()` and the middleware will use your samplerhook function instead of the standard rate.

Also the headerContext list allows you to tell middy-beeline which headers to capture as context and what they should be named. Also by default, any errors are marked as `error:true` and `error_message: <the error message>`. You can change the context key for errors using `errorMessageContext`.

## Contributing

Feel free to open a Pull Request or Issue w/ a bug report or feature request.

## Creating a release

1. Update `package.json` version element to match the release you'll be using.
1. Create a new Release once your code is merged. If the two versions match, a new version will be delivered to [npm](https://www.npmjs.com/package/@resistbot/middy-beeline).
77 changes: 39 additions & 38 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,30 @@
let HC_INIT = false;

const setopts = (opts) => {
const defaults = {
writeKey: 'null',
serviceName: '',
dataset: 'test',
sampleRate: 10,
headerContext: [],
errorMessageContext: 'error_message',
};
const defaults = {
writeKey: 'null',
serviceName: '',
dataset: 'test',
sampleRate: 10,
headerContext: [],
errorMessageContext: 'error_message',
};

const honeycombMiddleware = (opts = {}) => {
const options = { ...defaults, ...opts };
return options;
};
module.exports = (opts) => ({
before: (handler, next) => {
const options = setopts(opts);

const honeycombMiddlewareBefore = (request) => {
if (!HC_INIT) {
if (options.samplerHook) {
// eslint-disable-next-line no-param-reassign, global-require
handler.event.beeline = require('honeycomb-beeline')({
request.event.beeline = require('honeycomb-beeline')({
writeKey: options.writeKey,
samplerHook: options.samplerHook,
serviceName: options.serviceName,
dataset: options.dataset,
});
} else {
// eslint-disable-next-line no-param-reassign, global-require
handler.event.beeline = require('honeycomb-beeline')({
request.event.beeline = require('honeycomb-beeline')({
writeKey: options.writeKey,
sampleRate: options.sampleRate,
serviceName: options.serviceName,
Expand All @@ -38,37 +34,42 @@ module.exports = (opts) => ({
HC_INIT = true;
} else {
// eslint-disable-next-line no-param-reassign, global-require
handler.event.beeline = require('honeycomb-beeline')();
request.event.beeline = require('honeycomb-beeline')();
}
// eslint-disable-next-line no-param-reassign
handler.event.trace = handler.event.beeline.startTrace();
request.event.trace = request.event.beeline.startTrace();

options.headerContext.forEach((head) => {
const { header, contextname } = head;
if (handler.event.headers[header]) {
handler.event.beeline.addContext({
[contextname]: handler.event.headers[header],
if (request.event.headers[header]) {
request.event.beeline.addContext({
[contextname]: request.event.headers[header],
});
}
});
return next();
},
after: (handler, next) => {
handler.event.beeline.finishTrace(handler.event.trace);
handler.event.beeline.flush();
return next();
},
onError: (handler, next) => {
const options = setopts(opts);
if (handler.event.beeline) {
handler.event.beeline.addContext({
};

const honeycombMiddlewareAfter = (request) => {
request.event.beeline.finishTrace(request.event.trace);
request.event.beeline.flush();
};

const honeycombMiddlewareOnError = (request) => {
if (request.event.beeline) {
request.event.beeline.addContext({
error: true,
[options.errorMessageContext]: handler.error.toString(),
[options.errorMessageContext]: request.error.toString(),
});
handler.event.beeline.finishTrace(handler.event.trace);
handler.event.beeline.flush();
request.event.beeline.finishTrace(request.event.trace);
request.event.beeline.flush();
}
};

return {
before: honeycombMiddlewareBefore,
after: honeycombMiddlewareAfter,
onError: honeycombMiddlewareOnError,
};
};

return next(handler.error);
},
});
module.exports = honeycombMiddleware;
24 changes: 8 additions & 16 deletions index.test.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
const middy = require('middy');
const middyBeeline = require('.');

describe('middy-beeline', () => {
it('should extract keys', (done) => {
const handler = middy((event, context, callback) => {
callback(null, event.extracted);
it('should extract keys', () => {
const middleware = middyBeeline({
writeKey: 'key',
serviceName: 'myService',
dataset: 'myDataset',
samplerHook: () => false,
});

handler.use(
middyBeeline({
writeKey: 'key',
serviceName: 'myService',
dataset: 'myDataset',
}),
);

const event = {
requestContext: {},
headers: {
'Content-Type': 'application/json',
},
};
handler(event, null, (err) => {
expect(err).toBe(null);
done();
});
const request = { event };
middleware.before(request);
});
});
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "@resistbot/middy-beeline",
"version": "0.1.4",
"version": "1.0.0",
"description": "Middy Middleware for Honeycomb Beeline",
"main": "index.js",
"engines": {
"node": ">=8.3.0"
"node": ">=12.13.0"
},
"scripts": {
"format": "prettier --write .",
Expand Down