skuba 4.2.0 → 4.2.2

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 (59) hide show
  1. package/README.md +1 -1
  2. package/lib/api/jest/index.d.ts +26 -11
  3. package/lib/cli/adapter/eslint.d.ts +2 -1
  4. package/lib/cli/adapter/eslint.js +5 -1
  5. package/lib/cli/adapter/eslint.js.map +1 -1
  6. package/lib/cli/configure/refreshIgnoreFiles.js +2 -1
  7. package/lib/cli/configure/refreshIgnoreFiles.js.map +1 -1
  8. package/lib/cli/lint/annotate/buildkite/index.js.map +1 -1
  9. package/lib/cli/lint/autofix.d.ts +7 -1
  10. package/lib/cli/lint/autofix.js +16 -8
  11. package/lib/cli/lint/autofix.js.map +1 -1
  12. package/lib/cli/lint/external.js +19 -18
  13. package/lib/cli/lint/external.js.map +1 -1
  14. package/lib/cli/test/reporters/github/index.d.ts +2 -2
  15. package/lib/cli/test/reporters/github/index.js +14 -3
  16. package/lib/cli/test/reporters/github/index.js.map +1 -1
  17. package/lib/utils/args.js +1 -1
  18. package/lib/utils/args.js.map +1 -1
  19. package/lib/utils/error.d.ts +14 -0
  20. package/lib/utils/error.js +16 -2
  21. package/lib/utils/error.js.map +1 -1
  22. package/lib/utils/version.js +3 -4
  23. package/lib/utils/version.js.map +1 -1
  24. package/lib/utils/wait.d.ts +17 -0
  25. package/lib/utils/wait.js +32 -0
  26. package/lib/utils/wait.js.map +1 -0
  27. package/lib/utils/worker.js +2 -1
  28. package/lib/utils/worker.js.map +1 -1
  29. package/package.json +18 -19
  30. package/template/express-rest-api/.buildkite/pipeline.yml +2 -1
  31. package/template/greeter/.buildkite/pipeline.yml +2 -1
  32. package/template/koa-rest-api/.buildkite/pipeline.yml +2 -1
  33. package/template/koa-rest-api/package.json +5 -5
  34. package/template/koa-rest-api/src/api/jobs/getJobs.ts +2 -2
  35. package/template/koa-rest-api/src/api/jobs/postJob.ts +2 -2
  36. package/template/koa-rest-api/src/framework/logging.ts +8 -5
  37. package/template/koa-rest-api/src/framework/metrics.ts +2 -2
  38. package/template/koa-rest-api/src/framework/server.test.ts +21 -21
  39. package/template/koa-rest-api/src/framework/server.ts +4 -3
  40. package/template/koa-rest-api/src/listen.ts +2 -2
  41. package/template/koa-rest-api/src/testing/logging.ts +5 -20
  42. package/template/lambda-sqs-worker/.buildkite/pipeline.yml +2 -1
  43. package/template/lambda-sqs-worker/.nvmrc +1 -1
  44. package/template/lambda-sqs-worker/Dockerfile +1 -1
  45. package/template/lambda-sqs-worker/package.json +4 -4
  46. package/template/lambda-sqs-worker/serverless.yml +2 -2
  47. package/template/lambda-sqs-worker/src/app.test.ts +9 -9
  48. package/template/lambda-sqs-worker/src/app.ts +2 -1
  49. package/template/lambda-sqs-worker/src/framework/handler.test.ts +10 -10
  50. package/template/lambda-sqs-worker/src/framework/handler.ts +14 -17
  51. package/template/lambda-sqs-worker/src/framework/logging.ts +11 -6
  52. package/template/lambda-sqs-worker/src/testing/logging.ts +7 -5
  53. package/template/lambda-sqs-worker-cdk/.buildkite/pipeline.yml +2 -1
  54. package/template/lambda-sqs-worker-cdk/.nvmrc +1 -1
  55. package/template/lambda-sqs-worker-cdk/Dockerfile +1 -1
  56. package/template/lambda-sqs-worker-cdk/infra/__snapshots__/appStack.test.ts.snap +2 -2
  57. package/template/lambda-sqs-worker-cdk/infra/appStack.ts +1 -1
  58. package/template/lambda-sqs-worker-cdk/package.json +9 -11
  59. package/template/private-npm-package/.buildkite/pipeline.yml +1 -1
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.withTimeout = exports.throwOnTimeout = exports.sleep = void 0;
4
+ const error_1 = require("./error");
5
+ const logging_1 = require("./logging");
6
+ const sleep = (ms) => {
7
+ let timeout;
8
+ return Object.assign(new Promise((resolve) => (timeout = setTimeout(resolve, ms))), { clear: () => clearTimeout(timeout) });
9
+ };
10
+ exports.sleep = sleep;
11
+ const throwOnTimeout = async (promise, { s }) => {
12
+ const result = await (0, exports.withTimeout)(promise, { s });
13
+ if (!result.ok) {
14
+ throw (0, error_1.createTerseError)(`Timed out after ${(0, logging_1.pluralise)(s, 'second')}`);
15
+ }
16
+ return result.value;
17
+ };
18
+ exports.throwOnTimeout = throwOnTimeout;
19
+ const withTimeout = async (promise, { s }) => {
20
+ const timeout = (0, exports.sleep)(s * 1000);
21
+ try {
22
+ return await Promise.race([
23
+ Promise.resolve(promise).then((value) => ({ ok: true, value })),
24
+ timeout.then(() => ({ ok: false })),
25
+ ]);
26
+ }
27
+ finally {
28
+ timeout.clear?.();
29
+ }
30
+ };
31
+ exports.withTimeout = withTimeout;
32
+ //# sourceMappingURL=wait.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wait.js","sourceRoot":"","sources":["../../src/utils/wait.ts"],"names":[],"mappings":";;;AAAA,mCAA2C;AAC3C,uCAAsC;AAM/B,MAAM,KAAK,GAAG,CAAC,EAAU,EAAW,EAAE;IAC3C,IAAI,OAAuB,CAAC;IAE5B,OAAO,MAAM,CAAC,MAAM,CAClB,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,EACnE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CACvC,CAAC;AACJ,CAAC,CAAC;AAPW,QAAA,KAAK,SAOhB;AAEK,MAAM,cAAc,GAAG,KAAK,EACjC,OAAuB,EACvB,EAAE,CAAC,EAAiB,EACR,EAAE;IACd,MAAM,MAAM,GAAG,MAAM,IAAA,mBAAW,EAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;IAEjD,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE;QACd,MAAM,IAAA,wBAAgB,EAAC,mBAAmB,IAAA,mBAAS,EAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;KACrE;IAED,OAAO,MAAM,CAAC,KAAK,CAAC;AACtB,CAAC,CAAC;AAXW,QAAA,cAAc,kBAWzB;AAIK,MAAM,WAAW,GAAG,KAAK,EAC9B,OAA2B,EAC3B,EAAE,CAAC,EAAiB,EACO,EAAE;IAC7B,MAAM,OAAO,GAAG,IAAA,aAAK,EAAC,CAAC,GAAG,IAAK,CAAC,CAAC;IAEjC,IAAI;QACF,OAAO,MAAM,OAAO,CAAC,IAAI,CAAmB;YAC1C,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YAC/D,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;SACpC,CAAC,CAAC;KACJ;YAAS;QACR,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;KACnB;AACH,CAAC,CAAC;AAdW,QAAA,WAAW,eActB"}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.postWorkerOutput = exports.execWorkerThread = void 0;
4
+ const util_1 = require("util");
4
5
  const worker_threads_1 = require("worker_threads");
