Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 1621e81

Browse files
ssolmonsonScott Solmonsonastuyve
authoredApr 25, 2024
Scott.solmonson/batch item failure metric (#532)
* Create new method for batch item failure metric * Create function to determine if response is batchItemFailures * Add call to function and new method * Add condition to check to an itemIdentifier entry so as not to increment on empty arrays * format and lint files * Add entry for metric test * fix: Use snake case instead of camelCase for metric name. * feat: Increment batch_item_failures metric by the number of batchItemFailures in the response. 0 is fine. * fix: remove whitespace change * fix: kebab-case file names * fix: kebab-case file names * fix: lint --------- Co-authored-by: Scott Solmonson <scott.solmonson@nlb-int-svc-proxy-06a01ef5ff9ffd47.elb.us-gov-west-1.amazonaws.com> Co-authored-by: AJ Stuyvenberg <astuyve@gmail.com>
1 parent 856ff60 commit 1621e81

File tree

6 files changed

+105
-3
lines changed

6 files changed

+105
-3
lines changed
 

‎src/index.spec.ts

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ import {
99
sendDistributionMetricWithDate,
1010
_metricsQueue,
1111
} from "./index";
12-
import { incrementErrorsMetric, incrementInvocationsMetric } from "./metrics/enhanced-metrics";
12+
import {
13+
incrementErrorsMetric,
14+
incrementInvocationsMetric,
15+
incrementBatchItemFailureMetric,
16+
} from "./metrics/enhanced-metrics";
1317
import { LogLevel, setLogLevel } from "./utils";
1418
import { HANDLER_STREAMING, STREAM_RESPONSE } from "./constants";
1519
import { PassThrough } from "stream";
@@ -22,6 +26,9 @@ jest.mock("./metrics/enhanced-metrics");
2226

2327
const mockedIncrementErrors = incrementErrorsMetric as jest.Mock<typeof incrementErrorsMetric>;
2428
const mockedIncrementInvocations = incrementInvocationsMetric as jest.Mock<typeof incrementInvocationsMetric>;
29+
const mockedIncrementBatchItemFailures = incrementBatchItemFailureMetric as jest.Mock<
30+
typeof incrementBatchItemFailureMetric
31+
>;
2532

2633
const mockARN = "arn:aws:lambda:us-east-1:123497598159:function:my-test-lambda";
2734
const mockContext = {
@@ -88,6 +95,7 @@ describe("datadog", () => {
8895

8996
mockedIncrementErrors.mockClear();
9097
mockedIncrementInvocations.mockClear();
98+
mockedIncrementBatchItemFailures.mockClear();
9199
});
92100
afterEach(() => {
93101
process.env = oldEnv;
@@ -379,6 +387,65 @@ describe("datadog", () => {
379387
expect(mockedIncrementErrors).toBeCalledWith(expect.anything(), mockContext);
380388
});
381389

390+
it("increments batch item failures enhanced metric", async () => {
391+
const lambdaResponse: any = {
392+
batchItemFailures: [{ itemIdentifier: "abc123" }, { itemIdentifier: "def456" }],
393+
};
394+
395+
const wrapped = datadog(async () => {
396+
return lambdaResponse;
397+
});
398+
399+
const lambdaResult = await wrapped({}, mockContext, () => {});
400+
401+
expect(lambdaResult).toEqual(lambdaResponse);
402+
403+
expect(mockedIncrementBatchItemFailures).toBeCalledTimes(1);
404+
expect(mockedIncrementInvocations).toBeCalledTimes(1);
405+
406+
expect(mockedIncrementBatchItemFailures).toBeCalledWith(expect.anything(), 2, mockContext);
407+
expect(mockedIncrementInvocations).toBeCalledWith(expect.anything(), mockContext);
408+
});
409+
410+
it("sets batch item failures enhanced metric to zero if list is empty", async () => {
411+
const lambdaResponse: any = {
412+
batchItemFailures: [],
413+
};
414+
415+
const wrapped = datadog(async () => {
416+
return lambdaResponse;
417+
});
418+
419+
const lambdaResult = await wrapped({}, mockContext, () => {});
420+
421+
expect(lambdaResult).toEqual(lambdaResponse);
422+
423+
expect(mockedIncrementBatchItemFailures).toBeCalledTimes(1);
424+
expect(mockedIncrementInvocations).toBeCalledTimes(1);
425+
426+
expect(mockedIncrementBatchItemFailures).toBeCalledWith(expect.anything(), 0, mockContext);
427+
expect(mockedIncrementInvocations).toBeCalledWith(expect.anything(), mockContext);
428+
});
429+
430+
it("doesn't increment batch item failures if it's not a failure response", async () => {
431+
const lambdaResponse: any = {
432+
foo: "bar",
433+
};
434+
435+
const wrapped = datadog(async () => {
436+
return lambdaResponse;
437+
});
438+
439+
const lambdaResult = await wrapped({}, mockContext, () => {});
440+
441+
expect(lambdaResult).toEqual(lambdaResponse);
442+
443+
expect(mockedIncrementBatchItemFailures).toBeCalledTimes(0);
444+
expect(mockedIncrementInvocations).toBeCalledTimes(1);
445+
446+
expect(mockedIncrementInvocations).toBeCalledWith(expect.anything(), mockContext);
447+
});
448+
382449
it("doesn't increment errors or invocations with config false setting", async () => {
383450
const handlerError: Handler = (event, context, callback) => {
384451
throw Error("Some error");

‎src/index.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,25 @@ import { HANDLER_STREAMING, STREAM_RESPONSE } from "./constants";
33
import {
44
incrementErrorsMetric,
55
incrementInvocationsMetric,
6+
incrementBatchItemFailureMetric,
67
KMSService,
78
MetricsConfig,
89
MetricsListener,
910
MetricsQueue,
1011
} from "./metrics";
1112
import { TraceConfig, TraceListener } from "./trace";
1213
import { subscribeToDC } from "./runtime";
13-
import { logDebug, Logger, LogLevel, promisifiedHandler, setSandboxInit, setLogger, setLogLevel } from "./utils";
14+
import {
15+
isBatchItemFailure,
16+
batchItemFailureCount,
17+
logDebug,
18+
Logger,
19+
LogLevel,
20+
promisifiedHandler,
21+
setSandboxInit,
22+
setLogger,
23+
setLogLevel,
24+
} from "./utils";
1425
import { getEnhancedMetricTags } from "./metrics/enhanced-metrics";
1526
import { DatadogTraceHeaders } from "./trace/context/extractor";
1627

@@ -190,6 +201,9 @@ export function datadog<TEvent, TResult>(
190201
if (responseIs5xxError) {
191202
incrementErrorsMetric(metricsListener, context);
192203
}
204+
if (isBatchItemFailure(localResult)) {
205+
incrementBatchItemFailureMetric(metricsListener, batchItemFailureCount(localResult), context);
206+
}
193207
}
194208
return localResult;
195209
};

‎src/metrics/enhanced-metrics.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,12 @@ export function incrementInvocationsMetric(listener: MetricsListener, context: C
8181
export function incrementErrorsMetric(listener: MetricsListener, context: Context): void {
8282
incrementEnhancedMetric(listener, "errors", context);
8383
}
84+
85+
export function incrementBatchItemFailureMetric(listener: MetricsListener, count: number, context: Context): void {
86+
listener.sendDistributionMetric(
87+
"aws.lambda.enhanced.batch_item_failures",
88+
count,
89+
true,
90+
...getEnhancedMetricTags(context),
91+
);
92+
}

‎src/metrics/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
export { MetricsConfig, MetricsListener } from "./listener";
22
export { MetricsQueue } from "./queue";
33
export { KMSService } from "./kms-service";
4-
export { incrementErrorsMetric, incrementInvocationsMetric } from "./enhanced-metrics";
4+
export { incrementErrorsMetric, incrementInvocationsMetric, incrementBatchItemFailureMetric } from "./enhanced-metrics";

‎src/utils/batch-item-failures.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export function isBatchItemFailure(lambdaResponse: any): boolean {
2+
return (
3+
typeof lambdaResponse === "object" &&
4+
"batchItemFailures" in lambdaResponse &&
5+
Array.isArray(lambdaResponse.batchItemFailures)
6+
);
7+
}
8+
9+
export function batchItemFailureCount(lambdaResponse: any): number {
10+
return lambdaResponse?.batchItemFailures?.length || 0; // Guard clause in case someone calls this without checking isBatchItemFailure
11+
}

‎src/utils/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ export { wrap, promisifiedHandler } from "./handler";
33
export { Timer } from "./timer";
44
export { logWarning, logError, logDebug, Logger, setLogLevel, setLogger, LogLevel } from "./log";
55
export { tagObject } from "./tag-object";
6+
export { batchItemFailureCount, isBatchItemFailure } from "./batch-item-failures";

0 commit comments

Comments
 (0)