funktor 0.2.1

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 (58) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +6 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +7 -0
  7. data/Gemfile.lock +84 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +154 -0
  10. data/Rakefile +6 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +8 -0
  13. data/exe/funktor +13 -0
  14. data/exe/funktor-deploy +8 -0
  15. data/funktor.gemspec +38 -0
  16. data/lib/funktor.rb +63 -0
  17. data/lib/funktor/active_job_handler.rb +52 -0
  18. data/lib/funktor/aws/sqs/event.rb +20 -0
  19. data/lib/funktor/aws/sqs/record.rb +14 -0
  20. data/lib/funktor/cli/application.rb +23 -0
  21. data/lib/funktor/cli/bootstrap.rb +35 -0
  22. data/lib/funktor/cli/generate.rb +0 -0
  23. data/lib/funktor/cli/generate/base.rb +13 -0
  24. data/lib/funktor/cli/generate/work_queue.rb +25 -0
  25. data/lib/funktor/cli/init.rb +78 -0
  26. data/lib/funktor/cli/templates/Gemfile +9 -0
  27. data/lib/funktor/cli/templates/config/environment.yml +4 -0
  28. data/lib/funktor/cli/templates/config/funktor.yml +51 -0
  29. data/lib/funktor/cli/templates/config/package.yml +9 -0
  30. data/lib/funktor/cli/templates/config/ruby_layer.yml +11 -0
  31. data/lib/funktor/cli/templates/function_definitions/active_job_handler.yml +11 -0
  32. data/lib/funktor/cli/templates/function_definitions/incoming_job_handler.yml +11 -0
  33. data/lib/funktor/cli/templates/funktor.yml.tt +51 -0
  34. data/lib/funktor/cli/templates/gitignore +2 -0
  35. data/lib/funktor/cli/templates/handlers/active_job_handler.rb +17 -0
  36. data/lib/funktor/cli/templates/handlers/incoming_job_handler.rb +8 -0
  37. data/lib/funktor/cli/templates/iam_permissions/active_job_queue.yml +8 -0
  38. data/lib/funktor/cli/templates/iam_permissions/incoming_job_queue.yml +8 -0
  39. data/lib/funktor/cli/templates/iam_permissions/ssm.yml +5 -0
  40. data/lib/funktor/cli/templates/package.json +1 -0
  41. data/lib/funktor/cli/templates/resources/active_job_queue.yml +22 -0
  42. data/lib/funktor/cli/templates/resources/cloudwatch_dashboard.yml +518 -0
  43. data/lib/funktor/cli/templates/resources/incoming_job_queue.yml +22 -0
  44. data/lib/funktor/cli/templates/resources/incoming_job_queue_user.yml +26 -0
  45. data/lib/funktor/cli/templates/serverless.yml +54 -0
  46. data/lib/funktor/cli/templates/workers/hello_worker.rb +8 -0
  47. data/lib/funktor/deploy/cli.rb +42 -0
  48. data/lib/funktor/deploy/serverless.rb +60 -0
  49. data/lib/funktor/deploy/serverless_templates/serverless.yml +156 -0
  50. data/lib/funktor/fake_job_queue.rb +15 -0
  51. data/lib/funktor/incoming_job_handler.rb +39 -0
  52. data/lib/funktor/job.rb +76 -0
  53. data/lib/funktor/middleware/metrics.rb +51 -0
  54. data/lib/funktor/middleware_chain.rb +62 -0
  55. data/lib/funktor/testing.rb +69 -0
  56. data/lib/funktor/version.rb +3 -0
  57. data/lib/funktor/worker.rb +86 -0
  58. metadata +173 -0
