puma-cloudwatch 0.4.8 → 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: b0f5f9757f6fd2ca0da318c57d6e16f05072b2f7e004b7c67e863567e6a21feb
4
- data.tar.gz: 354658460c267d9a730fd297f3b42e1d5d19b162a9503679d9f5f0ed40776138
3
+ metadata.gz: 310c3534fa2d00a6da76f26f6cbe908ac842ced68f02d49fb0ff4f7d0922e95b
4
+ data.tar.gz: 0ef2173e64a9517866be68af190256529184f40aacb6830c0f93960203dc2919
5
5
  SHA512:
6
- metadata.gz: 28412c44a0d354767ef34d855f86560cb6f467d72ac1721897e4302a393f4d05fc3b5d681490008435c105c84c77b4d236662485282cffbb36df7e53fa662d85
7
- data.tar.gz: 20437ec6faed3244a69f6ff90ba5cd6e4c1da64990509c222275133e588c718bd31dda8accb6c725946b486df474376ca78740bc5ba00cedd39d56c4258532f2
6
+ metadata.gz: 44a1e9b69e28968779ed60237c102a21e8d1bb3729a6ee5f013932efab906f00f723694b004e585f6b285db6ffadd2f1c1c935ba4d2a0eaff78fbf434ef52604
7
+ data.tar.gz: 21f44b53b79331912008bec96ac4c27b3903d16d21f79ae22ee4259ae8a8ba25fa16d79b5d4724ac9be2818097743ccc9abb65a209a344b502c32747626ef019
data/CHANGELOG.md CHANGED
@@ -3,6 +3,10 @@
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
+
6
10
  ## [0.4.8] - 2023-02-24
7
11
  - [#10](https://github.com/tongueroo/puma-cloudwatch/pull/10) fix region if check
8
12
  - loosen development dependencies
data/README.md CHANGED
@@ -38,6 +38,8 @@ 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
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)
41
43
  PUMA\_CLOUDWATCH\_MUTE\_START\_MESSAGE | Mutes the "puma-cloudwatch plugin" startup message | (unset)
42
44
 
43
45
  ### Sum and Frequency Normalization
@@ -60,10 +62,10 @@ And then execute:
60
62
 
61
63
  $ bundle
62
64
 
63
- In your `config/puma.rb`
64
-
65
65
  Add these 2 lines your `config/puma.rb`:
66
66
 
67
+ config/puma.rb
68
+
67
69
  ```ruby
68
70
  activate_control_app
69
71
  plugin :cloudwatch
@@ -75,10 +77,88 @@ It activates the puma control rack application, and enables the puma-cloudwatch
75
77
 
76
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.
77
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
+
78
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)
79
83
 
80
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.
81
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
+
82
162
  ## Contributing
83
163
 
84
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")
@@ -19,6 +19,8 @@ class PumaCloudwatch::Metrics
19
19
  @frequency = Integer(ENV['PUMA_CLOUDWATCH_FREQUENCY'] || 60)
20
20
  @enabled = ENV['PUMA_CLOUDWATCH_ENABLED'] || false
21
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']
22
24
  end
23
25
 
24
26
  def call
@@ -103,13 +105,20 @@ class PumaCloudwatch::Metrics
103
105
  !!@enabled
104
106
  end
105
107
 
106
- def cloudwatch
107
- @cloudwatch ||= if @region.nil? || @region.empty?
108
- Aws::CloudWatch::Client.new
109
- else
110
- Aws::CloudWatch::Client.new(region: @region)
111
- end
108
+ def aws_credentials
109
+ return nil if @access_key_id.nil? || @access_key_id.empty? || @secret_access_key.nil? || @secret_access_key.empty?
112
110
 
111
+ @aws_credentials ||= Aws::Credentials.new(
112
+ @access_key_id,
113
+ @secret_access_key
114
+ )
115
+ end
116
+
117
+ def cloudwatch
118
+ @cloudwatch ||= Aws::CloudWatch::Client.new({
119
+ region: @region,
120
+ credentials: aws_credentials
121
+ }.compact)
113
122
  rescue Aws::Errors::MissingRegionError => e
114
123
  # Happens when:
115
124
  # 1. ~/.aws/config is not also setup locally
@@ -1,3 +1,3 @@
1
1
  module PumaCloudwatch
2
- VERSION = "0.4.8"
2
+ VERSION = "0.5.0"
3
3
  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.8
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tung Nguyen
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-02-24 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
@@ -66,7 +66,7 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
- description:
69
+ description:
70
70
  email:
71
71
  - tongueroo@gmail.com
72
72
  executables: []
@@ -99,7 +99,7 @@ homepage: https://github.com/boltops-tools/puma-cloudwatch
99
99
  licenses:
100
100
  - MIT
101
101
  metadata: {}
102
- post_install_message:
102
+ post_install_message:
103
103
  rdoc_options: []
104
104
  require_paths:
105
105
  - lib
@@ -114,8 +114,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
114
  - !ruby/object:Gem::Version
115
115
  version: '0'
116
116
  requirements: []
117
- rubygems_version: 3.3.26
118
- signing_key:
117
+ rubygems_version: 3.4.10
118
+ signing_key:
119
119
  specification_version: 4
120
120
  summary: Puma plugin sends puma stats to CloudWatch
121
121
  test_files: []