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

feat(context functions): expose core functions for ease of use #14

Merged
merged 2 commits into from
May 3, 2018
Merged
Show file tree
Hide file tree
Changes from all 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
24 changes: 23 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,32 @@ exports.handler = iopipe((event, context) => {
});
```

By default this package will enable the tracing plugin. For more information on how to use Iopipe and the tracing plugin, see the documentation below:
By default this package will enable @iopipe/trace and @iopipe/event-info plugins. For more information on how to use IOpipe and these plugins, see the documentation below:
- [IOpipe Documentation](https://github.com/iopipe/iopipe-js-core#readme)
- [IOpipe Tracing Plugin Documentation](https://github.com/iopipe/iopipe-plugin-trace#readme)

Example With Tracing, Custom Metrics, and Labels (ES6 Module Format):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯


```js
import iopipe, {mark, metric, label} from '@iopipe/iopipe';

exports.handler = iopipe()(async (event, context) => {
// add a trace measurement for the database call
mark.start('db-call');
// fetch some data from the database
const rows = await sql(`select * from dogs where status = 'goodboy'`);
mark.end('db-call');

// add a custom metric for IOpipe search and alerts
metric('rows-from-db', rows.length);

// add a label to this invocation for easy filter/sort on dashboard.iopipe.com
label('used-db-cache');

context.succeed('This is my serverless function!');
});
```

# License

Apache 2.0
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,11 @@
},
"dependencies": {
"@iopipe/config": "^1.0.0",
"@iopipe/core": "^1.6.0"
"@iopipe/core": "^1.10.0"
},
"devDependencies": {
"@iopipe/scripts": "^1.4.1",
"aws-lambda-mock-context": "^3.1.1",
"lodash": "^4.17.4"
},
"eslintConfig": {
Expand Down
10 changes: 10 additions & 0 deletions src/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`lib warns correctly for getContext methods 1`] = `
Array [
"mark.start(test-mark) was called from @iopipe/iopipe but this method was not available. You may have called this method outside of an invocation or @iopipe/core needs to be upgraded to satisfy version ^1.11.0",
"mark.end(try-mark) was called from @iopipe/iopipe but this method was not available. You may have called this method outside of an invocation or @iopipe/core needs to be upgraded to satisfy version ^1.11.0",
"metric(test-metric-key,test-metric-value) was called from @iopipe/iopipe but this method was not available. You may have called this method outside of an invocation or @iopipe/core needs to be upgraded to satisfy version ^1.11.0",
"label(great-label) was called from @iopipe/iopipe but this method was not available. You may have called this method outside of an invocation or @iopipe/core needs to be upgraded to satisfy version ^1.11.0",
]
`;
35 changes: 35 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,36 @@
module.exports = require('@iopipe/core');

function warning(fn, ...args) {
/*eslint-disable no-console*/
const str = `${fn}(${args.join(
','
)}) was called from @iopipe/iopipe but this method was not available. You may have called this method outside of an invocation or @iopipe/core needs to be upgraded to satisfy version ^1.11.0`;
console.warn(str);
return str;
/*eslint-enable no-console*/
}

function ctx() {
const context =
(typeof module.exports.getContext === 'function' &&
module.exports.getContext()) ||
{};
return (
context.iopipe || {
mark: {
start: warning.bind(null, 'mark.start'),
end: warning.bind(null, 'mark.end')
},
metric: warning.bind(null, 'metric'),
label: warning.bind(null, 'label')
}
);
}

module.exports.mark = {
start: (...args) => ctx().mark.start(...args),
end: (...args) => ctx().mark.end(...args)
};

module.exports.metric = (...args) => ctx().metric(...args);
module.exports.label = (...args) => ctx().label(...args);
75 changes: 65 additions & 10 deletions src/index.test.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,39 @@
const _ = require('lodash');
const iopipe = require('./index');
import _ from 'lodash';
import mockContext from 'aws-lambda-mock-context';

describe('iopipe kitchen sink', () => {
beforeEach(() => {
delete process.env.IOPIPE_TOKEN;
});
import iopipe from '.';

beforeEach(() => {
delete process.env.IOPIPE_TOKEN;
});

test('lib warns correctly for getContext methods', () => {
const { mark: { start, end }, metric, label } = iopipe;
const messages = [
start('test-mark'),
end('try-mark'),
metric('test-metric-key', 'test-metric-value'),
label('great-label')
];
expect(messages).toMatchSnapshot();
});

describe('iopipe kitchen sink', () => {
it('has trace and event info plugins pre-bundled', done => {
iopipe({ clientId: 'foobar' })((event, context) => {
let invocation;
iopipe({
clientId: 'foobar',
plugins: [inv => (invocation = inv) && { meta: { name: 'wow' } }]
})((event, context) => {
try {
const { config } = context.iopipe;

expect(config.extends).toBe('@iopipe/config');

expect(config.plugins).toHaveLength(2);
expect(invocation.plugins).toHaveLength(3);
expect(invocation.plugins.map(p => p.meta.name)).toEqual([
'wow',
'@iopipe/trace',
'@iopipe/event-info'
]);

expect(_.isFunction(config.plugins[0])).toBe(true);

Expand All @@ -26,3 +46,38 @@ describe('iopipe kitchen sink', () => {
})({}, {});
});
});

test('lib has mark, metric, label methods', async () => {
const ctx = mockContext({ functionName: 'mark' });
let invocation;

iopipe({ token: 'trace', plugins: [inv => (invocation = inv)] })((e, c) => {
const { mark: { start, end }, metric, label } = iopipe;
start('trace-test');
metric('foobar', 100);
label('animals');
label('cats');
setTimeout(() => {
end('trace-test');
c.succeed(200);
}, 101);
})({}, ctx);

const val = await ctx.Promise;
expect(val).toBe(200);

const {
performanceEntries,
labels,
custom_metrics: metrics
} = invocation.report.report;

expect(_.map(performanceEntries, 'name')).toEqual([
'start:trace-test',
'measure:trace-test',
'end:trace-test'
]);
expect(performanceEntries[1].duration).toBeGreaterThan(101);
expect(metrics).toEqual([{ name: 'foobar', n: 100, s: undefined }]);
expect(labels).toEqual(['animals', 'cats']);
});
Loading