skuba 4.2.1-beta.0 → 4.3.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/README.md +1 -1
  2. package/jest-preset.js +5 -1
  3. package/lib/api/git/index.d.ts +1 -0
  4. package/lib/api/git/index.js +3 -1
  5. package/lib/api/git/index.js.map +1 -1
  6. package/lib/api/git/pull.d.ts +35 -0
  7. package/lib/api/git/pull.js +34 -0
  8. package/lib/api/git/pull.js.map +1 -0
  9. package/lib/api/github/index.d.ts +1 -0
  10. package/lib/api/github/index.js +5 -1
  11. package/lib/api/github/index.js.map +1 -1
  12. package/lib/api/github/push.d.ts +62 -0
  13. package/lib/api/github/push.js +133 -0
  14. package/lib/api/github/push.js.map +1 -0
  15. package/lib/api/jest/index.d.ts +26 -11
  16. package/lib/cli/adapter/eslint.d.ts +2 -1
  17. package/lib/cli/adapter/eslint.js +5 -1
  18. package/lib/cli/adapter/eslint.js.map +1 -1
  19. package/lib/cli/configure/analysis/diff.d.ts +1 -1
  20. package/lib/cli/configure/analysis/package.d.ts +1 -1
  21. package/lib/cli/configure/processing/ignoreFile.d.ts +1 -1
  22. package/lib/cli/configure/processing/javascript.d.ts +1 -1
  23. package/lib/cli/configure/processing/json.d.ts +1 -1
  24. package/lib/cli/configure/processing/package.d.ts +11 -11
  25. package/lib/cli/lint/annotate/buildkite/index.js.map +1 -1
  26. package/lib/cli/lint/autofix.d.ts +7 -1
  27. package/lib/cli/lint/autofix.js +35 -18
  28. package/lib/cli/lint/autofix.js.map +1 -1
  29. package/lib/cli/lint/external.d.ts +1 -0
  30. package/lib/cli/lint/external.js +16 -16
  31. package/lib/cli/lint/external.js.map +1 -1
  32. package/lib/cli/test/reporters/github/annotations.js +19 -7
  33. package/lib/cli/test/reporters/github/annotations.js.map +1 -1
  34. package/lib/cli/test/reporters/github/index.d.ts +2 -2
  35. package/lib/cli/test/reporters/github/index.js +11 -1
  36. package/lib/cli/test/reporters/github/index.js.map +1 -1
  37. package/lib/utils/args.js +1 -1
  38. package/lib/utils/args.js.map +1 -1
  39. package/lib/utils/error.d.ts +14 -0
  40. package/lib/utils/error.js +14 -1
  41. package/lib/utils/error.js.map +1 -1
  42. package/lib/utils/version.js +3 -4
  43. package/lib/utils/version.js.map +1 -1
  44. package/lib/utils/wait.d.ts +17 -0
  45. package/lib/utils/wait.js +32 -0
  46. package/lib/utils/wait.js.map +1 -0
  47. package/lib/wrapper/http.d.ts +1 -1
  48. package/package.json +23 -20
  49. package/template/express-rest-api/.buildkite/pipeline.yml +5 -4
  50. package/template/express-rest-api/package.json +1 -1
  51. package/template/greeter/.buildkite/pipeline.yml +2 -1
  52. package/template/koa-rest-api/.buildkite/pipeline.yml +5 -4
  53. package/template/koa-rest-api/package.json +6 -6
  54. package/template/koa-rest-api/src/api/jobs/getJobs.ts +2 -2
  55. package/template/koa-rest-api/src/api/jobs/postJob.ts +2 -2
  56. package/template/koa-rest-api/src/framework/logging.ts +8 -5
  57. package/template/koa-rest-api/src/framework/metrics.ts +2 -2
  58. package/template/koa-rest-api/src/framework/server.test.ts +21 -21
  59. package/template/koa-rest-api/src/framework/server.ts +4 -3
  60. package/template/koa-rest-api/src/listen.ts +2 -2
  61. package/template/koa-rest-api/src/testing/logging.ts +5 -20
  62. package/template/lambda-sqs-worker/.buildkite/pipeline.yml +2 -1
  63. package/template/lambda-sqs-worker/.nvmrc +1 -1
  64. package/template/lambda-sqs-worker/Dockerfile +1 -1
  65. package/template/lambda-sqs-worker/package.json +5 -5
  66. package/template/lambda-sqs-worker/serverless.yml +2 -2
  67. package/template/lambda-sqs-worker/src/app.test.ts +9 -9
  68. package/template/lambda-sqs-worker/src/app.ts +2 -1
  69. package/template/lambda-sqs-worker/src/framework/handler.test.ts +10 -10
  70. package/template/lambda-sqs-worker/src/framework/handler.ts +14 -17
  71. package/template/lambda-sqs-worker/src/framework/logging.ts +11 -6
  72. package/template/lambda-sqs-worker/src/testing/logging.ts +7 -5
  73. package/template/lambda-sqs-worker-cdk/.buildkite/pipeline.yml +2 -1
  74. package/template/lambda-sqs-worker-cdk/.nvmrc +1 -1
  75. package/template/lambda-sqs-worker-cdk/Dockerfile +1 -1
  76. package/template/lambda-sqs-worker-cdk/infra/__snapshots__/appStack.test.ts.snap +2 -2
  77. package/template/lambda-sqs-worker-cdk/infra/appStack.ts +1 -1
  78. package/template/lambda-sqs-worker-cdk/package.json +9 -11
  79. package/template/private-npm-package/.buildkite/pipeline.yml +1 -1
