serverless-plugin-warmup 6.1.0 → 7.0.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.
package/README.md CHANGED
@@ -2,14 +2,15 @@
2
2
  [![Serverless][serverless-badge]](serverless-badge-url)
3
3
  [![npm version][npm-version-badge]][npm-version-badge-url]
4
4
  [![npm monthly downloads][npm-downloads-badge]][npm-version-badge-url]
5
- [![Build Status][travis-badge]][travis-badge-url]
5
+ [![Node.js CI](https://github.com/juanjoDiaz/serverless-plugin-warmup/actions/workflows/on-push.yaml/badge.svg)](https://github.com/juanjoDiaz/serverless-plugin-warmup/actions/workflows/on-push.yaml)
6
6
  [![Coverage Status][coveralls-badge]][coveralls-badge-url]
7
7
  [![license](https://img.shields.io/npm/l/serverless-plugin-warmup.svg)](https://raw.githubusercontent.com/juanjoDiaz/serverless-plugin-warmup/master/LICENSE)
8
8
 
9
9
  Keep your lambdas warm during winter.
10
10
 
11
11
  **Requirements:**
12
- * Serverless *v2.32.x* or higher
12
+ * Node *v14.x* or higher
13
+ * Serverless *v3.x* or higher
13
14
  * AWS provider
14
15
 
15
16
  ## How it works
@@ -43,6 +44,7 @@ custom:
43
44
  events:
44
45
  - schedule: cron(0/5 8-17 ? * MON-FRI *)
45
46
  concurrency: 10
47
+ logRetentionInDays: 10
46
48
  outOfOfficeHoursWarmer:
47
49
  enabled: true
48
50
  events:
@@ -68,6 +70,7 @@ The options are the same for all the warmers:
68
70
  * **timeout** How many seconds until the warmer lambda times out. (defaults to `10`)
69
71
  * **environment** Can be used to set environment variables in the warmer lambda. You can also unset variables configured at the provider by setting them to undefined. However, you should almost never have to change the default. (defaults to unset all package level environment variables. )
70
72
  * **tracing** Specify whether to enable/disable tracing at the function level. When tracing is enabled, warmer functions will use NPM to install the X-Ray client and use it to trace requests (It takes any of the values supported by serverless as `boolean`, `Active`or `PassThrough` and defaults to the provider-level setting)
73
+ * **logRetentionInDays** Set the retention time in days for the log group associated to this warmer lamba
71
74
  * **prewarm** If set to true, it warms up your lambdas right after deploying (defaults to `false`)
72
75
 
73
76
  There are also some options which can be set under `custom.warmup.<yourWarmer>` to be applied to all your lambdas or under `yourLambda.warmup.<yourWarmer>` to overridde the global configuration for that particular lambda. Keep in mind that in order to configure a warmer at the function level, it needed to be previously configured at the `custom` section or the pluging will error.
@@ -103,6 +106,7 @@ custom:
103
106
  - ./**
104
107
  timeout: 20
105
108
  tracing: true
109
+ logRetentionInDays: 10
106
110
  prewarm: true # Run WarmUp immediately after a deploymentlambda
107
111
  clientContext:
108
112
  source: my-custom-source
@@ -600,8 +604,6 @@ This software is released under the MIT license. See [the license file](LICENSE)
600
604
  [npm-version-badge]: https://badge.fury.io/js/serverless-plugin-warmup.svg
601
605
  [npm-version-badge-url]: https://www.npmjs.com/package/serverless-plugin-warmup
602
606
  [npm-downloads-badge]: https://img.shields.io/npm/dm/serverless-plugin-warmup.svg
603
- [travis-badge]: https://travis-ci.org/juanjoDiaz/serverless-plugin-warmup.svg
604
- [travis-badge-url]: https://travis-ci.org/juanjoDiaz/serverless-plugin-warmup
605
607
  [coveralls-badge]: https://coveralls.io/repos/juanjoDiaz/serverless-plugin-warmup/badge.svg?branch=master
606
608
  [coveralls-badge-url]: https://coveralls.io/r/juanjoDiaz/serverless-plugin-warmup?branch=master
607
609
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "serverless-plugin-warmup",
3
- "version": "6.1.0",
3
+ "version": "7.0.2",
4
4
  "description": "Keep your lambdas warm during winter.",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -35,6 +35,6 @@
35
35
  "eslint-config-airbnb-base": "^15.0.0",
36
36
  "eslint-plugin-import": "^2.24.2",
37
37
  "husky": "^7.0.2",
38
- "jest": "^27.2.0"
38
+ "jest": "^27.5.0"
39
39
  }
40
40
  }
package/src/config.js CHANGED
@@ -41,6 +41,9 @@ function getWarmerConfig(config, defaultOpts) {
41
41
  ? config.environment
42
42
  : defaultOpts.environment,
43
43
  tracing: (config.tracing !== undefined) ? config.tracing : defaultOpts.tracing,
44
+ logRetentionInDays: (config.logRetentionInDays !== undefined)
45
+ ? config.logRetentionInDays
46
+ : defaultOpts.logRetentionInDays,
44
47
  prewarm: (config.prewarm !== undefined) ? config.prewarm : defaultOpts.prewarm,
45
48
  };
46
49
  /* eslint-enable no-nested-ternary */
@@ -79,7 +82,7 @@ function getFunctionConfig(config, defaultOpts) {
79
82
  *
80
83
  * @return {Array} - List of functions to be warmed up and their specific configs
81
84
  * */
82
- function getFunctionsByWarmer(service, stage, configsByWarmer) {
85
+ function getFunctionsByWarmer(service, stage, configsByWarmer, serverlessClasses) {
83
86
  const functions = service.getAllFunctions()
84
87
  .map((name) => service.getFunction(name))
85
88
  .map((config) => {
@@ -97,7 +100,7 @@ function getFunctionsByWarmer(service, stage, configsByWarmer) {
97
100
  const unknownWarmers = Object.keys(config.warmup)
98
101
  .filter((warmerName) => configsByWarmer[warmerName] === undefined);
99
102
  if (unknownWarmers.length > 0) {
100
- throw new Error(`WarmUp: Invalid function-level warmup configuration (${unknownWarmers.join(', ')}) in function ${config.name}. Every warmer should be declared in the custom section.`);
103
+ throw new serverlessClasses.Error(`WarmUp: Invalid function-level warmup configuration (${unknownWarmers.join(', ')}) in function ${config.name}. Every warmer should be declared in the custom section.`);
101
104
  }
102
105
 
103
106
  return {
@@ -134,7 +137,7 @@ function getFunctionsByWarmer(service, stage, configsByWarmer) {
134
137
  *
135
138
  * @return {Object} - Configuration options to be used by the plugin
136
139
  * */
137
- function getConfigsByWarmer(service, stage) {
140
+ function getConfigsByWarmer({ service, classes }, stage) {
138
141
  const getWarmerDefaultOpts = (warmerName) => ({
139
142
  folderName: path.join('.warmup', warmerName),
140
143
  cleanFolder: true,
@@ -167,7 +170,7 @@ function getConfigsByWarmer(service, stage) {
167
170
  },
168
171
  }), {});
169
172
 
170
- const functionsByWarmer = getFunctionsByWarmer(service, stage, configsByWarmer);
173
+ const functionsByWarmer = getFunctionsByWarmer(service, stage, configsByWarmer, classes);
171
174
 
172
175
  return Object.entries(configsByWarmer).reduce((warmers, [warmerName, warmerConfig]) => ({
173
176
  ...warmers,
package/src/index.js CHANGED
@@ -28,12 +28,13 @@ class WarmUp {
28
28
  * @constructor
29
29
  *
30
30
  * @param {!Object} serverless - Serverless object
31
- * @param {!Object} options - Serverless options
31
+ * @param {!Object} cliOptions - Serverless cliOptions
32
32
  * */
33
- constructor(serverless, options) {
33
+ constructor(serverless, cliOptions, { log }) {
34
34
  /** Serverless variables */
35
35
  this.serverless = serverless;
36
- this.options = options;
36
+ this.cliOptions = cliOptions;
37
+ this.log = log;
37
38
 
38
39
  this.provider = this.serverless.getProvider('aws');
39
40
 
@@ -46,7 +47,7 @@ class WarmUp {
46
47
  cleanupTempDir: { lifecycleEvents: ['cleanup'] },
47
48
  prewarm: {
48
49
  lifecycleEvents: ['start', 'end'],
49
- options: {
50
+ cliOptions: {
50
51
  warmers: {
51
52
  shortcut: 'w',
52
53
  usage: 'Comma-separated list of warmer names to prewarm.',
@@ -70,8 +71,8 @@ class WarmUp {
70
71
  'warmup:cleanupTempDir:cleanup': this.cleanUp.bind(this),
71
72
  'before:warmup:prewarm:start': this.configPlugin.bind(this),
72
73
  'warmup:prewarm:start': this.prewarmFunctions.bind(this),
73
- // Workaround webpack/bundle plugins, reset the plugin and ignore changes
74
- 'before:package:createDeploymentArtifacts': this.initializeWarmers.bind(this),
74
+ // Workaround webpack/bundle plugins and serverless_sdk
75
+ 'before:package:createDeploymentArtifacts': this.resetWarmerConfigs.bind(this),
75
76
  };
76
77
 
77
78
  // Fixed for issues in Serverles
@@ -85,7 +86,7 @@ class WarmUp {
85
86
  configPlugin() {
86
87
  this.stage = this.stage || this.provider.getStage();
87
88
  this.configsByWarmer = this.configsByWarmer
88
- || getConfigsByWarmer(this.serverless.service, this.stage);
89
+ || getConfigsByWarmer(this.serverless, this.stage);
89
90
  }
90
91
 
91
92
  /**
@@ -101,6 +102,23 @@ class WarmUp {
101
102
  .map(([warmerName, warmerConfig]) => this.configureWarmer(warmerName, warmerConfig)));
102
103
  }
103
104
 
105
+ /**
106
+ * @description Workaround webpack/bundle plugins and serverless_sdk.
107
+ * Reset the plugin and ignore changes
108
+ *
109
+ * @fulfil {} — Warm up set
110
+ * @reject {Error} Warm up error
111
+ *
112
+ * @return {Promise}
113
+ * */
114
+ async resetWarmerConfigs() {
115
+ Object.entries(this.configsByWarmer)
116
+ .forEach(([warmerName, warmerConfig]) => {
117
+ if (warmerConfig.functions.length === 0) return;
118
+ addWarmUpFunctionToService(this.serverless.service, warmerName, warmerConfig);
119
+ });
120
+ }
121
+
104
122
  /**
105
123
  * @description Warmup cleanup hook.
106
124
  *
@@ -122,7 +140,7 @@ class WarmUp {
122
140
  );
123
141
  } catch (err) {
124
142
  if (err.code !== 'ENOENT') {
125
- this.serverless.cli.log(`WarmUp: Couldn't clean up temporary folder ${folderToClean}.`);
143
+ this.log.error(`WarmUp: Couldn't clean up temporary folder ${folderToClean}.`);
126
144
  }
127
145
  }
128
146
  }));
@@ -137,7 +155,7 @@ class WarmUp {
137
155
  }
138
156
  } catch (err) {
139
157
  if (err.code !== 'ENOENT') {
140
- this.serverless.cli.log('WarmUp: Couldn\'t clean up temporary folder .warmup.');
158
+ this.log.error('WarmUp: Couldn\'t clean up temporary folder .warmup.');
141
159
  }
142
160
  }
143
161
  }
@@ -151,8 +169,8 @@ class WarmUp {
151
169
  * @return {Promise}
152
170
  * */
153
171
  async prewarmFunctions() {
154
- const warmerNames = (this.options.warmers)
155
- ? this.options.warmers.split(',')
172
+ const warmerNames = (this.cliOptions.warmers)
173
+ ? this.cliOptions.warmers.split(',')
156
174
  : Object.entries(this.configsByWarmer)
157
175
  .filter(([, warmerConfig]) => warmerConfig.prewarm)
158
176
  .map(([warmerName]) => warmerName);
@@ -160,7 +178,7 @@ class WarmUp {
160
178
  await Promise.all(warmerNames.map(async (warmerName) => {
161
179
  const warmerConfig = this.configsByWarmer[warmerName];
162
180
  if (!warmerConfig) {
163
- throw new Error(`Warmer names ${warmerName} doesn't exist.`);
181
+ throw new this.serverless.classes.Error(`Warmer names ${warmerName} doesn't exist.`);
164
182
  }
165
183
  addWarmUpFunctionToService(this.serverless.service, warmerName, warmerConfig);
166
184
  await this.invokeWarmer(warmerName, warmerConfig);
@@ -173,18 +191,13 @@ class WarmUp {
173
191
  * */
174
192
  async configureWarmer(warmerName, warmerConfig) {
175
193
  if (warmerConfig.functions.length === 0) {
176
- this.serverless.cli.log(`WarmUp: Skipping warmer "${warmerName}" creation. No functions to warm up.`);
177
- return;
178
- }
179
-
180
- // Avoid double processing due to the workaround for webpack/bundle plugins
181
- // resetting the plugin and ignoring changes
182
- if (this.serverless.service.functions[`warmUpPlugin${capitalize(warmerName)}`]) {
194
+ this.log.warning(`WarmUp: Skipping warmer "${warmerName}" creation. No functions to warm up.`);
183
195
  return;
184
196
  }
185
197
 
186
- this.serverless.cli.log(`WarmUp: Creating warmer "${warmerName}" to warm up ${warmerConfig.functions.length} function${warmerConfig.functions.length === 1 ? '' : 's'}:`);
187
- warmerConfig.functions.forEach((func) => this.serverless.cli.log(` * ${func.name}`));
198
+ this.log.notice(`WarmUp: Creating warmer "${warmerName}" to warm up ${warmerConfig.functions.length} function${warmerConfig.functions.length === 1 ? '' : 's'}`);
199
+ this.log.info(':');
200
+ warmerConfig.functions.forEach((func) => this.log.info(` * ${func.name}`));
188
201
 
189
202
  const handlerFolder = path.join(this.serviceDir, warmerConfig.folderName);
190
203
 
@@ -209,11 +222,11 @@ class WarmUp {
209
222
 
210
223
  async invokeWarmer(warmerName, warmerConfig) {
211
224
  if (warmerConfig.functions.length === 0) {
212
- this.serverless.cli.log(`WarmUp: Skipping prewarming using warmer "${warmerName}". No functions to warm up.`);
225
+ this.log.warning(`WarmUp: Skipping prewarming using warmer "${warmerName}". No functions to warm up.`);
213
226
  return;
214
227
  }
215
228
 
216
- this.serverless.cli.log(`WarmUp: Prewarming up your functions using warmer "${warmerName}".`);
229
+ this.log.notice(`WarmUp: Prewarming up your functions using warmer "${warmerName}".`);
217
230
 
218
231
  try {
219
232
  const { SERVERLESS_ALIAS } = this.serverless.service.getFunction(`warmUpPlugin${capitalize(warmerName)}`).environment || {};
@@ -226,9 +239,9 @@ class WarmUp {
226
239
  };
227
240
 
228
241
  await this.provider.request('Lambda', 'invoke', params);
229
- this.serverless.cli.log(`WarmUp: Warmer "${warmerName}" successfully prewarmed your functions.`);
242
+ this.log.notice(`WarmUp: Warmer "${warmerName}" successfully prewarmed your functions.`);
230
243
  } catch (err) {
231
- this.serverless.cli.log(`WarmUp: Error while prewarming your functions using warmer "${warmerName}".`, err);
244
+ this.log.error(`WarmUp: Error while prewarming your functions using warmer "${warmerName}".`, err);
232
245
  }
233
246
  }
234
247
  }
package/src/schema.js CHANGED
@@ -107,6 +107,10 @@ function extendServerlessSchema(serverless) {
107
107
  timeout: { $ref: '#/definitions/awsLambdaTimeout' },
108
108
  environment: { $ref: '#/definitions/awsLambdaEnvironment' },
109
109
  tracing: { $ref: '#/definitions/awsLambdaTracing' },
110
+ logRetentionInDays: {
111
+ type: 'number',
112
+ enum: [1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, 3653],
113
+ },
110
114
  prewarm: { type: 'boolean' },
111
115
  };
112
116
 
@@ -135,6 +139,7 @@ function extendServerlessSchema(serverless) {
135
139
  serverless.configSchemaHandler.defineCustomProperties({
136
140
  properties: {
137
141
  warmup: {
142
+ type: 'object',
138
143
  patternProperties: {
139
144
  '.*': {
140
145
  type: 'object',
@@ -152,10 +157,11 @@ function extendServerlessSchema(serverless) {
152
157
  type: 'object',
153
158
  properties: {
154
159
  warmup: {
160
+ type: 'object',
155
161
  patternProperties: {
156
162
  '.*': {
157
163
  type: 'object',
158
- properties: { functionConfigSchemaProperties },
164
+ properties: functionConfigSchemaProperties,
159
165
  additionalProperties: false,
160
166
  },
161
167
  },
package/src/warmer.js CHANGED
@@ -225,6 +225,9 @@ function addWarmUpFunctionToService(service, warmerName, warmerConfig) {
225
225
  ? { environment: warmerConfig.environment }
226
226
  : {}),
227
227
  ...(warmerConfig.tracing !== undefined ? { tracing: warmerConfig.tracing } : {}),
228
+ ...(warmerConfig.logRetentionInDays !== undefined
229
+ ? { logRetentionInDays: warmerConfig.logRetentionInDays }
230
+ : {}),
228
231
  ...(warmerConfig.role ? { role: warmerConfig.role } : {}),
229
232
  ...(warmerConfig.tags ? { tags: warmerConfig.tags } : {}),
230
233
  ...(warmerConfig.vpc ? { vpc: warmerConfig.vpc } : {}),