Skip to content

Commit d272e5a

Browse files
committed
add support for callback based lambda functions
1 parent b876a0f commit d272e5a

File tree

4 files changed

+101
-6
lines changed

4 files changed

+101
-6
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,19 @@ All notable changes to this project will be documented in this file.
55

66
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
77

8+
## [0.1.15] 2023-07-17
9+
10+
- Add support for callback based lambda functions
11+
12+
813
## [0.1.14] 2023-07-07
914

1015
- Add lots of aws lambda resource spans
1116
- GZIP
1217

18+
19+
The latest layer is: `arn:aws:lambda:${your-region-here}:097948374213:layer:baselime-node:8`
20+
1321
## [0.1.13] 2023-07-05
1422

1523
- Make sure flushing is not canceled

examples/sst/stacks/MyStack.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@ import { LayerVersion } from "aws-cdk-lib/aws-lambda";
33
import { Tags } from "aws-cdk-lib";
44

55

6-
function magicShit(api) {
7-
console.log(api)
8-
}
96
export function API({ stack }: StackContext) {
107

118
const bus = new EventBus(stack, "bus", {
@@ -17,7 +14,9 @@ export function API({ stack }: StackContext) {
1714
const api = new Api(stack, "api", {
1815
defaults: {
1916
function: {
20-
17+
environment: {
18+
BEEP: "YARP"
19+
},
2120
bind: [bus],
2221
nodejs: {
2322
esbuild: {

src/index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import api, { trace, context, propagation, Context as OtelContext, ROOT_CONTEXT, Attributes } from "@opentelemetry/api";
2-
import { Handler, DynamoDBStreamEvent, S3Event } from "aws-lambda";
2+
import { Handler, DynamoDBStreamEvent, S3Event, Callback } from "aws-lambda";
33
import { flatten } from "flat"
44
import { Context } from 'aws-lambda';
5+
import { promisify } from 'node:util';
56
export * as logger from './logger';
67

78
declare const global: {
@@ -17,7 +18,7 @@ type FaasDocument = {
1718
let coldstart = true;
1819

1920
export function wrap(handler: Handler) {
20-
return async (event: any, lambda_context: Context) => {
21+
return async function (event: any, lambda_context: Context, callback?: Callback) {
2122
const tracer = trace.getTracer('@baselime/baselime-lambda-wrapper', '1');
2223
const service = detectService(event);
2324
const trigger = triggerToServiceType(service);
@@ -55,6 +56,9 @@ export function wrap(handler: Handler) {
5556
const ctx = trace.setSpan(context.active(), span);
5657

5758
try {
59+
if(callback) {
60+
handler = promisify(handler);
61+
}
5862
const result = await context.with(ctx, handler as (args: any[]) => any, null, event, lambda_context);
5963
span.setAttributes(flatten({ result }) as Attributes);
6064
span.end();

tests/wrap.test.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { describe, expect, test } from "vitest";
2+
import { wrap } from '../src/index';
3+
import { NodeTracerProvider, ReadableSpan } from "@opentelemetry/sdk-trace-node";
4+
import { Resource } from "@opentelemetry/resources";
5+
6+
let spans: ReadableSpan[] = [];
7+
8+
function setupOtelTestHarness() {
9+
const provider = new NodeTracerProvider({
10+
resource: new Resource({
11+
"testing": true,
12+
}),
13+
});
14+
15+
provider.register();
16+
17+
provider.addSpanProcessor({
18+
forceFlush: async () => console.log('im called'),
19+
onStart: (span, context) => { },
20+
onEnd: (span) => { spans.push(span); },
21+
shutdown: async () => console.log('im called'),
22+
})
23+
24+
return {
25+
getSpan() {
26+
return spans.pop();
27+
}
28+
}
29+
}
30+
31+
32+
async function asyncHandler(event, context) {
33+
return "async lambda go brrr"
34+
};
35+
36+
function callbackHandler(event, context, callback) {
37+
callback(null, "callback lambda go brrr");
38+
}
39+
40+
const context = {
41+
functionName: "test",
42+
awsRequestId: "1234",
43+
invokedFunctionArn: "arn:aws:lambda:us-east-1:123456789012:function:test",
44+
callbackWaitsForEmptyEventLoop: false,
45+
memoryLimitInMB: "128",
46+
logGroupName: "test",
47+
logStreamName: "test",
48+
getRemainingTimeInMillis: () => 1000,
49+
functionVersion: "1",
50+
invokedFunctionUniqueIdentifier: "1",
51+
done: () => { },
52+
fail: () => { },
53+
succeed: () => { }
54+
55+
}
56+
describe("wrap", () => {
57+
const { getSpan } = setupOtelTestHarness()
58+
test("should wrap a callback lambda handler and not error", async () => {
59+
const wrapped = wrap(callbackHandler);
60+
await wrapped({}, context, (err, result) => {
61+
expect(result).toBe("callback lambda go brrr");
62+
63+
});
64+
65+
const span = getSpan();
66+
expect(span).toBeDefined();
67+
expect(span?.name).toBe("test");
68+
expect(span?.attributes.result).toBe("callback lambda go brrr");
69+
70+
71+
});
72+
test("should wrap a async lambda handler and not error", async () => {
73+
const wrapped = wrap(asyncHandler);
74+
const result = await wrapped({}, context);
75+
const span = getSpan();
76+
expect(span).toBeDefined();
77+
expect(span?.name).toBe("test");
78+
expect(span?.attributes.result).toBe("async lambda go brrr");
79+
80+
expect(result).toBe("async lambda go brrr");
81+
});
82+
83+
84+
});

0 commit comments

Comments
 (0)