Talend入門 (11)　～ロギング～

##全体の目的
Talendの超簡単なサンプルジョブを作成して，ETLジョブ開発に必要なスキルを習得することが目的です。

##対象者
ETL / EAI技術者

##環境
|使用環境|バージョン|
|:----:|:------------------|
|OS|Windows10|
|Talend|7.3.1|
|PostgreSQL|14.0|	


##サンプル一覧
以下の順番で習得していきます

|#|内容|
|:----:|:------------------|
|1|[はじめてのTalend](https://qiita.com/airkoda/items/a837d3c5d851d98d2612)|
|2|[ファイルI/O](https://qiita.com/airkoda/items/1cd12c05c6136add7178)|
|3|[データベースI/O](https://qiita.com/airkoda/items/bc807c920c3adebad837)|
|4|[tMap](https://qiita.com/airkoda/items/fa4a9c022b5d688698e0)|
|5|[イテレータ](https://qiita.com/airkoda/items/404d2d65eff535b2126c)|
|6|[メタデータ](https://qiita.com/airkoda/items/4b42cf2a86f34abb6c87)|
|7|[Context変数](https://qiita.com/airkoda/items/42d294fca40b81aa20fb)|
|8|[Global Map](https://qiita.com/airkoda/items/1aba0d36905c755deeae)|
|9|[tHashInput/tHashOutput](https://qiita.com/airkoda/items/d9347865190f0f3ab180)|
|10|[エラーハンドリング](https://qiita.com/airkoda/items/85e7c49a9bf6a21db6d5)|
|**11**|**[ロギング（今回）](https://qiita.com/y-fujioka-yoshiharu/items/e0280f34cff2e3d00bda)**|
|12|[子ジョブ（ジョブのネスト）](https://qiita.com/y-fujioka-yoshiharu/items/04ea4bd74ded382cf03c)|
|13-1|[設定ファイル読み込みオリジナル版](https://qiita.com/airaotaku/items/92f114795108f25e6d0f)|
|13-2|[設定ファイル読み込みコンポ版](https://qiita.com/airyama/items/83c2bf9b2d51a79c3714)|
|14|[tJava](https://qiita.com/airkoda/items/4d81d76c36b6fcbd4d89)|

[サンプルコード（Talendプロジェクトデータ）](https://github.com/kd2air/qiita)

##今回の目的
ロギングの方法について理解する。

##ロギングとは
ロギングとはどんなエラーが起きたのか、どんな操作を行ったかなどのデータを時系列で記録し蓄積することです。

IT用語辞典でロギングについて調べると以下のように記述されています。
>ロギングとは、起こった出来事についての情報などを一定の形式で時系列に記録・蓄積すること。そのように記録されたデータのことを「ログ」（log）という。
[IT用語辞典 e-Words](https://e-words.jp/w/%E3%83%AD%E3%82%AE%E3%83%B3%E3%82%B0.html)

##talendのログ
talendには統計情報ログ、ユーザーログ、流量メーターの3種類のログがあります。それぞれ、特定のコンポーネントで値をキャッチし、その値をロギングします。

また、talendはログをコンソールやファイル、データベースに簡単に出力できます。

##サンプルプログラム概要
それぞれサンプルプログラムを動かしながら使い方を見ていきましょう。


##サンプル作成
今回はジョブをたくさん作るのでフォルダ上にジョブを作成します。
[Standard]を右クリックしてフォルダの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2252625/ea9b050c-df30-1e18-7152-12f60bf523bd.png)
[ラベル]に**log_sample**と入力し[Finish]ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2252625/5aef9941-f367-ca12-db91-3ec740cd8c14.png)

###tStatCatcherでロギング
リポジトリの[log_sample]を右クリックし[標準ジョブを作成]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2252625/27ca920d-ed85-55fe-a003-5d3b4f0f98a0.png)
[名前]に**tLogCatcher**と入力し[Finish]ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2252625/3f974359-1d88-223c-5fe8-792b68919860.png)
[tRowGenerator]と[tLogRow]を配置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2252625/a6e1a398-e17a-89f6-c49e-d586dd5a8298.png)
[tRowGenerator]のスキーマ編集画面で+を１回クリックし１カラム定義します。

|列|カラム|
|:--|:--|
|１列目|newColumn|

| 項目名         | 設定内容 |    説明  |
|:---------------|:--------|:------------------|
| 生成する行数    | 3      | テストデータを3行だけ作成します |
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2252625/d6c79b64-8148-d774-520f-a000f39f2d27.png)
[tRowGenerator_1]と[tLogRow_1]をロウでつなぎます。
[tLogRow_1]のモードはテーブル形式にしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2252625/122b38a4-058f-7337-91d6-feb1346dfc5a.png)

[tStatCatcher]と[tLogRow]を配置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2252625/15933933-3f5e-9d91-c81f-a033849e078b.png)
[tStatCatcher_1]と[tLogRow_2]をロウでつなぎます。
ロウでつない後、[tLogRow_2]の同期カラムをクリックしてモードはテーブル形式にしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2252625/84537fa1-2229-0533-477d-41b92d596cc1.png)
実行してみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2252625/19db2eb5-6b34-ba69-804c-45e7acb1a379.png)
[tStatCatcher]はジョブプロセスメタデータをジョブレベルおよびコンポーネントレベルで収集し、ログデータを後続のコンポーネントに転送します。
[tLogRow_2]で表示した値が[tStatCatcher_1]で取得したログデータとなります。

[tLogRow]だとコンソールにログ結果を表示することになりますが[tFileOutputDelimited]や[tPostgresqlOutput]を使用することでログデータをファイルやデータベースに保存することができます。

###tLogCatcherでロギング
[tLogCatcher]はJava例外、[tDie]、[tWarn]で発生したログをキャッチするることができます。[tLogCatcher]の使い方は[講義１０のエラーハンドリング](https://qiita.com/airkoda/items/85e7c49a9bf6a21db6d5)で詳しく説明しておりますので、今回は省略いたします。

こちらも[tLogCatcher]の後続を[tFileOutputDelimited]や[tPostgresqlOutput]を使用することでログデータをファイルやデータベースに保存することができます。

###tFlowMeterCatcherでロギング
リポジトリの[log_sample]を右クリックし[標準ジョブを作成]を選択します。
[名前]に**tFlowMeterCatcher**と入力し[Finish]ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2252625/564668f8-021c-080b-2e33-0d2557137fca.png)

[tRowGenerator]と[tFlowMeter]、[tLogRow]x2、[tFlowMeterCatcher]を配置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2252625/3195425f-ec5a-e28f-ce9e-c3683df93366.png)
[tRowGenerator_1]のスキーマ編集画面で+を１回クリックし１カラム定義します。

|列|カラム|
|:--|:--|
|１列目|newColumn|

| 項目名         | 設定内容 |    説明  |
|:---------------|:--------|:------------------|
| 生成する行数    | 3      | テストデータを3行だけ作成します |
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2252625/d6c79b64-8148-d774-520f-a000f39f2d27.png)

[tRowGenerator_1]と[tFlowMeter_1]、[tFlowMeter_1]と[tLogRow_1]、[tFlowMeterCatcher_1]と[tLogRow_2]をロウでつなぎます。
[tLogRow_1]と[tLogRow_2]のモードはテーブル形式にしておきます。
実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2252625/b397e6e2-c029-8e47-9b99-aadd08bf5090.png)

[tFlowMeter]は定義されたフローで処理された行数をカウントする機能です。[tFlowMeterCatcher]は[tFlowMeter]のログをキャッチするときに使用します。[tLogRow_2]のカラム[count]を見ると３となっており、正しく行数をカウントしていることがわかります。

こちらも[tFlowMeterCatcher]の後続を[tFileOutputDelimited]や[tPostgresqlOutput]を使用することでログデータをファイルやデータベースに保存することができます。

###発展
これまでに[tStatCatcher]、[tLogCatcher]、[tFlowMeterCatcher]の３つのコンポーネントを使用してロギングできることを学んできました。そしてさらに、talendにはより簡単にロギングできる機能があります。

###統計＆ログでロギング
リポジトリの[log_sample]を右クリックし[標準ジョブを作成]を選択します。
[名前]に**joblog**と入力し[Finish]ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2252625/a58e18e1-c450-1ebb-312b-238b9e2e8ebe.png)

[tRowGenerator]x2、[tFlowMeter]、[tLowRog]、[tPostgresqlOutput]、[tDie]を配置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2252625/4ab8d16e-df98-cf58-19ff-b2ce3aa230b0.png)
[tRowGenerator_1]、[tRowGenerator_2]のスキーマ編集画面で+を１回クリックし１カラム定義します。

|列|カラム|
|:--|:--|
|１列目|newColumn|

| 項目名         | 設定内容 |    説明  |
|:---------------|:--------|:------------------|
| 生成する行数    | 3      | テストデータを3行だけ作成します |

[tRowGenerator_1]と[tFlowMeter_1]、[tFlowMeter_1]と[tLogRow_1]、[tRowGenerator_2]と[tDBOutput_1]をロウでつなぎます。
[tRowGenerator_1]と[tRowGenerator_2]をOnSubjobk、[tRowGenerator_2]と[tDie]をOnSubjobErrorでつなぎます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2252625/1ad88270-52d4-8c13-c99f-88a874abe877.png)

[tLogRow_1]のモードはテーブル形式にしておきます。
[tDBOutput_1]でエラーが出てほしいのでここでは何も設定しません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2252625/a3f58782-007d-09df-d24e-ed6a998aa184.png)

