Docker输入jdbc插件中的Logstash没有拾取新行

时间:2015-12-17 22:27:44

标签: jdbc elasticsearch duplicates logstash

我正在尝试在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字段是Date字段而不是时间戳字段。 sql_last_start是一个时间戳字段。比较是否正确?表中的日期不是UTC。我不知道如何将其转换为logstash理解的格式。

我尝试了几种比较方法,包括使用UTC将日期字段转换为时间戳字段 - 没有工作。

每次重新启动logstash都会遍历整个文件。为了防止重复,我使用了

中的解决方案

Logstash input jdbc is duplicating results

任何输入都会有所帮助。

1 个答案:

答案 0 :(得分:0)

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

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

my_unixtimestamp_column > 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引擎有意义。

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