From cfbb9e13ba214027be998fda57fc20f2328a9dad Mon Sep 17 00:00:00 2001 From: Shizuo Fujita Date: Wed, 9 Sep 2026 17:10:08 +0900 Subject: [PATCH] support json gem v3.x (#5492) **Which issue(s) this PR fixes**: Fixes # **What this PR does / why we need it**: json 3.0 dropped the positional options argument from `JSON.parse`, so every call passing `Fluent::DEFAULT_JSON_PARSE_OPTIONS` now fails with `ArgumentError: wrong number of arguments (given 2, expected 1)`. Ref. https://github.com/fluent/fluentd/actions/runs/34311091836 Pass the options as keyword arguments instead. **Docs Changes**: N/A **Release Note**: * Support json gem v3.x Signed-off-by: Shizuo Fujita --- lib/fluent/command/cat.rb | 2 +- lib/fluent/config/literal_parser.rb | 4 ++-- lib/fluent/config/types.rb | 4 ++-- lib/fluent/daemon.rb | 2 +- lib/fluent/plugin/filter_record_transformer.rb | 2 +- lib/fluent/plugin/in_monitor_agent.rb | 2 +- lib/fluent/plugin/in_sample.rb | 2 +- lib/fluent/plugin/parser_json.rb | 2 +- lib/fluent/plugin/sd_file.rb | 2 +- lib/fluent/plugin/storage_local.rb | 4 ++-- 10 files changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/fluent/command/cat.rb b/lib/fluent/command/cat.rb index 31de6b254a..2439c96a73 100644 --- a/lib/fluent/command/cat.rb +++ b/lib/fluent/command/cat.rb @@ -326,7 +326,7 @@ def abort_message(time, record) when 'json' begin while line = $stdin.gets - record = JSON.parse(line, Fluent::DEFAULT_JSON_PARSE_OPTIONS) + record = JSON.parse(line, **Fluent::DEFAULT_JSON_PARSE_OPTIONS) w.write(record) end rescue diff --git a/lib/fluent/config/literal_parser.rb b/lib/fluent/config/literal_parser.rb index 8868dc0a96..c24ddb896e 100644 --- a/lib/fluent/config/literal_parser.rb +++ b/lib/fluent/config/literal_parser.rb @@ -252,7 +252,7 @@ def scan_json(is_array) # '{"foo":"bar", #' -> '{"foo":"bar"}' (to check) parsed = nil begin - parsed = JSON.parse(buffer + line_buffer.rstrip.sub(/,$/, '') + (is_array ? "]" : "}"), Fluent::DEFAULT_JSON_PARSE_OPTIONS) + parsed = JSON.parse(buffer + line_buffer.rstrip.sub(/,$/, '') + (is_array ? "]" : "}"), **Fluent::DEFAULT_JSON_PARSE_OPTIONS) rescue JSON::ParserError # This '#' is in json string literals end @@ -287,7 +287,7 @@ def scan_json(is_array) line_buffer << char begin - result = JSON.parse(buffer + line_buffer, Fluent::DEFAULT_JSON_PARSE_OPTIONS) + result = JSON.parse(buffer + line_buffer, **Fluent::DEFAULT_JSON_PARSE_OPTIONS) rescue JSON::ParserError # Incomplete json string yet end diff --git a/lib/fluent/config/types.rb b/lib/fluent/config/types.rb index 2fe5cd4c8e..26f104e4dd 100644 --- a/lib/fluent/config/types.rb +++ b/lib/fluent/config/types.rb @@ -201,7 +201,7 @@ def self.hash_value(val, opts = {}, name = nil) return nil if val.nil? param = if val.is_a?(String) - val.start_with?('{') ? JSON.parse(val, Fluent::DEFAULT_JSON_PARSE_OPTIONS) : Hash[val.strip.split(/\s*,\s*/).map{|v| v.split(':', 2)}] + val.start_with?('{') ? JSON.parse(val, **Fluent::DEFAULT_JSON_PARSE_OPTIONS) : Hash[val.strip.split(/\s*,\s*/).map{|v| v.split(':', 2)}] else val end @@ -228,7 +228,7 @@ def self.array_value(val, opts = {}, name = nil) return nil if val.nil? param = if val.is_a?(String) - val.start_with?('[') ? JSON.parse(val, Fluent::DEFAULT_JSON_PARSE_OPTIONS) : val.strip.split(/\s*,\s*/) + val.start_with?('[') ? JSON.parse(val, **Fluent::DEFAULT_JSON_PARSE_OPTIONS) : val.strip.split(/\s*,\s*/) elsif val.is_a?(Array) val elsif val.is_a?(Numeric) || val == true || val == false diff --git a/lib/fluent/daemon.rb b/lib/fluent/daemon.rb index ed45758042..b76bbb9da1 100644 --- a/lib/fluent/daemon.rb +++ b/lib/fluent/daemon.rb @@ -10,5 +10,5 @@ server_module = Fluent.const_get(ARGV[0]) worker_module = Fluent.const_get(ARGV[1]) -params = JSON.parse(ARGV[2], Fluent::DEFAULT_JSON_PARSE_OPTIONS) +params = JSON.parse(ARGV[2], **Fluent::DEFAULT_JSON_PARSE_OPTIONS) ServerEngine::Daemon.run_server(server_module, worker_module) { Fluent::Supervisor.serverengine_config(params) } diff --git a/lib/fluent/plugin/filter_record_transformer.rb b/lib/fluent/plugin/filter_record_transformer.rb index 57e4cba260..bccb09299d 100644 --- a/lib/fluent/plugin/filter_record_transformer.rb +++ b/lib/fluent/plugin/filter_record_transformer.rb @@ -117,7 +117,7 @@ def filter_stream(tag, es) def parse_value(value_str) if value_str.start_with?('{', '[') - JSON.parse(value_str, Fluent::DEFAULT_JSON_PARSE_OPTIONS) + JSON.parse(value_str, **Fluent::DEFAULT_JSON_PARSE_OPTIONS) else value_str end diff --git a/lib/fluent/plugin/in_monitor_agent.rb b/lib/fluent/plugin/in_monitor_agent.rb index 3e743a50cc..e4cd5576ca 100644 --- a/lib/fluent/plugin/in_monitor_agent.rb +++ b/lib/fluent/plugin/in_monitor_agent.rb @@ -102,7 +102,7 @@ def render_json(obj, code: 200, pretty_json: nil) end def render_ltsv(obj, code: 200) - normalized = JSON.parse(obj.to_json, Fluent::DEFAULT_JSON_PARSE_OPTIONS) + normalized = JSON.parse(obj.to_json, **Fluent::DEFAULT_JSON_PARSE_OPTIONS) text = '' normalized.each do |hash| row = [] diff --git a/lib/fluent/plugin/in_sample.rb b/lib/fluent/plugin/in_sample.rb index a2b5b3926f..1bdc9821f9 100644 --- a/lib/fluent/plugin/in_sample.rb +++ b/lib/fluent/plugin/in_sample.rb @@ -45,7 +45,7 @@ class SampleInput < Input desc "The sample data to be generated. An array of JSON hashes or a single JSON hash." config_param :sample, alias: :dummy, default: [{"message" => "sample"}] do |val| begin - parsed = JSON.parse(val, Fluent::DEFAULT_JSON_PARSE_OPTIONS) + parsed = JSON.parse(val, **Fluent::DEFAULT_JSON_PARSE_OPTIONS) rescue JSON::ParserError => ex # Fluent::ConfigParseError, "got incomplete JSON" will be raised # at literal_parser.rb with --use-v1-config, but I had to diff --git a/lib/fluent/plugin/parser_json.rb b/lib/fluent/plugin/parser_json.rb index ebbcf333f4..7275ad2de6 100644 --- a/lib/fluent/plugin/parser_json.rb +++ b/lib/fluent/plugin/parser_json.rb @@ -41,7 +41,7 @@ class JSONParser < Parser # Use a shared proc rather than a per-call lambda so that # configure_json_parser returns the same object every time. - JSON_PARSE_PROC = ->(text) { JSON.parse(text, Fluent::DEFAULT_JSON_PARSE_OPTIONS) } + JSON_PARSE_PROC = ->(text) { JSON.parse(text, **Fluent::DEFAULT_JSON_PARSE_OPTIONS) } def configure(conf) if conf.has_key?('time_format') diff --git a/lib/fluent/plugin/sd_file.rb b/lib/fluent/plugin/sd_file.rb index 0b30541c35..322f7814d0 100644 --- a/lib/fluent/plugin/sd_file.rb +++ b/lib/fluent/plugin/sd_file.rb @@ -76,7 +76,7 @@ def parser -> (v) { YAML.safe_load(v).map } when :json require 'json' - -> (v) { JSON.parse(v, Fluent::DEFAULT_JSON_PARSE_OPTIONS) } + -> (v) { JSON.parse(v, **Fluent::DEFAULT_JSON_PARSE_OPTIONS) } end end diff --git a/lib/fluent/plugin/storage_local.rb b/lib/fluent/plugin/storage_local.rb index bc66c83d2e..8afb3f05eb 100644 --- a/lib/fluent/plugin/storage_local.rb +++ b/lib/fluent/plugin/storage_local.rb @@ -90,7 +90,7 @@ def configure(conf) log.warn "detect empty plugin storage file during startup. Ignored: #{@path}" return end - data = JSON.parse(data, Fluent::DEFAULT_JSON_PARSE_OPTIONS) + data = JSON.parse(data, **Fluent::DEFAULT_JSON_PARSE_OPTIONS) raise Fluent::ConfigError, "Invalid contents (not object) in plugin storage file: '#{@path}'" unless data.is_a?(Hash) rescue => e log.error "failed to read data from plugin storage file", path: @path, error: e @@ -114,7 +114,7 @@ def load return unless File.exist?(@path) begin json_string = File.open(@path, 'r:utf-8:utf-8'){ |io| io.read } - json = JSON.parse(json_string, Fluent::DEFAULT_JSON_PARSE_OPTIONS) + json = JSON.parse(json_string, **Fluent::DEFAULT_JSON_PARSE_OPTIONS) unless json.is_a?(Hash) log.error "broken content for plugin storage (Hash required: ignored)", type: json.class log.debug "broken content", content: json_string