# logstash 采集 oracle 表数据

# 背景

因为项目数据量比较大,而且需要作一些 metrics 给大家看,所以准备先将数据存储到 ES,然后通过 Grafana 作图。

为什么不从 grafana 直连 oracle 呢?因为 Grafana 连接 oracle 需要安装插件,并且这个插件需要付费使用参考。所以为了节约不必要的花费,我们将数据先转存到 ES(正好我们之前有搭建过 es 集群),然后从 grafana 配置 es 作为数据源。

现配置 logstash 采集 oracle 数据。

# 安装 logstash

可以通过压缩包(tar.gz)或者 RPM 包等形式安装,推荐 RPM 包形式安装,压缩包的形式安装可以玩一玩,但是由于无法使用 systemctl 等一些功能,后续配置稍微比较麻烦。

# 前期准备

[root@chumingcheng logstash]# wget https://artifacts.elastic.co/downloads/logstash/logstash-7.6.1.rpm
[root@chumingcheng logstash]# rpm -ivh logstash-7.6.1.rpm
[root@chumingcheng logstash]# cd /var/log/logstash/     # logstash 日志 log 目录
[root@chumingcheng logstash]# cd /etc/logstash/conf.d/   # logstash 配置文件目录
[root@chumingcheng conf.d]# mkdir table_user.sql    # 创建采集数据的 sql
[root@chumingcheng conf.d]# mkdir table_user.conf   # logstash 采集配置
[root@chumingcheng conf.d]# vi table_user.sql     # 编辑 sql

# 编辑 sql 脚本

select * from table_user where lastmodifiedtime > cast(:sql_last_value as date)

# 编辑 logstash 配置

[root@chumingcheng conf.d]# vi table_user.conf   # 编辑采集配置

先给一个简单的配置用来测试,很简单,接收控制台输入,然后将数据输出到 es,并且输出到控制台,所以这里有两个输出

input { stdin { } }
output {
  elasticsearch {
    index => "myindextest"
    hosts => ["localhost:9200"]
    user => "elastic"
    password => "********"
  }
  stdout { codec => rubydebug }
}

下面是一个正式的从 oracle 采集并输出到 es 的配置

input{
    stdin{
    }
    jdbc{
        jdbc_connection_string => "jdbc:oracle:thin:@xx.xx.xxx.xx:1701/xxxservicename"
        jdbc_user => "xxx"
        jdbc_password => "********"
        jdbc_driver_library => "/opt/jdbc/ojdbc8-full/ojdbc8.jar"
        jdbc_driver_class => "Java::oracle.jdbc.driver.OracleDriver"
        jdbc_paging_enabled => "true"
        jdbc_page_size => "100000"
        jdbc_fetch_size => "100000"
        statement_filepath => "/etc/logstash/conf.d/table_user.sql"
        record_last_run => "true"
        use_column_value => "true"
        tracking_column => "lastmodifiedtime"
        tracking_column_type => "timestamp"
        last_run_metadata_path => "/var/log/logstash/last_run_metadata_for_table_user"
        clean_run => "false"
        schedule => "* * * * *"
        type => "table_user"
    }
}


output{
    if [type] == "table_user" {
        elasticsearch{
            hosts => ["xxx.xxx.xxx.xxx:9200"]
            user => "elastic"
            password => "**********"
            index => "table_user"
            document_id => "%{column1}_%{column2}_%{column3}"
        }
    }
}

测试配置并启动

[root@chumingcheng conf.d]# /usr/share/logstash/bin/logstash -f table_user.conf -t   # 测试配置
[root@chumingcheng conf.d]# /usr/share/logstash/bin/logstash -f table_user.conf   # 启动测试,看 log 调试
[root@chumingcheng conf.d]# systemctl start logstash   # 上一步没问题的话,执行这个命令后台启动

# 问题

  1. 启动 logstash 时可能遇到 /tmp 路径访问的问题,执行下 mount -o remount,exec /tmp 试试
  2. 也可能遇到 ojdbc driver 的问题,可以尝试更换下版本,比如从 ojdbc10 降低到 ojdbc8
  3. 必要时使用 chmod -777 ojdbc10 给个 777 权限试试

# 注意

  1. 因为 sql 是以 lastmodifiedtime 为准的,所以对于老的数据没有办法删除,可以尝试通过 api 的方式删除 es 里不想要的数据
  2. 第一次启动 logstash 后,logstash 会自动去配置的表里拿所有数据,将这些数据同步到 es 里你新建的 index 下面
  3. 注意给你的 index 创建一个 index pattern,这样你就能从 kibana 里通过 Lucene 或者 KQL 查询你的数据了
  4. 注意 logstash 的 output 里有设置一个 documnet_id, 这样后续如果 logstash 再次抓到了一条相同 document_id 的数据时,就会覆盖前面一条老的数据,所以尽量用 oracle 表主键或聚合主键作为 document_id
  5. 注意用 systemctl 启动前进行 配置文件测试 和启动测试,这样方便看 log 找问题
  6. 注意 table_user 在 input 和 output 是要关联起来的
  7. 重要:理论上我应该使用更高版本的 logstash 去规避 log4j 漏洞,但是配合相应的 es 和 kibana 都要做 upgrade,所以没有去做
  8. 我的 es 和 kibana 都是普通用户启动的,因为有用户级别的警告,不过 logstash 我直接用 root 用户启动了,暂时没发现什么问题
  9. lastmodifiedtime 必须是 timestamp 类型或者 int 类型,timestamp 对应 oracle 里 Date 类型,int 可以对应自增主键
  10. sql_last_value 是固定的命名,不要试图改变它
  11. 我这里是一个 conf 配置文件采集一个 oracle 表,从上面一个 conf 对应一个 sql 文件就可以看出,
  12. 实际中会有很多 logstash 的 conf 配置,直接放在 conf.d 目录下就行,通过 systemctl 启动会自动加载 conf.d 目录下所有 conf 文件,不用一一指定配置文件启动。
更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

Jalen Chu 微信支付

微信支付

Jalen Chu 支付宝

支付宝

Jalen Chu 公众号

公众号