之所以選擇4.4.0,因為公司還在用Java6編程……
但是項目的需求是:實施人員上傳kettle的文件,然后在界面上點擊運行,運行完之后需要在頁面上看日志。
當然 kettle 是自帶日志輸出功能的,不過我們總不能跟客戶說:“你在kettle里面定義好日志輸出,然后自己去數據庫或者某個文件夾中查詢日志即可”
當然不可能讓客戶去看數據庫或者服務器上生成的日志文件。那現在的問題是怎樣讓自己的代碼控制 kettle 的日志。只要能夠通過程序獲取,或者按照我們的規則重定向輸出,那么事情就好辦了,我們就可以按照自己的意願存儲和查詢日志(job和trans運行方式不一樣,但是在代碼層面 編程的方式 是類似的,下面只說Job,看懂了Job,Trans自然就明白了)
Kettle中自帶日志輸出功能,先說下在kettle中怎么輸出日志到數據庫表
1、切換到主對象樹選項卡
2、雙擊 自己 寫的 Job ,就會彈出一個窗口
切換到日志選項卡
左邊選擇Job
右邊配一下數據庫連接(這個窗口的最下方有個SQL按鈕,點擊一下可以看到建表的SQL)
然后配置連接下面的 一些屬性
然后運行 Job 的時候,就會記錄日志到數據庫中:
會記錄很多字段,圖中只是一部分。關鍵字段有3個:
CHANNEL_ID 可以關聯到某個Job(下面會講怎么關聯。可以通過此運行記錄找到這條數據,然后找到日志信息)
ERRORS 某個Job的錯誤個數,0表示完美運行完畢(如果不為0,說明有錯誤)
LOG_FIELD 這個是BLOB或者TEXT字段,存放的是日志詳情(這就是我們需要的內容)
這樣生成的日志我們能夠查詢,在Job中有個方法 job.getLogChannelId() ,可以獲取CHANNEL_ID,通過這個字段可以關聯到日志表。但是這么做需要什么前提呢?
前提是 用 kettle 的人要手動去配置一下我上面所說的步驟:打開日志功能,配置連接
如果條件允許,這么做也行,但是有兩個問題:
1、用kettle文件的人知道 日志要放到那個數據庫的哪張表嗎?
就算知道,他有權訪問數據庫嗎?
就算知道並且有權訪問,那這位實施人員要待在客戶那里實施嗎?
當然啦,可以通過在 kettle 中配置變量的方式解決,就是數據庫連接信息和表信息等 用變量占位符。用 kettle 的人在本地用自己本地的數據庫,傳到服務端后,通過變量替換的方式使用服務端的數據庫。這種方式可以解決問題,但是需要用 kettle 的人配合,因為需要配置很多變量。
2、增加開發難度
因為數據這種東西是比較重要的,萬一用kettle的人哪里配錯了,丟到服務端運行……那就不好了
有沒有更好的方式,不讓用kettle的人關心日志呢?
既然kettle支持日志輸出到表,那這些信息一定會在kettle生成的ktr文件中,然后kettle運行的時候去解析這個 ktr文件,得到各種Java對象(因為kettle是用Java開發的)
那我只要找到 kettle 日志相關的那些 類(class),自己在代碼中加入不就好了嗎,然后還真就找到了,下面說一下如何實現:
這是得到Job對象的代碼:
JobMeta jobMeta = new JobMeta(ktrFilePath, null);
Job job = new Job(null, jobMeta);
然后現在要做的是,創建一個數據庫連接對象和 連接的具體信息,添加到這個 job中(需要在上面兩行代碼的中間添加代碼)。創建數據庫連接對象的代碼如下:
DatabaseMeta databaseMeta = new DatabaseMeta();
databaseMeta.setName("連接名");
databaseMeta.setDatabaseType("ORACLE");
databaseMeta.setAccessType(DatabaseMeta.TYPE_ACCESS_NATIVE);
databaseMeta.setHostname("數據庫IP");
databaseMeta.setDBName("orcl");
databaseMeta.setDBPort("數據庫端口");
databaseMeta.setUsername("用戶名");
databaseMeta.setPassword("密碼");
jobMeta.addDatabase(databaseMeta);
上面有些地方我用中文換掉了,這不是重點,重點是這些代碼就創建了數據庫連接對象,並添加到了Job元數據中。現在還需要連接信息,也就是schema和表名之類的,通過JobLogTable 這個對象設置,
JobLogTable jobLogTable = JobLogTable.getDefault(jobMeta, jobMeta);
jobLogTable.setConnectionName("連接名");
jobLogTable.setSchemaName("數據庫的SCHEMA");
jobLogTable.setTableName("表名");
jobMeta.setJobLogTable(jobLogTable);
要注意的是連接名 必須和 上面創建的數據庫連接對象 中的連接名一致,這樣就完成了 連接信息的配置,並和job元數據完成了關聯,當然還可以配置很多其他信息,這些只是最基本的配置。
配置信息可以放到properties文件中可供配置
然后,可以啟動 job了,日志會輸出到對應的表中^_^