@@ -8,7 +8,7 @@
8
8
  "@types/express": "^4.17.13",
9
9
  "@types/node": "^16.0.0",
10
10
  "@types/supertest": "^2.0.11",
11
- "pino-pretty": "^7.1.0",
11
+ "pino-pretty": "^8.0.0",
12
12
  "skuba": "*",
13
13
  "supertest": "^6.1.6"
14
14
  },
@@ -9,7 +9,7 @@ configs:
9
9
  NPM_READ_TOKEN: arn:aws:secretsmanager:ap-southeast-2:987872074697:secret:npm/npm-read-token
10
10
 
11
11
  - &docker-ecr-cache
12
- seek-oss/docker-ecr-cache#v1.11.0:
12
+ seek-oss/docker-ecr-cache#v2.0.0:
13
13
  cache-on:
14
14
  - package.json
15
15
  - yarn.lock
@@ -34,3 +34,4 @@ steps:
34
34
  - *docker-ecr-cache
35
35
  - docker-compose#v3.9.0:
36
36
  run: app
37
+ timeout_in_minutes: 10
@@ -9,7 +9,7 @@ configs:
9
9
  NPM_READ_TOKEN: arn:aws:secretsmanager:ap-southeast-2:987872074697:secret:npm/npm-read-token
10
10
 
11
11
  - &docker-ecr-cache
12
- seek-oss/docker-ecr-cache#v1.11.0:
12
+ seek-oss/docker-ecr-cache#v2.0.0:
13
13
  cache-on:
14
14
  - package.json
15
15
  - yarn.lock
@@ -53,6 +53,7 @@ steps:
53
53
  - *docker-ecr-cache
54
54
  - docker-compose#v3.9.0:
55
55
  run: app
56
+ timeout_in_minutes: 10
56
57
 
57
58
  - label: 📦 Build & Package
58
59
  depends_on: warm-prod
@@ -60,7 +61,7 @@ steps:
60
61
  - *aws-sm
61
62
  - *private-npm
62
63
  - *docker-ecr-cache
63
- - seek-jobs/gantry#v1.7.0:
64
+ - seek-jobs/gantry#v1.8.1:
64
65
  command: build
65
66
  file: gantry.build.yml
66
67
  region: <%- region %>
@@ -77,7 +78,7 @@ steps:
77
78
  concurrency_group: <%- teamName %>/deploy/gantry/<%- devGantryEnvironmentName %>
78
79
  key: deploy-dev
79
80
  plugins:
80
- - seek-jobs/gantry#v1.7.0:
81
+ - seek-jobs/gantry#v1.8.1:
81
82
  command: apply
82
83
  environment: <%- devGantryEnvironmentName %>
83
84
  file: gantry.apply.yml
@@ -92,7 +93,7 @@ steps:
92
93
  concurrency_group: <%- teamName %>/deploy/gantry/<%- prodGantryEnvironmentName %>
93
94
  depends_on: deploy-dev
94
95
  plugins:
95
- - seek-jobs/gantry#v1.7.0:
96
+ - seek-jobs/gantry#v1.8.1:
96
97
  command: apply
