cloudwatch-metrics 0.1.24 → 0.1.26

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 42322dee77d4b10cbb7118d4f76bbe6631c757822bfd920b81603fa26a8b0cf8
4
- data.tar.gz: d3536c5c8ad7457b97882a1026bc3a711216539e258b4f7169d7d3844d8dc717
3
+ metadata.gz: 28559f6e9beaa0232533fc708bc611ce9a36bfb6ceba507750dcb96fa0d7ff58
4
+ data.tar.gz: 15e3fdcb7cb15b25232b3cebd2e38924f4b3c3478f6e5ff9fca5d94312ea4029
5
5
  SHA512:
6
- metadata.gz: 5a0ebee838a22456130bb39acf86ab92532cc5fb89803405ba734512ba3bd227ae73d9bfd1cc8a7efaa2d0b687d57c7903b5785f8d564e4ebec7bb26d9ce8904
7
- data.tar.gz: bbe37d0490b24e7724b0d114883ac73e707a74e9320f69d4ee6acfbdf7c11f7eb39bfcde88ad57b1d709793ce248235d69b2c9236e432a4ef17f20f11620163e
6
+ metadata.gz: 9b8adc74f221b238cfe66e5fd9820c0988e5e2adad395ffc9f475fcdcbc8f80ee67592ff54f5fb842ff1c81ff0f199a5ac3b1b82f779dbbe6f29d1be5b90542d
7
+ data.tar.gz: a8c7c353c71566b128745eb294420dcb3c8dc894eaed53a16acf266f2871fb1eec4cc76d4281bb5c955956ba53ac69a036c67d5bcec8bc5ad3ac8216f5215611
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,354 @@
1
+ inherit_from:
2
+ - .rubocop_strict.yml
3
+
4
+ inherit_mode:
5
+ merge:
6
+ - Exclude
7
+
8
+ require:
9
+ - rubocop-rspec
10
+ - rubocop-performance
11
+ - rubocop-rails
12
+
13
+ ## For Reference:
14
+ ## Rubocop docs: https://docs.rubocop.org/
15
+ ## Ruby Style Guide: https://rubystyle.guide/
16
+ ## Rails Style Guide: https://rails.rubystyle.guide/
17
+ ## RSpec Style Guide: https://rspec.rubystyle.guide/
18
+
19
+ AllCops:
20
+ TargetRubyVersion: 3.0.3
21
+ SuggestExtensions: false
22
+ NewCops: enable
23
+ Exclude:
24
+ - bin/**/*
25
+ - config/**/*
26
+ - db/seeds/**/*
27
+ - db/*
28
+ - node_modules/**/*
29
+ - vendor/**/*
30
+ - tmp/**/*
31
+
32
+ Layout/SpaceInsideHashLiteralBraces:
33
+ Enabled: true
34
+ EnforcedStyle: no_space
35
+ EnforcedStyleForEmptyBraces: no_space
36
+
37
+ Layout/MultilineMethodCallIndentation:
38
+ Enabled: true
39
+ EnforcedStyle: indented
40
+
41
+ Layout/ArrayAlignment:
42
+ Enabled: true
43
+ EnforcedStyle: with_fixed_indentation
44
+
45
+ Layout/FirstHashElementIndentation:
46
+ Enabled: true
47
+ EnforcedStyle: consistent
48
+
49
+ Style/NegatedIf:
50
+ Enabled: true
51
+ EnforcedStyle: postfix
52
+
53
+ Layout/FirstArgumentIndentation:
54
+ Enabled: true
55
+ EnforcedStyle: consistent
56
+
57
+ Layout/MultilineOperationIndentation:
58
+ Enabled: true
59
+ EnforcedStyle: indented
60
+
61
+ Layout/FirstArrayElementIndentation:
62
+ Enabled: true
63
+ EnforcedStyle: consistent
64
+
65
+ Style/HashSyntax:
66
+ Enabled: true
67
+ EnforcedStyle: ruby19_no_mixed_keys
68
+
69
+ Style/EmptyMethod:
70
+ Enabled: true
71
+ EnforcedStyle: expanded
72
+
73
+ Style/RescueModifier:
74
+ Enabled: true
75
+ Exclude:
76
+ - spec/**/*
77
+
78
+ Rails/Output:
79
+ Enabled: true
80
+ Exclude:
81
+ - lib/**/*
82
+ - app/services/tasks/*
83
+
84
+ Rails/UnknownEnv:
85
+ Enabled: true
86
+ Environments:
87
+ - production
88
+ - staging
89
+ - test
90
+ - development
91
+
92
+ Metrics/BlockNesting:
93
+ Enabled: true
94
+ Max: 3
95
+
96
+ # Default Max: 10
97
+ Metrics/MethodLength:
98
+ Max: 20
99
+ CountAsOne: ['array', 'hash']
100
+
101
+ Metrics/ModuleLength:
102
+ Enabled: true
103
+ Max: 100
104
+ CountAsOne: ['array', 'hash']
105
+
106
+ Metrics/PerceivedComplexity:
107
+ Enabled: true
108
+ Max: 16
109
+
110
+ Metrics/ParameterLists:
111
+ Enabled: true
112
+ Max: 8
113
+
114
+ RSpec/ExampleLength:
115
+ Enabled: true
116
+ Max: 10
117
+
118
+ RSpec/MultipleMemoizedHelpers:
119
+ Enabled: true
120
+ Max: 20
121
+
122
+ RSpec/NestedGroups:
123
+ Enabled: true
124
+ Max: 4
125
+
126
+ Rails/Delegate:
127
+ Enabled: false
128
+
129
+ Style/Documentation:
130
+ Enabled: false
131
+
132
+ # Leave disabled in favor of Perceived/Complexity
133
+ Metrics/AbcSize:
134
+ Enabled: false
135
+
136
+ Style/ClassAndModuleChildren:
137
+ Enabled: false
138
+
139
+ Style/IfUnlessModifier:
140
+ Enabled: false
141
+
142
+ Naming/RescuedExceptionsVariableName:
143
+ Enabled: false
144
+
145
+ Style/InverseMethods:
146
+ Enabled: false
147
+
148
+ Style/StringConcatenation:
149
+ Enabled: false
150
+
151
+ Style/HashEachMethods:
152
+ Enabled: false
153
+
154
+ Style/CaseLikeIf:
155
+ Enabled: false
156
+
157
+ # Leave disabled in favor of PerceivedComplexity
158
+ Metrics/CyclomaticComplexity:
159
+ Enabled: false
160
+
161
+ Style/Next:
162
+ Enabled: false
163
+
164
+ Layout/EmptyLineAfterGuardClause:
165
+ Enabled: false
166
+
167
+ Style/HashAsLastArrayItem:
168
+ Enabled: false
169
+
170
+ Lint/ShadowingOuterLocalVariable:
171
+ Enabled: false
172
+
173
+ Naming/AccessorMethodName:
174
+ Enabled: false
175
+
176
+ Style/IfWithBooleanLiteralBranches:
177
+ Enabled: false
178
+
179
+ Metrics/BlockLength:
180
+ Enabled: false
181
+
182
+ Style/NumericPredicate:
183
+ Enabled: false
184
+
185
+ Style/SoleNestedConditional:
186
+ Enabled: false
187
+
188
+ Style/GuardClause:
189
+ Enabled: false
190
+
191
+ Style/SymbolArray:
192
+ Enabled: false
193
+
194
+ Style/WordArray:
195
+ Enabled: false
196
+
197
+ Naming/VariableNumber:
198
+ Enabled: false
199
+
200
+ Naming/MethodParameterName:
201
+ Enabled: false
202
+
203
+ Lint/DuplicateBranch:
204
+ Enabled: false
205
+
206
+ Style/MultilineTernaryOperator:
207
+ Enabled: false
208
+
209
+ Naming/MemoizedInstanceVariableName:
210
+ Enabled: false
211
+
212
+ Style/SymbolProc:
213
+ Enabled: false
214
+
215
+ Lint/UselessAccessModifier:
216
+ Enabled: false
217
+
218
+ Lint/UselessMethodDefinition:
219
+ Enabled: false
220
+
221
+ Lint/EmptyBlock:
222
+ Enabled: false
223
+
224
+ Style/CaseEquality:
225
+ Enabled: false
226
+
227
+ Style/ExplicitBlockArgument:
228
+ Enabled: false
229
+
230
+ Lint/TripleQuotes:
231
+ Enabled: false
232
+
233
+ Style/ZeroLengthPredicate:
234
+ Enabled: false
235
+
236
+ Style/StringChars:
237
+ Enabled: false
238
+
239
+ Performance/RedundantSplitRegexpArgument:
240
+ Enabled: false
241
+
242
+ Style/OptionalBooleanParameter:
243
+ Enabled: false
244
+
245
+ Style/RedundantArgument:
246
+ Enabled: false
247
+
248
+ Style/MutableConstant:
249
+ Enabled: false
250
+
251
+ Naming/PredicateName:
252
+ Enabled: false
253
+
254
+ Lint/UnusedBlockArgument:
255
+ Enabled: false
256
+
257
+ Style/RaiseArgs:
258
+ Enabled: false
259
+
260
+ Style/MultilineBlockChain:
261
+ Enabled: false
262
+
263
+ Performance/Sum:
264
+ Enabled: false
265
+
266
+ Lint/UnexpectedBlockArity:
267
+ Enabled: false
268
+
269
+ Lint/SymbolConversion:
270
+ Enabled: false
271
+
272
+ Performance/CollectionLiteralInLoop:
273
+ Enabled: false
274
+
275
+ Style/FormatString:
276
+ Enabled: false
277
+
278
+ Style/FormatStringToken:
279
+ Enabled: false
280
+
281
+ Lint/MissingSuper:
282
+ Enabled: false
283
+
284
+ Style/NumericLiterals:
285
+ Enabled: false
286
+
287
+ Style/RegexpLiteral:
288
+ Enabled: false
289
+
290
+ Style/PreferredHashMethods:
291
+ Enabled: false
292
+
293
+ Lint/EmptyClass:
294
+ Enabled: false
295
+
296
+ Style/WhileUntilModifier:
297
+ Enabled: false
298
+
299
+ Lint/DisjunctiveAssignmentInConstructor:
300
+ Enabled: false
301
+
302
+ Style/FloatDivision:
303
+ Enabled: false
304
+
305
+ Lint/ToJSON:
306
+ Enabled: false
307
+
308
+ Performance/Casecmp:
309
+ Enabled: false
310
+
311
+ Style/CommentAnnotation:
312
+ Enabled: false
313
+
314
+ Lint/EmptyFile:
315
+ Enabled: false
316
+
317
+ Style/AccessorGrouping:
318
+ Enabled: false
319
+
320
+ Naming/MethodName:
321
+ Enabled: false
322
+
323
+ Style/DoubleNegation:
324
+ Enabled: false
325
+
326
+ Lint/AmbiguousBlockAssociation:
327
+ Enabled: false
328
+
329
+ Performance/TimesMap:
330
+ Enabled: false
331
+
332
+ Style/ExpandPathArguments:
333
+ Enabled: false
334
+
335
+ Style/Lambda:
336
+ Enabled: false
337
+
338
+ Style/RedundantSelfAssignment:
339
+ Enabled: false
340
+
341
+ Layout/EmptyLinesAroundAttributeAccessor:
342
+ Enabled: false
343
+
344
+ Style/NegatedIfElseCondition:
345
+ Enabled: false
346
+
347
+ Lint/ImplicitStringConcatenation:
348
+ Enabled: false
349
+
350
+ Rails/RenderInline:
351
+ Enabled: false
352
+
353
+ Rails/LexicallyScopedActionFilter:
354
+ Enabled: false
@@ -0,0 +1,23 @@
1
+ # Inspiration: https://evilmartians.com/chronicles/rubocoping-with-legacy-bring-your-ruby-code-up-to-standard
2
+ # There are a handful of cops that should be applied to all
3
+ # files always regardless of anything.
4
+ # These are those cops.
5
+ Lint/Debugger: # don't leave binding.pry
6
+ Enabled: true
7
+ Exclude: []
8
+
9
+ RSpec/Focus: # run ALL tests on CI
10
+ Enabled: true
11
+ Exclude: []
12
+
13
+ Rails/Output: # Don't leave puts-debugging
14
+ Enabled: true
15
+ Exclude: []
16
+
17
+ Rails/FindEach: # each could severely affect the performance, use find_each
18
+ Enabled: true
19
+ Exclude: []
20
+
21
+ Rails/UniqBeforePluck: # uniq.pluck and not pluck.uniq
22
+ Enabled: true
23
+ Exclude: []
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+ gemspec
5
+
6
+ group :development, :test do
7
+ gem 'debug', '>= 1.0.0'
8
+ gem 'rspec', '~> 3.11'
9
+ gem 'rubocop', '~> 1.21', require: false
10
+ gem 'rubocop-performance', '~> 1.18', require: false
11
+ gem 'rubocop-rails', '~> 2.19', require: false
12
+ gem 'rubocop-rspec', '~> 2.22', require: false
13
+ gem 'simplecov', '~> 0.22', require: false
14
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,122 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ cloudwatch-metrics (0.1.25)
5
+ activesupport (~> 7.0)
6
+ aws-sdk-cloudwatch (~> 1.73)
7
+ rake (~> 13.0)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ activesupport (7.0.5)
13
+ concurrent-ruby (~> 1.0, >= 1.0.2)
14
+ i18n (>= 1.6, < 2)
15
+ minitest (>= 5.1)
16
+ tzinfo (~> 2.0)
17
+ ast (2.4.2)
18
+ aws-eventstream (1.2.0)
19
+ aws-partitions (1.780.0)
20
+ aws-sdk-cloudwatch (1.75.0)
21
+ aws-sdk-core (~> 3, >= 3.174.0)
22
+ aws-sigv4 (~> 1.1)
23
+ aws-sdk-core (3.175.0)
24
+ aws-eventstream (~> 1, >= 1.0.2)
25
+ aws-partitions (~> 1, >= 1.651.0)
26
+ aws-sigv4 (~> 1.5)
27
+ jmespath (~> 1, >= 1.6.1)
28
+ aws-sigv4 (1.5.2)
29
+ aws-eventstream (~> 1, >= 1.0.2)
30
+ concurrent-ruby (1.2.2)
31
+ debug (1.8.0)
32
+ irb (>= 1.5.0)
33
+ reline (>= 0.3.1)
34
+ diff-lcs (1.5.0)
35
+ docile (1.4.0)
36
+ i18n (1.14.1)
37
+ concurrent-ruby (~> 1.0)
38
+ io-console (0.6.0)
39
+ irb (1.7.0)
40
+ reline (>= 0.3.0)
41
+ jmespath (1.6.2)
42
+ json (2.6.3)
43
+ minitest (5.18.0)
44
+ parallel (1.23.0)
45
+ parser (3.2.2.3)
46
+ ast (~> 2.4.1)
47
+ racc
48
+ racc (1.7.1)
49
+ rack (3.0.8)
50
+ rainbow (3.1.1)
51
+ rake (13.0.6)
52
+ regexp_parser (2.8.1)
53
+ reline (0.3.5)
54
+ io-console (~> 0.5)
55
+ rexml (3.2.5)
56
+ rspec (3.12.0)
57
+ rspec-core (~> 3.12.0)
58
+ rspec-expectations (~> 3.12.0)
59
+ rspec-mocks (~> 3.12.0)
60
+ rspec-core (3.12.2)
61
+ rspec-support (~> 3.12.0)
62
+ rspec-expectations (3.12.3)
63
+ diff-lcs (>= 1.2.0, < 2.0)
64
+ rspec-support (~> 3.12.0)
65
+ rspec-mocks (3.12.5)
66
+ diff-lcs (>= 1.2.0, < 2.0)
67
+ rspec-support (~> 3.12.0)
68
+ rspec-support (3.12.0)
69
+ rubocop (1.52.1)
70
+ json (~> 2.3)
71
+ parallel (~> 1.10)
72
+ parser (>= 3.2.2.3)
73
+ rainbow (>= 2.2.2, < 4.0)
74
+ regexp_parser (>= 1.8, < 3.0)
75
+ rexml (>= 3.2.5, < 4.0)
76
+ rubocop-ast (>= 1.28.0, < 2.0)
77
+ ruby-progressbar (~> 1.7)
78
+ unicode-display_width (>= 2.4.0, < 3.0)
79
+ rubocop-ast (1.29.0)
80
+ parser (>= 3.2.1.0)
81
+ rubocop-capybara (2.18.0)
82
+ rubocop (~> 1.41)
83
+ rubocop-factory_bot (2.23.1)
84
+ rubocop (~> 1.33)
85
+ rubocop-performance (1.18.0)
86
+ rubocop (>= 1.7.0, < 2.0)
87
+ rubocop-ast (>= 0.4.0)
88
+ rubocop-rails (2.19.1)
89
+ activesupport (>= 4.2.0)
90
+ rack (>= 1.1)
91
+ rubocop (>= 1.33.0, < 2.0)
92
+ rubocop-rspec (2.22.0)
93
+ rubocop (~> 1.33)
94
+ rubocop-capybara (~> 2.17)
95
+ rubocop-factory_bot (~> 2.22)
96
+ ruby-progressbar (1.13.0)
97
+ simplecov (0.22.0)
98
+ docile (~> 1.1)
99
+ simplecov-html (~> 0.11)
100
+ simplecov_json_formatter (~> 0.1)
101
+ simplecov-html (0.12.3)
102
+ simplecov_json_formatter (0.1.4)
103
+ tzinfo (2.0.6)
104
+ concurrent-ruby (~> 1.0)
105
+ unicode-display_width (2.4.2)
106
+
107
+ PLATFORMS
108
+ arm64-darwin-22
109
+ x86_64-linux
110
+
111
+ DEPENDENCIES
112
+ cloudwatch-metrics!
113
+ debug (>= 1.0.0)
114
+ rspec (~> 3.11)
115
+ rubocop (~> 1.21)
116
+ rubocop-performance (~> 1.18)
117
+ rubocop-rails (~> 2.19)
118
+ rubocop-rspec (~> 2.22)
119
+ simplecov (~> 0.22)
120
+
121
+ BUNDLED WITH
122
+ 2.2.32
data/README.md ADDED
@@ -0,0 +1,99 @@
1
+ # CloudwatchMetrics
2
+
3
+ `CloudwatchMetrics` is a Ruby gem for writing custom metrics to AWS Cloudwatch.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+ ```ruby
9
+ gem 'cloudwatch-metrics'
10
+ ```
11
+
12
+ And then execute:
13
+ ```
14
+ bundle install
15
+ ```
16
+
17
+ To create the initializer:
18
+ ```
19
+ rails generate cloudwatch_metrics:initializer
20
+ ```
21
+
22
+ The initializer contains descriptions for all available options. The only options you must provide a value for are listed below:
23
+
24
+ * **namespace**: This is the default namespace that all metrics will be published to. This should probably match the name of your application or service.
25
+
26
+ ## Usage
27
+
28
+ Available methods are in the `CloudwatchMetrics` module. For convenience this is aliased to `CW` by default. I.e `CloudwatchMetrics.record(...)` is equivalent to `CW.record(...)`.
29
+
30
+ Metrics are recorded using `CW.record` for single data points, or `CW.record_all` for collections of data points. Required and optional parameters for these methods are detailed below.
31
+
32
+ ### CW.record Required Parameters
33
+
34
+ * `name`: The name of the metric.
35
+ * `value`: The value for the single data point being recorded.
36
+
37
+ E.g. `CW.record(name: 'search_result_count', value: 25)`
38
+
39
+
40
+ `CW.record_all` has a similar method signature, but takes an array of values, and a corresponding array indicating how many times each value occurred during the period.
41
+
42
+ ### CW.record_all Required Parameters
43
+
44
+ * `name`: The name of the metric.
45
+ * `values`: Array of values for the data points being recorded.
46
+ * `counts`: Array of numbers indicating the number of times each value occurred during the period. The length of this array should match the length of the `values` array.
47
+
48
+ E.g. `CW.record_all(name: 'search_result_count', values: [25, 50, 65], counts: [1, 2, 1])`
49
+
50
+ This means that for the `search_result_count` metric we had one search with 25 results, two searches with 50 results, and one search with 65 results.
51
+
52
+ ### Optional Parameters
53
+
54
+ Both recording methods accept optional parameters, which are detailed below, along with their default values
55
+
56
+ * `unit`: The unit of measure for this data point. Units help provide conceptual meaning to your data, but CloudWatch attaches no significance to a unit internally. Common values are `Seconds`, `Kilobytes`, `Percent`, `Count`, `Kilobytes/Second`. Default value is `None`. A full list of available units is available at `CloudwatchMetrics::Units`.
57
+ * `namespace`: Override the namespace set in the initializer. Default is `nil`.
58
+ * `dimensions`: A hash of name/value pairs that form part of the identity of a metric. Dimensions allow you to group and filter data points for a particular metric. Default is `nil`.
59
+ * `timestamp`: The time associated with the data point. The timestamp can be up to two weeks in the past and up to two hours into the future. Default is the current time.
60
+
61
+ E.g. `CW.record(name: 'search_result_count', value: 25, unit: CW::COUNT, namespace: 'custom_namespace', dimensions: { group: 'A', subgroup: 'B' }, timestamp: Time.current - 1.day)`
62
+
63
+ ### Local development
64
+
65
+ By default, `CloudWatchMetrics` only publishes to Cloudwatch in the production environment. In other environments it will write to the configured logger. These settings can be changed in the initializer.
66
+
67
+ ### AWS Credentials
68
+
69
+ See [HOWTO Assume AWS role](https://docs.google.com/document/d/1NCXtlhddpJCttBPs2V4mv3J59V0C3ShTzaoSidBAVTU/edit#heading=h.kr4pxvf3gqqt) for info about setting up AWS credential locally. You can read more about AWS SDK configuration in the [AWS docs](https://docs.aws.amazon.com/sdk-for-ruby/v3/developer-guide/setup-config.html).
70
+
71
+ The short version: Create a file `~/.aws/config` and add your access keys there:
72
+ ```
73
+ [default]
74
+ aws_access_key_id = $AWS_ACCESS_KEY_ID
75
+ aws_secret_access_key = $AWS_SECRET_ACCESS_KEY
76
+ ```
77
+
78
+ You'll also want an `~/.aws/config` file to set the default region
79
+ ```
80
+ [default]
81
+ region = us-west-2
82
+ output = json
83
+ ```
84
+
85
+ ## Cloudwatch Concepts
86
+
87
+ Refer to the [Cloudwatch Documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch_concepts.html) for a general overview of custom metrics in CloudWatch.
88
+
89
+ ## Changing this gem
90
+
91
+ If you make changes to this gem you need to do a few things to make those updates available to clients.
92
+
93
+ **Prerequisites**: You will need an account on [rubygems.org](https://rubygems.org/) and you will need to be added as an owner of this gem. Talk to Seth for this. ([Managing Owners](https://guides.rubygems.org/managing-owners-using-ui/))
94
+
95
+ 1. Bump the version in `lib/cloudwatch_metrics/version.rb`
96
+ 2. Build the updated gem with `gem build cloudwatch_metrics.gemspec`
97
+ 3. Push the updated to gem to rubygems with `gem push ./cloudwatch-metrics-[VERSION].gem`
98
+
99
+ When the change has been published clients can update to the latest version with `bundle update cloudwatch-metrics`.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require 'rubocop/rake_task'
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "cloudwatch_metrics"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CloudwatchMetrics
4
+ class Configuration
5
+ attr_accessor :namespace, :region, :environment
6
+ attr_writer :no_cw_alias, :publish_environments, :logger
7
+
8
+ def no_cw_alias
9
+ @no_cw_alias ||= false
10
+ end
11
+
12
+ def publish_environments
13
+ @publish_environments ||= %w[production]
14
+ end
15
+
16
+ def logger
17
+ @logger ||= Logger.new($stdout)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CloudwatchMetrics
4
+ SECONDS = 'Seconds'
5
+ MICROSECONDS = 'Microseconds'
6
+ MILLISECONDS = 'Milliseconds'
7
+ BYTES = 'Bytes'
8
+ KILOBYTES = 'Kilobytes'
9
+ MEGABYTES = 'Megabytes'
10
+ GIGABYTES = 'Gigabytes'
11
+ TERABYTES = 'Terabytes'
12
+ BITS = 'Bits'
13
+ KILOBITS = 'Kilobits'
14
+ MEGABITS = 'Megabits'
15
+ GIGABITS = 'Gigabits'
16
+ TERABITS = 'Terabits'
17
+ PERCENT = 'Percent'
18
+ COUNT = 'Count'
19
+ BYTES_PER_SECOND = 'Bytes/Second'
20
+ KILOBYTES_PER_SECOND = 'Kilobytes/Second'
21
+ MEGABYTES_PER_SECOND = 'Megabytes/Second'
22
+ GIGABYTES_PER_SECOND = 'Gigabytes/Second'
23
+ TERABYTES_PER_SECOND = 'Terabytes/Second'
24
+ BITS_PER_SECOND = 'Bits/Second'
25
+ KILOBITS_PER_SECOND = 'Kilobits/Second'
26
+ MEGABITS_PER_SECOND = 'Megabits/Second'
27
+ GIGABITS_PER_SECOND = 'Gigabits/Second'
28
+ TERABITS_PER_SECOND = 'Terabits/Second'
29
+ COUNT_PER_SECOND = 'Count/Second'
30
+ NONE = 'None'
31
+
32
+ UNITS = [
33
+ SECONDS, MICROSECONDS, MILLISECONDS, BYTES, KILOBYTES, MEGABYTES, GIGABYTES, TERABYTES, BITS, KILOBITS,
34
+ MEGABITS, GIGABITS, TERABITS, PERCENT, COUNT, BYTES_PER_SECOND, KILOBYTES_PER_SECOND, MEGABYTES_PER_SECOND,
35
+ GIGABYTES_PER_SECOND, TERABYTES_PER_SECOND, BITS_PER_SECOND, KILOBITS_PER_SECOND, MEGABITS_PER_SECOND,
36
+ GIGABITS_PER_SECOND, TERABITS_PER_SECOND, COUNT_PER_SECOND, NONE
37
+ ]
38
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CloudwatchMetrics
4
+ VERSION = '0.1.26'
5
+ end
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aws-sdk-cloudwatch'
4
+ require 'active_support'
5
+ require 'active_support/core_ext/module/delegation'
6
+ require 'active_support/core_ext/time'
7
+ require_relative 'cloudwatch_metrics/configuration'
8
+ require_relative 'cloudwatch_metrics/constants'
9
+
10
+ # Posts custom metrics to AWS CloudWatch
11
+ module CloudwatchMetrics
12
+ class Error < StandardError; end
13
+
14
+ class << self
15
+ delegate :configuration, :configure, :record, :record_all, to: :instance
16
+
17
+ def instance
18
+ @instance ||= CloudwatchMetrics::Client.new
19
+ end
20
+
21
+ def flush
22
+ @instance = nil
23
+ end
24
+ end
25
+
26
+ class Client
27
+ def configuration
28
+ @configuration ||= CloudwatchMetrics::Configuration.new
29
+ end
30
+
31
+ def configure
32
+ yield(configuration)
33
+ end
34
+
35
+ def record(
36
+ name:, value:, unit: nil, namespace: configuration.namespace, dimensions: nil, timestamp: nil
37
+ )
38
+ metric_data = [{
39
+ metric_name: name,
40
+ value: value,
41
+ unit: unit,
42
+ dimensions: map_dimensions(dimensions),
43
+ timestamp: timestamp
44
+ }]
45
+ put_data(namespace: namespace, metric_data: metric_data)
46
+ end
47
+
48
+ def record_all(
49
+ name:, values:, counts:, unit: nil, namespace: configuration.namespace, dimensions: nil, timestamp: nil
50
+ )
51
+ metric_data = [{
52
+ metric_name: name,
53
+ values: values,
54
+ counts: counts,
55
+ unit: unit,
56
+ dimensions: map_dimensions(dimensions),
57
+ timestamp: timestamp
58
+ }]
59
+ put_data(namespace: namespace, metric_data: metric_data)
60
+ end
61
+
62
+ private
63
+
64
+ def put_data(namespace:, metric_data:)
65
+ if configuration.publish_environments.include?(environment)
66
+ cloudwatch_client.put_metric_data({namespace: namespace, metric_data: metric_data})
67
+ else
68
+ configuration.logger.info("CloudwatchMetrics (#{namespace}): #{metric_data}")
69
+ end
70
+
71
+ nil
72
+ rescue StandardError => e
73
+ configuration.logger.error("CloudwatchMetrics error: #{e.message}")
74
+ raise CloudwatchMetrics::Error, e.message
75
+ end
76
+
77
+ def cloudwatch_client
78
+ return @cloudwatch_client unless @cloudwatch_client.nil?
79
+
80
+ @cloudwatch_client = if !configuration.region.nil?
81
+ Aws::CloudWatch::Client.new(region: configuration.region)
82
+ else
83
+ Aws::CloudWatch::Client.new
84
+ end
85
+ end
86
+
87
+ def environment
88
+ configuration.environment || ENV.fetch('RAILS_ENV', 'development')
89
+ end
90
+
91
+ # convert key/value hash to format expected by AWS SDK
92
+ def map_dimensions(dimensions)
93
+ return [] if dimensions.nil?
94
+
95
+ mapped_values = []
96
+ dimensions.keys.each do |key|
97
+ mapped_values << {
98
+ name: key.to_s,
99
+ value: dimensions[key]
100
+ }
101
+ end
102
+
103
+ mapped_values
104
+ end
105
+ end
106
+ end
107
+
108
+ Object.const_set(:CW, CloudwatchMetrics) unless CloudwatchMetrics.configuration.no_cw_alias
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CloudwatchMetrics
4
+ module Generators
5
+ class InitializerGenerator < Rails::Generators::Base
6
+ source_root File.expand_path('templates', __dir__)
7
+
8
+ def copy_initializer_file
9
+ copy_file 'cloudwatch_metrics.rb', 'config/initializers/cloudwatch_metrics.rb'
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cloudwatch_metrics'
4
+
5
+ CloudwatchMetrics.configure do |config|
6
+ # This is the default namespace that all metrics will be published to.
7
+ # This should probably match the name of your application or service.
8
+ config.namespace = ''
9
+
10
+ # This is an optional configuration that will allow you to disable the
11
+ # `CW` alias. This is useful if you have a constant named `CW` that
12
+ # conflicts with the alias. Default is `false`.
13
+ # config.no_cw_alias = true
14
+
15
+ # This is an optional configuration to set the region that
16
+ # the metrics will be published to. This is useful if you want to publish
17
+ # to a region other than the default region for your AWS configuration.
18
+ # config.region = 'us-east-1'
19
+
20
+ # By default metrics will only be published in the production environment.
21
+ # In all other environments metrics will be logged.
22
+ # You can override this behavior by specifying an array of environments
23
+ # that you want to publish metrics in.
24
+ # config.publish_environments = %w[production development]
25
+
26
+ # This is an optional configuration to set the logger that
27
+ # the metrics will be logged to. Defaults to `Logger.new(STDOUT)`.
28
+ # For rails applications you can set this to `Rails.logger`.
29
+ # config.logger = Rails.logger
30
+
31
+ # This is an optional configuration to set the running environment.
32
+ # This is useful if the gem is being used in a non-rails application.
33
+ # Defaults to ENV['RAILS_ENV'] if present or 'development'` otherwise.
34
+ # config.environment = 'production'
35
+ end
@@ -0,0 +1,65 @@
1
+ ## Type of PR
2
+ <!-- Guidance: Each PR should fall into ONE of these categories. If it falls into multiple, please consider breaking up the PR. -->
3
+
4
+ - [ ] Bug Fix
5
+ - [ ] New Feature
6
+ - [ ] Style Changes/Code Refactor
7
+ - [ ] Data Updates/Migrations
8
+ - [ ] Instrumentation or alerting
9
+
10
+ ## Description
11
+ <!-- Guidance: Please describe what this PR does in such a way that an engineer less familiar with this work could understand it. -->
12
+
13
+ ## References
14
+ - [Ticket]()
15
+ - [Design]()
16
+ - [Tech Spec]()
17
+ - [Product Spec]()
18
+
19
+ ## Size
20
+ <!-- Guidance: Most PRs should be S-M sizes. Please don’t submit a L or XL PR without prior agreement from both the person doing the code review and a staff engineer. -->
21
+
22
+ - [ ] S <10 lines
23
+ - [ ] M <300 lines
24
+ - [ ] L <1000 lines
25
+ - [ ] XL >1000 lines
26
+
27
+ ## Business Impact of Affected Code
28
+ <!-- Guidance: Most PRs should be S-L impact. Please don’t submit an XL PR without prior agreement from both the person doing the code review and a staff engineer. If the PR is an XL, ensure there is a strict testing and rollback plan in place with an SLA for when to rollback if an outage occurs. -->
29
+
30
+ - [ ] S (zero impact)
31
+ - [ ] M (may cause features not to work or small bugs)
32
+ - [ ] L (may cause a P1 outage or data corruption)
33
+ - [ ] XL (may cause a P0 outage or data corruption)
34
+
35
+ ## Rollout Strategy
36
+ <!-- Guidance: Err on the side of caution with the rollout strategy. If there are multiple PRs, please link to them below. Get explicit sign off from the Product Manager or stakeholder on the rollout strategy and timing of the rollout. Align with them on the test plan for production. Ensure the test plan is both detailed and has sufficient metrics to determine whether to keep the change in place or to rollback. Should be in checklist form and completed on the closed PR. -->
37
+ - [ ] Behind feature flag
38
+ - [ ] Immediately into production
39
+ - [ ] Unused until other action is taken (add link to PR, link to ticket or describe action that needs to be taken)
40
+
41
+ Test Plan for Production:
42
+
43
+
44
+ ## Rollback Strategy
45
+ <!-- Guidance: This is a runbook for rolling this change back in the event of an issue. It should be detailed enough to be completed by any engineer on the team and in checklist form. -->
46
+
47
+ ## Local Testing
48
+ <!-- Guidance: Be sure to test both the happy path scenario and the unhappy path scenario. Ideally both automated tests and manual testing should have occurred but only one is required. The local testing plan must have been executed before the PR is put up. Please elaborate on the workflow and services tested, as well as the different data variations. -->
49
+
50
+ - [ ] Covered by automated tests
51
+ - [ ] Tested manually
52
+
53
+ Local Testing Plan Executed:
54
+
55
+ ## Instrumentation/Alerting
56
+ <!-- Guidance: Instrumentation and alerting should be a part of a new feature PR or have a separate instrumentation/alerting PR linked as a fast follow. For other types of PRs, this is optional (unless it’s an instrumentation/alerting PR). -->
57
+
58
+ - [ ] Instrumentation included
59
+ - [ ] Alerting to Sentry included
60
+
61
+ ## Screencaps
62
+
63
+
64
+
65
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cloudwatch-metrics
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.24
4
+ version: 0.1.26
5
5
  platform: ruby
6
6
  authors:
7
7
  - Seth Puckett
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-06-08 00:00:00.000000000 Z
11
+ date: 2023-06-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -54,11 +54,27 @@ dependencies:
54
54
  version: '13.0'
55
55
  description:
56
56
  email:
57
- - puckett.seth@gmail.com
57
+ - seth.puckett@pathccm.com
58
58
  executables: []
59
59
  extensions: []
60
60
  extra_rdoc_files: []
61
- files: []
61
+ files:
62
+ - ".rspec"
63
+ - ".rubocop.yml"
64
+ - ".rubocop_strict.yml"
65
+ - Gemfile
66
+ - Gemfile.lock
67
+ - README.md
68
+ - Rakefile
69
+ - bin/console
70
+ - bin/setup
71
+ - lib/cloudwatch_metrics.rb
72
+ - lib/cloudwatch_metrics/configuration.rb
73
+ - lib/cloudwatch_metrics/constants.rb
74
+ - lib/cloudwatch_metrics/version.rb
75
+ - lib/generators/cloudwatch_metrics/initializer_generator.rb
76
+ - lib/generators/cloudwatch_metrics/templates/cloudwatch_metrics.rb
77
+ - pull_request_template.md
62
78
  homepage: https://github.com/pathccm/cloudwatch_metrics
63
79
  licenses: []
64
80
  metadata: