fluentd-json-size-limit 0.1.4 → 0.2.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.
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fluent/plugin/json_size_limit/processing_guard"
4
+ require "fluent/plugin/json_size_limit/record_measurer"
5
+ require "fluent/plugin/json_size_limit/record_reducer"
6
+
7
+ module Fluent
8
+ module Plugin
9
+ module JsonSizeLimit
10
+ class RecordProcessor
11
+ Result = Struct.new(:status, :original_json_bytes, :json_bytes)
12
+
13
+ def initialize(max_json_bytes:, safety_options:, clock: ProcessingGuard::MONOTONIC_TIME)
14
+ @max_json_bytes = max_json_bytes
15
+ @safety_options = safety_options
16
+ @clock = clock
17
+ end
18
+
19
+ def call(record)
20
+ guard = ProcessingGuard.new(**@safety_options, clock: @clock)
21
+ original_json_bytes = RecordMeasurer.new(guard).measure(record)
22
+
23
+ if original_json_bytes <= @max_json_bytes
24
+ return Result.new(
25
+ status: :within_limit,
26
+ original_json_bytes: original_json_bytes,
27
+ json_bytes: original_json_bytes
28
+ )
29
+ end
30
+
31
+ # Node and input counters are phase-local, while the absolute
32
+ # deadline remains shared by measurement and reduction.
33
+ guard.reset_phase!(track_input: false)
34
+ reduced_json_bytes = RecordReducer.new(
35
+ record,
36
+ original_json_bytes: original_json_bytes,
37
+ max_json_bytes: @max_json_bytes,
38
+ guard: guard,
39
+ validated_record: true
40
+ ).reduce_to_limit
41
+ guard.checkpoint!
42
+
43
+ Result.new(
44
+ status: (reduced_json_bytes <= @max_json_bytes) ? :reduced : :overflow,
45
+ original_json_bytes: original_json_bytes,
46
+ json_bytes: reduced_json_bytes
47
+ )
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,258 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fluent/plugin/json_size_limit/json_string"
4
+ require "fluent/plugin/json_size_limit/processing_guard"
5
+
6
+ module Fluent
7
+ module Plugin
8
+ module JsonSizeLimit
9
+ # Reduces string values proportionally while preserving record shape,
10
+ # aliases, key names, encodings, and non-string values.
11
+ class RecordReducer
12
+ HASH_EACH_PAIR = Hash.instance_method(:each_pair)
13
+ ARRAY_EACH_WITH_INDEX = Array.instance_method(:each_with_index)
14
+ HASH_SET = Hash.instance_method(:[]=)
15
+ ARRAY_SET = Array.instance_method(:[]=)
16
+
17
+ class StringLocation < JsonString
18
+ attr_reader :container, :key, :original_value
19
+ attr_accessor :occurrences, :replacement_value, :replacement_content_bytes
20
+
21
+ def initialize(container, key, value, encoding_validated: false)
22
+ super(value, validate_encoding: !encoding_validated)
23
+ @container = container
24
+ @key = key
25
+ @original_value = value
26
+ @occurrences = 1
27
+ @replacement_value = value
28
+ @replacement_content_bytes = content_bytes
29
+ end
30
+
31
+ def truncate_to(content_budget)
32
+ @replacement_value = truncate(content_budget)
33
+ @replacement_content_bytes = truncated_content_bytes
34
+ end
35
+ end
36
+
37
+ def initialize(record, original_json_bytes:, max_json_bytes:, guard: nil, validated_record: false)
38
+ @record = record
39
+ @original_json_bytes = original_json_bytes
40
+ @max_json_bytes = max_json_bytes
41
+ @guard = guard || ProcessingGuard.new(
42
+ timeout: 5,
43
+ max_nodes: 1_000_000,
44
+ max_input_bytes: Float::INFINITY,
45
+ max_nesting: 100
46
+ )
47
+ @validated_record = validated_record
48
+ end
49
+
50
+ def reduce_to_limit
51
+ locations, original_content_bytes = collect_string_locations
52
+ return @original_json_bytes if locations.empty?
53
+
54
+ immutable_json_bytes = @original_json_bytes - original_content_bytes
55
+ content_budget = @max_json_bytes - immutable_json_bytes
56
+ @guard.reset_phase!(track_input: false)
57
+ replacements, current_content_bytes = build_replacements(locations, content_budget, original_content_bytes)
58
+
59
+ @guard.reset_phase!(track_input: false)
60
+ apply_replacements(replacements)
61
+ immutable_json_bytes + current_content_bytes
62
+ end
63
+
64
+ private
65
+
66
+ # JSON serializes aliases once per occurrence. The common tree path
67
+ # avoids a per-field index; alias accounting is activated only when a
68
+ # shared Hash or Array identity is observed.
69
+ def collect_string_locations
70
+ collect_tree_string_locations || begin
71
+ @guard.reset_phase!(track_input: false)
72
+ collect_aliased_string_locations
73
+ end
74
+ end
75
+
76
+ def collect_tree_string_locations
77
+ locations = []
78
+ seen_containers = {}.compare_by_identity
79
+ total_content_bytes = 0
80
+ containers_to_scan = [[@record, 0]]
81
+ @scan_operations = 0
82
+
83
+ until containers_to_scan.empty?
84
+ container, depth = containers_to_scan.pop
85
+ scan_visit!(depth)
86
+ return nil if seen_containers.key?(container)
87
+
88
+ seen_containers[container] = true
89
+
90
+ each_container_value(container) do |key, value|
91
+ if value.instance_of?(String) && !value.empty?
92
+ location = StringLocation.new(container, key, value, encoding_validated: @validated_record)
93
+ locations << location
94
+ total_content_bytes += location.content_bytes
95
+ scan_visit!(depth + 1)
96
+ elsif value.instance_of?(Hash) || value.instance_of?(Array)
97
+ containers_to_scan << [value, depth + 1]
98
+ else
99
+ scan_visit!(depth + 1)
100
+ end
101
+ end
102
+ end
103
+
104
+ [locations, total_content_bytes]
105
+ end
106
+
107
+ def collect_aliased_string_locations
108
+ locations = []
109
+ locations_by_container = {}.compare_by_identity
110
+ total_content_bytes = 0
111
+ containers_to_scan = [[@record, 0]]
112
+ @scan_operations = 0
113
+
114
+ until containers_to_scan.empty?
115
+ container, depth = containers_to_scan.pop
116
+ scan_visit!(depth)
117
+ location_indexes = locations_by_container[container] ||= {}
118
+
119
+ each_container_value(container) do |key, value|
120
+ if value.instance_of?(String) && !value.empty?
121
+ location = location_indexes[key]
122
+
123
+ if location
124
+ location.occurrences += 1
125
+ else
126
+ location = StringLocation.new(container, key, value, encoding_validated: @validated_record)
127
+ location_indexes[key] = location
128
+ locations << location
129
+ end
130
+
131
+ total_content_bytes += location.content_bytes
132
+ scan_visit!(depth + 1)
133
+ elsif value.instance_of?(Hash) || value.instance_of?(Array)
134
+ containers_to_scan << [value, depth + 1]
135
+ else
136
+ scan_visit!(depth + 1)
137
+ end
138
+ end
139
+ end
140
+
141
+ [locations, total_content_bytes]
142
+ end
143
+
144
+ def each_container_value(container, &block)
145
+ if container.instance_of?(Hash)
146
+ HASH_EACH_PAIR.bind_call(container, &block)
147
+ else
148
+ ARRAY_EACH_WITH_INDEX.bind_call(container) { |value, index| block.call(index, value) }
149
+ end
150
+ end
151
+
152
+ def scan_visit!(depth)
153
+ unless @validated_record
154
+ @guard.visit!(depth)
155
+ return
156
+ end
157
+
158
+ @scan_operations += 1
159
+ @guard.checkpoint! if (@scan_operations & 255).zero?
160
+ end
161
+
162
+ def build_replacements(locations, content_budget, original_content_bytes)
163
+ remaining_budget = [content_budget, 0].max
164
+ remaining_original = original_content_bytes
165
+ current_content_bytes = 0
166
+
167
+ locations.each_with_index do |location, index|
168
+ @guard.checkpoint! if (index & 255).zero?
169
+ weighted_original = location.content_bytes * location.occurrences
170
+ weighted_target = remaining_budget.positive? ? remaining_budget * weighted_original / remaining_original : 0
171
+ target_per_occurrence = weighted_target / location.occurrences
172
+
173
+ location.truncate_to(target_per_occurrence)
174
+ @guard.checkpoint! if location.content_bytes >= 64 * 1024
175
+ weighted_replacement = location.replacement_content_bytes * location.occurrences
176
+
177
+ current_content_bytes += weighted_replacement
178
+ remaining_budget -= weighted_replacement
179
+ remaining_original -= weighted_original
180
+ end
181
+
182
+ @guard.reset_phase!(track_input: false)
183
+ current_content_bytes += distribute_remaining_budget(locations, remaining_budget)
184
+ @guard.reset_phase!(track_input: false)
185
+ replacements = build_replacement_list(locations)
186
+
187
+ [replacements, current_content_bytes]
188
+ end
189
+
190
+ def distribute_remaining_budget(locations, remaining_budget)
191
+ added_content_bytes = 0
192
+
193
+ locations.each_with_index do |location, index|
194
+ @guard.checkpoint! if (index & 255).zero?
195
+ break unless remaining_budget.positive?
196
+ next if location.replacement_content_bytes >= location.content_bytes
197
+
198
+ additional_per_occurrence = remaining_budget / location.occurrences
199
+ next unless additional_per_occurrence.positive?
200
+
201
+ previous_replacement_bytes = location.replacement_content_bytes
202
+ location.truncate_to(previous_replacement_bytes + additional_per_occurrence)
203
+ @guard.checkpoint! if location.content_bytes >= 64 * 1024
204
+ replacement_bytes = location.replacement_content_bytes
205
+ weighted_addition = (replacement_bytes - previous_replacement_bytes) * location.occurrences
206
+ remaining_budget -= weighted_addition
207
+ added_content_bytes += weighted_addition
208
+ end
209
+
210
+ added_content_bytes
211
+ end
212
+
213
+ def build_replacement_list(locations)
214
+ # A flat tuple buffer avoids allocating one small Array per changed
215
+ # field on records with many strings.
216
+ replacements = []
217
+ index = 0
218
+
219
+ locations.each do |location|
220
+ @guard.checkpoint! if (index & 255).zero?
221
+ unless location.replacement_value.equal?(location.original_value)
222
+ replacements << location.container << location.key << location.original_value << location.replacement_value
223
+ end
224
+ index += 1
225
+ end
226
+
227
+ replacements
228
+ end
229
+
230
+ def apply_replacements(replacements)
231
+ applied = 0
232
+
233
+ while applied < replacements.length
234
+ @guard.checkpoint! if (applied & 1023).zero?
235
+ set_container_value(replacements[applied], replacements[applied + 1], replacements[applied + 3])
236
+ applied += 4
237
+ end
238
+ rescue
239
+ rollback_replacements(replacements, applied)
240
+ raise
241
+ end
242
+
243
+ def rollback_replacements(replacements, applied)
244
+ index = 0
245
+ while index < applied
246
+ set_container_value(replacements[index], replacements[index + 1], replacements[index + 2])
247
+ index += 4
248
+ end
249
+ end
250
+
251
+ def set_container_value(container, key, value)
252
+ method = container.instance_of?(Hash) ? HASH_SET : ARRAY_SET
253
+ method.bind_call(container, key, value)
254
+ end
255
+ end
256
+ end
257
+ end
258
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fluent/plugin/json_size_limit/errors"
4
+
5
+ module Fluent
6
+ module Plugin
7
+ module JsonSizeLimit
8
+ module StringEncoding
9
+ module_function
10
+
11
+ def validate!(value)
12
+ unless value.valid_encoding?
13
+ raise InvalidStringEncodingError, value.encoding.name
14
+ end
15
+
16
+ # Binary bytes have no character boundaries, so truncating them could
17
+ # silently change payload semantics. ASCII-only binary strings are safe.
18
+ if value.encoding == Encoding::ASCII_8BIT && !value.ascii_only?
19
+ raise InvalidStringEncodingError, value.encoding.name
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fluent/plugin/json_size_limit/errors"
4
+
5
+ module Fluent
6
+ module Plugin
7
+ module JsonSizeLimit
8
+ class Telemetry
9
+ DEFINITIONS = {
10
+ oversized_records: "Number of records exceeding max_size",
11
+ reduced_records: "Number of oversized records reduced to max_size",
12
+ unreducible_records: "Number of records whose immutable JSON exceeds max_size",
13
+ error_records: "Number of records that failed measurement or reduction",
14
+ dropped_records: "Number of records dropped by configured actions",
15
+ processing_limit_records: "Number of records stopped by automatic safety limits",
16
+ unsupported_records: "Number of records containing unsupported Ruby value classes",
17
+ removed_bytes: "Total JSON bytes removed from oversized records"
18
+ }.freeze
19
+
20
+ def initialize(&metric_factory)
21
+ raise ArgumentError, "metric factory block is required" unless metric_factory
22
+
23
+ @metrics = DEFINITIONS.to_h do |name, help_text|
24
+ metric = metric_factory.call(name.to_s, help_text)
25
+ validate_metric!(name, metric)
26
+ [name, metric]
27
+ end
28
+ end
29
+
30
+ def increment(name, amount = 1)
31
+ unless amount.is_a?(Integer) && amount.positive?
32
+ raise ArgumentError, "metric increment must be a positive integer"
33
+ end
34
+
35
+ metric = @metrics.fetch(name)
36
+ (amount == 1) ? metric.inc : metric.add(amount)
37
+ end
38
+
39
+ def record_error(error)
40
+ increment(:error_records)
41
+ increment(:processing_limit_records) if error.is_a?(ProcessingLimitError) || error.is_a?(CyclicRecordError)
42
+ increment(:unsupported_records) if error.is_a?(UnsupportedRecordError)
43
+ end
44
+
45
+ def statistics
46
+ @metrics.transform_keys(&:to_s).transform_values(&:get)
47
+ end
48
+
49
+ private
50
+
51
+ def validate_metric!(name, metric)
52
+ missing_methods = %i[inc add get].reject { |method_name| metric.respond_to?(method_name) }
53
+ return if missing_methods.empty?
54
+
55
+ raise ArgumentError, "metric #{name} must respond to #{missing_methods.map { |name| "##{name}" }.join(", ")}"
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fluent
4
+ module Plugin
5
+ module JsonSizeLimit
6
+ VERSION = "0.2.0"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Internal component bundle. Fluentd registration remains in the stable
4
+ # filter_jsonsizelimit discovery entry point to avoid a circular require.
5
+ require "fluent/plugin/json_size_limit/version"
6
+ require "fluent/plugin/json_size_limit/errors"
7
+ require "fluent/plugin/json_size_limit/string_encoding"
8
+ require "fluent/plugin/json_size_limit/json_string"
9
+ require "fluent/plugin/json_size_limit/rate_limited_logger"
10
+ require "fluent/plugin/json_size_limit/processing_guard"
11
+ require "fluent/plugin/json_size_limit/record_measurer"
12
+ require "fluent/plugin/json_size_limit/record_reducer"
13
+ require "fluent/plugin/json_size_limit/record_processor"
14
+ require "fluent/plugin/json_size_limit/filter_configuration"
15
+ require "fluent/plugin/json_size_limit/telemetry"
metadata CHANGED
@@ -1,64 +1,141 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluentd-json-size-limit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - CreatorIQ
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-02-09 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: bundler
15
14
  requirement: !ruby/object:Gem::Requirement