5
6
  const logging_1 = require("./logging");
6
7
  /**
@@ -39,7 +40,7 @@ const postWorkerOutput = (fn, logger = logging_1.log) => {
39
40
  fn(worker_threads_1.workerData)
40
41
  .then((output) => port.postMessage(output))
41
42
  .catch((err) => {
42
- logger.err(err);
43
+ logger.err((0, util_1.inspect)(err));
43
44
  process.exit(1);
44
45
  });
45
46
  };
@@ -1 +1 @@
1
- {"version":3,"file":"worker.js","sourceRoot":"","sources":["../../src/utils/worker.ts"],"names":[],"mappings":";;;AAAA,mDAAgE;AAEhE,uCAAgC;AAEhC;;GAEG;AACI,MAAM,gBAAgB,GAAG,KAAK,EACnC,QAAgB,EAChB,KAAY,EACZ,EAAE;IACF,IAAI,MAAc,CAAC;IACnB,IAAI,eAAe,GAAG,KAAK,CAAC;IAE5B,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAC7C,IAAI,uBAAM,CAAC,QAAQ,EAAE;QACnB,UAAU,EAAE,KAAK;KAClB,CAAC;SACC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;SACnB,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CACnB,eAAe;QACb,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;QACjB,CAAC,CAAC,MAAM,CACJ,IAAI,KAAK,CACP,IAAI;YACF,CAAC,CAAC,uCAAuC,IAAI,EAAE;YAC/C,CAAC,CAAC,gDAAgD,CACrD,CACF,CACN;SACA,EAAE,CAAC,SAAS,EAAE,CAAC,OAAe,EAAE,EAAE;QACjC,0DAA0D;QAC1D,MAAM,GAAG,OAAO,CAAC;QACjB,eAAe,GAAG,IAAI,CAAC;IACzB,CAAC,CAAC;SACD,EAAE,CAAC,cAAc,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAC5C,CAAC;AACJ,CAAC,CAAC;AA9BW,QAAA,gBAAgB,oBA8B3B;AAEF;;;GAGG;AACI,MAAM,gBAAgB,GAAG,CAC9B,EAAqC,EACrC,MAAM,GAAG,aAAG,EACZ,EAAE;IACF,MAAM,IAAI,GAAG,2BAAU,CAAC;IAExB,IAAI,CAAC,IAAI,EAAE;QACT,MAAM,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;QAE3E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACjB;IAED,EAAE,CAAC,2BAAmB,CAAC;SACpB,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;SAC1C,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACb,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEhB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACP,CAAC,CAAC;AAnBW,QAAA,gBAAgB,oBAmB3B"}
1
+ {"version":3,"file":"worker.js","sourceRoot":"","sources":["../../src/utils/worker.ts"],"names":[],"mappings":";;;AAAA,+BAA+B;AAC/B,mDAAgE;AAEhE,uCAAgC;AAEhC;;GAEG;AACI,MAAM,gBAAgB,GAAG,KAAK,EACnC,QAAgB,EAChB,KAAY,EACZ,EAAE;IACF,IAAI,MAAc,CAAC;IACnB,IAAI,eAAe,GAAG,KAAK,CAAC;IAE5B,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAC7C,IAAI,uBAAM,CAAC,QAAQ,EAAE;QACnB,UAAU,EAAE,KAAK;KAClB,CAAC;SACC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;SACnB,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CACnB,eAAe;QACb,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;QACjB,CAAC,CAAC,MAAM,CACJ,IAAI,KAAK,CACP,IAAI;YACF,CAAC,CAAC,uCAAuC,IAAI,EAAE;YAC/C,CAAC,CAAC,gDAAgD,CACrD,CACF,CACN;SACA,EAAE,CAAC,SAAS,EAAE,CAAC,OAAe,EAAE,EAAE;QACjC,0DAA0D;QAC1D,MAAM,GAAG,OAAO,CAAC;QACjB,eAAe,GAAG,IAAI,CAAC;IACzB,CAAC,CAAC;SACD,EAAE,CAAC,cAAc,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAC5C,CAAC;AACJ,CAAC,CAAC;AA9BW,QAAA,gBAAgB,oBA8B3B;AAEF;;;GAGG;AACI,MAAM,gBAAgB,GAAG,CAC9B,EAAqC,EACrC,MAAM,GAAG,aAAG,EACZ,EAAE;IACF,MAAM,IAAI,GAAG,2BAAU,CAAC;IAExB,IAAI,CAAC,IAAI,EAAE;QACT,MAAM,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;QAE3E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACjB;IAED,EAAE,CAAC,2BAAmB,CAAC;SACpB,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;SAC1C,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACb,MAAM,CAAC,GAAG,CAAC,IAAA,cAAO,EAAC,GAAG,CAAC,CAAC,CAAC;QAEzB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACP,CAAC,CAAC;AAnBW,QAAA,gBAAgB,oBAmB3B"}
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "dependencies": {
9
9
  "@octokit/rest": "^18.12.0",
10
10
  "@octokit/types": "^6.34.0",
11
- "@types/jest": "^27.4.0",
11
+ "@types/jest": "^27.5.0",
12
12
  "@types/node": ">=14.18",
13
13
  "chalk": "^4.1.0",
14
14
  "concurrently": "^7.0.0",
@@ -16,7 +16,7 @@
16
16
  "ejs": "^3.1.6",
17
17
  "enquirer": "^2.3.6",
18
18
  "eslint": "^8.11.0",
19
- "eslint-config-skuba": "1.0.16",
19
+ "eslint-config-skuba": "1.1.0",
20
20
  "execa": "^5.0.0",
21
21
  "fdir": "^5.0.0",
22
22
  "fs-extra": "^10.0.0",
@@ -25,7 +25,7 @@
25
25
  "ignore": "^5.1.8",
26
26
  "is-installed-globally": "^0.4.0",
27
27
  "isomorphic-git": "^1.11.1",
28
- "jest": "^27.4.5",
28
+ "jest": "^28.1.0",
29
29
  "latest-version": "^5.1.0",
30
30
  "lodash.mergewith": "^4.6.2",
31
31
  "normalize-package-data": "^4.0.0",
@@ -39,35 +39,35 @@
39
39
  "serialize-error": "^8.0.1",
40
40
  "simple-git": "^3.5.0",
41
41
  "strip-ansi": "^6.0.1",
42
- "ts-jest": "^27.1.2",
43
- "ts-node": "^10.5.0",
42
+ "ts-jest": "^28.0.2",
43
+ "ts-node": "^10.7.0",
44
44
  "ts-node-dev": "^2.0.0-0",
45
- "tsconfig-paths": "^3.11.0",
45
+ "tsconfig-paths": "^4.0.0",
46
46
  "tsconfig-seek": "1.0.2",
47
- "typescript": "~4.6.2"
47
+ "typescript": "~4.6.4"
48
48
  },
49
49
  "description": "SEEK development toolkit for backend applications and packages",
50
50
  "devDependencies": {
51
51
  "@changesets/cli": "2.22.0",
52
52
  "@changesets/get-github-info": "0.5.0",
53
- "@jest/reporters": "27.5.1",
54
- "@types/ejs": "3.1.0",
53
+ "@jest/reporters": "28.1.0",
54
+ "@types/ejs": "3.1.1",
55
55
  "@types/express": "4.17.13",
56
56
  "@types/fs-extra": "9.0.13",
57
57
  "@types/koa": "2.13.4",
58
- "@types/lodash.mergewith": "4.6.6",
58
+ "@types/lodash.mergewith": "4.6.7",
59
59
  "@types/module-alias": "2.0.1",
60
60
  "@types/npm-which": "3.0.1",
61
61
  "@types/picomatch": "2.3.0",
62
62
  "@types/supertest": "2.0.12",
63
- "enhanced-resolve": "5.9.2",
64
- "express": "4.17.3",
63
+ "enhanced-resolve": "5.9.3",
64
+ "express": "4.18.1",
65
65
  "jsonfile": "6.1.0",
66
66
  "koa": "2.13.4",
67
- "memfs": "3.4.1",
68
- "semver": "7.3.5",
69
- "supertest": "6.2.2",
70
- "type-fest": "2.12.1"
67
+ "memfs": "3.4.3",
68
+ "semver": "7.3.7",
69
+ "supertest": "6.2.3",
70
+ "type-fest": "2.12.2"
71
71
  },
72
72
  "engines": {
73
73
  "node": ">=14.18"
@@ -99,8 +99,7 @@
99
99
  "url": "git+https://github.com/seek-oss/skuba.git"
100
100
  },
101
101
  "resolutions": {
102
- "**/@types/node": ">=14.18",
103
- "semantic-release/@semantic-release/npm/npm/**/ansi-regex": "5.0.1"
102
+ "**/@types/node": ">=14.18"
104
103
  },
105
104
  "scripts": {
106
105
  "build": "ts-node --transpile-only src/skuba build && scripts/postbuild.sh",
@@ -124,5 +123,5 @@
124
123
  "version": "4.0.0"
125
124
  },
126
125
  "types": "./lib/index.d.ts",
127
- "version": "4.2.0"
126
+ "version": "4.2.2"
128
127
  }
@@ -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
@@ -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
@@ -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": "^5.2.1",
19
19
  "skuba-dive": "^2.0.0",
20
20
  "uuid": "^8.3.2"
21
21
  },
@@ -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
15
  "pino-pretty": "^7.1.0",
16
- "serverless": "^3.0.0",
17
- "serverless-plugin-canary-deployments": "^0.7.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.