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.
@@ -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
@@ -0,0 +1,11 @@
1
+ /.bundle
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /gemfiles/.bundle
11
+ *.gemfile.lock
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.8
4
+ - 2.3.4
5
+ - 2.4.2
6
+ before_install: gem install bundler
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
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.
@@ -0,0 +1,203 @@
1
+ # fluent-plugin-cloudwatch-put
2
+ [![Build Status](https://travis-ci.org/joker1007/fluent-plugin-cloudwatch-put.svg?branch=master)](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
@@ -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
@@ -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