16
15
  requirements:
17
- - - "~>"
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '2.6'
19
+ - - "<"
18
20
  - !ruby/object:Gem::Version
19
- version: 2.4.22
21
+ version: '5'
20
22
  type: :development
21
23
  prerelease: false
22
24
  version_requirements: !ruby/object:Gem::Requirement
23
25
  requirements:
24
- - - "~>"
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: '2.6'
29
+ - - "<"
30
+ - !ruby/object:Gem::Version
31
+ version: '5'
32
+ - !ruby/object:Gem::Dependency
33
+ name: benchmark
34
+ requirement: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '0.4'
39
+ - - "<"
40
+ - !ruby/object:Gem::Version
41
+ version: '1'
42
+ type: :development
43
+ prerelease: false
44
+ version_requirements: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0.4'
49
+ - - "<"
25
50
  - !ruby/object:Gem::Version
26
- version: 2.4.22
51
+ version: '1'
27
52
  - !ruby/object:Gem::Dependency
28
53
  name: rake
29
54
  requirement: !ruby/object:Gem::Requirement
30
55
  requirements:
31
- - - "~>"
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: '13.2'
59
+ - - "<"
60
+ - !ruby/object:Gem::Version
61
+ version: '14'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '13.2'
69
+ - - "<"
70
+ - !ruby/object:Gem::Version
71
+ version: '14'
72
+ - !ruby/object:Gem::Dependency
73
+ name: simplecov
74
+ requirement: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '1.0'
79
+ - - "<"
80
+ - !ruby/object:Gem::Version
81
+ version: '2'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '1.0'
89
+ - - "<"
90
+ - !ruby/object:Gem::Version
91
+ version: '2'
92
+ - !ruby/object:Gem::Dependency
93
+ name: standard
94
+ requirement: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '1.56'
99
+ - - "<"
32
100
  - !ruby/object:Gem::Version
