aws-embedded-metrics-customink 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +29 -23
- data/README.md +19 -4
- data/lib/aws-embedded-metrics-customink/config.rb +17 -3
- data/lib/aws-embedded-metrics-customink/logger.rb +15 -10
- data/lib/aws-embedded-metrics-customink/sinks/sink_error.rb +9 -0
- data/lib/aws-embedded-metrics-customink/sinks/tcp.rb +93 -0
- data/lib/aws-embedded-metrics-customink/sinks.rb +3 -0
- data/lib/aws-embedded-metrics-customink/units.rb +49 -0
- data/lib/aws-embedded-metrics-customink/version.rb +1 -1
- data/lib/aws-embedded-metrics-customink.rb +1 -0
- metadata +9 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1cc2867474c435e6c5de18f3c599aeffd9f589b0164e9659fecf4d26ecda8478
|
4
|
+
data.tar.gz: a5a7bd3e0c2f4bf710343e1f54707d69a79c889ecf38025ac9106b7fcac44cd0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e4021d0eb717b34bd6f25421c4fc39ea65138570ace643fabdd2eac2551155314310eb2c44f7bd2755bd4a70ea51e6dde4d12e68c629b492a0e05ae9c1a87bea
|
7
|
+
data.tar.gz: d41ed4bf3b8ba2f0b3cbcb5d8eb5bef2b4e214cf41ce61deb151cefdb206db7a94eda3f6a3886dcff9d615a26a58be0901f6913bb7345151ddbb0c8943a0c98c
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,22 @@
|
|
3
3
|
|
4
4
|
See this http://keepachangelog.com link for information on how we want this documented formatted.
|
5
5
|
|
6
|
+
## v0.8.0
|
7
|
+
|
8
|
+
### Added
|
9
|
+
|
10
|
+
- New TCP Sink.
|
11
|
+
- Support for `LogGroupName` and `LogStreamName`.
|
12
|
+
- New `Metrics::Units` constants.
|
13
|
+
|
14
|
+
## v0.7.0
|
15
|
+
|
16
|
+
### Added
|
17
|
+
|
18
|
+
- A new `Tcp` sink is added. The `Tcp` sink can send EMF messages to any valid TCP endpoint.
|
19
|
+
- `tcp-client` will be required at runtime if you use the `Tcp` sink. Originally a small hand-written TCP client was used but it proved unreliable and well outside the scope of this library.
|
20
|
+
- Added the new `Units` class for easy reference to the accepted metric units.
|
21
|
+
|
6
22
|
## v0.6.0
|
7
23
|
|
8
24
|
### Fixed
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,41 +1,46 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
aws-embedded-metrics-customink (0.
|
4
|
+
aws-embedded-metrics-customink (0.8.0)
|
5
5
|
concurrent-ruby
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
ast (2.4.
|
10
|
+
ast (2.4.2)
|
11
11
|
coderay (1.1.3)
|
12
|
-
concurrent-ruby (1.1.
|
12
|
+
concurrent-ruby (1.1.10)
|
13
|
+
json (2.6.3)
|
13
14
|
method_source (1.0.0)
|
14
|
-
minitest (5.
|
15
|
-
mocha (
|
16
|
-
|
17
|
-
|
15
|
+
minitest (5.17.0)
|
16
|
+
mocha (2.0.2)
|
17
|
+
ruby2_keywords (>= 0.0.5)
|
18
|
+
parallel (1.22.1)
|
19
|
+
parser (3.2.0.0)
|
18
20
|
ast (~> 2.4.1)
|
19
|
-
pry (0.
|
21
|
+
pry (0.14.2)
|
20
22
|
coderay (~> 1.1)
|
21
23
|
method_source (~> 1.0)
|
22
|
-
rainbow (3.
|
23
|
-
rake (13.0.
|
24
|
-
regexp_parser (
|
25
|
-
rexml (3.2.
|
26
|
-
rubocop (
|
24
|
+
rainbow (3.1.1)
|
25
|
+
rake (13.0.6)
|
26
|
+
regexp_parser (2.6.1)
|
27
|
+
rexml (3.2.5)
|
28
|
+
rubocop (1.43.0)
|
29
|
+
json (~> 2.3)
|
27
30
|
parallel (~> 1.10)
|
28
|
-
parser (>= 2.
|
31
|
+
parser (>= 3.2.0.0)
|
29
32
|
rainbow (>= 2.2.2, < 4.0)
|
30
|
-
regexp_parser (>= 1.
|
31
|
-
rexml
|
32
|
-
rubocop-ast (>=
|
33
|
+
regexp_parser (>= 1.8, < 3.0)
|
34
|
+
rexml (>= 3.2.5, < 4.0)
|
35
|
+
rubocop-ast (>= 1.24.1, < 2.0)
|
33
36
|
ruby-progressbar (~> 1.7)
|
34
|
-
unicode-display_width (>=
|
35
|
-
rubocop-ast (
|
36
|
-
parser (>=
|
37
|
-
ruby-progressbar (1.
|
38
|
-
|
37
|
+
unicode-display_width (>= 2.4.0, < 3.0)
|
38
|
+
rubocop-ast (1.24.1)
|
39
|
+
parser (>= 3.1.1.0)
|
40
|
+
ruby-progressbar (1.11.0)
|
41
|
+
ruby2_keywords (0.0.5)
|
42
|
+
tcp-client (0.11.4)
|
43
|
+
unicode-display_width (2.4.2)
|
39
44
|
|
40
45
|
PLATFORMS
|
41
46
|
ruby
|
@@ -47,6 +52,7 @@ DEPENDENCIES
|
|
47
52
|
pry
|
48
53
|
rake
|
49
54
|
rubocop
|
55
|
+
tcp-client
|
50
56
|
|
51
57
|
BUNDLED WITH
|
52
|
-
2.
|
58
|
+
2.3.5
|
data/README.md
CHANGED
@@ -13,10 +13,8 @@ Pulled from these two projects using the [Embedded Metric Format Specification](
|
|
13
13
|
|
14
14
|
However, unlike these projects, we differ in the following ways. Again, contributions are very much welcome if you want to see more or change this.
|
15
15
|
|
16
|
-
* Initial focus on Lambda.
|
17
|
-
*
|
18
|
-
- `LogGroupName`
|
19
|
-
- `LogStreamName`
|
16
|
+
* Initial focus on Lambda. A TCP sink has been added, but no UDP sink exists.
|
17
|
+
* No default Dimensions or Configuration for:
|
20
18
|
- `ServiceName`
|
21
19
|
- `ServiceType`
|
22
20
|
|
@@ -29,11 +27,19 @@ gem 'aws-embedded-metrics-customink'
|
|
29
27
|
```
|
30
28
|
## Usage
|
31
29
|
|
30
|
+
If using outside of Rails, require the gem:
|
31
|
+
```ruby
|
32
|
+
require 'aws-embedded-metrics-customink'
|
33
|
+
```
|
34
|
+
|
32
35
|
Simple configuration:
|
33
36
|
|
34
37
|
```ruby
|
35
38
|
Aws::Embedded::Metrics.configure do |c|
|
36
39
|
c.namespace = 'MyApplication'
|
40
|
+
# Optional
|
41
|
+
c.log_group_name = 'MyLogGroup'
|
42
|
+
c.log_stream_name = 'MyLogStream-UniqueID'
|
37
43
|
end
|
38
44
|
```
|
39
45
|
|
@@ -45,6 +51,15 @@ Aws::Embedded::Metrics.configure do |c|
|
|
45
51
|
end
|
46
52
|
```
|
47
53
|
|
54
|
+
Using the `Tcp` sink to write over a network:
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
Aws::Embedded::Metrics.configure do |c|
|
58
|
+
c.sink = Aws::Embedded::Metrics::Sinks::Tcp.new(conn_str: "tcp://localhost:25888",
|
59
|
+
logger: Rails.logger)
|
60
|
+
end
|
61
|
+
```
|
62
|
+
|
48
63
|
Usage is in a scope block. All metrics are flushed afterward
|
49
64
|
|
50
65
|
```ruby
|
@@ -22,7 +22,10 @@ module Aws
|
|
22
22
|
|
23
23
|
class Configuration
|
24
24
|
|
25
|
-
attr_writer :
|
25
|
+
attr_writer :log_group_name,
|
26
|
+
:log_stream_name,
|
27
|
+
:namespace,
|
28
|
+
:sink
|
26
29
|
|
27
30
|
def reconfigure
|
28
31
|
instance_variables.each { |var| instance_variable_set var, nil }
|
@@ -30,16 +33,27 @@ module Aws
|
|
30
33
|
self
|
31
34
|
end
|
32
35
|
|
36
|
+
def log_group_name
|
37
|
+
return @log_group_name if defined?(@log_group_name)
|
38
|
+
|
39
|
+
ENV.fetch('AWS_EMF_LOG_GROUP_NAME', nil)
|
40
|
+
end
|
41
|
+
|
42
|
+
def log_stream_name
|
43
|
+
return @log_stream_name if defined?(@log_stream_name)
|
44
|
+
|
45
|
+
ENV.fetch('AWS_EMF_LOG_STREAM_NAME', nil)
|
46
|
+
end
|
47
|
+
|
33
48
|
def namespace
|
34
49
|
return @namespace if defined?(@namespace)
|
35
50
|
|
36
|
-
ENV
|
51
|
+
ENV.fetch('AWS_EMF_NAMESPACE', 'aws-embedded-metrics')
|
37
52
|
end
|
38
53
|
|
39
54
|
def sink
|
40
55
|
@sink ||= DEFAULT_SINK.new
|
41
56
|
end
|
42
|
-
|
43
57
|
end
|
44
58
|
end
|
45
59
|
end
|
@@ -5,6 +5,8 @@ module Aws
|
|
5
5
|
|
6
6
|
def initialize(sink = Config.config.sink)
|
7
7
|
@sink = sink
|
8
|
+
@log_group_name = Config.config.log_group_name
|
9
|
+
@log_stream_name = Config.config.log_stream_name
|
8
10
|
@namespace = Config.config.namespace
|
9
11
|
@dimensions = Concurrent::Array.new
|
10
12
|
@metrics = Concurrent::Array.new
|
@@ -50,17 +52,20 @@ module Aws
|
|
50
52
|
end
|
51
53
|
|
52
54
|
def message
|
55
|
+
aws = {
|
56
|
+
'Timestamp' => timestamp,
|
57
|
+
'CloudWatchMetrics' => [{
|
58
|
+
'Namespace' => @namespace,
|
59
|
+
'Dimensions' => [@dimensions.map(&:keys).flatten],
|
60
|
+
'Metrics' => @metrics
|
61
|
+
}]
|
62
|
+
}
|
63
|
+
|
64
|
+
aws['LogGroupName'] = @log_group_name if @log_group_name
|
65
|
+
aws['LogStreamName'] = @log_stream_name if @log_stream_name
|
66
|
+
|
53
67
|
{
|
54
|
-
'_aws' =>
|
55
|
-
'Timestamp' => timestamp,
|
56
|
-
'CloudWatchMetrics' => [
|
57
|
-
{
|
58
|
-
'Namespace' => @namespace,
|
59
|
-
'Dimensions' => [@dimensions.map(&:keys).flatten],
|
60
|
-
'Metrics' => @metrics
|
61
|
-
}
|
62
|
-
]
|
63
|
-
}
|
68
|
+
'_aws' => aws
|
64
69
|
}.tap do |m|
|
65
70
|
@dimensions.each { |dim| m.merge!(dim) }
|
66
71
|
m.merge!(@properties)
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
gem 'tcp-client'
|
4
|
+
require 'tcp-client'
|
5
|
+
|
6
|
+
module Aws
|
7
|
+
module Embedded
|
8
|
+
module Metrics
|
9
|
+
module Sinks
|
10
|
+
#
|
11
|
+
# Create a sink that will communicate to a CloudWatch Log Agent over a TCP connection.
|
12
|
+
#
|
13
|
+
# See https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Embedded_Metric_Format_Generation_CloudWatch_Agent.html
|
14
|
+
# for configuration information
|
15
|
+
class Tcp
|
16
|
+
AWS_EMF_AGENT_ENDPOINT_ENV_VAR = 'AWS_EMF_AGENT_ENDPOINT'
|
17
|
+
attr_reader :queue
|
18
|
+
attr :client_opts
|
19
|
+
|
20
|
+
#
|
21
|
+
# Create a new TCP sink. It will use the +AWS_EMF_AGENT_ENDPOINT+ environment variable by default to
|
22
|
+
# connect to a CloudWatch Metric Agent.
|
23
|
+
#
|
24
|
+
# @param conn_str [String] A connection string, formatted like 'tcp://127.0.0.1:25888'.
|
25
|
+
# @param conn_timeout_secs [Numeric] The number of seconds before timing out the connection to the agent.
|
26
|
+
# @param write_timeout_secs [Numeric] The number of seconds to wait before timing out a write.
|
27
|
+
# @param logger [Logger] A standard Ruby logger to propagate warnings and errors.
|
28
|
+
# Suggested to use Rails.logger.
|
29
|
+
def initialize(conn_str: ENV.fetch(AWS_EMF_AGENT_ENDPOINT_ENV_VAR, nil),
|
30
|
+
conn_timeout_secs: 10,
|
31
|
+
write_timeout_secs: 10,
|
32
|
+
logger: nil)
|
33
|
+
if conn_str.nil?
|
34
|
+
raise Sinks::Error, "Must specify a connection string or set environment variable #{AWS_EMF_AGENT_ENDPOINT_ENV_VAR}"
|
35
|
+
end
|
36
|
+
|
37
|
+
@logger = logger
|
38
|
+
@cw_agent_uri = URI.parse(conn_str)
|
39
|
+
if @cw_agent_uri.scheme != 'tcp' || !@cw_agent_uri.host || !@cw_agent_uri.port
|
40
|
+
raise Sinks::Error, "Expected connection string to be in format tcp://<host>:<port>, got '#{conn_str}'"
|
41
|
+
end
|
42
|
+
|
43
|
+
@client_opts = TCPClient::Configuration.create(
|
44
|
+
buffered: true,
|
45
|
+
keep_alive: true,
|
46
|
+
reverse_lookup: true,
|
47
|
+
connect_timeout: conn_timeout_secs,
|
48
|
+
write_timeout: write_timeout_secs
|
49
|
+
)
|
50
|
+
@conn = nil
|
51
|
+
end
|
52
|
+
|
53
|
+
def log_warn(msg)
|
54
|
+
@logger&.warn(msg)
|
55
|
+
end
|
56
|
+
|
57
|
+
def log_err(msg)
|
58
|
+
@logger&.error(msg)
|
59
|
+
end
|
60
|
+
|
61
|
+
def create_conn(host, port, opts)
|
62
|
+
TCPClient.open("#{host}:#{port}", opts)
|
63
|
+
end
|
64
|
+
|
65
|
+
def connection
|
66
|
+
@conn = create_conn(@cw_agent_uri.host, @cw_agent_uri.port, @client_opts) if @conn.nil? || @conn.closed?
|
67
|
+
@conn
|
68
|
+
end
|
69
|
+
|
70
|
+
def send_message(message)
|
71
|
+
retries = 2
|
72
|
+
conn = nil
|
73
|
+
begin
|
74
|
+
conn = connection
|
75
|
+
conn.write(message)
|
76
|
+
rescue Errno::ECONNREFUSED
|
77
|
+
conn.close unless conn.nil? || conn.closed?
|
78
|
+
log_warn("Could not connect to CloudWatch Agent at #{@cw_agent_uri.scheme}://#{@cw_agent_uri.host}:#{@cw_agent_uri.port}")
|
79
|
+
retries -= 1
|
80
|
+
retry if retries >= 0
|
81
|
+
rescue StandardError => e
|
82
|
+
log_err("#{e.class}: #{e.message}: #{e.backtrace.join("\n")}")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def accept(message)
|
87
|
+
send_message("#{JSON.dump(message)}\n")
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Aws
|
4
|
+
module Embedded
|
5
|
+
module Metrics
|
6
|
+
class Units
|
7
|
+
# Time
|
8
|
+
SECONDS = 'Seconds'
|
9
|
+
MICROSECONDS = 'Microseconds'
|
10
|
+
MILLISECONDS = 'Milliseconds'
|
11
|
+
|
12
|
+
# Size
|
13
|
+
BYTES = 'Bytes'
|
14
|
+
KILOBYTES = 'Kilobytes'
|
15
|
+
MEGABYTES = 'Megabytes'
|
16
|
+
GIGABYTES = 'Gigabytes'
|
17
|
+
TERABYTES = 'Terabytes'
|
18
|
+
|
19
|
+
BITS = 'Bits'
|
20
|
+
KILOBITS = 'Kilobits'
|
21
|
+
MEGABITS = 'Megabits'
|
22
|
+
GIGABITS = 'Gigabits'
|
23
|
+
TERABITS = 'Terabits'
|
24
|
+
|
25
|
+
# Simple units
|
26
|
+
PERCENT = 'Percent'
|
27
|
+
COUNT = 'Count'
|
28
|
+
|
29
|
+
# Size over time
|
30
|
+
BYTES_SECOND = "#{BYTES}/Second"
|
31
|
+
KILOBYTES_SECOND = "#{KILOBYTES}/Second"
|
32
|
+
MEGABYTES_SECOND = "#{MEGABYTES}/Second"
|
33
|
+
GIGABYTES_SECOND = "#{GIGABYTES}/Second"
|
34
|
+
TERABYTES_SECOND = "#{TERABYTES}/Second"
|
35
|
+
|
36
|
+
BITS_SECOND = "#{BITS}/Second"
|
37
|
+
KILOBITS_SECOND = "#{KILOBITS}/Second"
|
38
|
+
MEGABITS_SECOND = "#{MEGABITS}/Second"
|
39
|
+
GIGABITS_SECOND = "#{GIGABITS}/Second"
|
40
|
+
TERABITS_SECOND = "#{TERABITS}/Second"
|
41
|
+
|
42
|
+
COUNT_SECOND = "#{COUNT}/Second"
|
43
|
+
|
44
|
+
# Unit-less
|
45
|
+
NONE = 'None'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -6,6 +6,7 @@ require 'aws-embedded-metrics-customink/version'
|
|
6
6
|
require 'aws-embedded-metrics-customink/sinks'
|
7
7
|
require 'aws-embedded-metrics-customink/config'
|
8
8
|
require 'aws-embedded-metrics-customink/logger'
|
9
|
+
require 'aws-embedded-metrics-customink/units'
|
9
10
|
require 'aws-embedded-metrics-customink/instance' if defined?(Rails)
|
10
11
|
|
11
12
|
module Aws
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aws-embedded-metrics-customink
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ken Collins
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-04-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -54,7 +54,10 @@ files:
|
|
54
54
|
- lib/aws-embedded-metrics-customink/logger.rb
|
55
55
|
- lib/aws-embedded-metrics-customink/sinks.rb
|
56
56
|
- lib/aws-embedded-metrics-customink/sinks/logger.rb
|
57
|
+
- lib/aws-embedded-metrics-customink/sinks/sink_error.rb
|
57
58
|
- lib/aws-embedded-metrics-customink/sinks/stdout.rb
|
59
|
+
- lib/aws-embedded-metrics-customink/sinks/tcp.rb
|
60
|
+
- lib/aws-embedded-metrics-customink/units.rb
|
58
61
|
- lib/aws-embedded-metrics-customink/version.rb
|
59
62
|
homepage: https://github.com/customink/aws-embedded-metrics-customink
|
60
63
|
licenses:
|
@@ -63,7 +66,7 @@ metadata:
|
|
63
66
|
homepage_uri: https://github.com/customink/aws-embedded-metrics-customink
|
64
67
|
source_code_uri: https://github.com/customink/aws-embedded-metrics-customink
|
65
68
|
changelog_uri: https://github.com/customink/aws-embedded-metrics-customink/blob/master/CHANGELOG.md
|
66
|
-
post_install_message:
|
69
|
+
post_install_message:
|
67
70
|
rdoc_options: []
|
68
71
|
require_paths:
|
69
72
|
- lib
|
@@ -78,8 +81,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
78
81
|
- !ruby/object:Gem::Version
|
79
82
|
version: '0'
|
80
83
|
requirements: []
|
81
|
-
rubygems_version: 3.
|
82
|
-
signing_key:
|
84
|
+
rubygems_version: 3.4.7
|
85
|
+
signing_key:
|
83
86
|
specification_version: 4
|
84
87
|
summary: Amazon CloudWatch Embedded Metric Format Client Library
|
85
88
|
test_files: []
|