Skip to content

Commit 98dd7ce

Browse files
committed
move to use metricScope
1 parent c1425c5 commit 98dd7ce

2 files changed

Lines changed: 54 additions & 63 deletions

File tree

lambdas/authorizer/src/__tests__/index.test.ts

Lines changed: 45 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,30 @@ import {
44
Callback,
55
Context,
66
} from "aws-lambda";
7+
import { metricScope } from "aws-embedded-metrics";
78
import pino from "pino";
89
import { Deps } from "../deps";
910
import { EnvVars } from "../env";
1011
import createAuthorizerHandler from "../authorizer";
1112

13+
jest.mock("aws-embedded-metrics", () => {
14+
const metricsMock = {
15+
setNamespace: jest.fn(),
16+
putMetric: jest.fn(),
17+
};
18+
19+
return {
20+
metricScope: jest.fn((handler: (metrics: typeof metricsMock) => unknown) => {
21+
const wrapped = handler(metricsMock);
22+
if (typeof wrapped === "function") {
23+
return wrapped();
24+
}
25+
return undefined;
26+
}),
27+
__metricsMock: metricsMock,
28+
};
29+
});
30+
1231
const mockedDeps: jest.Mocked<Deps> = {
1332
logger: {
1433
info: jest.fn(),
@@ -56,18 +75,25 @@ describe("Authorizer Lambda Function", () => {
5675
});
5776

5877
describe("Certificate expiry check", () => {
59-
let consoleLogSpy: jest.SpyInstance;
60-
6178
beforeEach(() => {
6279
jest
6380
.useFakeTimers({ doNotFake: ["nextTick"] })
6481
.setSystemTime(new Date("2025-11-03T14:19:00Z"));
65-
consoleLogSpy = jest.spyOn(console, "log").mockImplementation();
82+
(metricScope as jest.Mock).mockClear();
83+
const metricsMock = (jest.requireMock(
84+
"aws-embedded-metrics",
85+
) as {
86+
__metricsMock: {
87+
setNamespace: jest.Mock;
88+
putMetric: jest.Mock;
89+
};
90+
}).__metricsMock;
91+
metricsMock.setNamespace.mockClear();
92+
metricsMock.putMetric.mockClear();
6693
});
6794

6895
afterEach(() => {
6996
jest.useRealTimers();
70-
consoleLogSpy.mockRestore();
7197
});
7298

7399
it("Should not log CloudWatch metric when certificate is null", async () => {
@@ -77,7 +103,7 @@ describe("Authorizer Lambda Function", () => {
77103
handler(mockEvent, mockContext, mockCallback);
78104
await new Promise(process.nextTick);
79105

80-
expect(consoleLogSpy).not.toHaveBeenCalled();
106+
expect(metricScope).not.toHaveBeenCalled();
81107
});
82108

83109
it("Should log CloudWatch metric when the certificate expiry threshold is reached", async () => {
@@ -89,28 +115,19 @@ describe("Authorizer Lambda Function", () => {
89115
handler(mockEvent, mockContext, mockCallback);
90116
await new Promise(process.nextTick);
91117

92-
expect(consoleLogSpy).toHaveBeenCalledWith(
93-
JSON.stringify({
94-
_aws: {
95-
Timestamp: 1_762_179_540_000,
96-
CloudWatchMetrics: [
97-
{
98-
Namespace: "cloudwatch-namespace",
99-
Dimensions: ["SUBJECT_DN", "NOT_AFTER"],
100-
Metrics: [
101-
{
102-
Name: "apim-client-certificate-near-expiry",
103-
Unit: "Count",
104-
Value: 1,
105-
},
106-
],
107-
},
108-
],
109-
},
110-
SUBJECT_DN: "CN=test-subject",
111-
NOT_AFTER: "2025-11-17T14:19:00Z",
112-
"apim-client-certificate-near-expiry": 1,
113-
}),
118+
const metricsMock = (jest.requireMock("aws-embedded-metrics") as {
119+
__metricsMock: {
120+
setNamespace: jest.Mock;
121+
putMetric: jest.Mock;
122+
};
123+
}).__metricsMock;
124+
125+
expect(metricScope).toHaveBeenCalledTimes(1);
126+
expect(metricsMock.setNamespace).toHaveBeenCalledWith("authorizer");
127+
expect(metricsMock.putMetric).toHaveBeenCalledWith(
128+
"apim-client-certificate-near-expiry",
129+
14,
130+
"Count",
114131
);
115132
});
116133

@@ -123,7 +140,7 @@ describe("Authorizer Lambda Function", () => {
123140
handler(mockEvent, mockContext, mockCallback);
124141
await new Promise(process.nextTick);
125142

126-
expect(consoleLogSpy).not.toHaveBeenCalled();
143+
expect(metricScope).not.toHaveBeenCalled();
127144
});
128145
});
129146

lambdas/authorizer/src/authorizer.ts

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import {
66
APIGatewayRequestAuthorizerHandler,
77
Callback,
88
Context,
9-
} from "aws-lambda";
9+
} from "aws-lambda"
10+
import { MetricsLogger, metricScope } from "aws-embedded-metrics";
1011
import { Supplier } from "@internal/datastore";
1112
import { Deps } from "./deps";
1213

@@ -100,33 +101,6 @@ function getCertificateExpiryInDays(
100101
return (expiry - now) / (1000 * 60 * 60 * 24);
101102
}
102103

103-
function buildCloudWatchMetric(
104-
namespace: string,
105-
certificate: APIGatewayEventClientCertificate,
106-
) {
107-
return {
108-
_aws: {
109-
Timestamp: Date.now(),
110-
CloudWatchMetrics: [
111-
{
112-
Namespace: namespace,
113-
Dimensions: ["SUBJECT_DN", "NOT_AFTER"],
114-
Metrics: [
115-
{
116-
Name: "apim-client-certificate-near-expiry",
117-
Unit: "Count",
118-
Value: 1,
119-
},
120-
],
121-
},
122-
],
123-
},
124-
SUBJECT_DN: certificate.subjectDN,
125-
NOT_AFTER: certificate.validity.notAfter,
126-
"apim-client-certificate-near-expiry": 1,
127-
};
128-
}
129-
130104
async function checkCertificateExpiry(
131105
certificate: APIGatewayEventClientCertificate | null,
132106
deps: Deps,
@@ -146,11 +120,11 @@ async function checkCertificateExpiry(
146120
const expiry = getCertificateExpiryInDays(certificate);
147121

148122
if (expiry <= deps.env.CLIENT_CERTIFICATE_EXPIRATION_ALERT_DAYS) {
149-
const metric = buildCloudWatchMetric(
150-
deps.env.CLOUDWATCH_NAMESPACE,
151-
certificate,
152-
);
153-
deps.logger.warn(metric, `APIM Certificated expiry in ${expiry} days`);
154-
console.log(JSON.stringify(metric));
155-
}
123+
metricScope(
124+
(metrics: MetricsLogger) => async () => {
125+
deps.logger.warn(`APIM Certificated expiry in ${expiry} days`);
126+
metrics.setNamespace(process.env.AWS_LAMBDA_FUNCTION_NAME || 'authorizer');
127+
metrics.putMetric("apim-client-certificate-near-expiry", expiry, "Count");
128+
});
129+
};
156130
}

0 commit comments

Comments
 (0)