【问题标题】:Logstash in docker input jdbc plugin not picking up new rowsdocker input jdbc插件中的Logstash没有拾取新行
【发布时间】:2018-09-27 06:11:05
【问题描述】:

我正在尝试在 dockerized logstash 容器中使用输入 jdbc 插件。

jdbc {
type => "logs"
jdbc_driver_library => "/opt/logstash/driver/ojdbc6.jar"
jdbc_driver_class => "Java::oracle.jdbc.driver.OracleDriver"
jdbc_connection_string => "jdbc:oracle:thin:@//<host>:<port>/<database>"
jdbc_user => "****"
jdbc_password => "****"
jdbc_fetch_size => 1000
schedule => "* * * * *" 
statement => "select ROWIDTONCHAR ( rowid ) AS rid_obj ,CONNECTION_ID, IPADDRESS,  START_DATE,  ELAPSED_TIME_MS,  GUI_EVENT_TYPE,  GUI_EVENT_NAME,  GUI_EVENT_PARAMS 
                 from table where start_date>:sql_last_start"
clean_run => false
record_last_run => true
last_run_metadata_path => "/opt/logstash/lastrun/.logstash_jdbc_last_run"
}   

元数据文件的卷映射如下:

-v - /opt/logstash/lastrun/.logstash_jdbc_last_run:/opt/logstash/lastrun/.logstash_jdbc_last_run

问题: start_date 字段是日期字段而不是时间戳字段。 sql_last_start 是一个时间戳字段。比较是否正确?表中的日期不是 UTC。我不确定如何将其转换为 logstash 可以理解的格式。

我尝试了几种比较方法,包括将日期字段转换为带有 UTC 的时间戳字段 - 均无效。

每次我重新启动 logstash 时都会检查整个文件。为了防止重复,我使用了来自

的解决方案

Logstash input jdbc is duplicating results

任何意见都会有所帮助。

【问题讨论】:

  • 在进一步检查日志后,我发现日期以这样的方式存储在元数据文件中 - 2015-12-18 17:14:00.236000000 Z 而在日志中显示为 2015-12 -18 17:14:00 世界标准时间。我无法追踪配置格式的位置。
  • 有人遇到过这个问题吗?如果是这样,你能分享你的解决方案吗?谢谢
  • start_date列的数据格式是什么?如果你给我一些关于该专栏内容的例子,我们可以解决这个问题。

标签: jdbc elasticsearch duplicates logstash


【解决方案1】:

我也无法找到格式化 jdbc 插件在上次运行元数据文件中存储的时间戳的方法。

所以我的解决方案是使用 SQL 函数进行转换,将存储在 :sql_last_value 中的日期时间戳重新格式化为可以与数据库中的时间戳进行比较的值。我使用的是 mysql,在 mysql 中,我通过在查询中执行此操作将上次运行元数据文件中的 2018-09-26 18:42:00.007000000 Z 时间戳转换为 unixtimestamp:

my_unixtimestamp_column &gt; UNIX_TIMESTAMP(STR_TO_DATE(:sql_last_value, '%Y-%m-%d %T.%f000 Z'))

我不知道您是否在 start_date 列中使用 Oracle 的 TIMESTAMP 或 DATE 数据类型,或者您为要呈现的数据创建的格式。所以,我将根据两个猜测来回答,并且也许您可以从那里调整您的解决方案。

我的第一个猜测是 start_date 是一种 TIMESTAMP 数据类型,并且您将其格式化如下:DD-MON-YY HH:MI:SSXFF 所以您的数据最终看起来像这样:

01-JAN-03 02:00:00.000000 AM 01-JAN-04 04:21:55.891000 AM 等等

因此,任务是将存储在 :sql_last_value 中的时间戳转换为数据库引擎可以在 sql 查询本身中与其列值进行比较的格式。

鉴于上述假设,这是我可能的解决方案:

statement => "select ROWIDTONCHAR ( rowid ) AS rid_obj ,CONNECTION_ID, IPADDRESS,  START_DATE,  ELAPSED_TIME_MS,  GUI_EVENT_TYPE,  GUI_EVENT_NAME,  GUI_EVENT_PARAMS 
             from table where start_date>TO_TIMESTAMP_TZ(:sql_last_value, 'YYYY-MM-DD HH.MI.SSXFF Z')"

由于我没有可供测试的 Oracle 系统并且不知道您使用的格式,因此您的解决方案会有所不同,但这应该会为您指明正确的方向。基本思想是将上次运行元文件中捕获的:sql_last_value 转换为与您存储在列中的日期或时间戳格式相同的日期或时间戳格式,因此您的比较对您正在使用的 SQL 引擎有意义。

虽然理论上可以将数据库列中的值格式转换为上次运行元数据中存储的日期格式,但我认为这会慢得多。将静态存储日期转换一次以与表中的行进行比较应该比转换表中的每一行以与静态字符串进行比较更快。高温

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-09
    • 2011-12-03
    • 2016-09-22
    • 1970-01-01
    • 1970-01-01
    • 2021-03-05
    • 2018-08-23
    • 1970-01-01
    相关资源
    最近更新 更多