fluent-plugin-timestream 1.0.0 → 1.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7666d682c4ca710160fb52118b24b10f189b763579fac67b5593f2e0492bdb49
4
- data.tar.gz: '0947bacb4d5410a5c3246f1c1124fa5638e9b93aadabdb6375f21175097a7cc1'
3
+ metadata.gz: 39a7dfff0e1443346bc334799685c2faed6e546aa0ad4a8782392e6368ca9c19
4
+ data.tar.gz: dd333c9f9218c7582df76efe842b346bea39561f0ff23cbde73a83f94bc33a26
5
5
  SHA512:
6
- metadata.gz: aa9828797c6851f7a6579f4a714fd5569a646fe1d372291ea48e6c6b62c3b9ae945c79ad7870088d7ead2dca39840e0ef405a09477354ba5abaada2aee33593b
7
- data.tar.gz: be95ba6868b25490a2d071356a08b24960ce831bfc413806a3cb488488d339ea4b09c0681c58573ab314457865e675eb7083d97202909c15bc55ba838f194b26
6
+ metadata.gz: 57a1df5e1b0e8fe4bb2a3054df8946cdaa11a2ccdb0c2be117a85294dd7e62bb1720b9c9684bbbec8a486090cc8274a661b2f9742d61d7f4ea4fdde008612291
7
+ data.tar.gz: 0d710f85903d023fddbd5c3a540e6f05477c17e5a8ac0418af199dd0aa7caca27e8aa587d9fa2f246002bab410abc8bd25c811fd132700184834bc2d01051daf
data/README.md CHANGED
@@ -24,5 +24,3 @@ e.g. `{dimension1: null, dimension2: "", measure: "value"}` => ignores this reco
24
24
 
25
25
  The plugin ignores record when measure specified in the config has `null` or empty value.
26
26
  e.g. `{dimension1: "value", measure: ""}` => ignores this record
27
-
28
- Configuring multiple `MeasureName`s is not supported.
data/fluent.conf.sample CHANGED
@@ -65,10 +65,30 @@
65
65
  # MeasureName: '-'
66
66
  # MeasureValue: '-'
67
67
  # MeasureValueType: 'VARCHAR'
68
+ #
69
+ # Single measure example:
68
70
  #<measure>
69
71
  # name "measureNameXXX"
70
72
  # type "VARCHAR"
71
73
  #</measure>
74
+ #
75
+ # To specify multiple measures, the parent measure must have type "MULTI" and contain nested measure definitions.
76
+ # For more details about multi-measure records in Timestream, see:
77
+ # https://docs.aws.amazon.com/timestream/latest/developerguide/writes.html
78
+ #
79
+ # Multi-measure example:
80
+ #<measure>
81
+ # name "multiMeasureNameXXX"
82
+ # type "MULTI"
83
+ # <measure>
84
+ # name "measureName1XXX"
85
+ # type "VARCHAR"
86
+ # </measure>
87
+ # <measure>
88
+ # name "measureName2XXX"
89
+ # type "BIGINT"
90
+ # </measure>
91
+ #</measure>
72
92
 
73
93
  # 'chunk_limit_records' must be configured less or equal to 100.
74
94
  # If not, plugin may fails to write record.
@@ -18,6 +18,8 @@ module Fluent
18
18
  NANOSECONDS
19
19
  ].freeze
20
20
 
21
+ DUMMY_MEASURE = { name: '-', value: '-', type: 'VARCHAR' }.freeze
22
+
21
23
  # Raise when measure has empty value
22
24
  class EmptyValueError < StandardError
23
25
  def initialize(key_name = '')
@@ -45,6 +47,11 @@ module Fluent
45
47
  param_name: 'target_measure', required: false, multi: false do
46
48
  config_param :name, :string
47
49
  config_param :type, :string
50
+ config_section :measure,
51
+ param_name: 'multi_measures', required: false, multi: true do
52
+ config_param :name, :string
53
+ config_param :type, :string
54
+ end
48
55
  end
49
56
  config_param :time_unit, :string, default: 'SECONDS'
50
57
  config_param :time_key, default: nil
@@ -89,16 +96,13 @@ module Fluent
89
96
  [time, record].to_msgpack
90
97
  end
91
98
 
92
- def create_timestream_record(dimensions, time, measure)
99
+ def create_timestream_record(dimensions, time, measures)
93
100
  raise NoDimensionsError if dimensions.empty?
94
- measure = { name: '-', value: '-', type: 'VARCHAR' } if measure.empty?
95
101
  {
96
102
  dimensions: dimensions,
97
103
  time: time.to_s,
98
104
  time_unit: @time_unit,
99
- measure_name: measure[:name],
100
- measure_value: measure[:value],
101
- measure_value_type: measure[:type]
105
+ **build_measure_payload(measures)
102
106
  }
103
107
  end
104
108
 
@@ -116,7 +120,7 @@ module Fluent
116
120
  }
117
121
  end
118
122
 
119
- def create_timestream_measure(key, value)
123
+ def create_timestream_measure(key, value, type)
120
124
  value = value.to_s