####コンソールに出力
まずはログをコンソールに出力してみます。
[ジョブ]から[統計＆ログ]をクリックし、以下のように設定します。

| 項目名 | 設定内容 |
|:-|:-|
|プロジェクト設定の使用|チェックをはずす|
|統計情報ログの使用|チェックを付ける|
|ユーザーログの使用|チェックを付ける|
|流量メータの使用|チェックを付ける|
|コンソールに出力|チェックを付ける|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2252625/44eafea7-a5e9-c055-2a45-841c0bb22545.png)

実行してみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2252625/10fa5e40-4e42-f164-161f-72af4ee0ff5c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2252625/d2a83a48-6aab-d80a-dbb3-b2b17001e4d5.png)
長くて少しわかりにくいですが
以下のログは統計情報ログによるジョブがスタートしたときのログになります。

```
2021-11-08 11:54:29|UBZuxI|UBZuxI|UBZuxI|14356|LOCAL_PROJECT|joblog|_byFY4EA6EeycNM2CtAxbOA|0.1|Default||begin||
```
以下のログは流量メータによる定義されたフローで処理された行数をカウントしたログになります。

```
2021-11-08 11:54:29|UBZuxI|UBZuxI|UBZuxI|14356|LOCAL_PROJECT|joblog|_byFY4EA6EeycNM2CtAxbOA|0.1|Default|tFlowMeter_1|row1|3||
```
以下のログはユーザーログによる終了コードのログになります。

