puma-cloudwatch 0.4.5 → 0.5.0

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: 70ae556e3b7f637e097d36d0296652566b0dae5c66f1d257013b1653393cf7c4
4
- data.tar.gz: 80e4da1709178513fc7e8057bb800d15a87e6e2c261b0b5e6916ad10f41eaf04
3
+ metadata.gz: 310c3534fa2d00a6da76f26f6cbe908ac842ced68f02d49fb0ff4f7d0922e95b
4
+ data.tar.gz: 0ef2173e64a9517866be68af190256529184f40aacb6830c0f93960203dc2919
5
5
  SHA512:
6
- metadata.gz: 4d8f25242c010a545080e1236e9f9b6b3b608c660f6a096bbace315632cd2326925e4f322fda0bdf2b31195f5b898c09a2bf7f20c922d3daf6cd657d8e31014a
7
- data.tar.gz: 998bf6b0ebcd485d5a7212ccc0a2f189ebf588c6b08652f3549628d5dfc97fd6d93eb054ee6f8f670284d1d54453290b6b12bd02f5d470bc2de9db59c3ef6265
6
+ metadata.gz: 44a1e9b69e28968779ed60237c102a21e8d1bb3729a6ee5f013932efab906f00f723694b004e585f6b285db6ffadd2f1c1c935ba4d2a0eaff78fbf434ef52604
7
+ data.tar.gz: 21f44b53b79331912008bec96ac4c27b3903d16d21f79ae22ee4259ae8a8ba25fa16d79b5d4724ac9be2818097743ccc9abb65a209a344b502c32747626ef019
data/CHANGELOG.md CHANGED
@@ -3,6 +3,20 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  This project *loosely tries* to adhere to [Semantic Versioning](http://semver.org/).
5
5
 
6
+ ## [0.5.0] - 2023-07-11
7
+ - [#11](https://github.com/tongueroo/puma-cloudwatch/pull/11) Added support for PUMA_CLOUDWATCH_AWS_ACCESS_KEY_ID and PUMA_CLOUDWATCH_AWS_SECRET_ACCESS_KEY env vars to configure an AWS access key
8
+ - [#12](https://github.com/tongueroo/puma-cloudwatch/pull/12) http tcp port support also
9
+
10
+ ## [0.4.8] - 2023-02-24
11
+ - [#10](https://github.com/tongueroo/puma-cloudwatch/pull/10) fix region if check
12
+ - loosen development dependencies
13
+
14
+ ## [0.4.7] - 2023-02-24
15
+ - [#9](https://github.com/tongueroo/puma-cloudwatch/pull/9) fix region if check
16
+
17
+ ## [0.4.6] - 2023-01-05
18
+ - [#7](https://github.com/tongueroo/puma-cloudwatch/pull/7) Add PUMA_CLOUDWATCH_AWS_REGION
19
+
6
20
  ## [0.4.5] - 2021-11-09
7
21
  - [#5](https://github.com/boltops-tools/puma-cloudwatch/pull/5) Enabling high-resolution Cloudwatch metrics if frequency is lower tha…
8
22
 
data/README.md CHANGED
@@ -37,6 +37,9 @@ PUMA\_CLOUDWATCH\_DIMENSION\_VALUE | CloudWatch metric dimension value | puma
37
37
  PUMA\_CLOUDWATCH\_ENABLED | Enables sending of the data to CloudWatch. | (unset)
38
38
  PUMA\_CLOUDWATCH\_FREQUENCY | How often to send data to CloudWatch in seconds. | 60
39
39
  PUMA\_CLOUDWATCH\_NAMESPACE | CloudWatch metric namespace | WebServer
40
+ PUMA\_CLOUDWATCH\_AWS\_REGION | CloudWatch metric AWS region | (unset)
41
+ PUMA\_CLOUDWATCH\_AWS\_ACCESS_KEY_ID | AWS access key ID | (unset)
42
+ PUMA\_CLOUDWATCH\_AWS\_SECRET_ACCESS_KEY | AWS secret access key | (unset)
40
43
  PUMA\_CLOUDWATCH\_MUTE\_START\_MESSAGE | Mutes the "puma-cloudwatch plugin" startup message | (unset)
41
44
 
42
45
  ### Sum and Frequency Normalization
@@ -59,10 +62,10 @@ And then execute:
59
62
 
60
63
  $ bundle
61
64
 
62
- In your `config/puma.rb`
63
-
64
65
  Add these 2 lines your `config/puma.rb`:
65
66
 
67
+ config/puma.rb
68
+
66
69
  ```ruby
67
70
  activate_control_app
68
71
  plugin :cloudwatch
@@ -74,10 +77,88 @@ It activates the puma control rack application, and enables the puma-cloudwatch
74
77
 
75
78
  Make sure that EC2 instance running the puma server has IAM permission to publish to CloudWatch. If you are using ECS, the default permissions for the ECS task should work.
76
79
 
80
+ Alternatively, you may configure an AWS Access Key ID and Secret Key with the `PUMA_CLOUDWATCH_AWS_ACCESS_KEY_ID` and `PUMA_CLOUDWATCH_AWS_SECRET_ACCESS_KEY` env variables.
81
+
77
82
  If are you using ECS awsvpc, make sure you have the task running on private subnets with a NAT. From the AWS docs: [Task Networking with the awsvpc Network Mode](https://docs.aws.amazon.com/en_pv/AmazonECS/latest/developerguide/task-networking.html)
78
83
 
79
84
  > The awsvpc network mode does not provide task ENIs with public IP addresses for tasks that use the EC2 launch type. To access the internet, tasks that use the EC2 launch type must be launched in a private subnet that is configured to use a NAT gateway.
80
85
 
86
+ ## How It Works: Internal Puma Stats Server
87
+
88
+ Puma has an internal server that has a stats endpoint. It runs on a unix socket by default. The puma-cloudwatch works by running continuous loop that polls this puma socket.
89
+
90
+ ### Debug Internal Puma Server: Socket
91
+
92
+ By default, the socket file is a random path and token. You can use `PUMA_CLOUDWATCH_DEBUG` to see the puma `control_url` and `control_auth_token`.
93
+
94
+ You'll see something like this:
95
+
96
+ $ PUMA_CLOUDWATCH_DEBUG=1 rail server
97
+ * Starting control server on unix:///tmp/puma-status-1689096041362-18083
98
+ Use Ctrl-C to stop
99
+ puma control_url unix:///tmp/puma-status-1689096041362-18083
100
+ puma control_auth_token 609a3fe77de470ad87eaaf0a28a4d22d
101
+
102
+ To test the socket
103
+
104
+ echo -e "GET /stats?token=62a21462ce921590337cfe8a2bf53505 HTTP/1.1\r\nHost: localhost\r\n\r\n" | socat - UNIX-CONNECT:/tmp/puma-status-1689095966545-17509
105
+
106
+ You can specify the path and disable the token to make it easier:
107
+
108
+ config/puma.rb
109
+
110
+ ```ruby
111
+ activate_control_app "unix://tmp/pumactl.sock", { no_token: true }
112
+ # another example with full path, note the additinal beginning /
113
+ # activate_control_app "unix:///full/path/tmp/pumactl.sock", { no_token: true }
114
+ plugin :cloudwatch
115
+ ```
116
+
117
+ Send a stats request to the socket with `socat`
118
+
119
+ $ echo -e "GET /stats HTTP/1.1\r\nHost: localhost\r\n\r\n" | socat - UNIX-CONNECT:tmp/pumactl.sock
120
+ HTTP/1.1 200 OK
121
+ Content-Type: application/json
122
+ Connection: close
123
+ Content-Length: 114
124
+
125
+ {"started_at":"2023-07-11T16:32:37Z","backlog":0,"running":5,"pool_capacity":5,"max_threads":5,"requests_count":0}
126
+
127
+ ### Debug Internal Puma Server: TCP Port
128
+
129
+ You can also use a tcp port instead.
130
+
131
+ config/puma.rb
132
+
133
+ ```ruby
134
+ activate_control_app "tcp://127.0.0.1:9293", { no_token: true }
135
+ plugin :cloudwatch
136
+ ```
137
+
138
+ You can see the stats with `curl`.
139
+
140
+ $ curl "localhost:9293/stats"
141
+ {"started_at":"2023-07-11T17:17:31Z","backlog":0,"running":5,"pool_capacity":5,"max_threads":5,"requests_count":0}
142
+
143
+ ### puma control-url option note
144
+
145
+ If you're calling puma directly, there's an option to specify the control url and token, example:
146
+
147
+ $ puma --control-url tcp://127.0.0.1:9293 --control-token foo
148
+ * Listening on http://0.0.0.0:3000
149
+ * Starting control server on http://127.0.0.1:9293
150
+
151
+ This conflicts with activate the control app in the puma.rb
152
+
153
+ config/puma.rb
154
+
155
+ ```ruby
156
+ activate_control_app
157
+ plugin :cloudwatch
158
+ ```
159
+
160
+ So do not use those options when using this puma plugin.
161
+
81
162
  ## Contributing
82
163
 
83
164
  Bug reports and pull requests are welcome on GitHub at https://github.com/boltops-tools/puma-cloudwatch
@@ -1,21 +1,43 @@
1
1
  require "json"
2
2
  require "socket"
3
+ require "net/http"
4
+ require "uri"
3
5
 
4
6
  class PumaCloudwatch::Metrics
5
7
  class Fetcher
6
8
  def initialize(options={})
7
9
  @control_url = options[:control_url]
8
10
  @control_auth_token = options[:control_auth_token]
11
+ if ENV['PUMA_CLOUDWATCH_DEBUG']
12
+ puts "puma control_url #{@control_url}"
13
+ puts "puma control_auth_token #{@control_auth_token}"
14
+ end
9
15
  end
10
16
 
11
17
  def call
12
18
  body = with_retries do
13
- read_socket
19
+ read_data
14
20
  end
15
21
  JSON.parse(body.split("\n").last) # stats
16
22
  end
17
23
 
18
24
  private
25
+ def read_data
26
+ if @control_url.start_with?("unix://")
27
+ read_socket
28
+ else # starts with tcp://
29
+ read_http
30
+ end
31
+ end
32
+
33
+ def read_http
34
+ http_url = @control_url.sub('tcp://', 'http://')
35
+ url = "#{http_url}/stats?token=#{@control_auth_token}"
36
+ uri = URI.parse(url)
37
+ resp = Net::HTTP.get_response(uri)
38
+ resp.body
39
+ end
40
+
19
41
  def read_socket
20
42
  Socket.unix(@control_url.gsub('unix://', '')) do |socket|
21
43
  socket.print("GET /stats?token=#{@control_auth_token} HTTP/1.0\r\n\r\n")
@@ -18,6 +18,9 @@ class PumaCloudwatch::Metrics
18
18
  @dimension_value = ENV['PUMA_CLOUDWATCH_DIMENSION_VALUE'] || "puma"
19
19
  @frequency = Integer(ENV['PUMA_CLOUDWATCH_FREQUENCY'] || 60)
20
20
  @enabled = ENV['PUMA_CLOUDWATCH_ENABLED'] || false
21
+ @region = ENV['PUMA_CLOUDWATCH_AWS_REGION']
22
+ @access_key_id = ENV['PUMA_CLOUDWATCH_AWS_ACCESS_KEY_ID']
23
+ @secret_access_key = ENV['PUMA_CLOUDWATCH_AWS_SECRET_ACCESS_KEY']
21
24
  end
22
25
 
23
26
  def call
@@ -102,8 +105,20 @@ class PumaCloudwatch::Metrics
102
105
  !!@enabled
103
106
  end
104
107
 
108
+ def aws_credentials
109
+ return nil if @access_key_id.nil? || @access_key_id.empty? || @secret_access_key.nil? || @secret_access_key.empty?
110
+
111
+ @aws_credentials ||= Aws::Credentials.new(
112
+ @access_key_id,
113
+ @secret_access_key
114
+ )
115
+ end
116
+
105
117
  def cloudwatch
106
- @cloudwatch ||= Aws::CloudWatch::Client.new
118
+ @cloudwatch ||= Aws::CloudWatch::Client.new({
119
+ region: @region,
120
+ credentials: aws_credentials
121
+ }.compact)
107
122
  rescue Aws::Errors::MissingRegionError => e
108
123
  # Happens when:
109
124
  # 1. ~/.aws/config is not also setup locally
@@ -1,3 +1,3 @@
1
1
  module PumaCloudwatch
2
- VERSION = "0.4.5"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
23
23
 
24
24
  spec.add_dependency "aws-sdk-cloudwatch"
25
25
 
26
- spec.add_development_dependency "bundler", "~> 2.0"
27
- spec.add_development_dependency "rake", "~> 10.0"
28
- spec.add_development_dependency "rspec", "~> 3.0"
26
+ spec.add_development_dependency "bundler"
27
+ spec.add_development_dependency "rake"
28
+ spec.add_development_dependency "rspec"
29
29
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puma-cloudwatch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.5
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tung Nguyen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-11-09 00:00:00.000000000 Z
11
+ date: 2023-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-cloudwatch
@@ -28,44 +28,44 @@ dependencies:
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '2.0'
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '2.0'
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '10.0'
47
+ version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '10.0'
54
+ version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '3.0'
61
+ version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '3.0'
68
+ version: '0'
69
69
  description:
70
70
  email:
71
71
  - tongueroo@gmail.com
@@ -114,7 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
114
  - !ruby/object:Gem::Version
115
115
  version: '0'
116
116
  requirements: []
117
- rubygems_version: 3.1.6
117
+ rubygems_version: 3.4.10
118
118
  signing_key:
119
119
  specification_version: 4
120
120
  summary: Puma plugin sends puma stats to CloudWatch