121
125
 
122
126
  # Timestream does not accept empty string.
@@ -126,21 +130,35 @@ module Fluent
126
130
  {
127
131
  name: key,
128
132
  value: value,
129
- type: @target_measure[:type]
133
+ type: type
130
134
  }
131
135
  end
132
136
 
133
- def create_timestream_dimensions_and_measure(record)
134
- measure = {}
135
- dimensions = record.each_with_object([]) do |(k, v), result|
136
- if @target_measure && k == @target_measure[:name]
137
- measure = create_timestream_measure(k, v)
138
- next
137
+ def create_timestream_dimensions_and_measures(record)
138
+ record.each_with_object([[], []]) do |(key, value), (dimensions, measures)|
139
+ measure_type = measure_types[key]
140
+ if measure_type
141
+ measure = create_timestream_measure(key, value, measure_type)
142
+ measures << measure if measure
143
+ else
144
+ dimension = create_timestream_dimension(key, value)
145
+ dimensions << dimension if dimension
139
146
  end
140
- dimension = create_timestream_dimension(k, v)
141
- result.push(dimension) unless dimension.nil?
142
147
  end
143
- return [dimensions, measure]
148
+ end
149
+
150
+ def measure_types
151
+ @measure_types ||= if @target_measure.nil?
152
+ {}
153
+ elsif multi_measure?
154
+ @target_measure.multi_measures.to_h { |m| [m.name, m.type] }
155
+ else
156
+ { @target_measure.name => @target_measure.type }
157
+ end
158
+ end
159
+
160
+ def multi_measure?
161
+ @target_measure&.type == 'MULTI'
144
162
  end
145
163
 
146
164
  # rubocop:disable Metrics/MethodLength
@@ -148,8 +166,8 @@ module Fluent
148
166
  timestream_records = []
149
167
  chunk.each do |time, record|
150
168
  time = record.delete(@time_key) unless @time_key.nil?
151
- dimensions, measure = create_timestream_dimensions_and_measure(record)
152
- timestream_records.push(create_timestream_record(dimensions, time, measure))
169
+ dimensions, measures = create_timestream_dimensions_and_measures(record)
170
+ timestream_records.push(create_timestream_record(dimensions, time, measures))
153
171
  rescue EmptyValueError, NoDimensionsError => e
154
172
  log.warn("ignored record due to (#{e})")
155
173
  log.debug("ignored record details: #{record}")
@@ -177,6 +195,31 @@ module Fluent
177
195
  log.error(e.rejected_records)
178
196
  end
179
197
 
198
+ def build_measure_payload(measures)
199
+ if multi_measure? && !measures.empty?
200
+ multi_measure_payload(measures)
201
+ else
202
+ single_measure_payload(measures)
203
+ end
204
+ end
205
+
206
+ def multi_measure_payload(measures)
207
+ {
208
+ measure_name: @target_measure.name,
209
+ measure_value_type: 'MULTI',
210
+ measure_values: measures
211
+ }
212
+ end
213
+
214
+ def single_measure_payload(measures)
215
+ measure = measures.empty? ? DUMMY_MEASURE : measures.first
216
+ {
217
+ measure_name: measure[:name],
218
+ measure_value: measure[:value],
219
+ measure_value_type: measure[:type]
220
+ }
221
+ end
222
+
180
223
  end
181
224
  # rubocop: enable Metrics/ClassLength
182
225
  end
@@ -3,7 +3,7 @@
3
3
  module Fluent
4
4
  module Plugin
5
5
  module Timestream
6
- VERSION = '1.0.0'
6
+ VERSION = '1.1.0'
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-timestream
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Studist Corporation
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-08-13 00:00:00.000000000 Z
11
+ date: 2024-10-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-timestreamwrite
@@ -80,8 +80,8 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: 1.4.2
83
- description:
84
- email:
83
+ description:
84
+ email:
85
85
  executables: []
86
86
  extensions: []
87
87
  extra_rdoc_files: []
@@ -99,13 +99,13 @@ files:
99
99
  - fluent.conf.sample
100
100
  - lib/fluent/plugin/out_timestream.rb
101
101
  - lib/fluent/plugin/timestream/version.rb
102
- homepage:
102
+ homepage:
103
103
  licenses:
104
104
  - MIT
105
105
  metadata:
106
106
  source_code_uri: https://github.com/StudistCorporation/fluent-plugin-timestream
107
107
  changelog_uri: https://github.com/StudistCorporation/fluent-plugin-timestream/CHANGELOG.md
108
- post_install_message:
108
+ post_install_message:
109
109
  rdoc_options: []
110
110
  require_paths:
111
111
  - lib
@@ -120,8 +120,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
120
120
  - !ruby/object:Gem::Version
121
121
  version: '0'
122
122
  requirements: []
123
- rubygems_version: 3.0.3
124
- signing_key:
123
+ rubygems_version: 3.2.32
124
+ signing_key:
125
125
  specification_version: 4
126
126
  summary: Fluentd output plugin which writes Amazon Timestream record.
127
127
  test_files: []