funktor 0.4.7 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/.tool-versions +2 -0
  3. data/Gemfile.lock +7 -3
  4. data/funktor-testapp/.envrc +1 -0
  5. data/funktor-testapp/.gitignore +7 -0
  6. data/funktor-testapp/Gemfile +25 -0
  7. data/funktor-testapp/Gemfile.lock +51 -0
  8. data/funktor-testapp/app/services/job_flood.rb +38 -0
  9. data/funktor-testapp/app/workers/audit_worker.rb +49 -0
  10. data/funktor-testapp/app/workers/greetings_worker.rb +3 -0
  11. data/funktor-testapp/app/workers/hello_worker.rb +18 -0
  12. data/funktor-testapp/deploy-dev.sh +5 -0
  13. data/funktor-testapp/funktor_config/boot.rb +17 -0
  14. data/funktor-testapp/funktor_config/environment.yml +15 -0
  15. data/funktor-testapp/funktor_config/function_definitions/default_queue_handler.yml +11 -0
  16. data/funktor-testapp/funktor_config/function_definitions/incoming_job_handler.yml +11 -0
  17. data/funktor-testapp/funktor_config/function_definitions/job_activator.yml +8 -0
  18. data/funktor-testapp/funktor_config/function_definitions/random_job_generator.yml +18 -0
  19. data/funktor-testapp/funktor_config/function_definitions/single_thread_queue_handler.yml +11 -0
  20. data/funktor-testapp/funktor_config/funktor.yml +114 -0
  21. data/funktor-testapp/funktor_config/iam_permissions/activity_table.yml +5 -0
  22. data/funktor-testapp/funktor_config/iam_permissions/default_queue.yml +8 -0
  23. data/funktor-testapp/funktor_config/iam_permissions/incoming_job_queue.yml +8 -0
  24. data/funktor-testapp/funktor_config/iam_permissions/jobs_table.yml +5 -0
  25. data/funktor-testapp/funktor_config/iam_permissions/jobs_table_secondary_index.yml +8 -0
  26. data/funktor-testapp/funktor_config/iam_permissions/single_thread_queue.yml +8 -0
  27. data/funktor-testapp/funktor_config/iam_permissions/ssm.yml +5 -0
  28. data/funktor-testapp/funktor_config/package.yml +11 -0
  29. data/funktor-testapp/funktor_config/resources/activity_table.yml +22 -0
  30. data/funktor-testapp/funktor_config/resources/cloudwatch_dashboard.yml +804 -0
  31. data/funktor-testapp/funktor_config/resources/default_queue.yml +22 -0
  32. data/funktor-testapp/funktor_config/resources/incoming_job_queue.yml +22 -0
  33. data/funktor-testapp/funktor_config/resources/incoming_job_queue_user.yml +26 -0
  34. data/funktor-testapp/funktor_config/resources/jobs_table.yml +44 -0
  35. data/funktor-testapp/funktor_config/resources/single_thread_queue.yml +22 -0
  36. data/funktor-testapp/funktor_config/ruby_layer.yml +11 -0
  37. data/funktor-testapp/funktor_init.yml +61 -0
  38. data/funktor-testapp/lambda_event_handlers/default_queue_handler.rb +8 -0
  39. data/funktor-testapp/lambda_event_handlers/incoming_job_handler.rb +8 -0
  40. data/funktor-testapp/lambda_event_handlers/job_activator.rb +8 -0
  41. data/funktor-testapp/lambda_event_handlers/random_job_generator.rb +35 -0
  42. data/funktor-testapp/lambda_event_handlers/single_thread_queue_handler.rb +8 -0
  43. data/funktor-testapp/package-lock.json +248 -0
  44. data/funktor-testapp/package.json +8 -0
  45. data/funktor-testapp/serverless.yml +65 -0
  46. data/funktor.gemspec +1 -0
  47. data/lib/active_job/queue_adapters/funktor_adapter.rb +3 -3
  48. data/lib/funktor.rb +39 -7
  49. data/lib/funktor/activity_tracker.rb +102 -0
  50. data/lib/funktor/cli/bootstrap.rb +0 -1
  51. data/lib/funktor/cli/init.rb +13 -0
  52. data/lib/funktor/cli/templates/app/workers/hello_worker.rb +1 -1
  53. data/lib/funktor/cli/templates/funktor_config/environment.yml +4 -0
  54. data/lib/funktor/cli/templates/funktor_config/function_definitions/job_activator.yml +8 -0
  55. data/lib/funktor/cli/templates/funktor_config/funktor.yml +28 -2
  56. data/lib/funktor/cli/templates/funktor_config/iam_permissions/activity_table.yml +5 -0
  57. data/lib/funktor/cli/templates/funktor_config/iam_permissions/jobs_table.yml +5 -0
  58. data/lib/funktor/cli/templates/funktor_config/iam_permissions/jobs_table_secondary_index.yml +8 -0
  59. data/lib/funktor/cli/templates/funktor_config/resources/activity_table.yml +22 -0
  60. data/lib/funktor/cli/templates/funktor_config/resources/cloudwatch_dashboard.yml +10 -10
  61. data/lib/funktor/cli/templates/funktor_config/resources/jobs_table.yml +44 -0
  62. data/lib/funktor/cli/templates/funktor_init.yml.tt +2 -8
  63. data/lib/funktor/cli/templates/lambda_event_handlers/job_activator.rb +8 -0
  64. data/lib/funktor/cli/templates/lambda_event_handlers/work_queue_handler.rb +1 -1
  65. data/lib/funktor/cli/templates/serverless.yml +2 -2
  66. data/lib/funktor/counter.rb +4 -1
  67. data/lib/funktor/incoming_job_handler.rb +52 -12
  68. data/lib/funktor/job.rb +10 -5
  69. data/lib/funktor/job_activator.rb +98 -0
  70. data/lib/funktor/job_pusher.rb +0 -2
  71. data/lib/funktor/middleware/metrics.rb +8 -3
  72. data/lib/funktor/testing.rb +49 -47
  73. data/lib/funktor/version.rb +1 -1
  74. data/lib/funktor/{active_job_handler.rb → work_queue_handler.rb} +17 -15
  75. data/lib/funktor/worker.rb +0 -7
  76. metadata +69 -3
@@ -0,0 +1,5 @@
1
+ Effect: Allow
2
+ Action:
3
+ - dynamodb:*
4
+ Resource:
5
+ - "Fn::GetAtt": [ ActivityTable, 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": [ DefaultQueue, 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
+ - dynamodb:*
4
+ Resource:
5
+ - "Fn::GetAtt": [ JobsTable, Arn ]
@@ -0,0 +1,8 @@
1
+ Effect: Allow
2
+ Action:
3
+ - dynamodb:Query
4
+ Resource:
5
+ Fn::Join:
6
+ - ""
7
+ - - "Fn::GetAtt": [ JobsTable, Arn ]
8
+ - "/index/performAtIndex"
@@ -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": [ SingleThreadQueue, 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,11 @@
1
+ # TODO - Figure out how to allow individual packaging to work out of the box.
2
+ individually: false
3
+ include:
4
+ - Gemfile
5
+ - Gemfile.lock
6
+ - funktor_config/boot.rb
7
+ - app/**
8
+ # Evertyting is excluded by default with serverless-ruby-layer, but you could use
9
+ # the lines below to exlude files that are inside an include path.
10
+ #exclude:
11
+ # - workers/excluded_worker.rb
@@ -0,0 +1,22 @@
1
+ Resources:
2
+ ActivityTable:
3
+ Type: AWS::DynamoDB::Table
4
+ Properties:
5
+ # Generate a name based on the stage
6
+ TableName: ${self:custom.funktor.ActivityTableName}
7
+ BillingMode: PAY_PER_REQUEST
8
+ AttributeDefinitions:
9
+ - AttributeName: category
10
+ AttributeType: S
11
+ - AttributeName: statName
12
+ AttributeType: S
13
+ KeySchema:
14
+ - AttributeName: category
15
+ KeyType: HASH
16
+ - AttributeName: statName
17
+ KeyType: RANGE
18
+
19
+ Outputs:
20
+ ActivityTable:
21
+ Value:
22
+ Ref: ActivityTable
@@ -0,0 +1,804 @@
1
+ Resources:
2
+ FunktorDashboard:
3
+ Type: AWS::CloudWatch::Dashboard
4
+ Properties:
5
+ DashboardName: ${self:custom.funktor.DashboardName}
6
+ DashboardBody: >
7
+ {
8
+ "widgets": [
9
+
10
+
11
+
12
+ {
13
+ "height": 3,
14
+ "width": 24,
15
+ "y": 0,
16
+ "x": 0,
17
+ "type": "text",
18
+ "properties": {
19
+ "markdown": "\n# Funktor Auto-generated Dashbaord\n\n This dashboard is auto-generated by Funktor and will be updated as Funktor progresses. If you want to customize this dashboard you should use 'Actions => Save dashbaord as' in the toolbar above to create a new dashboard of your own.\n\n The upper section shows you high level queue and worker stats, the lower sections show more details about all the AWS resources at play."
20
+ }
21
+ },
22
+
23
+
24
+ {
25
+ "height": 6,
26
+ "width": 12,
27
+ "y": 3,
28
+ "x": 12,
29
+ "type": "metric",
30
+ "properties": {
31
+ "metrics": [
32
+ [ "funktor-testapp", "Duration", "WorkerClassName", "AuditWorker" ],
33
+ [ "...", { "stat": "p99" } ],
34
+ [ "funktor-testapp", "Duration", "WorkerClassName", "GreetingsWorker" ],
35
+ [ "...", { "stat": "p99" } ],
36
+ [ "funktor-testapp", "Duration", "WorkerClassName", "HelloWorker" ],
37
+ [ "...", { "stat": "p99" } ]
38
+ ],
39
+ "view": "timeSeries",
40
+ "stacked": false,
41
+ "region": "us-east-1",
42
+ "stat": "Average",
43
+ "period": 60,
44
+ "title": "Job Duration by Worker"
45
+ }
46
+ },
47
+
48
+ {
49
+ "height": 6,
50
+ "width": 12,
51
+ "y": 3,
52
+ "x": 0,
53
+ "type": "metric",
54
+ "properties": {
55
+ "metrics": [
56
+ [ "funktor-testapp", "processed", "WorkerClassName", "AuditWorker" ],
57
+ [ ".", "failed", ".", "." ],
58
+ [ "funktor-testapp", "processed", "WorkerClassName", "GreetingsWorker" ],
59
+ [ ".", "failed", ".", "." ],
60
+ [ "funktor-testapp", "processed", "WorkerClassName", "HelloWorker" ],
61
+ [ ".", "failed", ".", "." ]
62
+ ],
63
+ "view": "timeSeries",
64
+ "stacked": false,
65
+ "region": "us-east-1",
66
+ "title": "Process/Failed Jobs By Worker",
67
+ "period": 60,
68
+ "stat": "Sum"
69
+ }
70
+ },
71
+
72
+ {
73
+ "height": 6,
74
+ "width": 12,
75
+ "y": 9,
76
+ "x": 12,
77
+ "type": "metric",
78
+ "properties": {
79
+ "metrics": [
80
+ [ "funktor-testapp", "Duration", "Queue", "default" ],
81
+ [ "...", { "stat": "p99" } ],
82
+ [ "funktor-testapp", "Duration", "Queue", "singleThread" ],
83
+ [ "...", { "stat": "p99" } ]
84
+ ],
85
+ "view": "timeSeries",
86
+ "stacked": false,
87
+ "region": "us-east-1",
88
+ "stat": "Average",
89
+ "period": 60,
90
+ "title": "Job Duration by Queue"
91
+ }
92
+ },
93
+ {
94
+ "height": 6,
95
+ "width": 12,
96
+ "y": 9,
97
+ "x": 0,
98
+ "type": "metric",
99
+ "properties": {
100
+ "metrics": [
101
+ [ "funktor-testapp", "processed", "Queue", "default" ],
102
+ [ ".", "failed", ".", "." ],
103
+ [ "funktor-testapp", "processed", "Queue", "singleThread" ],
104
+ [ ".", "failed", ".", "." ]
105
+ ],
106
+ "view": "timeSeries",
107
+ "stacked": false,
108
+ "region": "us-east-1",
109
+ "title": "Process/Failed Jobs By Queue",
110
+ "period": 60,
111
+ "stat": "Sum"
112
+ }
113
+ },
114
+
115
+
116
+ {
117
+ "height": 3,
118
+ "width": 24,
119
+ "y": 9,
120
+ "x": 0,
121
+ "type": "text",
122
+ "properties": {
123
+ "markdown": "\n# Behind the scenes\n\n The stats below give some insight into the inner workings of the Funktor apparatus."
124
+ }
125
+ },
126
+
127
+
128
+
129
+
130
+ {
131
+ "height": 3,
132
+ "width": 6,
133
+ "y": 18,
134
+ "x": 0,
135
+ "type": "text",
136
+ "properties": {
137
+ "markdown": "\n# Incoming Jobs\n"
138
+ }
139
+ },
140
+ {
141
+ "height": 3,
142
+ "width": 3,
143
+ "y": 18,
144
+ "x": 6,
145
+ "type": "metric",
146
+ "properties": {
147
+ "metrics": [
148
+ [ "AWS/SQS", "NumberOfMessagesReceived", "QueueName", "${self:custom.funktor.IncomingJobQueueName}", { "label": "Messages Per Minute" } ]
149
+ ],
150
+ "view": "singleValue",
151
+ "region": "us-east-1",
152
+ "stat": "Sum",
153
+ "period": 60,
154
+ "title": "Messages Per Minute"
155
+ }
156
+ },
157
+ {
158
+ "height": 3,
159
+ "width": 15,
160
+ "y": 18,
161
+ "x": 9,
162
+ "type": "metric",
163
+ "properties": {
164
+ "metrics": [
165
+ [ "AWS/Lambda", "Duration", "FunctionName", "${self:custom.funktor.IncomingJobHandlerName}", "Resource", "${self:custom.funktor.IncomingJobHandlerName}", { "label": "p10" } ],
166
+ [ "...", { "label": "p50", "stat": "p50" } ],
167
+ [ "...", { "label": "p99", "stat": "p99" } ],
168
+ [ "...", { "label": "Average", "stat": "Average" } ]
169
+ ],
170
+ "view": "singleValue",
171
+ "region": "us-east-1",
172
+ "stat": "p10",
173
+ "period": 60,
174
+ "title": "Handler Duration"
175
+ }
176
+ },
177
+
178
+
179
+
180
+ {
181
+ "height": 6,
182
+ "width": 9,
183
+ "y": 21,
184
+ "x": 0,
185
+ "type": "metric",
186
+ "properties": {
187
+ "metrics": [
188
+ [ "AWS/SQS", "NumberOfMessagesReceived", "QueueName", "${self:custom.funktor.IncomingJobQueueName}", { "label": "Received" } ],
189
+ [ ".", "NumberOfMessagesDeleted", ".", ".", { "label": "Handled" } ],
190
+ [ "AWS/Lambda", "Invocations", "FunctionName", "${self:custom.funktor.IncomingJobHandlerName}", "Resource", "${self:custom.funktor.IncomingJobHandlerName}", { "label": "Handler Invocations" } ],
191
+ [ "AWS/SQS", "ApproximateNumberOfMessagesVisible", "QueueName", "${self:custom.funktor.IncomingJobQueueName}", { "label": "Pending?" } ],
192
+ [ ".", "ApproximateNumberOfMessagesNotVisible", ".", ".", { "label": "Backlog?" } ],
193
+ [ ".", "NumberOfMessagesSent", ".", ".", { "label": "Sent" } ],
194
+ [ ".", "ApproximateNumberOfMessagesDelayed", ".", ".", { "label": "Delayed" } ]
195
+ ],
196
+ "view": "timeSeries",
197
+ "stacked": false,
198
+ "region": "us-east-1",
199
+ "title": "Incoming Job Queue (Async & scheduled jobs land here first)",
200
+ "period": 60,
201
+ "stat": "Sum",
202
+ "setPeriodToTimeRange": true,
203
+ "liveData": true
204
+ }
205
+ },
206
+ {
207
+ "height": 6,
208
+ "width": 9,
209
+ "y": 21,
210
+ "x": 9,
211
+ "type": "metric",
212
+ "properties": {
213
+ "period": 60,
214
+ "metrics": [
215
+ [ "AWS/Lambda", "Duration", "FunctionName", "${self:custom.funktor.IncomingJobHandlerName}", { "stat": "Minimum" } ],
216
+ [ "...", { "stat": "Average" } ],
217
+ [ "...", { "stat": "Maximum" } ]
218
+ ],
219
+ "region": "us-east-1",
220
+ "title": "Incoming Job Handler Duration in Milliseconds",
221
+ "view": "timeSeries",
222
+ "stacked": false,
223
+ "liveData": true
224
+ }
225
+ },
226
+ {
227
+ "height": 3,
228
+ "width": 6,
229
+ "y": 21,
230
+ "x": 18,
231
+ "type": "metric",
232
+ "properties": {
233
+ "period": 60,
234
+ "metrics": [
235
+ [ "AWS/Lambda", "Errors", "FunctionName", "${self:custom.funktor.IncomingJobHandlerName}", { "id": "errors", "stat": "Sum", "color": "#d13212" } ],
236
+ [ ".", "Invocations", ".", ".", { "id": "invocations", "stat": "Sum", "visible": false } ],
237
+ [ { "expression": "100 - 100 * errors / MAX([errors, invocations])", "label": "Success rate (%)", "id": "availability", "yAxis": "right", "region": "us-east-1" } ]
238
+ ],
239
+ "region": "us-east-1",
240
+ "title": "Incoming Job Handler Error count and success rate (%)",
241
+ "yAxis": {
242
+ "right": {
243
+ "max": 100
244
+ }
245
+ },
246
+ "view": "timeSeries",
247
+ "stacked": false,
248
+ "liveData": true
249
+ }
250
+ },
251
+
252
+
253
+ {
254
+ "height": 3,
255
+ "width": 6,
256
+ "y": 24,
257
+ "x": 18,
258
+ "type": "metric",
259
+ "properties": {
260
+ "period": 60,
261
+ "metrics": [
262
+ [ "AWS/Lambda", "ConcurrentExecutions", "FunctionName", "${self:custom.funktor.IncomingJobHandlerName}", { "stat": "Maximum" } ]
263
+ ],
264
+ "region": "us-east-1",
265
+ "title": "Incoming Job Handler Concurrent Executions",
266
+ "view": "timeSeries",
267
+ "stacked": false,
268
+ "liveData": true
269
+ }
270
+ },
271
+
272
+
273
+
274
+
275
+ {
276
+ "height": 3,
277
+ "width": 6,
278
+ "y": 27,
279
+ "x": 0,
280
+ "type": "text",
281
+ "properties": {
282
+ "markdown": "\n# Default Queue\n"
283
+ }
284
+ },
285
+ {
286
+ "height": 3,
287
+ "width": 3,
288
+ "y": 27,
289
+ "x": 6,
290
+ "type": "metric",
291
+ "properties": {
292
+ "metrics": [
293
+ [ "AWS/SQS", "NumberOfMessagesReceived", "QueueName",
294
+ "${self:custom.funktor.DefaultQueueName}", { "label": "Messages Per Minute" } ]
295
+ ],
296
+ "view": "singleValue",
297
+ "region": "us-east-1",
298
+ "stat": "Sum",
299
+ "period": 60,
300
+ "title": "Messages Per Minute"
301
+ }
302
+ },
303
+ {
304
+ "height": 3,
305
+ "width": 15,
306
+ "y": 27,
307
+ "x": 9,
308
+ "type": "metric",
309
+ "properties": {
310
+ "metrics": [
311
+ [ "AWS/Lambda", "Duration", "FunctionName",
312
+ "${self:custom.funktor.DefaultQueueHandlerName}", "Resource",
313
+ "${self:custom.funktor.DefaultQueueHandlerName}", { "label": "p10" } ],
314
+ [ "...", { "label": "p50", "stat": "p50" } ],
315
+ [ "...", { "label": "p99", "stat": "p99" } ],
316
+ [ "...", { "label": "Average", "stat": "Average" } ]
317
+ ],
318
+ "view": "singleValue",
319
+ "region": "us-east-1",
320
+ "stat": "p10",
321
+ "period": 60,
322
+ "title": "Handler Duration"
323
+ }
324
+ },
325
+ {
326
+ "height": 6,
327
+ "width": 9,
328
+ "y": 30,
329
+ "x": 0,
330
+ "type": "metric",
331
+ "properties": {
332
+ "metrics": [
333
+ [ "AWS/SQS", "NumberOfMessagesReceived", "QueueName",
334
+ "${self:custom.funktor.DefaultQueueName}",
335
+ { "label": "Received" } ],
336
+ [ ".", "NumberOfMessagesDeleted", ".", ".", { "label": "Handled" } ],
337
+ [ "AWS/Lambda", "Invocations", "FunctionName",
338
+ "${self:custom.funktor.DefaultQueueHandlerName}", "Resource",
339
+ "${self:custom.funktor.DefaultQueueHandlerName}", { "label": "Handler Invocations" } ],
340
+ [ "AWS/SQS", "ApproximateNumberOfMessagesVisible", "QueueName",
341
+ "${self:custom.funktor.DefaultQueueName}", { "label": "Pending?" } ],
342
+ [ ".", "ApproximateNumberOfMessagesNotVisible", ".", ".", { "label": "Backlog?" } ],
343
+ [ ".", "NumberOfMessagesSent", ".", ".", { "label": "Sent" } ],
344
+ [ ".", "ApproximateNumberOfMessagesDelayed", ".", ".", { "label": "Delayed" } ]
345
+ ],
346
+ "view": "timeSeries",
347
+ "stacked": false,
348
+ "region": "us-east-1",
349
+ "title": "Default Queue (Async jobs go here immediately, scheduled jobs land here in the minute before they're scheduled)",
350
+ "period": 60,
351
+ "stat": "Sum",
352
+ "liveData": true
353
+ }
354
+ },
355
+ {
356
+ "height": 6,
357
+ "width": 9,
358
+ "y": 30,
359
+ "x": 9,
360
+ "type": "metric",
361
+ "properties": {
362
+ "period": 60,
363
+ "metrics": [
364
+ [ "AWS/Lambda", "Duration", "FunctionName", "${self:custom.funktor.DefaultQueueHandlerName}", { "stat": "Minimum" } ],
365
+ [ "...", { "stat": "Average" } ],
366
+ [ "...", { "stat": "Maximum" } ]
367
+ ],
368
+ "region": "us-east-1",
369
+ "title": "Default Queue Handler Duration in Milliseconds",
370
+ "view": "timeSeries",
371
+ "stacked": false,
372
+ "liveData": true
373
+ }
374
+ },
375
+ {
376
+ "height": 3,
377
+ "width": 6,
378
+ "y": 30,
379
+ "x": 18,
380
+ "type": "metric",
381
+ "properties": {
382
+ "period": 60,
383
+ "metrics": [
384
+ [ "AWS/Lambda", "Errors", "FunctionName",
385
+ "${self:custom.funktor.DefaultQueueHandlerName}", { "id": "errors", "stat": "Sum", "color": "#d13212" } ],
386
+ [ ".", "Invocations", ".", ".", { "id": "invocations", "stat": "Sum", "visible": false } ],
387
+ [ { "expression": "100 - 100 * errors / MAX([errors, invocations])", "label": "Success rate (%)", "id": "availability", "yAxis": "right", "region": "us-east-1" } ]
388
+ ],
389
+ "region": "us-east-1",
390
+ "title": "Default Queue Handler Error count and success rate (%)",
391
+ "yAxis": {
392
+ "right": {
393
+ "max": 100
394
+ }
395
+ },
396
+ "view": "timeSeries",
397
+ "stacked": false,
398
+ "liveData": true
399
+ }
400
+ },
401
+ {
402
+ "height": 3,
403
+ "width": 6,
404
+ "y": 33,
405
+ "x": 18,
406
+ "type": "metric",
407
+ "properties": {
408
+ "period": 60,
409
+ "metrics": [
410
+ [ "AWS/Lambda", "ConcurrentExecutions", "FunctionName",
411
+ "${self:custom.funktor.DefaultQueueHandlerName}", { "stat": "Maximum" } ]
412
+ ],
413
+ "region": "us-east-1",
414
+ "title": "Default Queue Handler Concurrent executions",
415
+ "view": "timeSeries",
416
+ "stacked": false,
417
+ "liveData": true
418
+ }
419
+ },
420
+
421
+
422
+ {
423
+ "height": 3,
424
+ "width": 6,
425
+ "y": 36,
426
+ "x": 0,
427
+ "type": "text",
428
+ "properties": {
429
+ "markdown": "\n# SingleThread Queue\n"
430
+ }
431
+ },
432
+ {
433
+ "height": 3,
434
+ "width": 3,
435
+ "y": 36,
436
+ "x": 6,
437
+ "type": "metric",
438
+ "properties": {
439
+ "metrics": [
440
+ [ "AWS/SQS", "NumberOfMessagesReceived", "QueueName",
441
+ "${self:custom.funktor.SingleThreadQueueName}", { "label": "Messages Per Minute" } ]
442
+ ],
443
+ "view": "singleValue",
444
+ "region": "us-east-1",
445
+ "stat": "Sum",
446
+ "period": 60,
447
+ "title": "Messages Per Minute"
448
+ }
449
+ },
450
+ {
451
+ "height": 3,
452
+ "width": 15,
453
+ "y": 36,
454
+ "x": 9,
455
+ "type": "metric",
456
+ "properties": {
457
+ "metrics": [
458
+ [ "AWS/Lambda", "Duration", "FunctionName",
459
+ "${self:custom.funktor.SingleThreadQueueHandlerName}", "Resource",
460
+ "${self:custom.funktor.SingleThreadQueueHandlerName}", { "label": "p10" } ],
461
+ [ "...", { "label": "p50", "stat": "p50" } ],
462
+ [ "...", { "label": "p99", "stat": "p99" } ],
463
+ [ "...", { "label": "Average", "stat": "Average" } ]
464
+ ],
465
+ "view": "singleValue",
466
+ "region": "us-east-1",
467
+ "stat": "p10",
468
+ "period": 60,
469
+ "title": "Handler Duration"
470
+ }
471
+ },
472
+ {
473
+ "height": 6,
474
+ "width": 9,
475
+ "y": 39,
476
+ "x": 0,
477
+ "type": "metric",
478
+ "properties": {
479
+ "metrics": [
480
+ [ "AWS/SQS", "NumberOfMessagesReceived", "QueueName",
481
+ "${self:custom.funktor.SingleThreadQueueName}",
482
+ { "label": "Received" } ],
483
+ [ ".", "NumberOfMessagesDeleted", ".", ".", { "label": "Handled" } ],
484
+ [ "AWS/Lambda", "Invocations", "FunctionName",
485
+ "${self:custom.funktor.SingleThreadQueueHandlerName}", "Resource",
486
+ "${self:custom.funktor.SingleThreadQueueHandlerName}", { "label": "Handler Invocations" } ],
487
+ [ "AWS/SQS", "ApproximateNumberOfMessagesVisible", "QueueName",
488
+ "${self:custom.funktor.SingleThreadQueueName}", { "label": "Pending?" } ],
489
+ [ ".", "ApproximateNumberOfMessagesNotVisible", ".", ".", { "label": "Backlog?" } ],
490
+ [ ".", "NumberOfMessagesSent", ".", ".", { "label": "Sent" } ],
491
+ [ ".", "ApproximateNumberOfMessagesDelayed", ".", ".", { "label": "Delayed" } ]
492
+ ],
493
+ "view": "timeSeries",
494
+ "stacked": false,
495
+ "region": "us-east-1",
496
+ "title": "SingleThread Queue (Async jobs go here immediately, scheduled jobs land here in the minute before they're scheduled)",
497
+ "period": 60,
498
+ "stat": "Sum",
499
+ "liveData": true
500
+ }
501
+ },
502
+ {
503
+ "height": 6,
504
+ "width": 9,
505
+ "y": 39,
506
+ "x": 9,
507
+ "type": "metric",
508
+ "properties": {
509
+ "period": 60,
510
+ "metrics": [
511
+ [ "AWS/Lambda", "Duration", "FunctionName", "${self:custom.funktor.SingleThreadQueueHandlerName}", { "stat": "Minimum" } ],
512
+ [ "...", { "stat": "Average" } ],
513
+ [ "...", { "stat": "Maximum" } ]
514
+ ],
515
+ "region": "us-east-1",
516
+ "title": "SingleThread Queue Handler Duration in Milliseconds",
517
+ "view": "timeSeries",
518
+ "stacked": false,
519
+ "liveData": true
520
+ }
521
+ },
522
+ {
523
+ "height": 3,
524
+ "width": 6,
525
+ "y": 39,
526
+ "x": 18,
527
+ "type": "metric",
528
+ "properties": {
529
+ "period": 60,
530
+ "metrics": [
531
+ [ "AWS/Lambda", "Errors", "FunctionName",
532
+ "${self:custom.funktor.SingleThreadQueueHandlerName}", { "id": "errors", "stat": "Sum", "color": "#d13212" } ],
533
+ [ ".", "Invocations", ".", ".", { "id": "invocations", "stat": "Sum", "visible": false } ],
534
+ [ { "expression": "100 - 100 * errors / MAX([errors, invocations])", "label": "Success rate (%)", "id": "availability", "yAxis": "right", "region": "us-east-1" } ]
535
+ ],
536
+ "region": "us-east-1",
537
+ "title": "SingleThread Queue Handler Error count and success rate (%)",
538
+ "yAxis": {
539
+ "right": {
540
+ "max": 100
541
+ }
542
+ },
543
+ "view": "timeSeries",
544
+ "stacked": false,
545
+ "liveData": true
546
+ }
547
+ },
548
+ {
549
+ "height": 3,
550
+ "width": 6,
551
+ "y": 42,
552
+ "x": 18,
553
+ "type": "metric",
554
+ "properties": {
555
+ "period": 60,
556
+ "metrics": [
557
+ [ "AWS/Lambda", "ConcurrentExecutions", "FunctionName",
558
+ "${self:custom.funktor.SingleThreadQueueHandlerName}", { "stat": "Maximum" } ]
559
+ ],
560
+ "region": "us-east-1",
561
+ "title": "SingleThread Queue Handler Concurrent executions",
562
+ "view": "timeSeries",
563
+ "stacked": false,
564
+ "liveData": true
565
+ }
566
+ },
567
+
568
+
569
+
570
+
571
+
572
+ {
573
+ "height": 3,
574
+ "width": 6,
575
+ "y": 45,
576
+ "x": 0,
577
+ "type": "text",
578
+ "properties": {
579
+ "markdown": "\n# Delayed Jobs\n"
580
+ }
581
+ },
582
+ {
583
+ "height": 3,
584
+ "width": 3,
585
+ "y": 45,
586
+ "x": 6,
587
+ "type": "metric",
588
+ "properties": {
589
+ "metrics": [
590
+ [ "AWS/DynamoDB", "ReturnedItemCount", "TableName", "${self:custom.funktor.JobsTableName}", "Operation", "Query" ]
591
+ ],
592
+ "view": "singleValue",
593
+ "region": "us-east-1",
594
+ "stat": "Average",
595
+ "period": 60,
596
+ "title": "Messages To Be Scheduled"
597
+ }
598
+ },
599
+ {
600
+ "height": 3,
601
+ "width": 15,
602
+ "y": 45,
603
+ "x": 9,
604
+ "type": "metric",
605
+ "properties": {
606
+ "metrics": [
607
+ [ "AWS/Lambda", "Duration", "FunctionName", "${self:custom.funktor.JobActivatorName}", "Resource", "${self:custom.funktor.JobActivatorName}", { "label": "p10" } ],
608
+ [ "...", { "label": "p50", "stat": "p50" } ],
609
+ [ "...", { "label": "p99", "stat": "p99" } ],
610
+ [ "...", { "label": "Average", "stat": "Average" } ]
611
+ ],
612
+ "view": "singleValue",
613
+ "region": "us-east-1",
614
+ "stat": "p10",
615
+ "period": 60,
616
+ "title": "Handler Duration"
617
+ }
618
+ },
619
+
620
+
621
+
622
+
623
+ {
624
+ "height": 3,
625
+ "width": 6,
626
+ "y": 48,
627
+ "x": 18,
628
+ "type": "metric",
629
+ "properties": {
630
+ "period": 60,
631
+ "metrics": [
632
+ [ "AWS/Lambda", "Errors", "FunctionName", "${self:custom.funktor.JobActivatorName}", { "id": "errors", "stat": "Sum", "color": "#d13212" } ],
633
+ [ ".", "Invocations", ".", ".", { "id": "invocations", "stat": "Sum", "visible": false } ],
634
+ [ { "expression": "100 - 100 * errors / MAX([errors, invocations])", "label": "Success rate (%)", "id": "availability", "yAxis": "right", "region": "us-east-1" } ]
635
+ ],
636
+ "region": "us-east-1",
637
+ "title": "Delayed Job SchedulerError count and success rate (%)",
638
+ "yAxis": {
639
+ "right": {
640
+ "max": 100
641
+ }
642
+ },
643
+ "view": "timeSeries",
644
+ "stacked": false,
645
+ "liveData": true
646
+ }
647
+ },
648
+ {
649
+ "height": 3,
650
+ "width": 9,
651
+ "y": 48,
652
+ "x": 9,
653
+ "type": "metric",
654
+ "properties": {
655
+ "period": 60,
656
+ "metrics": [
657
+ [ "AWS/Lambda", "Duration", "FunctionName", "${self:custom.funktor.JobActivatorName}", { "stat": "Minimum" } ],
658
+ [ "...", { "stat": "Average" } ],
659
+ [ "...", { "stat": "Maximum" } ]
660
+ ],
661
+ "region": "us-east-1",
662
+ "title": "Delayed Job Scheduler Duration",
663
+ "view": "timeSeries",
664
+ "stacked": false,
665
+ "liveData": true
666
+ }
667
+ },
668
+ {
669
+ "height": 3,
670
+ "width": 9,
671
+ "y": 48,
672
+ "x": 0,
673
+ "type": "metric",
674
+ "properties": {
675
+ "metrics": [
676
+ [ "AWS/DynamoDB", "ReturnedItemCount", "TableName", "${self:custom.funktor.JobsTableName}", "Operation", "Query" ]
677
+ ],
678
+ "view": "timeSeries",
679
+ "stacked": false,
680
+ "region": "us-east-1",
681
+ "title": "Delayed Jobs To Be Executed In The Next 90 Seconds",
682
+ "period": 60,
683
+ "stat": "Average",
684
+ "liveData": true
685
+ }
686
+ },
687
+
688
+
689
+
690
+ {
691
+ "height": 3,
692
+ "width": 9,
693
+ "y": 51,
694
+ "x": 0,
695
+ "type": "metric",
696
+ "properties": {
697
+ "metrics": [
698
+ [ { "expression": "m2/PERIOD(m2)", "label": "Consumed Read Capacity Units", "id": "e1", "stat": "Sum", "region": "us-east-1" } ],
699
+ [ "AWS/DynamoDB", "ConsumedReadCapacityUnits", "TableName", "${self:custom.funktor.JobsTableName}", { "id": "m2", "visible": false } ],
700
+ [ ".", "ConsumedWriteCapacityUnits", ".", ".", { "yAxis": "left", "id": "m4", "visible": false } ],
701
+ [ ".", "WriteThrottleEvents", ".", ".", { "yAxis": "right", "id": "m5", "visible": false } ]
702
+ ],
703
+ "view": "timeSeries",
704
+ "stacked": false,
705
+ "region": "us-east-1",
706
+ "title": "Scheduled Job Table Read Capacity Units",
707
+ "period": 60,
708
+ "stat": "Sum",
709
+ "liveData": true
710
+ }
711
+ },
712
+ {
713
+ "height": 3,
714
+ "width": 6,
715
+ "y": 51,
716
+ "x": 18,
717
+ "type": "metric",
718
+ "properties": {
719
+ "period": 60,
720
+ "metrics": [
721
+ [ "AWS/Lambda", "ConcurrentExecutions", "FunctionName", "${self:custom.funktor.JobActivatorName}", { "stat": "Maximum" } ]
722
+ ],
723
+ "region": "us-east-1",
724
+ "title": "Delayd Job Schedule Concurrent executions",
725
+ "view": "timeSeries",
726
+ "stacked": false,
727
+ "liveData": true
728
+ }
729
+ },
730
+ {
731
+ "height": 3,
732
+ "width": 9,
733
+ "y": 51,
734
+ "x": 9,
735
+ "type": "metric",
736
+ "properties": {
737
+ "metrics": [
738
+ [ { "expression": "m4/PERIOD(m4)", "label": "Consumed Read Capacity Units", "id": "e1", "stat": "Sum", "region": "us-east-1" } ],
739
+ [ "AWS/DynamoDB", "ConsumedReadCapacityUnits", "TableName", "${self:custom.funktor.JobsTableName}", { "id": "m2", "visible": false } ],
740
+ [ ".", "ConsumedWriteCapacityUnits", ".", ".", { "yAxis": "left", "id": "m4", "visible": false } ],
741
+ [ ".", "WriteThrottleEvents", ".", ".", { "yAxis": "right", "id": "m5", "visible": false } ]
742
+ ],
743
+ "view": "timeSeries",
744
+ "stacked": false,
745
+ "region": "us-east-1",
746
+ "title": "Scheduled Job Table Write Capacity Units",
747
+ "period": 60,
748
+ "stat": "Sum",
749
+ "liveData": true
750
+ }
751
+ },
752
+
753
+
754
+
755
+
756
+ {
757
+ "height": 3,
758
+ "width": 18,
759
+ "y": 54,
760
+ "x": 0,
761
+ "type": "metric",
762
+ "properties": {
763
+ "metrics": [
764
+ [ "AWS/DynamoDB", "SuccessfulRequestLatency", "TableName", "${self:custom.funktor.JobsTableName}", "Operation", "PutItem", { "yAxis": "left" } ],
765
+ [ "...", "Query" ],
766
+ [ ".", "ThrottledRequests", ".", ".", ".", "PutItem", { "yAxis": "right", "visible": false } ],
767
+ [ ".", "SuccessfulRequestLatency", ".", ".", ".", "DeleteItem" ],
768
+ [ ".", "ThrottledRequests", ".", ".", ".", ".", { "yAxis": "right", "visible": false } ]
769
+ ],
770
+ "view": "timeSeries",
771
+ "stacked": false,
772
+ "region": "us-east-1",
773
+ "stat": "Average",
774
+ "period": 60,
775
+ "title": "Scheduled Job Table Latency",
776
+ "liveData": true
777
+ }
778
+ },
779
+ {
780
+ "height": 3,
781
+ "width": 6,
782
+ "y": 54,
783
+ "x": 18,
784
+ "type": "metric",
785
+ "properties": {
786
+ "metrics": [
787
+ [ "AWS/DynamoDB", "ThrottledRequests", "TableName", "${self:custom.funktor.JobsTableName}", "Operation", "DeleteItem" ],
788
+ [ "...", "PutItem" ]
789
+ ],
790
+ "view": "timeSeries",
791
+ "stacked": false,
792
+ "region": "us-east-1",
793
+ "stat": "Sum",
794
+ "period": 60,
795
+ "title": "Scheduled Job Table Throttled Operations",
796
+ "liveData": true
797
+ }
798
+ }
799
+
800
+
801
+
802
+
803
+ ]
804
+ }