You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Logstash installation source (e.g. built from source, with a package manager: DEB/RPM, expanded from tar or zip archive, docker): any
How is Logstash being run (e.g. as a service/service manager: systemd, upstart, etc. Via command line, docker/kubernetes): any
How was the Logstash Plugin installed: default
JVM (e.g. java -version): any
OS version (uname -a if on a Unix-like system): any
Description of the problem including expected versus actual behavior**:
GIVEN: a database table with times stored in a local timezone
GIVEN: a logstash instance in the same shared local timezone
OBSERVED: an instance of the JDBC input plugin configured without specifying jdbc_default_timezone will load timestamps correctly (that is: 2023-12-31T18:00:00.000 in America/Chicago becomes 2024-01-01T00:00:00.000Z)
HOWEVER: if another instance of the jdbc input plugin whose jdbc_default_timezone is set exists (or has ever existed) in the process:
OBSERVED: an instance of the JDBC input plugin configured without specifying jdbc_default_timezone will load timestamps incorrectly (that is: 2023-12-31T18:00:00.000 in America/Chicago becomes 2023-12-31T18:00:00.000Z)
Workaround
Always supply the jdbc_default_timezone when defining jdbc input plugins, optionally using TZ environment variable that is present on most systems and controls the Logstash process's timezone:
jdbc_default_timezone => "${TZ}"
Steps to reproduce:
This is easiest to reproduce in postgresql, although the concept applies to any database vendor.
download the jdbc driver jar, and export its absolute path to POSTGRESQL_JDBC_DRIVER_JAR:
bootstrap a local postgresql server and load it with data. In this case we create a view containing rows that have equivalent timestamps from the perspective of different time zones:
alter database postgres set timezone to 'America/Chicago';
create table timezones (id varchar(32) primary key);
insert into timezones values ('Etc/UTC'),('America/Chicago'),('Europe/Berlin');
create view timestamps_annotated as (select id as timezone, utc_iso8601, utc_iso8601::timestamptz at time zone id as timestamp_value from (select id, '2024-01-01T00:00:00.000Z' as utc_iso8601 from timezones) as intermediate);
and observe the values for timestamp_value, in the context of the respective timezone are equivalent to the origin utc_iso8601 value:
create readonly role with appropriate permissions to select from the table and a read_user who has the role:
create role readaccess;
grant connect on database postgres to readaccess;
grant usage on schema public to readaccess;
grant select on timestamps_annotated to readaccess;
create user read_user with password 'p4$$w0rd';
grant readaccess to read_user;
run a pipeline with a single jdbc input that has no jdbc_default_timezone:
Observe that all plugins that have jdbc_default_timezone defined correctly map their timestamp_value, but the the all-defaults plugin instance whose definition has not changed no longer handles timestamp_value correctly, and instead handles the value as if it were in Etc/UTC:
It boils down to a difference in the two different paths taken for time-like objects depending on the Sequel.datetime_class, which is modified when a single plugin contains a jdbc_default_timezone directive and activates Sequel's named timezones extension.
Time (default): uses Time.parse, which assumes local offset when none is given, and since the database is not configured with a timezone, no additional shifting is necessary
DateTime (when any instance has jdbc_default_timezone): uses DateTime.parse, which assumes UTC when no offset is given, and relies on the database instance's current timezone (as configured by the plugin's jdbc_default_timezone) to shift to the appropriate offset. When a plugin's database does not have a current timezone, the value remains in UTC.
The text was updated successfully, but these errors were encountered:
Sequel.datetime_class = Time is now supported when using the
named_timezones extension.
Behaviour of jdbc_default_timezone => "${TZ}" appears identical to the behaviour when the named timezones extension is not enabled (need to validate in context of plugin_timezone option, which is also leaky because it modifies Sequel.default_timezone)
Logstash information:
Please include the following information:
JVM (e.g.
java -version
): anyOS version (
uname -a
if on a Unix-like system): anyDescription of the problem including expected versus actual behavior**:
GIVEN: a database table with times stored in a local timezone
GIVEN: a logstash instance in the same shared local timezone
OBSERVED: an instance of the JDBC input plugin configured without specifying
jdbc_default_timezone
will load timestamps correctly (that is:2023-12-31T18:00:00.000
inAmerica/Chicago
becomes2024-01-01T00:00:00.000Z
)HOWEVER: if another instance of the jdbc input plugin whose
jdbc_default_timezone
is set exists (or has ever existed) in the process:OBSERVED: an instance of the JDBC input plugin configured without specifying
jdbc_default_timezone
will load timestamps incorrectly (that is:2023-12-31T18:00:00.000
inAmerica/Chicago
becomes2023-12-31T18:00:00.000Z
)Workaround
Always supply the
jdbc_default_timezone
when defining jdbc input plugins, optionally usingTZ
environment variable that is present on most systems and controls the Logstash process's timezone:Steps to reproduce:
This is easiest to reproduce in postgresql, although the concept applies to any database vendor.
download the jdbc driver jar, and export its absolute path to
POSTGRESQL_JDBC_DRIVER_JAR
:bootstrap a local postgresql server and load it with data. In this case we create a view containing rows that have equivalent timestamps from the perspective of different time zones:
and observe the values for
timestamp_value
, in the context of the respectivetimezone
are equivalent to the originutc_iso8601
value:create
readonly
role with appropriate permissions to select from the table and aread_user
who has the role:run a pipeline with a single jdbc input that has no
jdbc_default_timezone
:Observe that the
timestamp_value
is equivalent to the originutc_iso8601
timestamp, which is the correct behaviour we expect:run a pipeline that has a mix of jdbc input plugins, some specifying
jdbc_default_timezone
and some not:Observe that all plugins that have
jdbc_default_timezone
defined correctly map theirtimestamp_value
, but the theall-defaults
plugin instance whose definition has not changed no longer handlestimestamp_value
correctly, and instead handles the value as if it were inEtc/UTC
:Analysis
This issue shares a root cause with #53.
It boils down to a difference in the two different paths taken for time-like objects depending on the
Sequel.datetime_class
, which is modified when a single plugin contains ajdbc_default_timezone
directive and activates Sequel's named timezones extension.Time
(default): usesTime.parse
, which assumes local offset when none is given, and since the database is not configured with a timezone, no additional shifting is necessaryDateTime
(when any instance hasjdbc_default_timezone
): usesDateTime.parse
, which assumes UTC when no offset is given, and relies on the database instance's current timezone (as configured by the plugin'sjdbc_default_timezone
) to shift to the appropriate offset. When a plugin's database does not have a current timezone, the value remains in UTC.The text was updated successfully, but these errors were encountered: