search
数据采集 采集源配置 Oracle 数据采集

Oracle 数据采集

简介

采集 Oracle 数据上报到 DataFlux 中

前置条件

  • 已安装 Oracle 11g 及以上版本。

配置

对用户进行网络连接授权

使用 Oracle DBA 权限用户,sqlplus / as sysdba

为用户 testuser (假设用户已经存在)开通 UTL_HTTPDBMS_LOCKconnect 权限,权限开通文档

传递参数时,注意 principal 的英文大小写问题,参数 host 为 DataWay 的 IP 地址。

GRANT CONNECT, RESOURCE TO testuser;

GRANT EXECUTE ON UTL_HTTP TO testuser;

GRANT EXECUTE ON DBMS_LOCK TO testuser;

BEGIN
    DBMS_NETWORK_ACL_ADMIN.CREATE_ACL (
        acl        => 'test.xml',
        description    => 'data collection test',
        principal    => 'TESTUSER',
        is_grant    => true,
        privilege    => 'connect');

    DBMS_NETWORK_ACL_ADMINI.ASSIGN_ACL (
        acl        => 'test.xml',
        host        => 'DataWayHost);

END;
/

创建数据表

登录到 Oracle testuser 用户,创建一张数据表用以绑定触发器。

CREATE TABLE serverinfo (
    hostname    varchar2(128),
    ip        varcahr2(16),
    cpucore        number );

INSERT INTO serverinfo (hostname, ip, cpucore) VALUES('ubuntu-db', '192.168.0.11', 4);

dataway发送函数

建立 HTTP 连接时,HOST 和 Header 要根据 dataway 文档进行填写。

Oracle UTL_HTTP 文档

UTL_HTTP.BEGIN_REQUEST() 的参数为 DataWay 的接收 URL,需要根据 DataWay 文档来进行配置

根据 DataWay 的文档,为 HTTP 添加对应的 Header;

调用UTL_HTTP.WRITE_TEXT() 前,一定要先添加Content-Type Header,否则接收方将无法获取有效的 body。注意顺序不能颠倒。

在触发器结束之前,需要调用UTL_HTTP.END_RESPONSE() 释放连接,否则会造成连接资源的泄露。

CREATE OR REPLACE FUNCTION send_data(content IN VARCHAR2)
    RETURN NUMBER 
IS
    requ    UTL_HTTP.REQ;
    resp    UTL_HTTP.RESP;
BEGIN
    requ := UTL_HTTP.BEGIN_REQUEST('http://DataWayIP:PORT/v1/write/metrics?template=&token=&shortrp=&precision=ms');
    UTL_HTTP.SET_HEADER(requ, 'User-Agent', 'test-agent');
    UTL_HTTP.SET_HEADER(requ, 'X-Trace-Id', 'test-traceid');
    UTL_HTTP.SET_HEADER(requ, 'X-Datakit-UUID', 'test-UUID');
    UTL_HTTP.SET_HEADER(requ, 'X-Version', 'test-version');
    UTL_HTTP.SET_HEADER(requ, 'Content-Length', LENGTHB(content));

    ULT_HTTP.WRITE_TEXT(requ, content);
    resp := UTL_HTTP.GET_RESPONSE(requ);

    RETURN 0;
END;

创建触发器

触发器规则使用insert,并绑定到第二步创建的数据表'serverinfo'。

行协议是 DataWay 接收数据的通用格式,包括MeasurementTagFieldTimestamp四个部分,格式如下:

weather,location=us-midwest temperature=82 1465839830100400200
  |    -------------------- --------------  |
  |             |             |             |
  |             |             |             |
+-----------+--------+-+---------+-+---------+
|measurement|,tag_set| |field_set| |timestamp|
+-----------+--------+-+---------+-+---------+

例如:serverinfo,hostname=macbook-pro ip="127.0.0.1",cpucore=8i 1582874030123

行协议文档,需要注意:

  • 英文状态下逗号、双引号、等于号和空格都需要转义,在前面加转义字符\

  • Field 的值如果是整型,需要在后面加个英文字符 i,以示跟浮点型的区别,比如上面的 cpucore

CREATE OR REPLACE TRIGGER test_trigger
AFTER INSERT ON serverinfo
FOR EACH ROW
DECLARE
    PRAGMA  AUTONOMOUS_TRANSACTION; -- 自制事务处理
    jobid   NUMBER;
    time    VARCHAR2;
    content VARCHAR2;
BEGIN
    -- 获取当前时间戳,单位是毫秒
    SELECT (SYSDATE - TO_DATE('1970-1-1 8', 'YYYY-MM-DD HH24')) * 86400000 + TO_NUMBER(TO_CHAR(SYSTIMESTAMP(3), 'FF')) AS MILLIONS INTO time FROM DUAL;

    -- 要发送的数据,行协议格式
    content VARCHAR2(4096) := 'serverinfo,hostname='||:NEW.hostname||' ip="'||:NEW.ip||'",cpucore='||:NEW.cpucore||'i '||time||'\n';

    -- 调用 send_data() 函数,提交到任务队列
    DBMS_JOB.SUBMIT(jobid, 'exec declare out number; begin out := send_data(content); end;');

    COMMIT;
END;
/

完成 Oracle 触发器的创建后,向 serverinfo 插入一条新数据。此时在数据的接收方(即 DataWay)将会收到数据并进行解析。

注意事项

DataWay 对应的接收路由如果开启 AK 验证(查看 DataWay 配置文件中是否开启),需要在 HTTP 请求添加 Authorization Header,并进行大量的数据加密解密操作,PL/SQL 实现起来会相对困难,推荐使用 WDF(Web-Datakit-Framework)作为中间层

即,Oracle 的数据发送到 WDF 后,由 WDF 进行 Header 添加、行协议转换、签名验证等操作,Oracle 只负责数据的发送,会大大减少触发器的复杂度。