```
2021-11-08 11:54:29|UBZuxI|UBZuxI|UBZuxI|LOCAL_PROJECT|joblog|Default|5|tDie|tDie_1|the end is near|4
```
以下のログはユーザーログによるPostgreSQLでのエラーについてのログになります。

```
2021-11-08 11:54:29|UBZuxI|UBZuxI|UBZuxI|LOCAL_PROJECT|joblog|Default|6|Java Exception|tDBOutput_1|org.postgresql.util.PSQLException:FATAL: 開始パケットで指定されたPostgreSQLユーザー名は存在しません(pgjdbc: server-encoding として windows-31j  を自動検出しました、メッセージが読めない場合はデータベースログおよび host, port, dbname, user, password, pg_dba.conf を確認してください)|1
```
以下のログは統計情報ログによるジョブが終了したときのログになります。

```
2021-11-08 11:54:29|UBZuxI|UBZuxI|UBZuxI|14356|LOCAL_PROJECT|joblog|_byFY4EA6EeycNM2CtAxbOA|0.1|Default||end|failure|283
```

####ファイルに出力
続いてログをファイルに出力してみます。
[ジョブ]から[統計＆ログ]をクリックし、以下のように設定します。

| 項目名 | 設定内容 |
|:-|:-|
|プロジェクト設定の使用|チェックをはずす|
|統計情報ログの使用|チェックを付ける|
|ユーザーログの使用|チェックを付ける|
|流量メータの使用|チェックを付ける|
|ファイルに出力|チェックを付ける|
|ファイルパス|"C:/talend/workspace/joblog"|
|統計ファイル名|"stats_file.txt"|
|ユーザーログファイル名|"logs_file.txt"|
|メーターファイル名|"meter_file.txt"|
|エンコーディング|UTF-8|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2252625/008f0a51-5de7-23fb-66fb-7ed9bf613bba.png)

実行してみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2252625/a3d888d5-ff69-ab79-b422-446f9a523576.png)

`C:/talend/workspace/joblog`を開くとドキュメントファイルが３つ作成されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2252625/410b57b4-dbbf-75b5-64d5-3f6b2c784f32.png)

```logs_file.txt
2021-11-08 13:18:18;9lkqSn;9lkqSn;9lkqSn;LOCAL_PROJECT;joblog;Default;5;tDie;tDie_1;the end is near;4
2021-11-08 13:18:18;9lkqSn;9lkqSn;9lkqSn;LOCAL_PROJECT;joblog;Default;6;Java Exception;tDBOutput_1;org.postgresql.util.PSQLException:FATAL: 開始パケットで指定されたPostgreSQLユーザー名は存在しません(pgjdbc: server-encoding として windows-31j  を自動検出しました、メッセージが読めない場合はデータベースログおよび host, port, dbname, user, password, pg_dba.conf を確認してください);1
```
```meter_file.txt
2021-11-08 13:18:18;9lkqSn;9lkqSn;9lkqSn;16300;LOCAL_PROJECT;joblog;_byFY4EA6EeycNM2CtAxbOA;0.1;Default;tFlowMeter_1;row1;3;;
```
```stats_file.txt
2021-11-08 13:18:18;9lkqSn;9lkqSn;9lkqSn;16300;LOCAL_PROJECT;joblog;_byFY4EA6EeycNM2CtAxbOA;0.1;Default;;begin;;
2021-11-08 13:18:18;9lkqSn;9lkqSn;9lkqSn;16300;LOCAL_PROJECT;joblog;_byFY4EA6EeycNM2CtAxbOA;0.1;Default;;end;failure;345
```
何回か実行してからファイルの中身を確認するとログが溜まっていく様子が見れると思います。

