fluent-plugin-cloudwatch-put-timestamp 0.1.1
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 +7 -0
- data/.gitignore +11 -0
- data/.travis.yml +6 -0
- data/Gemfile +3 -0
- data/LICENSE +21 -0
- data/README.md +203 -0
- data/Rakefile +13 -0
- data/fluent-plugin-cloudwatch-put.gemspec +29 -0
- data/lib/fluent/plugin/out_cloudwatch_put.rb +269 -0
- data/test/helper.rb +9 -0
- data/test/plugin/test_out_cloudwatch_put.rb +334 -0
- metadata +145 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: df3cfc631ba9a373ab05582f82a5f1b256002562
|
4
|
+
data.tar.gz: 6e0692d11405e3cce5774af80fa75b77c16977db
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8a75016c5f2720893a4da6d3b52030860ebdb79cf849b9fcc77eb506d04e49a4e6a5ab7c3ff8023293b2def8c793fa6e9a9661dcfeca50d7665342629ed524bc
|
7
|
+
data.tar.gz: e982668c37b2ea834506072af62791732bc5ba188545d0fde135b022883ced021c5bb4a168b7c497eaf57e6ea738fd6a14a33abe1f11a632029161fee553eeb1
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2017 joker1007
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,203 @@
|
|
1
|
+
# fluent-plugin-cloudwatch-put
|
2
|
+
[](https://travis-ci.org/joker1007/fluent-plugin-cloudwatch-put)
|
3
|
+
|
4
|
+
[Fluentd](http://fluentd.org/) output plugin to put metric data to AWS CloudWatch.
|
5
|
+
|
6
|
+
This plugin for fluentd-0.14.x or later.
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
### RubyGems
|
11
|
+
|
12
|
+
```
|
13
|
+
$ gem install fluent-plugin-cloudwatch-put
|
14
|
+
```
|
15
|
+
|
16
|
+
### Bundler
|
17
|
+
|
18
|
+
Add following line to your Gemfile:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
gem "fluent-plugin-cloudwatch-put"
|
22
|
+
```
|
23
|
+
|
24
|
+
And then execute:
|
25
|
+
|
26
|
+
```
|
27
|
+
$ bundle
|
28
|
+
```
|
29
|
+
|
30
|
+
## Plugin helpers
|
31
|
+
|
32
|
+
* inject
|
33
|
+
|
34
|
+
* See also: Fluent::Plugin::Output
|
35
|
+
|
36
|
+
## Configuration
|
37
|
+
|
38
|
+
```
|
39
|
+
<match cloudwatch.metric_name>
|
40
|
+
@type cloudwatch_put
|
41
|
+
|
42
|
+
<buffer tag, key1>
|
43
|
+
path cloudwatch.*.buffer
|
44
|
+
|
45
|
+
flush_interval 1m
|
46
|
+
</buffer>
|
47
|
+
|
48
|
+
aws_key_id "#{ENV["AWS_ACCESS_KEY_ID"]}"
|
49
|
+
aws_sec_key "#{ENV["AWS_SECRET_ACCESS_KEY"]}"
|
50
|
+
|
51
|
+
region ap-northeast-1
|
52
|
+
|
53
|
+
namespace "Dummy/Namespace"
|
54
|
+
metric_name ${tag[1]}
|
55
|
+
unit Count
|
56
|
+
value_key value
|
57
|
+
|
58
|
+
use_statistic_sets
|
59
|
+
|
60
|
+
<dimensions>
|
61
|
+
name method
|
62
|
+
value ${key1}
|
63
|
+
</dimensions>
|
64
|
+
</match>
|
65
|
+
```
|
66
|
+
|
67
|
+
### namespace (string) (required)
|
68
|
+
|
69
|
+
CloudWatch metric namespace (support placeholder)
|
70
|
+
|
71
|
+
### metric_name (string) (required)
|
72
|
+
|
73
|
+
CloudWatch metric name (support placeholder)
|
74
|
+
|
75
|
+
### key_as_metric_name (bool) (optional)
|
76
|
+
|
77
|
+
Use record key as metric name
|
78
|
+
|
79
|
+
Default value: `false`
|
80
|
+
|
81
|
+
### unit (string) (required)
|
82
|
+
|
83
|
+
CloudWatch metric unit (support placeholder)
|
84
|
+
|
85
|
+
### value_key (array\<string\>) (required)
|
86
|
+
|
87
|
+
Use this key as metric value
|
88
|
+
|
89
|
+
### storage_resolution (integer) (optional)
|
90
|
+
|
91
|
+
Cloudwatch storage resolution
|
92
|
+
|
93
|
+
Default value: `60`.
|
94
|
+
|
95
|
+
### use_statistic_sets (bool) (optional)
|
96
|
+
|
97
|
+
If this is true, aggregates record chunk before put metric
|
98
|
+
|
99
|
+
|
100
|
+
### \<dimensions\> section (required) (multiple)
|
101
|
+
|
102
|
+
#### name (string) (required)
|
103
|
+
|
104
|
+
Dimension name (support placeholder)
|
105
|
+
|
106
|
+
#### key (string) (optional)
|
107
|
+
|
108
|
+
Use this key as dimension value. If use_statistic_sets is true, this param is not supported. Use `value`
|
109
|
+
|
110
|
+
#### value (string) (optional)
|
111
|
+
|
112
|
+
Use static value as dimension value (support placeholder)
|
113
|
+
|
114
|
+
|
115
|
+
### \<buffer\> section (optional) (multiple)
|
116
|
+
|
117
|
+
#### chunk_limit_size (optional)
|
118
|
+
|
119
|
+
Default value: `30720`.
|
120
|
+
|
121
|
+
#### chunk_limit_records (optional)
|
122
|
+
|
123
|
+
Default value: `20`.
|
124
|
+
|
125
|
+
## Configuration for Authentication
|
126
|
+
|
127
|
+
### aws_key_id (string) (optional)
|
128
|
+
|
129
|
+
AWS access key id
|
130
|
+
|
131
|
+
### aws_sec_key (string) (optional)
|
132
|
+
|
133
|
+
AWS secret key.
|
134
|
+
|
135
|
+
### region (string) (optional)
|
136
|
+
|
137
|
+
region name
|
138
|
+
|
139
|
+
Default value: `us-east-1`.
|
140
|
+
|
141
|
+
### proxy_uri (string) (optional)
|
142
|
+
|
143
|
+
URI of proxy environment
|
144
|
+
|
145
|
+
### \<assume_role_credentials\> section (optional) (single)
|
146
|
+
|
147
|
+
#### role_arn (string) (required)
|
148
|
+
|
149
|
+
The Amazon Resource Name (ARN) of the role to assume
|
150
|
+
|
151
|
+
#### role_session_name (string) (required)
|
152
|
+
|
153
|
+
An identifier for the assumed role session
|
154
|
+
|
155
|
+
#### policy (string) (optional)
|
156
|
+
|
157
|
+
An IAM policy in JSON format
|
158
|
+
|
159
|
+
#### duration_seconds (integer) (optional)
|
160
|
+
|
161
|
+
The duration, in seconds, of the role session (900-3600)
|
162
|
+
|
163
|
+
#### external_id (string) (optional)
|
164
|
+
|
165
|
+
A unique identifier that is used by third parties when assuming roles in their customers' accounts.
|
166
|
+
|
167
|
+
### \<instance_profile_credentials\> section (optional) (single)
|
168
|
+
|
169
|
+
#### retries (integer) (optional)
|
170
|
+
|
171
|
+
Number of times to retry when retrieving credentials
|
172
|
+
|
173
|
+
#### ip_address (string) (optional)
|
174
|
+
|
175
|
+
IP address (default:169.254.169.254)
|
176
|
+
|
177
|
+
#### port (integer) (optional)
|
178
|
+
|
179
|
+
Port number (default:80)
|
180
|
+
|
181
|
+
#### http_open_timeout (float) (optional)
|
182
|
+
|
183
|
+
Number of seconds to wait for the connection to open
|
184
|
+
|
185
|
+
#### http_read_timeout (float) (optional)
|
186
|
+
|
187
|
+
Number of seconds to wait for one block to be read
|
188
|
+
|
189
|
+
### \<shared_credentials\> section (optional) (single)
|
190
|
+
|
191
|
+
#### path (string) (optional)
|
192
|
+
|
193
|
+
Path to the shared file. (default: $HOME/.aws/credentials)
|
194
|
+
|
195
|
+
#### profile_name (string) (optional)
|
196
|
+
|
197
|
+
Profile name. Default to 'default' or ENV['AWS_PROFILE']
|
198
|
+
|
199
|
+
## Copyright
|
200
|
+
|
201
|
+
* Copyright(c) 2017- joker1007
|
202
|
+
* License
|
203
|
+
* MIT License
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require "bundler"
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require "rake/testtask"
|
5
|
+
|
6
|
+
Rake::TestTask.new(:test) do |t|
|
7
|
+
t.libs.push("lib", "test")
|
8
|
+
t.test_files = FileList["test/**/test_*.rb"]
|
9
|
+
t.verbose = true
|
10
|
+
t.warning = true
|
11
|
+
end
|
12
|
+
|
13
|
+
task default: [:test]
|
@@ -0,0 +1,29 @@
|
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
|
4
|
+
Gem::Specification.new do |spec|
|
5
|
+
spec.name = "fluent-plugin-cloudwatch-put-timestamp"
|
6
|
+
spec.version = "0.1.1"
|
7
|
+
spec.authors = [""]
|
8
|
+
|
9
|
+
spec.summary = %q{Cloudwatch put metric plugin for fluentd.}
|
10
|
+
spec.description = %q{Cloudwatch put metric plugin for fluentd.}
|
11
|
+
spec.homepage = "https://github.com/jmmgr/fluent-plugin-cloudwatch-put"
|
12
|
+
spec.license = "MIT"
|
13
|
+
|
14
|
+
test_files, files = `git ls-files -z`.split("\x0").partition do |f|
|
15
|
+
f.match(%r{^(test|spec|features)/})
|
16
|
+
end
|
17
|
+
spec.files = files
|
18
|
+
spec.executables = files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
spec.test_files = test_files
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.14"
|
23
|
+
spec.add_development_dependency "rake", "~> 12.0"
|
24
|
+
spec.add_development_dependency "test-unit", "~> 3.0"
|
25
|
+
spec.add_development_dependency "test-unit-rr"
|
26
|
+
|
27
|
+
spec.add_runtime_dependency "fluentd", [">= 0.14.10", "< 2"]
|
28
|
+
spec.add_runtime_dependency "aws-sdk-cloudwatch", "~> 1"
|
29
|
+
end
|
@@ -0,0 +1,269 @@
|
|
1
|
+
require "fluent/plugin/output"
|
2
|
+
require "aws-sdk-cloudwatch"
|
3
|
+
|
4
|
+
module Fluent
|
5
|
+
module Plugin
|
6
|
+
class CloudWatchPutOutput < Fluent::Plugin::Output
|
7
|
+
Fluent::Plugin.register_output("cloudwatch_put", self)
|
8
|
+
|
9
|
+
helpers :inject
|
10
|
+
|
11
|
+
# Credential Configs from fluent-plugin-s3
|
12
|
+
# Apache License, version 2.0
|
13
|
+
desc "AWS access key id"
|
14
|
+
config_param :aws_key_id, :string, default: nil, secret: true
|
15
|
+
desc "AWS secret key."
|
16
|
+
config_param :aws_sec_key, :string, default: nil, secret: true
|
17
|
+
config_section :assume_role_credentials, multi: false do
|
18
|
+
desc "The Amazon Resource Name (ARN) of the role to assume"
|
19
|
+
config_param :role_arn, :string, secret: true
|
20
|
+
desc "An identifier for the assumed role session"
|
21
|
+
config_param :role_session_name, :string
|
22
|
+
desc "An IAM policy in JSON format"
|
23
|
+
config_param :policy, :string, default: nil
|
24
|
+
desc "The duration, in seconds, of the role session (900-3600)"
|
25
|
+
config_param :duration_seconds, :integer, default: nil
|
26
|
+
desc "A unique identifier that is used by third parties when assuming roles in their customers' accounts."
|
27
|
+
config_param :external_id, :string, default: nil, secret: true
|
28
|
+
end
|
29
|
+
config_section :instance_profile_credentials, multi: false do
|
30
|
+
desc "Number of times to retry when retrieving credentials"
|
31
|
+
config_param :retries, :integer, default: nil
|
32
|
+
desc "IP address (default:169.254.169.254)"
|
33
|
+
config_param :ip_address, :string, default: nil
|
34
|
+
desc "Port number (default:80)"
|
35
|
+
config_param :port, :integer, default: nil
|
36
|
+
desc "Number of seconds to wait for the connection to open"
|
37
|
+
config_param :http_open_timeout, :float, default: nil
|
38
|
+
desc "Number of seconds to wait for one block to be read"
|
39
|
+
config_param :http_read_timeout, :float, default: nil
|
40
|
+
# config_param :delay, :integer or :proc, :default => nil
|
41
|
+
# config_param :http_degub_output, :io, :default => nil
|
42
|
+
end
|
43
|
+
config_section :shared_credentials, multi: false do
|
44
|
+
desc "Path to the shared file. (default: $HOME/.aws/credentials)"
|
45
|
+
config_param :path, :string, default: nil
|
46
|
+
desc "Profile name. Default to 'default' or ENV['AWS_PROFILE']"
|
47
|
+
config_param :profile_name, :string, default: nil
|
48
|
+
end
|
49
|
+
|
50
|
+
desc "region name"
|
51
|
+
config_param :region, :string, default: ENV["AWS_REGION"] || "us-east-1"
|
52
|
+
|
53
|
+
desc "URI of proxy environment"
|
54
|
+
config_param :proxy_uri, :string, default: nil
|
55
|
+
|
56
|
+
desc "CloudWatch metric namespace (support placeholder)"
|
57
|
+
config_param :namespace, :string
|
58
|
+
desc "CloudWatch metric name (support placeholder)"
|
59
|
+
config_param :metric_name, :string, default: nil
|
60
|
+
desc "Use keyname as metric name"
|
61
|
+
config_param :key_as_metric_name, :bool, default: false
|
62
|
+
desc "CloudWatch metric unit (support placeholder)"
|
63
|
+
config_param :unit, :string
|
64
|
+
|
65
|
+
desc "Definition of dimension"
|
66
|
+
config_section :dimensions, multi: true, required: false do
|
67
|
+
desc "Dimension name (support placeholder)"
|
68
|
+
config_param :name, :string
|
69
|
+
#desc "Use this key as dimension value. If use_statistic_sets is true, this param is not supported. Use `value`"
|
70
|
+
#config_param :key, :string, default: nil
|
71
|
+
desc "Use static value as dimension value (support placeholder)"
|
72
|
+
config_param :value, :string, default: nil
|
73
|
+
end
|
74
|
+
|
75
|
+
desc "Use this key as metric value"
|
76
|
+
config_param :value_key, :array, value_type: :string
|
77
|
+
|
78
|
+
desc "Cloudwatch storage resolution"
|
79
|
+
config_param :storage_resolution, :integer, default: 60
|
80
|
+
|
81
|
+
#desc "If this is true, aggregates record chunk before put metric"
|
82
|
+
#config_param :use_statistic_sets, :bool, default: false
|
83
|
+
|
84
|
+
config_section :buffer do
|
85
|
+
config_set_default :chunk_limit_size, 30 * 1024
|
86
|
+
config_set_default :chunk_limit_records, 20 # max record size of metric_data payload
|
87
|
+
end
|
88
|
+
|
89
|
+
attr_reader :cloudwatch
|
90
|
+
|
91
|
+
def configure(conf)
|
92
|
+
super
|
93
|
+
|
94
|
+
unless !!@metric_name ^ @key_as_metric_name
|
95
|
+
raise Fluent::ConfigError, "'Either 'metric_name'' or 'key_as_metric_name' must be set"
|
96
|
+
end
|
97
|
+
|
98
|
+
@send_all_key = false
|
99
|
+
if @value_key.size == 1 && @value_key[0] == "*"
|
100
|
+
@send_all_key = true
|
101
|
+
end
|
102
|
+
|
103
|
+
placeholder_params = "namespace=#{@namespace}/metric_name=#{@metric_name}/unit=#{@unit}"
|
104
|
+
placeholder_validate!(:cloudwatch_put, placeholder_params)
|
105
|
+
end
|
106
|
+
|
107
|
+
def multi_workers_ready?
|
108
|
+
true
|
109
|
+
end
|
110
|
+
|
111
|
+
def start
|
112
|
+
super
|
113
|
+
|
114
|
+
options = setup_credentials
|
115
|
+
options[:region] = @region if @region
|
116
|
+
options[:http_proxy] = @proxy_uri if @proxy_uri
|
117
|
+
log.on_trace do
|
118
|
+
options[:http_wire_trace] = true
|
119
|
+
options[:logger] = log
|
120
|
+
end
|
121
|
+
|
122
|
+
@cloudwatch = Aws::CloudWatch::Client.new(options)
|
123
|
+
end
|
124
|
+
|
125
|
+
def write(chunk)
|
126
|
+
# if @use_statistic_sets
|
127
|
+
# metric_data = build_statistic_metric_data(chunk)
|
128
|
+
# else
|
129
|
+
metric_data = build_metric_data(chunk)
|
130
|
+
# end
|
131
|
+
|
132
|
+
namespace = extract_placeholders(@namespace, chunk.metadata)
|
133
|
+
log.debug "Put metric to #{namespace}, count=#{metric_data.size}"
|
134
|
+
log.on_trace do
|
135
|
+
log.trace metric_data.to_json
|
136
|
+
end
|
137
|
+
@cloudwatch.put_metric_data({
|
138
|
+
namespace: namespace,
|
139
|
+
metric_data: metric_data,
|
140
|
+
})
|
141
|
+
end
|
142
|
+
|
143
|
+
private
|
144
|
+
|
145
|
+
def base_metric_data(meta)
|
146
|
+
{
|
147
|
+
unit: extract_placeholders(@unit, meta),
|
148
|
+
storage_resolution: @storage_resolution,
|
149
|
+
}
|
150
|
+
end
|
151
|
+
|
152
|
+
def build_metric_data(chunk)
|
153
|
+
meta = chunk.metadata
|
154
|
+
metric_data = []
|
155
|
+
chunk.msgpack_each do |(timestamp, record)|
|
156
|
+
record.each do |k, v|
|
157
|
+
next unless @value_key.include?(k) || @send_all_key
|
158
|
+
timestamp_aws = record['timestamp'] || timestamp
|
159
|
+
metric_name = @key_as_metric_name ? k : extract_placeholders(@metric_name, meta)
|
160
|
+
|
161
|
+
unless timestamp_aws.is_a? Fixnum
|
162
|
+
log.error "Invalid timestamp for metric_name #{metric_name} timestamp #{timestamp_aws} needs to be a number"
|
163
|
+
timestamp_aws = timestamp
|
164
|
+
end
|
165
|
+
|
166
|
+
metric_data << {
|
167
|
+
metric_name: metric_name,
|
168
|
+
unit: extract_placeholders(@unit, meta),
|
169
|
+
storage_resolution: @storage_resolution,
|
170
|
+
dimensions: record['dimensions'].map do |dk, dv|
|
171
|
+
{
|
172
|
+
name: dk,
|
173
|
+
value: dv
|
174
|
+
}
|
175
|
+
end,
|
176
|
+
value: v.to_f,
|
177
|
+
timestamp: Time.at(timestamp_aws)
|
178
|
+
}
|
179
|
+
end
|
180
|
+
end
|
181
|
+
metric_data
|
182
|
+
end
|
183
|
+
|
184
|
+
# def build_statistic_metric_data(chunk)
|
185
|
+
# meta = chunk.metadata
|
186
|
+
# values = []
|
187
|
+
# timestamps = []
|
188
|
+
# chunk.msgpack_each do |(timestamp, record)|
|
189
|
+
# record.each do |k, v|
|
190
|
+
# next unless @value_key.include?(k) || @send_all_key
|
191
|
+
# values << v.to_f
|
192
|
+
# end
|
193
|
+
# timestamps << timestamp
|
194
|
+
# end
|
195
|
+
|
196
|
+
# [
|
197
|
+
# base_metric_data(meta).merge({
|
198
|
+
# metric_name: extract_placeholders(@metric_name, meta),
|
199
|
+
# dimensions: @dimensions.map { |d|
|
200
|
+
# {
|
201
|
+
# name: extract_placeholders(d.name, meta),
|
202
|
+
# value: extract_placeholders(d.value, meta),
|
203
|
+
# }
|
204
|
+
# }.select { |d| !d[:name].empty? },
|
205
|
+
# statistic_values: {
|
206
|
+
# sample_count: values.size,
|
207
|
+
# sum: values.inject(&:+),
|
208
|
+
# minimum: values.min,
|
209
|
+
# maximum: values.max,
|
210
|
+
# },
|
211
|
+
# timestamp: Time.at(timestamps.max)
|
212
|
+
# })
|
213
|
+
# ]
|
214
|
+
# end
|
215
|
+
|
216
|
+
# Credential Configs from fluent-plugin-s3
|
217
|
+
# Apache License, version 2.0
|
218
|
+
def setup_credentials
|
219
|
+
options = {}
|
220
|
+
credentials_options = {}
|
221
|
+
case
|
222
|
+
when @aws_key_id && @aws_sec_key
|
223
|
+
options[:access_key_id] = @aws_key_id
|
224
|
+
options[:secret_access_key] = @aws_sec_key
|
225
|
+
when @assume_role_credentials
|
226
|
+
c = @assume_role_credentials
|
227
|
+
credentials_options[:role_arn] = c.role_arn
|
228
|
+
credentials_options[:role_session_name] = c.role_session_name
|
229
|
+
credentials_options[:policy] = c.policy if c.policy
|
230
|
+
credentials_options[:duration_seconds] = c.duration_seconds if c.duration_seconds
|
231
|
+
credentials_options[:external_id] = c.external_id if c.external_id
|
232
|
+
if @region
|
233
|
+
credentials_options[:client] = Aws::STS::Client.new(region: @region)
|
234
|
+
end
|
235
|
+
options[:credentials] = Aws::AssumeRoleCredentials.new(credentials_options)
|
236
|
+
when @instance_profile_credentials
|
237
|
+
c = @instance_profile_credentials
|
238
|
+
credentials_options[:retries] = c.retries if c.retries
|
239
|
+
credentials_options[:ip_address] = c.ip_address if c.ip_address
|
240
|
+
credentials_options[:port] = c.port if c.port
|
241
|
+
credentials_options[:http_open_timeout] = c.http_open_timeout if c.http_open_timeout
|
242
|
+
credentials_options[:http_read_timeout] = c.http_read_timeout if c.http_read_timeout
|
243
|
+
if ENV["AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"]
|
244
|
+
options[:credentials] = Aws::ECSCredentials.new(credentials_options)
|
245
|
+
else
|
246
|
+
options[:credentials] = Aws::InstanceProfileCredentials.new(credentials_options)
|
247
|
+
end
|
248
|
+
when @shared_credentials
|
249
|
+
c = @shared_credentials
|
250
|
+
credentials_options[:path] = c.path if c.path
|
251
|
+
credentials_options[:profile_name] = c.profile_name if c.profile_name
|
252
|
+
options[:credentials] = Aws::SharedCredentials.new(credentials_options)
|
253
|
+
when @aws_iam_retries
|
254
|
+
log.warn("'aws_iam_retries' parameter is deprecated. Use 'instance_profile_credentials' instead")
|
255
|
+
credentials_options[:retries] = @aws_iam_retries
|
256
|
+
if ENV["AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"]
|
257
|
+
options[:credentials] = Aws::ECSCredentials.new(credentials_options)
|
258
|
+
else
|
259
|
+
options[:credentials] = Aws::InstanceProfileCredentials.new(credentials_options)
|
260
|
+
end
|
261
|
+
else
|
262
|
+
# Use default credentials
|
263
|
+
# See http://docs.aws.amazon.com/sdkforruby/api/Aws/S3/Client.html
|
264
|
+
end
|
265
|
+
options
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path("../../", __FILE__))
|
2
|
+
require "test-unit"
|
3
|
+
require "test/unit/rr"
|
4
|
+
require "fluent/test"
|
5
|
+
require "fluent/test/driver/output"
|
6
|
+
require "fluent/test/helpers"
|
7
|
+
|
8
|
+
Test::Unit::TestCase.include(Fluent::Test::Helpers)
|
9
|
+
Test::Unit::TestCase.extend(Fluent::Test::Helpers)
|
@@ -0,0 +1,334 @@
|
|
1
|
+
require "helper"
|
2
|
+
require "fluent/plugin/out_cloudwatch_put.rb"
|
3
|
+
|
4
|
+
class CloudWatchPutOutputTest < Test::Unit::TestCase
|
5
|
+
setup do
|
6
|
+
Fluent::Test.setup
|
7
|
+
end
|
8
|
+
|
9
|
+
DEFAULT_CONF = %q{
|
10
|
+
region ap-northeast-1
|
11
|
+
namespace Test
|
12
|
+
metric_name MetricName
|
13
|
+
unit Count
|
14
|
+
|
15
|
+
<dimensions>
|
16
|
+
name dim1
|
17
|
+
key key1
|
18
|
+
</dimensions>
|
19
|
+
|
20
|
+
<dimensions>
|
21
|
+
name dim2
|
22
|
+
key key2
|
23
|
+
</dimensions>
|
24
|
+
|
25
|
+
value_key key3
|
26
|
+
|
27
|
+
aws_key_id dummy
|
28
|
+
aws_sec_key dummy
|
29
|
+
}
|
30
|
+
|
31
|
+
test "configure" do
|
32
|
+
d = create_driver
|
33
|
+
assert { d.instance.buffer.chunk_limit_size == 30 * 1024 }
|
34
|
+
assert { d.instance.dimensions.size == 2 }
|
35
|
+
assert { d.instance.dimensions[0].name == "dim1" }
|
36
|
+
assert { d.instance.dimensions[1].name == "dim2" }
|
37
|
+
end
|
38
|
+
|
39
|
+
test "write" do
|
40
|
+
d = create_driver
|
41
|
+
now = Time.now.to_i
|
42
|
+
|
43
|
+
d.instance.start
|
44
|
+
|
45
|
+
mock(d.instance.cloudwatch).put_metric_data({
|
46
|
+
namespace: "Test",
|
47
|
+
metric_data: [
|
48
|
+
{
|
49
|
+
metric_name: "MetricName",
|
50
|
+
dimensions: [
|
51
|
+
{
|
52
|
+
name: "dim1",
|
53
|
+
value: "val1",
|
54
|
+
},
|
55
|
+
{
|
56
|
+
name: "dim2",
|
57
|
+
value: "val2",
|
58
|
+
},
|
59
|
+
],
|
60
|
+
timestamp: Time.at(now),
|
61
|
+
value: 1.0,
|
62
|
+
unit: "Count",
|
63
|
+
storage_resolution: 60,
|
64
|
+
},
|
65
|
+
{
|
66
|
+
metric_name: "MetricName",
|
67
|
+
dimensions: [
|
68
|
+
{
|
69
|
+
name: "dim1",
|
70
|
+
value: "val1",
|
71
|
+
},
|
72
|
+
{
|
73
|
+
name: "dim2",
|
74
|
+
value: "val2",
|
75
|
+
},
|
76
|
+
],
|
77
|
+
timestamp: Time.at(now),
|
78
|
+
value: 2.0,
|
79
|
+
unit: "Count",
|
80
|
+
storage_resolution: 60,
|
81
|
+
},
|
82
|
+
{
|
83
|
+
metric_name: "MetricName",
|
84
|
+
dimensions: [
|
85
|
+
{
|
86
|
+
name: "dim1",
|
87
|
+
value: "val1",
|
88
|
+
},
|
89
|
+
{
|
90
|
+
name: "dim2",
|
91
|
+
value: "val2",
|
92
|
+
},
|
93
|
+
],
|
94
|
+
timestamp: Time.at(now),
|
95
|
+
value: 3.0,
|
96
|
+
unit: "Count",
|
97
|
+
storage_resolution: 60,
|
98
|
+
},
|
99
|
+
]
|
100
|
+
})
|
101
|
+
|
102
|
+
d.run do
|
103
|
+
d.feed('tag', now, {"key1" => "val1", "key2" => "val2", "key3" => 1})
|
104
|
+
d.feed('tag', now, {"key1" => "val1", "key2" => "val2", "key3" => 2})
|
105
|
+
d.feed('tag', now, {"key1" => "val1", "key2" => "val2", "key3" => 3})
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
test "write (multi value_key)" do
|
110
|
+
conf = %q{
|
111
|
+
region ap-northeast-1
|
112
|
+
namespace Test
|
113
|
+
key_as_metric_name true
|
114
|
+
unit Count
|
115
|
+
|
116
|
+
<dimensions>
|
117
|
+
name dim1
|
118
|
+
value dim_value1
|
119
|
+
</dimensions>
|
120
|
+
|
121
|
+
<dimensions>
|
122
|
+
name dim2
|
123
|
+
value dim_value2
|
124
|
+
</dimensions>
|
125
|
+
|
126
|
+
value_key key1, key2, key3
|
127
|
+
|
128
|
+
aws_key_id dummy
|
129
|
+
aws_sec_key dummy
|
130
|
+
}
|
131
|
+
d = create_driver(conf)
|
132
|
+
now = Time.now.to_i
|
133
|
+
|
134
|
+
d.instance.start
|
135
|
+
|
136
|
+
mock(d.instance.cloudwatch).put_metric_data({
|
137
|
+
namespace: "Test",
|
138
|
+
metric_data: [
|
139
|
+
{
|
140
|
+
metric_name: "key1",
|
141
|
+
dimensions: [
|
142
|
+
{
|
143
|
+
name: "dim1",
|
144
|
+
value: "dim_value1",
|
145
|
+
},
|
146
|
+
{
|
147
|
+
name: "dim2",
|
148
|
+
value: "dim_value2",
|
149
|
+
},
|
150
|
+
],
|
151
|
+
timestamp: Time.at(now),
|
152
|
+
value: 1.0,
|
153
|
+
unit: "Count",
|
154
|
+
storage_resolution: 60,
|
155
|
+
},
|
156
|
+
{
|
157
|
+
metric_name: "key2",
|
158
|
+
dimensions: [
|
159
|
+
{
|
160
|
+
name: "dim1",
|
161
|
+
value: "dim_value1",
|
162
|
+
},
|
163
|
+
{
|
164
|
+
name: "dim2",
|
165
|
+
value: "dim_value2",
|
166
|
+
},
|
167
|
+
],
|
168
|
+
timestamp: Time.at(now),
|
169
|
+
value: 2.0,
|
170
|
+
unit: "Count",
|
171
|
+
storage_resolution: 60,
|
172
|
+
},
|
173
|
+
{
|
174
|
+
metric_name: "key3",
|
175
|
+
dimensions: [
|
176
|
+
{
|
177
|
+
name: "dim1",
|
178
|
+
value: "dim_value1",
|
179
|
+
},
|
180
|
+
{
|
181
|
+
name: "dim2",
|
182
|
+
value: "dim_value2",
|
183
|
+
},
|
184
|
+
],
|
185
|
+
timestamp: Time.at(now),
|
186
|
+
value: 3.0,
|
187
|
+
unit: "Count",
|
188
|
+
storage_resolution: 60,
|
189
|
+
},
|
190
|
+
]
|
191
|
+
})
|
192
|
+
|
193
|
+
d.run do
|
194
|
+
d.feed('tag', now, {"key1" => 1, "key2" => 2, "key3" => 3})
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
test "write (use_statistic_sets)" do
|
199
|
+
conf = %q{
|
200
|
+
region ap-northeast-1
|
201
|
+
namespace Test
|
202
|
+
metric_name MetricName
|
203
|
+
unit Count
|
204
|
+
|
205
|
+
use_statistic_sets
|
206
|
+
|
207
|
+
<dimensions>
|
208
|
+
name dim1
|
209
|
+
value dim_value1
|
210
|
+
</dimensions>
|
211
|
+
|
212
|
+
<dimensions>
|
213
|
+
name dim2
|
214
|
+
value dim_value2
|
215
|
+
</dimensions>
|
216
|
+
|
217
|
+
value_key key3
|
218
|
+
|
219
|
+
aws_key_id dummy
|
220
|
+
aws_sec_key dummy
|
221
|
+
}
|
222
|
+
d = create_driver(conf)
|
223
|
+
now = Time.now.to_i
|
224
|
+
|
225
|
+
d.instance.start
|
226
|
+
|
227
|
+
mock(d.instance.cloudwatch).put_metric_data({
|
228
|
+
namespace: "Test",
|
229
|
+
metric_data: [
|
230
|
+
{
|
231
|
+
metric_name: "MetricName",
|
232
|
+
dimensions: [
|
233
|
+
{
|
234
|
+
name: "dim1",
|
235
|
+
value: "dim_value1",
|
236
|
+
},
|
237
|
+
{
|
238
|
+
name: "dim2",
|
239
|
+
value: "dim_value2",
|
240
|
+
},
|
241
|
+
],
|
242
|
+
timestamp: Time.at(now),
|
243
|
+
statistic_values: {
|
244
|
+
sample_count: 3,
|
245
|
+
sum: 6.0,
|
246
|
+
minimum: 1.0,
|
247
|
+
maximum: 3.0,
|
248
|
+
},
|
249
|
+
unit: "Count",
|
250
|
+
storage_resolution: 60,
|
251
|
+
},
|
252
|
+
]
|
253
|
+
})
|
254
|
+
|
255
|
+
d.run do
|
256
|
+
d.feed('tag', now, {"key1" => "val1", "key2" => "val2", "key3" => 1})
|
257
|
+
d.feed('tag', now, {"key1" => "val1", "key2" => "val2", "key3" => 2})
|
258
|
+
d.feed('tag', now, {"key1" => "val1", "key2" => "val2", "key3" => 3})
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
test "write (use_statistic_sets) (placeholder)" do
|
263
|
+
conf = %q{
|
264
|
+
<buffer tag, key1, key2>
|
265
|
+
</buffer>
|
266
|
+
|
267
|
+
region ap-northeast-1
|
268
|
+
namespace ${tag[0]}
|
269
|
+
metric_name ${tag[1]}
|
270
|
+
unit Count
|
271
|
+
|
272
|
+
use_statistic_sets
|
273
|
+
|
274
|
+
<dimensions>
|
275
|
+
name dim1
|
276
|
+
value ${key1}
|
277
|
+
</dimensions>
|
278
|
+
|
279
|
+
<dimensions>
|
280
|
+
name dim2
|
281
|
+
value ${key2}
|
282
|
+
</dimensions>
|
283
|
+
|
284
|
+
value_key key3
|
285
|
+
|
286
|
+
aws_key_id dummy
|
287
|
+
aws_sec_key dummy
|
288
|
+
}
|
289
|
+
d = create_driver(conf)
|
290
|
+
now = Time.now.to_i
|
291
|
+
|
292
|
+
d.instance.start
|
293
|
+
|
294
|
+
mock(d.instance.cloudwatch).put_metric_data({
|
295
|
+
namespace: "namespace",
|
296
|
+
metric_data: [
|
297
|
+
{
|
298
|
+
metric_name: "metric_name",
|
299
|
+
dimensions: [
|
300
|
+
{
|
301
|
+
name: "dim1",
|
302
|
+
value: "val1",
|
303
|
+
},
|
304
|
+
{
|
305
|
+
name: "dim2",
|
306
|
+
value: "val2",
|
307
|
+
},
|
308
|
+
],
|
309
|
+
timestamp: Time.at(now),
|
310
|
+
statistic_values: {
|
311
|
+
sample_count: 3,
|
312
|
+
sum: 6.0,
|
313
|
+
minimum: 1.0,
|
314
|
+
maximum: 3.0,
|
315
|
+
},
|
316
|
+
unit: "Count",
|
317
|
+
storage_resolution: 60,
|
318
|
+
},
|
319
|
+
]
|
320
|
+
})
|
321
|
+
|
322
|
+
d.run do
|
323
|
+
d.feed('namespace.metric_name', now, {"key1" => "val1", "key2" => "val2", "key3" => 1})
|
324
|
+
d.feed('namespace.metric_name', now, {"key1" => "val1", "key2" => "val2", "key3" => 2})
|
325
|
+
d.feed('namespace.metric_name', now, {"key1" => "val1", "key2" => "val2", "key3" => 3})
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
private
|
330
|
+
|
331
|
+
def create_driver(conf = DEFAULT_CONF)
|
332
|
+
Fluent::Test::Driver::Output.new(Fluent::Plugin::CloudWatchPutOutput).configure(conf)
|
333
|
+
end
|
334
|
+
end
|
metadata
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fluent-plugin-cloudwatch-put-timestamp
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- ''
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-11-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.14'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.14'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '12.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '12.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: test-unit
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: test-unit-rr
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: fluentd
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.14.10
|
76
|
+
- - "<"
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '2'
|
79
|
+
type: :runtime
|
80
|
+
prerelease: false
|
81
|
+
version_requirements: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 0.14.10
|
86
|
+
- - "<"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '2'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: aws-sdk-cloudwatch
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '1'
|
96
|
+
type: :runtime
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - "~>"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '1'
|
103
|
+
description: Cloudwatch put metric plugin for fluentd.
|
104
|
+
email:
|
105
|
+
executables: []
|
106
|
+
extensions: []
|
107
|
+
extra_rdoc_files: []
|
108
|
+
files:
|
109
|
+
- ".gitignore"
|
110
|
+
- ".travis.yml"
|
111
|
+
- Gemfile
|
112
|
+
- LICENSE
|
113
|
+
- README.md
|
114
|
+
- Rakefile
|
115
|
+
- fluent-plugin-cloudwatch-put.gemspec
|
116
|
+
- lib/fluent/plugin/out_cloudwatch_put.rb
|
117
|
+
- test/helper.rb
|
118
|
+
- test/plugin/test_out_cloudwatch_put.rb
|
119
|
+
homepage: https://github.com/jmmgr/fluent-plugin-cloudwatch-put
|
120
|
+
licenses:
|
121
|
+
- MIT
|
122
|
+
metadata: {}
|
123
|
+
post_install_message:
|
124
|
+
rdoc_options: []
|
125
|
+
require_paths:
|
126
|
+
- lib
|
127
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - ">="
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
requirements: []
|
138
|
+
rubyforge_project:
|
139
|
+
rubygems_version: 2.5.1
|
140
|
+
signing_key:
|
141
|
+
specification_version: 4
|
142
|
+
summary: Cloudwatch put metric plugin for fluentd.
|
143
|
+
test_files:
|
144
|
+
- test/helper.rb
|
145
|
+
- test/plugin/test_out_cloudwatch_put.rb
|