33
- version: 13.0.6
101
+ version: '2'
34
102
  type: :development
35
103
  prerelease: false
36
104
  version_requirements: !ruby/object:Gem::Requirement
37
105
  requirements:
38
- - - "~>"
106
+ - - ">="
39
107
  - !ruby/object:Gem::Version
40
- version: 13.0.6
108
+ version: '1.56'
109
+ - - "<"
110
+ - !ruby/object:Gem::Version
111
+ version: '2'
41
112
  - !ruby/object:Gem::Dependency
42
113
  name: test-unit
43
114
  requirement: !ruby/object:Gem::Requirement
44
115
  requirements:
45
- - - "~>"
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '3.6'
119
+ - - "<"
46
120
  - !ruby/object:Gem::Version
47
- version: 3.5.7
121
+ version: '4'
48
122
  type: :development
49
123
  prerelease: false
50
124
  version_requirements: !ruby/object:Gem::Requirement
51
125
  requirements:
52
- - - "~>"
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '3.6'
129
+ - - "<"
53
130
  - !ruby/object:Gem::Version
54
- version: 3.5.7
131
+ version: '4'
55
132
  - !ruby/object:Gem::Dependency
56
133
  name: fluentd
57
134
  requirement: !ruby/object:Gem::Requirement
58
135
  requirements:
