Skip to content

Commit 460aa00

Browse files
log separate entries for batch post letters
1 parent 3a38fc3 commit 460aa00

3 files changed

Lines changed: 92 additions & 80 deletions

File tree

lambdas/api-handler/src/handlers/letter-status-update.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
} from "../contracts/letters";
88
import { Deps } from "../config/deps";
99
import { mapToUpdateLetter } from "../mappers/letter-mapper";
10-
import { buildEMFObject } from "../utils/metrics";
10+
import { buildEMFObject, MetricEntry } from "../utils/metrics";
1111

1212
export default function createLetterStatusUpdateHandler(
1313
deps: Deps,
@@ -40,7 +40,7 @@ export default function createLetterStatusUpdateHandler(
4040
}
4141

4242
function emitAndFlushMetricLog(message: SQSRecord, logger: pino.Logger) {
43-
const metric = {
43+
const metric: MetricEntry = {
4444
key: "statusUpdateFailed",
4545
value: 1,
4646
unit: Unit.Count,
Lines changed: 89 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { APIGatewayProxyHandler } from "aws-lambda";
2-
import { MetricsLogger, Unit, metricScope } from "aws-embedded-metrics";
2+
import { Unit } from "aws-embedded-metrics";
3+
import pino from "pino";
34
import type { Deps } from "../config/deps";
45
import { ApiErrorDetail } from "../contracts/errors";
56
import {
@@ -13,7 +14,7 @@ import { mapToUpdateCommands } from "../mappers/letter-mapper";
1314
import { enqueueLetterUpdateRequests } from "../services/letter-operations";
1415
import { extractCommonIds } from "../utils/common-ids";
1516
import { assertNotEmpty, requireEnvVar } from "../utils/validation";
16-
import { MetricStatus } from "../utils/metrics";
17+
import { MetricEntry, MetricStatus, buildEMFObject } from "../utils/metrics";
1718

1819
function duplicateIdsExist(postLettersRequest: PostLettersRequest) {
1920
const ids = postLettersRequest.data.map((item) => item.id);
@@ -23,17 +24,23 @@ function duplicateIdsExist(postLettersRequest: PostLettersRequest) {
2324
/**
2425
* emits metrics of successful letter updates, including the supplier and grouped by status
2526
*/
26-
function emitMetics(
27-
metrics: MetricsLogger,
27+
function emitSuccessMetrics(
2828
supplierId: string,
2929
statusesMapping: Map<string, number>,
30+
logger: pino.Logger,
3031
) {
3132
for (const [status, count] of statusesMapping) {
32-
metrics.putDimensions({
33+
const dimensions: Record<string, string> = {
3334
supplier: supplierId,
3435
eventType: status,
35-
});
36-
metrics.putMetric(MetricStatus.Success, count, Unit.Count);
36+
};
37+
const metric: MetricEntry = {
38+
key: "Letters posted",
39+
value: count,
40+
unit: Unit.Count,
41+
};
42+
const emf = buildEMFObject("postLetters", dimensions, metric);
43+
logger.info(emf);
3744
}
3845
}
3946

@@ -48,85 +55,90 @@ function populateStatusesMap(updateLetterCommands: UpdateLetterCommand[]) {
4855
export default function createPostLettersHandler(
4956
deps: Deps,
5057
): APIGatewayProxyHandler {
51-
return metricScope((metrics: MetricsLogger) => {
52-
return async (event) => {
53-
const commonIds = extractCommonIds(
54-
event.headers,
55-
event.requestContext,
56-
deps,
57-
);
58+
return async (event) => {
59+
const commonIds = extractCommonIds(
60+
event.headers,
61+
event.requestContext,
62+
deps,
63+
);
5864

59-
if (!commonIds.ok) {
60-
return processError(
61-
commonIds.error,
62-
commonIds.correlationId,
63-
deps.logger,
64-
);
65-
}
65+
if (!commonIds.ok) {
66+
return processError(
67+
commonIds.error,
68+
commonIds.correlationId,
69+
deps.logger,
70+
);
71+
}
6672

67-
const maxUpdateItems = requireEnvVar(deps.env, "MAX_LIMIT");
68-
requireEnvVar(deps.env, "QUEUE_URL");
73+
const maxUpdateItems = requireEnvVar(deps.env, "MAX_LIMIT");
74+
requireEnvVar(deps.env, "QUEUE_URL");
6975

70-
const { supplierId } = commonIds.value;
71-
metrics.setNamespace(
72-
process.env.AWS_LAMBDA_FUNCTION_NAME || "postLetters",
76+
const { supplierId } = commonIds.value;
77+
try {
78+
const body = assertNotEmpty(
79+
event.body,
80+
new ValidationError(ApiErrorDetail.InvalidRequestMissingBody),
7381
);
82+
83+
let postLettersRequest: PostLettersRequest;
84+
7485
try {
75-
const body = assertNotEmpty(
76-
event.body,
77-
new ValidationError(ApiErrorDetail.InvalidRequestMissingBody),
78-
);
86+
postLettersRequest = PostLettersRequestSchema.parse(JSON.parse(body));
87+
} catch (error) {
88+
const typedError =
89+
error instanceof Error
90+
? new ValidationError(ApiErrorDetail.InvalidRequestBody, {
91+
cause: error,
92+
})
93+
: error;
94+
throw typedError;
95+
}
7996

80-
let postLettersRequest: PostLettersRequest;
97+
if (postLettersRequest.data.length > maxUpdateItems) {
98+
throw new ValidationError(
99+
ApiErrorDetail.InvalidRequestLettersToUpdate,
100+
{ args: [maxUpdateItems] },
101+
);
102+
}
81103

82-
try {
83-
postLettersRequest = PostLettersRequestSchema.parse(JSON.parse(body));
84-
} catch (error) {
85-
const typedError =
86-
error instanceof Error
87-
? new ValidationError(ApiErrorDetail.InvalidRequestBody, {
88-
cause: error,
89-
})
90-
: error;
91-
throw typedError;
92-
}
104+
if (duplicateIdsExist(postLettersRequest)) {
105+
throw new ValidationError(
106+
ApiErrorDetail.InvalidRequestDuplicateLetterId,
107+
);
108+
}
93109

94-
if (postLettersRequest.data.length > maxUpdateItems) {
95-
throw new ValidationError(
96-
ApiErrorDetail.InvalidRequestLettersToUpdate,
97-
{ args: [maxUpdateItems] },
98-
);
99-
}
110+
const updateLetterCommands: UpdateLetterCommand[] = mapToUpdateCommands(
111+
postLettersRequest,
112+
supplierId,
113+
);
114+
const statusesMapping = populateStatusesMap(updateLetterCommands);
115+
await enqueueLetterUpdateRequests(
116+
updateLetterCommands,
117+
commonIds.value.correlationId,
118+
deps,
119+
);
100120

101-
if (duplicateIdsExist(postLettersRequest)) {
102-
throw new ValidationError(
103-
ApiErrorDetail.InvalidRequestDuplicateLetterId,
104-
);
105-
}
121+
emitSuccessMetrics(supplierId, statusesMapping, deps.logger);
122+
return {
123+
statusCode: 202,
124+
body: "",
125+
};
126+
} catch (error) {
127+
// error metrics
128+
emitErrorMetrics(supplierId, deps.logger);
106129

107-
const updateLetterCommands: UpdateLetterCommand[] = mapToUpdateCommands(
108-
postLettersRequest,
109-
supplierId,
110-
);
111-
const statusesMapping = populateStatusesMap(updateLetterCommands);
112-
await enqueueLetterUpdateRequests(
113-
updateLetterCommands,
114-
commonIds.value.correlationId,
115-
deps,
116-
);
130+
return processError(error, commonIds.value.correlationId, deps.logger);
131+
}
132+
};
133+
}
117134

118-
emitMetics(metrics, supplierId, statusesMapping);
119-
return {
120-
statusCode: 202,
121-
body: "",
122-
};
123-
} catch (error) {
124-
metrics.putDimensions({
125-
supplier: supplierId,
126-
});
127-
metrics.putMetric(MetricStatus.Failure, 1, Unit.Count);
128-
return processError(error, commonIds.value.correlationId, deps.logger);
129-
}
130-
};
131-
});
135+
function emitErrorMetrics(supplierId: string, logger: pino.Logger) {
136+
const dimensions: Record<string, string> = { supplier: supplierId };
137+
const metric: MetricEntry = {
138+
key: MetricStatus.Failure,
139+
value: 1,
140+
unit: Unit.Count,
141+
};
142+
const emf = buildEMFObject("postLetters", dimensions, metric);
143+
logger.info(emf);
132144
}

lambdas/api-handler/src/utils/metrics.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export enum MetricStatus {
2121
Failure = "failure",
2222
}
2323

24-
interface MetricEntry {
24+
export interface MetricEntry {
2525
key: string;
2626
value: number;
2727
unit: Unit;

0 commit comments

Comments
 (0)