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 +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +82 -2
- data/lib/puma_cloudwatch/metrics/fetcher.rb +23 -1
- data/lib/puma_cloudwatch/metrics/sender.rb +15 -6
- data/lib/puma_cloudwatch/version.rb +1 -1
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 310c3534fa2d00a6da76f26f6cbe908ac842ced68f02d49fb0ff4f7d0922e95b
|
4
|
+
data.tar.gz: 0ef2173e64a9517866be68af190256529184f40aacb6830c0f93960203dc2919
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
107
|
-
|
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
|
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
|
+
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-
|
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.
|
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: []
|