Skip to content

Commit 1277ae4

Browse files
committed
2 parents dadccce + 7ecd006 commit 1277ae4

File tree

6 files changed

+171
-68
lines changed

6 files changed

+171
-68
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
The purpose of this package is to easily organize the mapping between your code and your API request within Lambda functions that have more than one purpose. This takes away the need for the configuration of mapping templates and handles the standard event object that Amazon sends through with Lambda functions with proxy configuration. The desired effect of the package is to make it easier to build microservices that have multiple API Gateway endpoints.
88

9+
As this package relates to linking API Gateway and Lambda together, the request IDs for both services are logged out to CloudWatch so when an error occurs in API Gateway, you can search the for the Gateway request ID to find the logs. More information on this can be found [here](https://aws.amazon.com/blogs/compute/techniques-and-tools-for-better-serverless-api-logging-with-amazon-api-gateway-and-aws-lambda/).
10+
911
## Contents
1012
- [Usage](#usage)
1113
- [Defining Routes](#routes)

package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "A hapi inspired router for AWS Lambda proxy functions",
55
"main": "index.js",
66
"scripts": {
7-
"test": "npm run-script lint && nyc ava test && nyc report --reporter=text-lcov | coveralls",
7+
"test": "npm run-script lint && nyc ava test -s && nyc report --reporter=text-lcov | coveralls",
88
"lint": "eslint src/*.js test/*.js",
99
"build": "babel src -d build && cp package.json build/package.json && cp README.md build/README.md"
1010
},
@@ -33,7 +33,8 @@
3333
"eslint-plugin-import": "^1.16.0",
3434
"eslint-plugin-jsx-a11y": "^2.2.3",
3535
"eslint-plugin-react": "^6.4.1",
36-
"nyc": "^8.3.2"
36+
"nyc": "^8.3.2",
37+
"sinon": "^2.3.5"
3738
},
3839
"ava": {
3940
"babel": "inherit",

src/index.js

+24
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,36 @@ export default class Alpr {
1515
this.event = data.event || {};
1616
this.context = data.context || {};
1717
this.callback = data.callback;
18+
this.logRequestIds();
1819

1920
if (typeof this.callback !== 'function') {
2021
throw new Error('A callback must be specified.');
2122
}
2223
}
2324

25+
/**
26+
* Logs the request ids from API Gateway and Lambda to make debugging requests from API Gateway
27+
* easier.
28+
*
29+
* @return {void}
30+
*/
31+
logRequestIds() {
32+
let apiGatewayRequestId;
33+
let lambdaRequestId;
34+
35+
if (this.event && this.event.requestContext && this.event.requestContext.requestId) {
36+
apiGatewayRequestId = this.event.requestContext.requestId;
37+
}
38+
39+
if (this.context && this.context.awsRequestId) {
40+
lambdaRequestId = this.context.awsRequestId;
41+
}
42+
43+
if (apiGatewayRequestId && lambdaRequestId) {
44+
console.log(`Lambda request ID: ${lambdaRequestId}. API Gateway request ID: ${apiGatewayRequestId}`); // eslint-disable-line
45+
}
46+
}
47+
2448
/**
2549
* Router function. Should be called for each route you want to create.
2650
*

test/.eslintrc

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"rules": {
3+
"import/no-extraneous-dependencies": ["error", { "devDependencies": true }]
4+
}
5+
}

test/index.js

+23-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1+
import test from 'ava';
2+
import sinon from 'sinon';
13
import Alpr from './../src/index';
24
import data from './aws-data-file.json';
35

46
data.callback = () => {};
5-
// eslint-disable-next-line
6-
import test from 'ava';
77

88
const alprGlobal = new Alpr(data);
9+
const sandbox = sinon.sandbox;
10+
11+
test.afterEach(() => {
12+
sandbox.restore();
13+
});
914

1015
test('Route Matching > matches path strings and resource strings', (t) => {
1116
const result = alprGlobal.routeMatcher({
@@ -270,3 +275,19 @@ test('String Matching > will return false when no params are provided', (t) => {
270275
// Just for default params
271276
t.is(Alpr.inArrayOrIsString(), false);
272277
});
278+
279+
test('Logging request ids > Logs out the ids when they are available', (t) => {
280+
const spy = sandbox.spy(console, 'log');
281+
282+
alprGlobal.logRequestIds();
283+
const consoleLog = spy.getCall(0).args[0];
284+
t.true(consoleLog.includes(data.event.requestContext.requestId));
285+
t.true(consoleLog.includes(data.context.awsRequestId));
286+
});
287+
288+
test('Logging request ids > Does not log out the ids when they are not available', (t) => {
289+
const alprLocal = new Alpr({ callback: () => {} });
290+
alprLocal.logRequestIds();
291+
const spy = sandbox.spy(console, 'log');
292+
t.false(spy.calledOnce);
293+
});

0 commit comments

Comments
 (0)