@@ -0,0 +1,11 @@
1
+ handler: handlers/incoming_job_handler.call
2
+ timeout: ${self:custom.funktor.incomingJobHandler.timeout, 30}
3
+ reservedConcurrency: ${self:custom.funktor.incomingJobHandler.reservedConcurrency, null}
4
+ provisionedConcurrency: ${self:custom.funktor.incomingJobHandler.provisionedConcurrency, null}
5
+ memorySize: ${self:custom.funktor.incomingJobHandler.memorySize, 256}
6
+ events:
7
+ - sqs:
8
+ arn:
9
+ Fn::GetAtt:
10
+ - IncomingJobQueue
11
+ - Arn
@@ -0,0 +1,51 @@
1
+ # ℹ️ WARNING: This file doesn't control anything directly. It's used to allow you to set/maintain config options in a central place.
2
+ # When you make changes to this file you should run `funktor init` again to propagate the changes to the 'active' configuration files.
3
+ runtime: ruby2.7
4
+
5
+ # Incoming Job Handler
6
+ incoming_job_handler:
7
+ # Use memory_size to adjust the reousrces (both memory and CPU) available
8
+ # memory_size: 512
9
+ timeout_in_seconds: 20 # This handler might have to handle several incoming jobs at once
10
+ # WARNING : You probably don't want to limit concurrency on incoming jobs.
11
+ # concurrency: 100
12
+
13
+ # Delayed Job Activator
14
+ delayed_job_activator:
15
+ # Use memory_size to adjust the reousrces (both memory and CPU) available
16
+ # memory_size: 512
17
+ execution_schedule: rate(1 minute)
18
+ activation_window_in_seconds: 120 # Activate any jobs scheduled for the next two minutes
19
+ timeout_in_seconds: 300 # Allow an activation job to run for up to 5 minutes
20
+ concurrency: 1
21
+
22
+
23
+ queues:
24
+ default:
25
+ # Use memory_size to adjust the reousrces (both memory and CPU) available
26
+ # memory_size: 512
27
+ # You can set the batch size. Max of 10_000 for normal queues, 10 for FIFO.
28
+ # batch_size: 10
29
+ # How many seconds should AWS wait for a batch to fill up before executing lambda?
30
+ # For immediate execution set the batch size to 1.
31
+ # maximumBatchingWindow : 1
32
+ # A single handler can receive up to batch_size jobs at a time. Make sure timeout is long enough.
33
+ timeout_in_seconds: 300
34
+ # You might want to limit concurrency of executing jobs to stay within resource limits (like DB connections).
35
+ # concurrency: 10
36
+ # Visibility timeout should only come into play in the case of Funktor errors.
37
+ # Application level errors should be handled by Funktor retry mechanisms.
38
+ # The visibility timeout should be at least as long as the function timeout, and up to 6 times larger.
39
+ # visibility_timeout: 300
40
+ # TODO - Is it advisable to use FIFO queuues with Funktor?
41
+ # TODO - Maybe this isn't really even supported by CloudFormation?
42
+ # fifo: false
43
+
44
+ # TODO - Maybe this is handled in the Dockerfile?
45
+ package:
46
+ patterns:
47
+ - Gemfile
48
+ - Gemfile.lock
49
+ - ../app/**
50
+ - ../config/**
51
+ - ../lambda_handlers/**
@@ -0,0 +1,2 @@
1
+ .serverless
2
+ node_modules
@@ -0,0 +1,17 @@
1
+ require 'funktor'
2
+
3
+ # Bundler is hard to make work because AWS includes some gems in the basic ruby runtime.
4
+ # We're probably going to need to use containers...
5
+ #require "rubygems"
6
+ #require "bundler/setup"
7
+ #Bundler.require(:default)
8
+
9
+ # TODO : Ideally this wouldn't be needed
10
+ require_relative '../workers/hello_worker'
11
+
12
+ $handler = Funktor::ActiveJobHandler.new
13
+
14
+ def call(event:, context:)
15
+ $handler.call(event: event, context: context)
16
+ end
17
+
@@ -0,0 +1,8 @@
1
+ require 'funktor'
2
+
3
+ $handler = Funktor::IncomingJobHandler.new
4
+
5
+ def call(event:, context:)
6
+ $handler.call(event: event, context: context)
7
+ end
8
+
@@ -0,0 +1,8 @@
1
+ Effect: Allow
2
+ Action:
3
+ - sqs:ReceiveMessage
4
+ - sqs:DeleteMessage
5
+ - sqs:SendMessage
6
+ - sqs:GetQueueAttributes
7
+ Resource:
8
+ - "Fn::GetAtt": [ ActiveJobQueue, Arn ]
@@ -0,0 +1,8 @@
1
+ Effect: Allow
2
+ Action:
3
+ - sqs:ReceiveMessage
4
+ - sqs:DeleteMessage
5
+ - sqs:SendMessage
6
+ - sqs:GetQueueAttributes
7
+ Resource:
8
+ - "Fn::GetAtt": [ IncomingJobQueue, Arn ]
@@ -0,0 +1,5 @@
1
+ Effect: Allow
2
+ Action:
3
+ - ssm:Get*
4
+ Resource:
5
+ - '*' # TODO : This should probably be more selective...
@@ -0,0 +1 @@
1
+ {"name":"serverless-sub","description":"","version":"0.1.0","devDependencies":{"serverless-ruby-layer":"^1.4.0"}}
@@ -0,0 +1,22 @@
1
+ Resources:
2
+ ActiveJobQueue:
3
+ Type: AWS::SQS::Queue
4
+ Properties:
5
+ QueueName: ${self:custom.funktor.activeJobQueueName}
6
+ VisibilityTimeout: 300
7
+ RedrivePolicy:
8
+ deadLetterTargetArn:
9
+ "Fn::GetAtt": [ ActiveJobDeadLetterQueue, Arn ]
10
+ maxReceiveCount: 5
11
+ ActiveJobDeadLetterQueue:
12
+ Type: AWS::SQS::Queue
13
+ Properties:
14
+ QueueName: ${self:custom.funktor.deadJobQueueName}
15
+
16
+ Outputs:
17
+ ActiveJobQueueUrl:
18
+ Value:
19
+ Ref: ActiveJobQueue
20
+ ActiveJobDeadLetterQueueUrl:
21
+ Value:
22
+ Ref: ActiveJobDeadLetterQueue
@@ -0,0 +1,518 @@
1
+ Resources:
2
+ FunktorDashboard:
3
+ Type: AWS::CloudWatch::Dashboard
4
+ Properties:
5
+ DashboardName: ${self:custom.funktor.dashboardName}
6
+ DashboardBody: >
7
+ {
8
+ "widgets": [
9
+ {
10
+ "height": 6,
11
+ "width": 9,
12
+ "y": 3,
13
+ "x": 0,
14
+ "type": "metric",
15
+ "properties": {
16
+ "metrics": [
17
+ [ "AWS/SQS", "NumberOfMessagesReceived", "QueueName", "${self:custom.funktor.incomingJobQueueName}", { "label": "Received" } ],
18
+ [ ".", "NumberOfMessagesDeleted", ".", ".", { "label": "Handled" } ],
19
+ [ "AWS/Lambda", "Invocations", "FunctionName", "${self:service}-${self:provider.stage}-incoming_job_handler", "Resource", "${self:service}-${self:provider.stage}-incoming_job_handler", { "label": "Handler Invocations" } ],
20
+ [ "AWS/SQS", "ApproximateNumberOfMessagesVisible", "QueueName", "${self:custom.funktor.incomingJobQueueName}", { "label": "Pending?" } ],
21
+ [ ".", "ApproximateNumberOfMessagesNotVisible", ".", ".", { "label": "Backlog?" } ],
22
+ [ ".", "NumberOfMessagesSent", ".", ".", { "label": "Sent" } ],
23
+ [ ".", "ApproximateNumberOfMessagesDelayed", ".", ".", { "label": "Delayed" } ]
24
+ ],
25
+ "view": "timeSeries",
26
+ "stacked": false,
27
+ "region": "us-east-1",
28
+ "title": "Incoming Job Queue (Async & scheduled jobs land here first)",
29
+ "period": 60,
30
+ "stat": "Sum",
31
+ "setPeriodToTimeRange": true,
32
+ "liveData": true
33
+ }
34
+ },
35
+ {
36
+ "height": 6,
37
+ "width": 9,
38
+ "y": 12,
39
+ "x": 0,
40
+ "type": "metric",
41
+ "properties": {
42
+ "metrics": [
43
+ [ "AWS/SQS", "NumberOfMessagesReceived", "QueueName", "${self:custom.funktor.activeJobQueueName}", { "label": "Received" } ],
44
+ [ ".", "NumberOfMessagesDeleted", ".", ".", { "label": "Handled" } ],
45
+ [ "AWS/Lambda", "Invocations", "FunctionName", "${self:service}-${self:provider.stage}-activeJobHandler", "Resource", "${self:service}-${self:provider.stage}-activeJobHandler", { "label": "Handler Invocations" } ],
46
+ [ "AWS/SQS", "ApproximateNumberOfMessagesVisible", "QueueName", "${self:custom.funktor.activeJobQueueName}", { "label": "Pending?" } ],
47
+ [ ".", "ApproximateNumberOfMessagesNotVisible", ".", ".", { "label": "Backlog?" } ],
48
+ [ ".", "NumberOfMessagesSent", ".", ".", { "label": "Sent" } ],
49
+ [ ".", "ApproximateNumberOfMessagesDelayed", ".", ".", { "label": "Delayed" } ]
50
+ ],
51
+ "view": "timeSeries",
52
+ "stacked": false,
53
+ "region": "us-east-1",
54
+ "title": "Active Job Queue (Async jobs go here immediately, scheduled jobs land here in the minute before they're scheduled)",
55
+ "period": 60,
56
+ "stat": "Sum",
57
+ "liveData": true
58
+ }
59
+ },
60
+ {
61
+ "height": 3,
62
+ "width": 9,
63
+ "y": 30,
64
+ "x": 0,
65
+ "type": "metric",
66
+ "properties": {
67
+ "metrics": [
68
+ [ { "expression": "m2/PERIOD(m2)", "label": "Consumed Read Capacity Units", "id": "e1", "stat": "Sum", "region": "us-east-1" } ],
69
+ [ "AWS/DynamoDB", "ConsumedReadCapacityUnits", "TableName", "${self:service}-${self:custom.stage}-delayed-jobs", { "id": "m2", "visible": false } ],
70
+ [ ".", "ConsumedWriteCapacityUnits", ".", ".", { "yAxis": "left", "id": "m4", "visible": false } ],
71
+ [ ".", "WriteThrottleEvents", ".", ".", { "yAxis": "right", "id": "m5", "visible": false } ]
72
+ ],
73
+ "view": "timeSeries",
74
+ "stacked": false,
75
+ "region": "us-east-1",
76
+ "title": "Scheduled Job Table Read Capacity Units",
77
+ "period": 60,
78
+ "stat": "Sum",
79
+ "liveData": true
80
+ }
81
+ },
82
+ {
83
+ "height": 3,
84
+ "width": 18,
85
+ "y": 33,
86
+ "x": 0,
87
+ "type": "metric",
88
+ "properties": {
89
+ "metrics": [
90
+ [ "AWS/DynamoDB", "SuccessfulRequestLatency", "TableName", "${self:service}-${self:custom.stage}-delayed-jobs", "Operation", "PutItem", { "yAxis": "left" } ],
91
+ [ "...", "Query" ],
92
+ [ ".", "ThrottledRequests", ".", ".", ".", "PutItem", { "yAxis": "right", "visible": false } ],
93
+ [ ".", "SuccessfulRequestLatency", ".", ".", ".", "DeleteItem" ],
94
+ [ ".", "ThrottledRequests", ".", ".", ".", ".", { "yAxis": "right", "visible": false } ]
95
+ ],
96
+ "view": "timeSeries",
97
+ "stacked": false,
98
+ "region": "us-east-1",
99
+ "stat": "Average",
100
+ "period": 60,
101
+ "title": "Scheduled Job Table Latency",
102
+ "liveData": true
103
+ }
104
+ },
105
+ {
106
+ "height": 3,
107
+ "width": 6,
108
+ "y": 33,
109
+ "x": 18,
110
+ "type": "metric",
111
+ "properties": {
112
+ "metrics": [
113
+ [ "AWS/DynamoDB", "ThrottledRequests", "TableName", "${self:service}-${self:custom.stage}-delayed-jobs", "Operation", "DeleteItem" ],
114
+ [ "...", "PutItem" ]
115
+ ],
116
+ "view": "timeSeries",
117
+ "stacked": false,
118
+ "region": "us-east-1",
119
+ "stat": "Sum",
120
+ "period": 60,
121
+ "title": "Scheduled Job Table Throttled Operations",
122
+ "liveData": true
123
+ }
124
+ },
125
+ {
126
+ "height": 6,
127
+ "width": 9,
128
+ "y": 3,
129
+ "x": 9,
130
+ "type": "metric",
131
+ "properties": {
132
+ "period": 60,
133
+ "metrics": [
134
+ [ "AWS/Lambda", "Duration", "FunctionName", "${self:service}-${self:provider.stage}-incoming_job_handler", { "stat": "Minimum" } ],
135
+ [ "...", { "stat": "Average" } ],
136
+ [ "...", { "stat": "Maximum" } ]
137
+ ],
138
+ "region": "us-east-1",
139
+ "title": "Incoming Job Handler Duration in Milliseconds",
140
+ "view": "timeSeries",
141
+ "stacked": false,
142
+ "liveData": true
143
+ }
144
+ },
145
+ {
146
+ "height": 3,
147
+ "width": 6,
148
+ "y": 3,
149
+ "x": 18,
150
+ "type": "metric",
151
+ "properties": {
152
+ "period": 60,
153
+ "metrics": [
154
+ [ "AWS/Lambda", "Errors", "FunctionName", "${self:service}-${self:provider.stage}-incoming_job_handler", { "id": "errors", "stat": "Sum", "color": "#d13212" } ],
155
+ [ ".", "Invocations", ".", ".", { "id": "invocations", "stat": "Sum", "visible": false } ],
156
+ [ { "expression": "100 - 100 * errors / MAX([errors, invocations])", "label": "Success rate (%)", "id": "availability", "yAxis": "right", "region": "us-east-1" } ]
157
+ ],
158
+ "region": "us-east-1",
159
+ "title": "Incoming Job Handler Error count and success rate (%)",
160
+ "yAxis": {
161
+ "right": {
162
+ "max": 100
163
+ }
164
+ },
165
+ "view": "timeSeries",
166
+ "stacked": false,
167
+ "liveData": true
168
+ }
169
+ },
170
+ {
171
+ "height": 3,
172
+ "width": 6,
173
+ "y": 6,
174
+ "x": 18,
175
+ "type": "metric",
176
+ "properties": {
177
+ "period": 60,
178
+ "metrics": [
179
+ [ "AWS/Lambda", "ConcurrentExecutions", "FunctionName", "${self:service}-${self:provider.stage}-incoming_job_handler", { "stat": "Maximum" } ]
180
+ ],
181
+ "region": "us-east-1",
182
+ "title": "Incoming Job Handler Concurrent Executions",
183
+ "view": "timeSeries",
184
+ "stacked": false,
185
+ "liveData": true
186
+ }
187
+ },
188
+ {
189
+ "height": 6,
190
+ "width": 9,
191
+ "y": 12,
192
+ "x": 9,
193
+ "type": "metric",
194
+ "properties": {
195
+ "period": 60,
196
+ "metrics": [
197
+ [ "AWS/Lambda", "Duration", "FunctionName", "${self:service}-${self:provider.stage}-active_job_handler", { "stat": "Minimum" } ],
198
+ [ "...", { "stat": "Average" } ],
199
+ [ "...", { "stat": "Maximum" } ]
200
+ ],
201
+ "region": "us-east-1",
202
+ "title": "Active Job Handler Duration in Milliseconds",
203
+ "view": "timeSeries",
204
+ "stacked": false,
205
+ "liveData": true
206
+ }
207
+ },
208
+ {
209
+ "height": 3,
210
+ "width": 6,
211
+ "y": 12,
212
+ "x": 18,
213
+ "type": "metric",
214
+ "properties": {
215
+ "period": 60,
216
+ "metrics": [
217
+ [ "AWS/Lambda", "Errors", "FunctionName", "${self:service}-${self:provider.stage}-active_job_handler", { "id": "errors", "stat": "Sum", "color": "#d13212" } ],
218
+ [ ".", "Invocations", ".", ".", { "id": "invocations", "stat": "Sum", "visible": false } ],
219
+ [ { "expression": "100 - 100 * errors / MAX([errors, invocations])", "label": "Success rate (%)", "id": "availability", "yAxis": "right", "region": "us-east-1" } ]
220
+ ],
221
+ "region": "us-east-1",
222
+ "title": "Active Job HandlerError count and success rate (%)",
223
+ "yAxis": {
224
+ "right": {
225
+ "max": 100
226
+ }
227
+ },
228
+ "view": "timeSeries",
229
+ "stacked": false,
230
+ "liveData": true
231
+ }
232
+ },
233
+ {
234
+ "height": 3,
235
+ "width": 6,
236
+ "y": 15,
237
+ "x": 18,
238
+ "type": "metric",
239
+ "properties": {
240
+ "period": 60,
241
+ "metrics": [
242
+ [ "AWS/Lambda", "ConcurrentExecutions", "FunctionName", "${self:service}-${self:provider.stage}-active_job_handler", { "stat": "Maximum" } ]
243
+ ],
244
+ "region": "us-east-1",
245
+ "title": "Active Job Handler Concurrent executions",
246
+ "view": "timeSeries",
247
+ "stacked": false,
248
+ "liveData": true
249
+ }
250
+ },
251
+ {
252
+ "height": 3,
253
+ "width": 9,
254
+ "y": 27,
255
+ "x": 9,
256
+ "type": "metric",
257
+ "properties": {
258
+ "period": 60,
259
+ "metrics": [
260
+ [ "AWS/Lambda", "Duration", "FunctionName", "${self:service}-${self:provider.stage}-delayed_job_scheduler", { "stat": "Minimum" } ],
261
+ [ "...", { "stat": "Average" } ],
262
+ [ "...", { "stat": "Maximum" } ]
263
+ ],
264
+ "region": "us-east-1",
265
+ "title": "Delayed Job Scheduler Duration",
266
+ "view": "timeSeries",
267
+ "stacked": false,
268
+ "liveData": true
269
+ }
270
+ },
271
+ {
272
+ "height": 3,
273
+ "width": 6,
274
+ "y": 27,
275
+ "x": 18,
276
+ "type": "metric",
277
+ "properties": {
278
+ "period": 60,
279
+ "metrics": [
280
+ [ "AWS/Lambda", "Errors", "FunctionName", "${self:service}-${self:provider.stage}-delayed_job_scheduler", { "id": "errors", "stat": "Sum", "color": "#d13212" } ],
281
+ [ ".", "Invocations", ".", ".", { "id": "invocations", "stat": "Sum", "visible": false } ],
282
+ [ { "expression": "100 - 100 * errors / MAX([errors, invocations])", "label": "Success rate (%)", "id": "availability", "yAxis": "right", "region": "us-east-1" } ]
283
+ ],
284
+ "region": "us-east-1",
285
+ "title": "Delayed Job SchedulerError count and success rate (%)",
286
+ "yAxis": {
287
+ "right": {
288
+ "max": 100
289
+ }
290
+ },
291
+ "view": "timeSeries",
292
+ "stacked": false,
293
+ "liveData": true
294
+ }
295
+ },
296
+ {
297
+ "height": 3,
298
+ "width": 6,
299
+ "y": 30,
300
+ "x": 18,
301
+ "type": "metric",
302
+ "properties": {
303
+ "period": 60,
304
+ "metrics": [
305
+ [ "AWS/Lambda", "ConcurrentExecutions", "FunctionName", "${self:service}-${self:provider.stage}-delayed_job_scheduler", { "stat": "Maximum" } ]
306
+ ],
307
+ "region": "us-east-1",
308
+ "title": "Delayd Job Schedule Concurrent executions",
309
+ "view": "timeSeries",
310
+ "stacked": false,
311
+ "liveData": true
312
+ }
313
+ },
314
+ {
315
+ "height": 3,
316
+ "width": 9,
317
+ "y": 27,
318
+ "x": 0,
319
+ "type": "metric",
320
+ "properties": {
321
+ "metrics": [
322
+ [ "AWS/DynamoDB", "ReturnedItemCount", "TableName", "${self:service}-${self:custom.stage}-delayed-jobs", "Operation", "Query" ]
323
+ ],
324
+ "view": "timeSeries",
325
+ "stacked": false,
326
+ "region": "us-east-1",
327
+ "title": "Delayed Jobs To Be Executed In The Next 90 Seconds",
328
+ "period": 60,
329
+ "stat": "Average",
330
+ "liveData": true
331
+ }
332
+ },
333
+ {
334
+ "height": 3,
335
+ "width": 6,
336
+ "y": 0,
337
+ "x": 0,
338
+ "type": "text",
339
+ "properties": {
340
+ "markdown": "\n# Incoming Jobs\n"
341
+ }
342
+ },
343
+ {
344
+ "height": 3,
345
+ "width": 6,
346
+ "y": 9,
347
+ "x": 0,
348
+ "type": "text",
349
+ "properties": {
350
+ "markdown": "\n# Active Jobs\n"
351
+ }
352
+ },
353
+ {
354
+ "height": 3,
355
+ "width": 6,
356
+ "y": 24,
357
+ "x": 0,
358
+ "type": "text",
359
+ "properties": {
360
+ "markdown": "\n# Delayed Jobs\n"
361
+ }
362
+ },
363
+ {
364
+ "height": 3,
365
+ "width": 3,
366
+ "y": 0,
367
+ "x": 6,
368
+ "type": "metric",
369
+ "properties": {
370
+ "metrics": [
371
+ [ "AWS/SQS", "NumberOfMessagesReceived", "QueueName", "${self:custom.funktor.incomingJobQueueName}", { "label": "Messages Per Minute" } ]
372
+ ],
373
+ "view": "singleValue",
374
+ "region": "us-east-1",
375
+ "stat": "Sum",
376
+ "period": 60,
377
+ "title": "Messages Per Minute"
378
+ }
379
+ },
380
+ {
381
+ "height": 3,
382
+ "width": 3,
383
+ "y": 9,
384
+ "x": 6,
385
+ "type": "metric",
386
+ "properties": {
387
+ "metrics": [
388
+ [ "AWS/SQS", "NumberOfMessagesReceived", "QueueName", "${self:service}-${self:custom.stage}-active-jobs", { "label": "Messages Per Minute" } ]
389
+ ],
390
+ "view": "singleValue",
391
+ "region": "us-east-1",
392
+ "stat": "Sum",
393
+ "period": 60,
394
+ "title": "Messages Per Minute"
395
+ }
396
+ },
397
+ {
398
+ "height": 3,
399
+ "width": 15,
400
+ "y": 0,
401
+ "x": 9,
402
+ "type": "metric",
403
+ "properties": {
404
+ "metrics": [
405
+ [ "AWS/Lambda", "Duration", "FunctionName", "${self:service}-${self:provider.stage}-incoming_job_handler", "Resource", "${self:service}-${self:provider.stage}-incoming_job_handler", { "label": "p10" } ],
406
+ [ "...", { "label": "p50", "stat": "p50" } ],
407
+ [ "...", { "label": "p99", "stat": "p99" } ],
408
+ [ "...", { "label": "Average", "stat": "Average" } ]
409
+ ],
410
+ "view": "singleValue",
411
+ "region": "us-east-1",
412
+ "stat": "p10",
413
+ "period": 60,
414
+ "title": "Handler Duration"
415
+ }
416
+ },
417
+ {
418
+ "height": 3,
419
+ "width": 15,
420
+ "y": 9,
421
+ "x": 9,
422
+ "type": "metric",
423
+ "properties": {
424
+ "metrics": [
425
+ [ "AWS/Lambda", "Duration", "FunctionName", "${self:service}-${self:provider.stage}-active_job_handler", "Resource", "${self:service}-${self:provider.stage}-active_job_handler", { "label": "p10" } ],
426
+ [ "...", { "label": "p50", "stat": "p50" } ],
427
+ [ "...", { "label": "p99", "stat": "p99" } ],
428
+ [ "...", { "label": "Average", "stat": "Average" } ]
429
+ ],
430
+ "view": "singleValue",
431
+ "region": "us-east-1",
432
+ "stat": "p10",
433
+ "period": 60,
434
+ "title": "Handler Duration"
435
+ }
436
+ },
437
+ {
438
+ "height": 3,
439
+ "width": 3,
440
+ "y": 24,
441
+ "x": 6,
442
+ "type": "metric",
443
+ "properties": {
444
+ "metrics": [
445
+ [ "AWS/DynamoDB", "ReturnedItemCount", "TableName", "${self:service}-${self:custom.stage}-delayed-jobs", "Operation", "Query" ]
446
+ ],
447
+ "view": "singleValue",
448
+ "region": "us-east-1",
449
+ "stat": "Average",
450
+ "period": 60,
451
+ "title": "Messages To Be Scheduled"
452
+ }
453
+ },
454
+ {
455
+ "height": 3,
456
+ "width": 15,
457
+ "y": 24,
458
+ "x": 9,
459
+ "type": "metric",
460
+ "properties": {
461
+ "metrics": [
462
+ [ "AWS/Lambda", "Duration", "FunctionName", "${self:service}-${self:provider.stage}-delayed_job_scheduler", "Resource", "${self:service}-${self:provider.stage}-delayed_job_scheduler", { "label": "p10" } ],
463
+ [ "...", { "label": "p50", "stat": "p50" } ],
464
+ [ "...", { "label": "p99", "stat": "p99" } ],
465
+ [ "...", { "label": "Average", "stat": "Average" } ]
466
+ ],
467
+ "view": "singleValue",
468
+ "region": "us-east-1",
469
+ "stat": "p10",
470
+ "period": 60,
471
+ "title": "Handler Duration"
472
+ }
473
+ },
474
+ {
475
+ "height": 3,
476
+ "width": 9,
477
+ "y": 30,
478
+ "x": 9,
479
+ "type": "metric",
480
+ "properties": {
481
+ "metrics": [
482
+ [ { "expression": "m4/PERIOD(m4)", "label": "Consumed Read Capacity Units", "id": "e1", "stat": "Sum", "region": "us-east-1" } ],
483
+ [ "AWS/DynamoDB", "ConsumedReadCapacityUnits", "TableName", "${self:service}-${self:custom.stage}-delayed-jobs", { "id": "m2", "visible": false } ],
484
+ [ ".", "ConsumedWriteCapacityUnits", ".", ".", { "yAxis": "left", "id": "m4", "visible": false } ],
485
+ [ ".", "WriteThrottleEvents", ".", ".", { "yAxis": "right", "id": "m5", "visible": false } ]
486
+ ],
487
+ "view": "timeSeries",
488
+ "stacked": false,
489
+ "region": "us-east-1",
490
+ "title": "Scheduled Job Table Write Capacity Units",
491
+ "period": 60,
492
+ "stat": "Sum",
493
+ "liveData": true
494
+ }
495
+ },
496
+ {
497
+ "height": 6,
498
+ "width": 24,
499
+ "y": 18,
500
+ "x": 0,
501
+ "type": "metric",
502
+ "properties": {
503
+ "metrics": [
504
+ [ "rails-lambda-experiment", "Duration", "WorkerClassName", "HelloWorker" ],
505
+ [ "...", { "stat": "p99" } ],
506
+ [ "...", "HelloLaterWorker" ],
507
+ [ "...", { "stat": "p99" } ]
508
+ ],
509
+ "view": "timeSeries",
510
+ "stacked": false,
511
+ "region": "us-east-1",
512
+ "stat": "Average",
513
+ "period": 60,
514
+ "title": "Job Duration by Worker"
515
+ }
516
+ }
517
+ ]
518
+ }