59
136
  - - ">="
60
137
  - !ruby/object:Gem::Version
61
- version: 0.14.10
138
+ version: 1.16.11
62
139
  - - "<"
63
140
  - !ruby/object:Gem::Version
64
141
  version: '2'
@@ -68,35 +145,63 @@ dependencies:
68
145
  requirements:
69
146
  - - ">="
70
147
  - !ruby/object:Gem::Version
71
- version: 0.14.10
148
+ version: 1.16.11
72
149
  - - "<"
73
150
  - !ruby/object:Gem::Version
74
151
  version: '2'
75
- description: This plugin reduces the size of JSON records if they exceed a specified
76
- limit.
152
+ - !ruby/object:Gem::Dependency
153
+ name: json
154
+ requirement: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: 2.19.2
159
+ - - "<"
160
+ - !ruby/object:Gem::Version
161
+ version: '3'
162
+ type: :runtime
163
+ prerelease: false
164
+ version_requirements: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - ">="
167
+ - !ruby/object:Gem::Version
168
+ version: 2.19.2
169
+ - - "<"
170
+ - !ruby/object:Gem::Version
171
+ version: '3'
172
+ description: Reduces oversized Fluentd JSON records by safely and proportionally truncating
173
+ nested string values.
77
174
  email:
78
- - subcription-rubygems@creatoriq.com
175
+ - subscription-rubygems@creatoriq.com
79
176
  executables: []
