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 +4 -4
- data/README.md +0 -2
- data/fluent.conf.sample +20 -0
- data/lib/fluent/plugin/out_timestream.rb +61 -18
- data/lib/fluent/plugin/timestream/version.rb +1 -1
- metadata +9 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 39a7dfff0e1443346bc334799685c2faed6e546aa0ad4a8782392e6368ca9c19
|
4
|
+
data.tar.gz: dd333c9f9218c7582df76efe842b346bea39561f0ff23cbde73a83f94bc33a26
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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,
|
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
|
-
|
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:
|
133
|
+
type: type
|
130
134
|
}
|
131
135
|
end
|
132
136
|
|
133
|
-
def
|
134
|
-
|
135
|
-
|
136
|
-
if
|
137
|
-
measure = create_timestream_measure(
|
138
|
-
|
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
|
-
|
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,
|
152
|
-
timestream_records.push(create_timestream_record(dimensions, time,
|
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
|
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.
|
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:
|
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.
|
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: []
|