97
98
  environment: <%- prodGantryEnvironmentName %>
98
99
  file: gantry.apply.yml
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "dependencies": {
3
3
  "@koa/router": "^10.1.1",
4
- "@opentelemetry/api": "^1.0.4",
4
+ "@opentelemetry/api": "^1.1.0",
5
5
  "@opentelemetry/exporter-collector-grpc": "^0.25.0",
6
- "@opentelemetry/instrumentation-aws-sdk": "^0.6.0",
7
- "@opentelemetry/instrumentation-http": "^0.27.0",
8
- "@opentelemetry/sdk-node": "^0.27.0",
6
+ "@opentelemetry/instrumentation-aws-sdk": "^0.7.0",
7
+ "@opentelemetry/instrumentation-http": "^0.28.0",
8
+ "@opentelemetry/sdk-node": "^0.28.0",
9
9
  "@seek/logger": "^5.0.1",
10
10
  "aws-sdk": "^2.1039.0",
11
11
  "hot-shots": "^9.0.0",
@@ -15,7 +15,7 @@
15
15
  "runtypes": "^6.4.1",
16
16
  "runtypes-filter": "^0.6.0",
17
17
  "seek-datadog-custom-metrics": "^4.0.0",
18
- "seek-koala": "^5.1.0",
18
+ "seek-koala": "^6.0.0",
19
19
  "skuba-dive": "^2.0.0",
20
20
  "uuid": "^8.3.2"
21
21
  },
@@ -28,7 +28,7 @@
28
28
  "@types/supertest": "^2.0.11",
29
29
  "@types/uuid": "^8.3.1",
30
30
  "chance": "^1.1.8",
31
- "pino-pretty": "^7.1.0",
31
+ "pino-pretty": "^8.0.0",
32
32
  "skuba": "*",
33
33
  "supertest": "^6.1.6"
34
34
  },
@@ -1,4 +1,4 @@
1
- import { contextLogger } from 'src/framework/logging';
1
+ import { logger } from 'src/framework/logging';
2
2
  import { metricsClient } from 'src/framework/metrics';
3
3
  import * as storage from 'src/storage/jobs';
4
4
  import { Middleware } from 'src/types/koa';