80
177
  extensions: []
81
178
  extra_rdoc_files: []
82
179
  files:
83
- - ".gitignore"
84
- - ".gitlab-ci.yml"
85
- - Gemfile
86
- - Gemfile.lock
180
+ - CHANGELOG.md
87
181
  - LICENSE
182
+ - NOTICE.md
88
183
  - README.md
89
- - Rakefile
90
184
  - fluentd-json-size-limit.gemspec
91
185
  - lib/fluent/plugin/filter_jsonsizelimit.rb
92
- - test/helper.rb
93
- - test/plugin/test_fluentd-json-size-limit.rb
94
- homepage: ''
186
+ - lib/fluent/plugin/json_size_limit.rb
187
+ - lib/fluent/plugin/json_size_limit/errors.rb
188
+ - lib/fluent/plugin/json_size_limit/filter.rb
189
+ - lib/fluent/plugin/json_size_limit/filter_configuration.rb
190
+ - lib/fluent/plugin/json_size_limit/json_string.rb
191
+ - lib/fluent/plugin/json_size_limit/processing_guard.rb
192
+ - lib/fluent/plugin/json_size_limit/rate_limited_logger.rb
193
+ - lib/fluent/plugin/json_size_limit/record_measurer.rb
194
+ - lib/fluent/plugin/json_size_limit/record_processor.rb
195
+ - lib/fluent/plugin/json_size_limit/record_reducer.rb
196
+ - lib/fluent/plugin/json_size_limit/string_encoding.rb
197
+ - lib/fluent/plugin/json_size_limit/telemetry.rb
198
+ - lib/fluent/plugin/json_size_limit/version.rb
199
+ homepage: https://creatoriq.com
95
200
  licenses:
