From 7b00c70bb95bc61db84df2c6ec6b77f9942841bc Mon Sep 17 00:00:00 2001 From: Jonas Rutishauser Date: Wed, 29 May 2019 00:02:29 +0200 Subject: [PATCH 1/4] Fix error if timezone with name is used in parser Signed-off-by: Jonas Rutishauser --- lib/fluent/time.rb | 23 +++++++++++++++-------- test/test_time_parser.rb | 8 ++++++++ 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/lib/fluent/time.rb b/lib/fluent/time.rb index 30de690c88..643bff9a9b 100644 --- a/lib/fluent/time.rb +++ b/lib/fluent/time.rb @@ -201,12 +201,14 @@ def initialize(format = nil, localtime = true, timezone = nil) format_with_timezone = format && (format.include?("%z") || format.include?("%Z")) # unixtime_in_expected_tz = unixtime_in_localtime + offset_diff - offset_diff = case - when format_with_timezone then nil - when timezone then Time.now.localtime.utc_offset - Time.zone_offset(timezone) - when localtime then 0 - else Time.now.localtime.utc_offset # utc - end + offset_diff = ->(t){ + case + when format_with_timezone then nil + when timezone then Time.now.localtime.utc_offset - offset_utc(timezone, t) + when localtime then 0 + else Time.now.localtime.utc_offset # utc + end + } strptime = format && (Strptime.new(format) rescue nil) @@ -214,12 +216,17 @@ def initialize(format = nil, localtime = true, timezone = nil) when format_with_timezone && strptime then ->(v){ Fluent::EventTime.from_time(strptime.exec(v)) } when format_with_timezone then ->(v){ Fluent::EventTime.from_time(Time.strptime(v, format)) } when format == '%iso8601' then ->(v){ Fluent::EventTime.from_time(Time.iso8601(v)) } - when strptime then ->(v){ t = strptime.exec(v); Fluent::EventTime.new(t.to_i + offset_diff, t.nsec) } - when format then ->(v){ t = Time.strptime(v, format); Fluent::EventTime.new(t.to_i + offset_diff, t.nsec) } + when strptime then ->(v){ t = strptime.exec(v); Fluent::EventTime.new(t.to_i + offset_diff.call(t), t.nsec) } + when format then ->(v){ t = Time.strptime(v, format); Fluent::EventTime.new(t.to_i + offset_diff.call(t), t.nsec) } else ->(v){ Fluent::EventTime.parse(v) } end end + def offset_utc(timezone, time) + offset = Fluent::Timezone.utc_offset(timezone) + offset.respond_to?(:call) ? offset.call(time) : offset + end + # TODO: new cache mechanism using format string def parse(value) unless value.is_a?(String) diff --git a/test/test_time_parser.rb b/test/test_time_parser.rb index dc7c1a39a3..d7b5c07704 100644 --- a/test/test_time_parser.rb +++ b/test/test_time_parser.rb @@ -80,6 +80,14 @@ def test_parse_string_with_expected_timezone assert_equal_event_time(time, event_time("2016-09-02 18:42:31.123456789 -07:00", format: '%Y-%m-%d %H:%M:%S.%N %z')) end + def test_parse_time_with_expected_timezone_name + time = with_timezone("UTC-09") do + parser = Fluent::TimeParser.new("%Y-%m-%d %H:%M:%S.%N", nil, "Europe/Zurich") + parser.parse("2016-12-02 18:42:31.123456789") + end + assert_equal_event_time(time, event_time("2016-12-02 18:42:31.123456789 +01:00", format: '%Y-%m-%d %H:%M:%S.%N %z')) + end + sub_test_case 'TimeMixin::Parser' do class DummyForTimeParser include Fluent::Configurable From 098cde182a1d22016eacdc347c710cd5f87d37e2 Mon Sep 17 00:00:00 2001 From: Jonas Rutishauser Date: Wed, 5 Jun 2019 07:34:44 +0200 Subject: [PATCH 2/4] performance improvment Signed-off-by: Jonas Rutishauser --- lib/fluent/time.rb | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/lib/fluent/time.rb b/lib/fluent/time.rb index 643bff9a9b..3ecc42e307 100644 --- a/lib/fluent/time.rb +++ b/lib/fluent/time.rb @@ -201,14 +201,18 @@ def initialize(format = nil, localtime = true, timezone = nil) format_with_timezone = format && (format.include?("%z") || format.include?("%Z")) # unixtime_in_expected_tz = unixtime_in_localtime + offset_diff - offset_diff = ->(t){ - case - when format_with_timezone then nil - when timezone then Time.now.localtime.utc_offset - offset_utc(timezone, t) - when localtime then 0 - else Time.now.localtime.utc_offset # utc + offset_diff = case + when format_with_timezone then nil + when timezone then + offset = Fluent::Timezone.utc_offset(timezone) + if offset.respond_to?(:call) + ->(t) { Time.now.localtime.utc_offset - offset.call(t) } + else + ->(t) { Time.now.localtime.utc_offset - offset } end - } + when localtime then 0 + else Time.now.localtime.utc_offset # utc + end strptime = format && (Strptime.new(format) rescue nil) @@ -216,17 +220,17 @@ def initialize(format = nil, localtime = true, timezone = nil) when format_with_timezone && strptime then ->(v){ Fluent::EventTime.from_time(strptime.exec(v)) } when format_with_timezone then ->(v){ Fluent::EventTime.from_time(Time.strptime(v, format)) } when format == '%iso8601' then ->(v){ Fluent::EventTime.from_time(Time.iso8601(v)) } - when strptime then ->(v){ t = strptime.exec(v); Fluent::EventTime.new(t.to_i + offset_diff.call(t), t.nsec) } - when format then ->(v){ t = Time.strptime(v, format); Fluent::EventTime.new(t.to_i + offset_diff.call(t), t.nsec) } + when strptime then + if offset_diff.respond_to?(:call) + ->(v) { t = strptime.exec(v); Fluent::EventTime.new(t.to_i + offset_diff.call(t), t.nsec) } + else + ->(v) { t = strptime.exec(v); Fluent::EventTime.new(t.to_i + offset_diff, t.nsec) } + end + when format then ->(v){ t = Time.strptime(v, format); Fluent::EventTime.new(t.to_i + offset_diff, t.nsec) } else ->(v){ Fluent::EventTime.parse(v) } end end - def offset_utc(timezone, time) - offset = Fluent::Timezone.utc_offset(timezone) - offset.respond_to?(:call) ? offset.call(time) : offset - end - # TODO: new cache mechanism using format string def parse(value) unless value.is_a?(String) From 93b6716587f7cf66adb28b5c70199b82c7796a5b Mon Sep 17 00:00:00 2001 From: Jonas Rutishauser Date: Wed, 5 Jun 2019 07:37:36 +0200 Subject: [PATCH 3/4] performance improvement Signed-off-by: Jonas Rutishauser --- lib/fluent/time.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/fluent/time.rb b/lib/fluent/time.rb index 3ecc42e307..d112bde2a4 100644 --- a/lib/fluent/time.rb +++ b/lib/fluent/time.rb @@ -208,7 +208,7 @@ def initialize(format = nil, localtime = true, timezone = nil) if offset.respond_to?(:call) ->(t) { Time.now.localtime.utc_offset - offset.call(t) } else - ->(t) { Time.now.localtime.utc_offset - offset } + Time.now.localtime.utc_offset - offset end when localtime then 0 else Time.now.localtime.utc_offset # utc From 46196aee9fa1eb1af537fbb551bd48ced0737346 Mon Sep 17 00:00:00 2001 From: Jonas Rutishauser Date: Wed, 5 Jun 2019 18:53:20 +0200 Subject: [PATCH 4/4] fixed issue found by review Signed-off-by: Jonas Rutishauser --- lib/fluent/time.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/fluent/time.rb b/lib/fluent/time.rb index d112bde2a4..dbe1ddee35 100644 --- a/lib/fluent/time.rb +++ b/lib/fluent/time.rb @@ -226,7 +226,12 @@ def initialize(format = nil, localtime = true, timezone = nil) else ->(v) { t = strptime.exec(v); Fluent::EventTime.new(t.to_i + offset_diff, t.nsec) } end - when format then ->(v){ t = Time.strptime(v, format); Fluent::EventTime.new(t.to_i + offset_diff, t.nsec) } + when format then + if offset_diff.respond_to?(:call) + ->(v){ t = Time.strptime(v, format); Fluent::EventTime.new(t.to_i + offset_diff.call(t), t.nsec) } + else + ->(v){ t = Time.strptime(v, format); Fluent::EventTime.new(t.to_i + offset_diff, t.nsec) } + end else ->(v){ Fluent::EventTime.parse(v) } end end