####データベースに出力
続いてログをデータベースに出力してみます。
[ジョブ]から[統計＆ログ]をクリックし、以下のように設定します。

| 項目名 | 設定内容 |
|:-|:-|
|プロジェクト設定の使用|チェックをはずす|
|統計情報ログの使用|チェックを付ける|
|ユーザーログの使用|チェックを付ける|
|流量メータの使用|チェックを付ける|
|ファイルに出力|チェックを付ける|
|プロパティタイプからパスワード|DBの設定を記述する|
|統計テーブル|"stats_table"|
|ユーザーログテーブル|"logs_table"|
|メーターテーブル|"meter_table"|
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2252625/9ab102d1-e551-2d01-6484-909c36795e4f.png)

実行してみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2252625/4f45e1df-9af5-6404-655c-0949721e84e0.png)

データベースには以下のように登録されます。

```
postgres=# select * from stats_table;
       moment        |  pid   | father_pid | root_pid | system_pid |    project    |  job   |    job_repository_id    | job_version | context | origin | message_type | message | duration
---------------------+--------+------------+----------+------------+---------------+--------+-------------------------+-------------+---------+--------+--------------+---------+----------
 2021-11-08 13:38:22 | 7F7tW4 | 7F7tW4     | 7F7tW4   |      15968 | LOCAL_PROJECT | joblog | _byFY4EA6EeycNM2CtAxbOA | 0.1         | Default |        | begin        |         |
 2021-11-08 13:38:23 | 7F7tW4 | 7F7tW4     | 7F7tW4   |      15968 | LOCAL_PROJECT | joblog | _byFY4EA6EeycNM2CtAxbOA | 0.1         | Default |        | end          | failure |      382
(2 行)


postgres=# select * from logs_table;
       moment        |  pid   | root_pid | father_pid |    project    |  job   | context | priority |      type      |   origin    |                                                                                                                                         message                                                                                                                                          | code
---------------------+--------+----------+------------+---------------+--------+---------+----------+----------------+-------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------
 2021-11-08 13:38:23 | 7F7tW4 | 7F7tW4   | 7F7tW4     | LOCAL_PROJECT | joblog | Default |        5 | tDie           | tDie_1      | the end is near                                                                                                                                                                                                                                                                          |    4
 2021-11-08 13:38:23 | 7F7tW4 | 7F7tW4   | 7F7tW4     | LOCAL_PROJECT | joblog | Default |        6 | Java Exception | tDBOutput_1 | org.postgresql.util.PSQLException:FATAL: 開始パケットで指定されたPostgreSQLユーザー名は存在しません(pgjdbc: server-encoding として windows-31j  を自動検出しました、メッセージが読めない場合はデータベースログおよび host, port, dbname, user, password, pg_dba.conf を確認してください) |    1
(2 行)


postgres=# select * from meter_table;
       moment        |  pid   | father_pid | root_pid | system_pid |    project    |  job   |    job_repository_id    | job_version | context |    origin    | label | count | reference | thresholds
---------------------+--------+------------+----------+------------+---------------+--------+-------------------------+-------------+---------+--------------+-------+-------+-----------+------------
 2021-11-08 13:38:23 | 7F7tW4 | 7F7tW4     | 7F7tW4   |      15968 | LOCAL_PROJECT | joblog | _byFY4EA6EeycNM2CtAxbOA | 0.1         | Default | tFlowMeter_1 | row1  |     3 |           |
(1 行)
```

##まとめ
今回はロギングの方法をコンポーネントを配置する場合と[統計＆ログ]から設定する場合を試しました。
あらたに利用したコンポーネントと用途をおさらいしておきます。

- tStatCatcher
    - ジョブの開始と終了をキャッチするコンポーネント
- tFlowMeter
    - 定義されたフローで処理された行数をカウントするコンポーネント
- tFlowMeterCatcher
    - tFlowMeterの結果をキャッチするコンポーネント

毎度のことですが、ほんのさわりの部分だけを解説していますのでぜひここから深掘りしてみてください。

##次回以降
次回は子ジョブをやっていきます。