96
- - Copyright 2017 - 2024 SocialEdge, Inc., dba CreatorIQ.
201
+ - Copyright 2017 - 2026 SocialEdge, Inc., dba CreatorIQ.
97
202
  - Nonstandard
98
- metadata: {}
99
- post_install_message:
203
+ metadata:
204
+ allowed_push_host: https://rubygems.org
100
205
  rdoc_options: []
101
206
  require_paths:
102
207
  - lib
@@ -104,17 +209,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
104
209
  requirements:
105
210
  - - ">="
106
211
  - !ruby/object:Gem::Version
107
- version: '0'
212
+ version: '3.3'
213
+ - - "<"
214
+ - !ruby/object:Gem::Version
215
+ version: '5'
108
216
  required_rubygems_version: !ruby/object:Gem::Requirement
109
217
  requirements:
110
218
  - - ">="
111
219
  - !ruby/object:Gem::Version
112
220
  version: '0'
113
221
  requirements: []
114
- rubygems_version: 3.4.10
115
- signing_key:
222
+ rubygems_version: 4.0.16
116
223
  specification_version: 4
117
- summary: Fluentd plugin to limit JSON size
118
- test_files:
119
- - test/helper.rb
120
- - test/plugin/test_fluentd-json-size-limit.rb
224
+ summary: Fluentd filter that enforces a maximum JSON record size
225
+ test_files: []
data/.gitignore DELETED
@@ -1,2 +0,0 @@
1
- *.gem
2
- vendor