@@ -7,7 +7,7 @@ export const getJobsHandler: Middleware = async (ctx) => {
7
7
  const jobs = await storage.readJobs();
8
8
 
9
9
  // no PII in these jobs
10
- contextLogger(ctx).debug({ jobs }, 'read jobs');
10
+ logger.debug({ jobs }, 'read jobs');
11
11
 
12
12
  metricsClient.increment('job.reads', jobs.length);
13
13
 
@@ -1,4 +1,4 @@
1
- import { contextLogger } from 'src/framework/logging';
1
+ import { logger } from 'src/framework/logging';
2
2
  import { metricsClient } from 'src/framework/metrics';
3
3
  import { validateRequestBody } from 'src/framework/validation';
4
4
  import * as storage from 'src/storage/jobs';
@@ -11,7 +11,7 @@ export const postJobHandler: Middleware = async (ctx) => {
11
11
  const job = await storage.createJob(jobInput);
12
12
 
13
13
  // no PII in these jobs
14
- contextLogger(ctx).debug({ job }, 'created job');
14
+ logger.debug({ job }, 'created job');
15
15
 
16
16
  metricsClient.increment('job.creations');
17
17
 
@@ -2,14 +2,20 @@ import createLogger from '@seek/logger';
2
2
  import { RequestLogging } from 'seek-koala';
3
3
 
4
4
  import { config } from 'src/config';
5
- import { Context } from 'src/types/koa';
6
5
 
7
- export const rootLogger = createLogger({
6
+ const { createContextMiddleware, mixin } =
7
+ RequestLogging.createContextStorage();
8
+
9
+ export const contextMiddleware = createContextMiddleware();
10
+
11
+ export const logger = createLogger({
8
12
  base: {
9
13
  environment: config.environment,
10
14
  version: config.version,
11
15
  },
12
16
 
17
+ mixin,
18
+
13
19
  level: config.logLevel,
14
20
 
15
21
  name: config.name,
@@ -17,6 +23,3 @@ export const rootLogger = createLogger({
17
23
  transport:
18
24
  config.environment === 'local' ? { target: 'pino-pretty' } : undefined,
19
25
  });
20
-
21
- export const contextLogger = (ctx: Context) =>
22
- rootLogger.child(RequestLogging.contextFields(ctx));
@@ -3,9 +3,9 @@ import { createStatsDClient } from 'seek-datadog-custom-metrics';
3
3
 
4
4
  import { config } from 'src/config';
5
5
 
6
- import { rootLogger } from './logging';
6
+ import { logger } from './logging';
7
7
 
8
8
  /* istanbul ignore next: StatsD client is not our responsibility */
9
9
  export const metricsClient = createStatsDClient(StatsD, config, (err) =>
10
- rootLogger.error({ err }, 'StatsD error'),
10
+ logger.error({ err }, 'StatsD error'),
11
11
  );
@@ -1,6 +1,6 @@
1
1
  import Router from '@koa/router';
2
2
 
3
- import { rootLogger } from 'src/testing/logging';
3
+ import { logger } from 'src/testing/logging';
4
4
  import { metricsClient } from 'src/testing/metrics';
5
5
  import { agentFromRouter } from 'src/testing/server';
6
6
  import { chance } from 'src/testing/types';
@@ -15,10 +15,10 @@ const router = new Router()
15
15
  const agent = agentFromRouter(router);
16
16
 
17
17
  describe('createApp', () => {
18
- beforeAll(rootLogger.spy);
18
+ beforeAll(logger.spy);
19
19
 
20
20
  afterEach(metricsClient.clear);
21
- afterEach(rootLogger.clear);
21
+ afterEach(logger.clear);
22
22
 
23
23
  it('handles root route', async () => {
24
24
  middleware.mockImplementation((ctx) => (ctx.body = ''));
@@ -29,9 +29,9 @@ describe('createApp', () => {
29
29
  .expect('server', /.+/)
30
30
  .expect('x-api-version', /.+/);
31
31
 
32
- expect(rootLogger.error).not.toBeCalled();
32
+ expect(logger.error).not.toBeCalled();
33
33
 
34
- expect(rootLogger.info).not.toBeCalled();
34
+ expect(logger.info).not.toBeCalled();
35
35
 
36
36
  metricsClient.expectTagSubset(['env:test', 'version:test']);
37
37
  metricsClient.expectTagSubset([
@@ -51,9 +51,9 @@ describe('createApp', () => {
51
51
  .expect('server', /.+/)
52
52
  .expect('x-api-version', /.+/);
53
53
 
54
- expect(rootLogger.error).not.toBeCalled();
54
+ expect(logger.error).not.toBeCalled();
55
55
 
56
- expect(rootLogger.info).not.toBeCalled();
56
+ expect(logger.info).not.toBeCalled();
57
57
 
58
58
  metricsClient.expectTagSubset([
59
59
  'http_method:put',
@@ -72,9 +72,9 @@ describe('createApp', () => {
72
72
  .expect('server', /.+/)
73
73
  .expect('x-api-version', /.+/);
74
74
 
75
- expect(rootLogger.error).not.toBeCalled();
75
+ expect(logger.error).not.toBeCalled();
76
76
 
77
- expect(rootLogger.info).nthCalledWith(
77
+ expect(logger.info).nthCalledWith(
78
78
  1,
79
79
  expect.objectContaining({ status: 404 }),
80
80
  'Client error',
@@ -102,9 +102,9 @@ describe('createApp', () => {
102
102
  .expect('server', /.+/)
103
103
  .expect('x-api-version', /.+/);
104
104
 
105
- expect(rootLogger.error).not.toBeCalled();
105
+ expect(logger.error).not.toBeCalled();
106
106
 
107
- expect(rootLogger.info).nthCalledWith(
107
+ expect(logger.info).nthCalledWith(
108
108
  1,
109
109
  expect.objectContaining({ status: 400 }),
110
110
  'Client error',
@@ -129,9 +129,9 @@ describe('createApp', () => {
129
129
  .expect('server', /.+/)
130
130
  .expect('x-api-version', /.+/);
131
131
 
132
- expect(rootLogger.error).not.toBeCalled();
132
+ expect(logger.error).not.toBeCalled();
133
133
 
134
- expect(rootLogger.info).nthCalledWith(
134
+ expect(logger.info).nthCalledWith(
135
135
  1,
136
136
  expect.objectContaining({ err: expect.any(Error), status: 400 }),
137
137
  'Client error',
@@ -156,13 +156,13 @@ describe('createApp', () => {
156
156
  .expect('server', /.+/)
157
157
  .expect('x-api-version', /.+/);
158
158
 
159
- expect(rootLogger.error).nthCalledWith(
159
+ expect(logger.error).nthCalledWith(
160
160
  1,
161
161
  expect.objectContaining({ err: expect.any(Error), status: 500 }),
162
162
  'Server error',
163
163
  );
164
164
 
165
- expect(rootLogger.info).not.toBeCalled();
165
+ expect(logger.info).not.toBeCalled();
166
166
 
167
167
  metricsClient.expectTagSubset([
168
168
  'http_method:get',
@@ -185,13 +185,13 @@ describe('createApp', () => {
185
185
  .expect('server', /.+/)
186
186
  .expect('x-api-version', /.+/);
187
187
 
188
- expect(rootLogger.error).nthCalledWith(
188
+ expect(logger.error).nthCalledWith(
189
189
  1,
190
190
  expect.objectContaining({ err, status: 500 }),
191
191
  'Server error',
192
192
  );
193
193
 
194
- expect(rootLogger.info).not.toBeCalled();
194
+ expect(logger.info).not.toBeCalled();
195
195
 
196
196
  metricsClient.expectTagSubset([
197
197
  'http_method:get',
@@ -213,13 +213,13 @@ describe('createApp', () => {
213
213
  .expect('server', /.+/)
214
214
  .expect('x-api-version', /.+/);
215
215
 
216
- expect(rootLogger.error).nthCalledWith(
216
+ expect(logger.error).nthCalledWith(
217
217
  1,
218
218
  expect.objectContaining({ err: null, status: 500 }),
219
219
  'Server error',
220
220
  );
221
221
 
222
- expect(rootLogger.info).not.toBeCalled();
222
+ expect(logger.info).not.toBeCalled();
223
223
 
224
224
  metricsClient.expectTagSubset([
225
225
  'http_method:get',
@@ -242,13 +242,13 @@ describe('createApp', () => {
242
242
  .expect('server', /.+/)
243
243
  .expect('x-api-version', /.+/);
244
244
 
245
- expect(rootLogger.error).nthCalledWith(
245
+ expect(logger.error).nthCalledWith(
246
246
  1,
247
247
  expect.objectContaining({ err, status: 500 }),
248
248
  'Server error',
249
249
  );
250
250
 
251
- expect(rootLogger.info).not.toBeCalled();
251
+ expect(logger.info).not.toBeCalled();
252
252
 
253
253
  metricsClient.expectTagSubset([
254
254
  'http_method:get',
@@ -9,7 +9,7 @@ import {
9
9
  } from 'seek-koala';
10
10
 
11
11
  import { config } from 'src/config';
12
- import { rootLogger } from 'src/framework/logging';
12
+ import { contextMiddleware, logger } from 'src/framework/logging';
13
13
  import { metricsClient } from 'src/framework/metrics';
14
14
 
15
15
  const metrics = MetricsMiddleware.create(
@@ -26,8 +26,8 @@ const requestLogging = RequestLogging.createMiddleware((ctx, fields, err) => {
26
26
  }
27
27
 
28
28
  return ctx.status < 500
29
- ? rootLogger.info(fields, 'Client error')
30
- : rootLogger.error(fields, 'Server error');
29
+ ? logger.info(fields, 'Client error')
30
+ : logger.error(fields, 'Server error');
31
31
  });
32
32
 
33
33
  const version = VersionMiddleware.create({
@@ -43,6 +43,7 @@ export const createApp = <State, Context>(
43
43
  // https://github.com/seek-oss/koala/tree/master/src/secureHeaders
44
44
  // https://github.com/venables/koa-helmet
45
45
  // .use(SecureHeaders.middleware)
46
+ .use(contextMiddleware)
46
47
  .use(requestLogging)
47
48
  .use(metrics)
48
49
  .use(ErrorMiddleware.handle)
@@ -2,7 +2,7 @@ import './register';
2
2
 
3
3
  import app from './app';
4
4
  import { config } from './config';
5
- import { rootLogger } from './framework/logging';
5
+ import { logger } from './framework/logging';
6
6
 
7
7
  // This implements a minimal version of `koa-cluster`'s interface
8
8
  // If your application is deployed with more than 1 vCPU you can delete this
@@ -12,6 +12,6 @@ const listener = app.listen(config.port, () => {
12
12
  const address = listener.address();
13
13
 
14
14
  if (typeof address === 'object' && address) {
15
- rootLogger.debug(`listening on port ${address.port}`);
15
+ logger.debug(`listening on port ${address.port}`);
16
16
  }
17
17
  });
@@ -1,31 +1,16 @@
1
1
  import * as logging from 'src/framework/logging';
2
2
 
3
- export const contextLogger = {
3
+ export const logger = {
4
4
  error: jest.fn(),
5
5
  info: jest.fn(),
6
6
 
7
7
  clear: () => {
8
- contextLogger.error.mockClear();
9
- contextLogger.info.mockClear();
10
- },
11
-
12
- spy: () =>
13
- jest.spyOn(logging, 'contextLogger').mockReturnValue(contextLogger as any),
14
- };
15
-
16
- export const rootLogger = {
17
- error: jest.fn(),
18
- info: jest.fn(),
19
-
20
- clear: () => {
21
- rootLogger.error.mockClear();
22
- rootLogger.info.mockClear();
8
+ logger.error.mockClear();
9
+ logger.info.mockClear();
23
10
  },
24
11
 
25
12
  spy: () => {
26
- jest
27
- .spyOn(logging.rootLogger, 'error')
28
- .mockImplementation(rootLogger.error);
29
- jest.spyOn(logging.rootLogger, 'info').mockImplementation(rootLogger.info);
13
+ jest.spyOn(logging.logger, 'error').mockImplementation(logger.error);
14
+ jest.spyOn(logging.logger, 'info').mockImplementation(logger.info);
30
15
  },
31
16
  };
@@ -9,7 +9,7 @@ configs:
9
9
  NPM_READ_TOKEN: arn:aws:secretsmanager:ap-southeast-2:987872074697:secret:npm/npm-read-token
10
10
 
11
11
  - &docker-ecr-cache
12
- seek-oss/docker-ecr-cache#v1.11.0:
12
+ seek-oss/docker-ecr-cache#v2.0.0:
13
13
  cache-on:
14
14
  - package.json
15
15
  - yarn.lock
@@ -63,6 +63,7 @@ steps:
63
63
  - *docker-ecr-cache
64
64
  - docker-compose#v3.9.0:
65
65
  run: app
66
+ timeout_in_minutes: 10
66
67
 
67
68
  - agents:
68
69
  queue: <%- devBuildkiteQueueName %>
@@ -1 +1 @@
1
- 14
1
+ 16
@@ -1,6 +1,6 @@
1
1
  # syntax=docker/dockerfile:1.2
2
2
 
3
- FROM node:14-alpine AS dev-deps
3
+ FROM node:16-alpine AS dev-deps
4
4
 
5
5
  WORKDIR /workdir
6
6
 
@@ -10,16 +10,16 @@
10
10
  "devDependencies": {
11
11
  "@types/aws-lambda": "^8.10.84",
12
12
  "@types/chance": "^1.1.3",
13
- "@types/node": "^14.0.0",
13
+ "@types/node": "^16.0.0",
14
14
  "chance": "^1.1.8",
15
- "pino-pretty": "^7.1.0",
16
- "serverless": "^3.0.0",
17
- "serverless-plugin-canary-deployments": "^0.7.0",
15
+ "pino-pretty": "^8.0.0",
16
+ "serverless": "^3.17.0",
17
+ "serverless-plugin-canary-deployments": "^0.8.0",
18
18
  "serverless-prune-plugin": "^2.0.0",
19
19
  "skuba": "*"
20
20
  },
21
21
  "engines": {
22
- "node": ">=14"
22
+ "node": ">=16"
23
23
  },
24
24
  "license": "UNLICENSED",
25
25
  "private": true,
@@ -25,11 +25,11 @@ provider:
25
25
  logRetentionInDays: 30
26
26
  name: aws
27
27
  region: ap-southeast-2
28
- runtime: nodejs14.x
28
+ runtime: nodejs16.x
29
29
  architecture: arm64
30
+ deploymentMethod: direct
30
31
  stackName: ${self:service}
31
32
  stage: ${env:ENVIRONMENT}
32
- versionFunctions: true
33
33
  deploymentBucket:
34
34
  # Use a shared account-level bucket for Lambda bundles and other artefacts.
35
35
  # This is easier to manage in terms of access, deployment, and tagging.
@@ -1,6 +1,6 @@
1
1
  import { metricsClient } from 'src/framework/metrics';
2
2
  import { createCtx, createSqsEvent } from 'src/testing/handler';
3
- import { contextLogger } from 'src/testing/logging';
3
+ import { logger } from 'src/testing/logging';
4
4
  import { scoringService, sns } from 'src/testing/services';
5
5
  import { chance, mockJobPublishedEvent } from 'src/testing/types';
6
6
 
@@ -19,7 +19,7 @@ describe('handler', () => {
19
19
 
20
20
  const increment = jest.spyOn(metricsClient, 'increment').mockReturnValue();
21
21
 
22
- beforeAll(contextLogger.spy);
22
+ beforeAll(logger.spy);
23
23
  beforeAll(scoringService.spy);
24
24
  beforeAll(sns.spy);
25
25
 
@@ -31,7 +31,7 @@ describe('handler', () => {
31
31
  });
32
32
 
33
33
  afterEach(() => {
34
- contextLogger.clear();
34
+ logger.clear();
35
35
  increment.mockClear();
36
36
  scoringService.clear();
37
37
  sns.clear();
@@ -44,9 +44,9 @@ describe('handler', () => {
44
44
 
45
45
  expect(scoringService.request).toBeCalledTimes(1);
46
46
 
47
- expect(contextLogger.error).not.toBeCalled();
47
+ expect(logger.error).not.toBeCalled();
48
48
 
49
- expect(contextLogger.info.mock.calls).toEqual([
49
+ expect(logger.info.mock.calls).toEqual([
50
50
  [{ count: 1 }, 'received jobs'],
51
51
  [{ snsMessageId: expect.any(String) }, 'scored job'],
52
52
  ['request'],
@@ -75,7 +75,7 @@ describe('handler', () => {
75
75
 
76
76
  await expect(app.handler(event, ctx)).rejects.toThrow('invoke error');
77
77
 
78
- expect(contextLogger.error).toBeCalledWith({ err }, 'request');
78
+ expect(logger.error).toBeCalledWith({ err }, 'request');
79
79
  });
80
80
 
81
81
  it('bubbles up SNS error', async () => {
@@ -87,7 +87,7 @@ describe('handler', () => {
87
87
 
88
88
  await expect(app.handler(event, ctx)).rejects.toThrow('invoke error');
89
89
 
90
- expect(contextLogger.error).toBeCalledWith({ err }, 'request');
90
+ expect(logger.error).toBeCalledWith({ err }, 'request');
91
91
  });
92
92
 
93
93
  it('throws on zero records', async () => {
@@ -97,7 +97,7 @@ describe('handler', () => {
97
97
 
98
98
  await expect(app.handler(event, ctx)).rejects.toThrow('invoke error');
99
99
 
100
- expect(contextLogger.error).toBeCalledWith({ err }, 'request');
100
+ expect(logger.error).toBeCalledWith({ err }, 'request');
101
101
  });
102
102
 
103
103
  it('throws on multiple records', async () => {
@@ -110,6 +110,6 @@ describe('handler', () => {
110
110
 
111
111
  await expect(app.handler(event, ctx)).rejects.toThrow('invoke error');
112
112
 
113
- expect(contextLogger.error).toBeCalledWith({ err }, 'request');
113
+ expect(logger.error).toBeCalledWith({ err }, 'request');
114
114
  });
115
115
  });
@@ -3,6 +3,7 @@ import 'skuba-dive/register';
3
3
  import { SQSEvent } from 'aws-lambda';
4
4
 
5
5
  import { createHandler } from 'src/framework/handler';
6
+ import { logger } from 'src/framework/logging';
6
7
  import { metricsClient } from 'src/framework/metrics';
7
8
  import { validateJson } from 'src/framework/validation';
8
9
  import { scoreJobPublishedEvent, scoringService } from 'src/services/jobScorer';
@@ -16,7 +17,7 @@ const smokeTest = async () => {
16
17
  await Promise.all([scoringService.smokeTest(), sendPipelineEvent({}, true)]);
17
18
  };
18
19
 
19
- export const handler = createHandler<SQSEvent>(async (event, { logger }) => {
20
+ export const handler = createHandler<SQSEvent>(async (event) => {
20
21
  // Treat an empty object as our smoke test event.
21
22
  if (!Object.keys(event).length) {
22
23
  logger.info('received smoke test request');
@@ -1,5 +1,5 @@
1
1
  import { createCtx } from 'src/testing/handler';
2
- import { contextLogger } from 'src/testing/logging';
2
+ import { logger } from 'src/testing/logging';
3
3
  import { chance } from 'src/testing/types';
4
4
 
5
5
  import { createHandler } from './handler';
@@ -8,14 +8,14 @@ describe('createHandler', () => {
8
8
  const ctx = createCtx();
9
9
  const input = chance.paragraph();
10
10
 
11
- beforeAll(contextLogger.spy);
11
+ beforeAll(logger.spy);
12
12
 
13
- afterEach(contextLogger.clear);
13
+ afterEach(logger.clear);
14
14
 
15
15
  it('handles happy path', async () => {
16
16
  const output = chance.paragraph();
17
17
 
18
- const handler = createHandler((event, { logger }) => {
18
+ const handler = createHandler((event) => {
19
19
  expect(event).toBe(input);
20
20
 
21
21
  logger.info('hello from handler');
@@ -25,9 +25,9 @@ describe('createHandler', () => {
25
25
 
26
26
  await expect(handler(input, ctx)).resolves.toBe(output);
27
27
 
28
- expect(contextLogger.error).not.toBeCalled();
28
+ expect(logger.error).not.toBeCalled();
29
29
 
30
- expect(contextLogger.info.mock.calls).toEqual([
30
+ expect(logger.info.mock.calls).toEqual([
31
31
  ['hello from handler'],
32
32
  ['request'],
33
33
  ]);
@@ -40,9 +40,9 @@ describe('createHandler', () => {
40
40
 
41
41
  await expect(handler(input, ctx)).rejects.toThrow('invoke error');
42
42
 
43
- expect(contextLogger.error.mock.calls).toEqual([[{ err }, 'request']]);
43
+ expect(logger.error.mock.calls).toEqual([[{ err }, 'request']]);
44
44
 
45
- expect(contextLogger.info).not.toBeCalled();
45
+ expect(logger.info).not.toBeCalled();
46
46
  });
47
47
 
48
48
  it('handles sync error', async () => {
@@ -54,8 +54,8 @@ describe('createHandler', () => {
54
54
 
55
55
  await expect(handler(input, ctx)).rejects.toThrow('invoke error');
56
56
 
57
- expect(contextLogger.error.mock.calls).toEqual([[{ err }, 'request']]);
57
+ expect(logger.error.mock.calls).toEqual([[{ err }, 'request']]);
58
58
 
59
- expect(contextLogger.info).not.toBeCalled();
59
+ expect(logger.info).not.toBeCalled();
60
60
  });
61
61
  });
@@ -1,23 +1,20 @@
1
- import { Logger } from '@seek/logger';
2
1
  import { Context } from 'aws-lambda';
3
2
 
4
- import { contextLogger } from 'src/framework/logging';
3
+ import { logger, loggerContext } from 'src/framework/logging';
5
4
 
6
- export const createHandler = <Event, Output = unknown>(
7
- fn: (event: Event, ctx: { logger: Logger }) => Promise<Output>,
8
- ) =>
9
- async function lambdaHandler(event: Event, ctx: Context) {
10
- const logger = contextLogger(ctx);
5
+ export const createHandler =
6
+ <Event, Output = unknown>(fn: (event: Event) => Promise<Output>) =>
7
+ (event: Event, { awsRequestId }: Context) =>
8
+ loggerContext.run({ awsRequestId }, async () => {
9
+ try {
10
+ const output = await fn(event);
11
11
 
12
- try {
13
- const output = await fn(event, { logger });
12
+ logger.info('request');
14
13
 
15
- logger.info('request');
14
+ return output;
15
+ } catch (err) {
16
+ logger.error({ err }, 'request');
16
17
 
17
- return output;
18
- } catch (err) {
19
- logger.error({ err }, 'request');
20
-
21
- throw new Error('invoke error');
22
- }
23
- };
18
+ throw new Error('invoke error');
19
+ }
20
+ });