【MarkLogic Server】エラー等のログの概要

はじめに
========
一般的なアプリケーションと同様にMarkLogicもテキスト形式のログを出力します。この記事では、それらをまとめてみましょう。基本的にはMarkLogic ver9を念頭においてください。

ログの出力場所
========
ログは以下の場所に出力されます。

| OS | 場所 |
|---|---|---|
| Windows | C:\Program Files\MarkLogic\Data\Logs\ | 
| Red Hat Linux | /var/opt/MarkLogic/Logs/ | 
| Mac OS X | ~Library/Application Support/MARKlogic/Data/Logs/ | 

ログの種類
========
出力されるログは以下の通りです。

|種類| 説明 | ファイル名 |
|---|---|---|
| アクセスログ | 各種APサーバへのアクセス履歴を記録する | [ポート番号]_AccessLog.txt |
| エラーログ | エラー内容を記録する。(必ずしもエラーとは言えないものも一応記述されていく) | [ポート番号]_ErrorLog.txt, ErrorLog.txt |
| 監査ログ | 任意で設定できるユーザの挙動を記録する | AuditLog.txt |

ログレベル
========
ログには出力するレベルを設定することができます。これによってテキスト出力量を調節できます。ログレベルはFinest～Debug～Notice～Info～Error～Emergencyといった12段階です。(詳しくはこの[サイト](https://docs.marklogic.com/guide/admin/logfiles "サイト")をご覧ください。)
たとえば出力レベルをFinestとした場合、多くの情報が得られますが出力テキスト量が膨大になってしまいます。逆にAlertとした場合、Errorを見逃すことになります。現実的にはDebug～Infoの間で設定するのがよいと思います。

ログローテーション設定は管理者画面(ポート8001番)から、Configure->Groups->DefaultのConfigureタブの「file log level」によって変更可能です。

![loglevelsetting.jpg](https://qiita-image-store.s3.amazonaws.com/0/188643/326e3e19-089b-1fc8-c13e-e77923099ee3.jpeg)

ログローテーション
========
古いログは「ErrorLog_6.txt」といった番号で別ファイルとして保存されます。デフォルトでは日次でテキストファイルが切り替わり、7日後には削除されます。
ログローテーション設定は管理者画面(ポート8001番)から、Configure->Groups->DefaultのConfigureタブから変更可能です。

![ログ設定.jpg](https://qiita-image-store.s3.amazonaws.com/0/188643/49d84efc-89e8-5714-191f-1923a9777289.jpeg)

| パラメータ | 説明 |
|---|---|
| rotate log files | never:行わない、daily(デフォルト):日次、monday～sunday(週次)、monthly(月次) |
| keep log files | ログファイル保持数。デフォルトは7 |

あまり、大きなログテキストを作ると後々見るのが大変になるので、デフォルトのdailyのままにすることをお奨めします。

監査ログの設定
========
監査ログについては、デフォルトでは設定が有効化されません。設定は管理者画面(ポート8001番)から、Configure->Groups->Auditingから変更可能です。
設定対象項目は色々あるので[公式サイト](https://docs.marklogic.com/guide/admin/auditing "公式サイト")を見て頂くとして今回は以下のように設定しました。

![監査ログ設定.jpg](https://qiita-image-store.s3.amazonaws.com/0/188643/941db99b-7f2b-a96d-6c7a-1c17d558d278.jpeg)

☆全体設定

| パラメータ | 設定値 |
|---|---|
| audit enabled | true |
| rotate log files | daily |
| keep audit files | 7 |

☆監査イベント

| パラメータ | 設定値 |
|---|---|
| document-read | チェックを入れる |
| eval | チェックを入れる |
| search | チェックを入れる |

☆監査対象

| パラメータ | 設定値 |
|---|---|
| outcome | both |
| role | (今回は設定しません) |
| uri | include only /root |
| user | include only admin2 |

クエリコンソール(ポート8000番)で実際にadmin2ユーザにて検索関数を実行してみました。

![audit実例.jpg](https://qiita-image-store.s3.amazonaws.com/0/188643/b5d078c5-fb41-5928-c199-9f2921c74cea.jpeg)

するとこんな感じでAuditLog.txtに出力が出ました。

```
2017-12-11 11:25:05.179 event=eval; expr=fn:collection()/qconsole:workspace[qconsole:security/qconsole:userid = xs:unsignedLong("4745866157390971071")]; database=App-Services; success=true; user=admin2; roles=admin;
2017-12-11 11:25:05.201 event=eval; expr=fn:doc("/workspaces/2429500080931342152.xml"); database=App-Services; success=true; user=admin2; roles=admin;
2017-12-11 11:25:05.201 event=eval; expr=fn:collection()/qconsole:workspace[qconsole:security/qconsole:userid = xs:unsignedLong("4745866157390971071")]; database=App-Services; success=true; user=admin2; roles=admin;
2017-12-11 11:25:05.201 event=eval; expr=fn:doc("/workspaces/2429500080931342152.xml")/qconsole:workspace[qconsole:security/qconsole:userid = xs:unsignedLong("4745866157390971071")]; database=App-Services; success=true; user=admin2; roles=admin;
2017-12-11 11:25:05.201 event=eval; expr=fn:collection()/qconsole:workspace[qconsole:security/qconsole:userid = xs:unsignedLong("4745866157390971071")]; database=App-Services; success=true; user=admin2; roles=admin;
2017-12-11 11:25:05.359 event=eval; expr=fn:doc("/queries/863336884117240855.txt"); database=App-Services; success=true; user=admin2; roles=admin;
2017-12-11 11:25:05.359 event=eval; expr=fn:collection()/qconsole:workspace[qconsole:security/qconsole:userid = xs:unsignedLong("4745866157390971071")]; database=App-Services; success=true; user=admin2; roles=admin;
2017-12-11 11:25:06.664 event=eval; expr=fn:collection()/qconsole:workspace[qconsole:security/qconsole:userid = xs:unsignedLong("4745866157390971071")]; database=App-Services; success=true; user=admin2; roles=admin;
2017-12-11 11:25:06.665 event=eval; expr=fn:collection()/qconsole:workspace[qconsole:security/qconsole:userid = xs:unsignedLong("4745866157390971071")]; database=App-Services; success=true; user=admin2; roles=admin;
2017-12-11 11:25:06.665 event=eval; expr=fn:doc("/queries/863336884117240855.txt"); database=App-Services; success=true; user=admin2; roles=admin;
2017-12-11 11:25:06.864 event=eval; expr=fn:doc("/queries/863336884117240855.txt"); database=App-Services; success=true; user=admin2; roles=admin;
2017-12-11 11:25:06.864 event=eval; expr=fn:collection()/qconsole:history[qconsole:security/qconsole:userid = xs:unsignedLong("4745866157390971071")]; database=App-Services; success=true; user=admin2; roles=admin;
2017-12-11 11:25:11.546 event=eval; expr=fn:doc(); database=checkDataSize; success=true; user=admin2; roles=admin;
2017-12-11 11:25:18.058 event=eval; expr=fn:doc("/root/100/2/2017-02/10.xml"); database=checkDataSize; success=true; user=admin2; roles=admin;
2017-12-11 11:25:21.683 event=eval; expr=fn:doc(); database=checkDataSize; success=true; user=admin2; roles=admin;
2017-12-11 11:26:35.463 event=eval; expr=fn:doc("/queries/863336884117240855.txt"); database=App-Services; success=true; user=admin2; roles=admin;
2017-12-11 11:26:35.471 event=eval; expr=fn:doc("/queries/863336884117240855.txt"); database=App-Services; success=true; user=admin2; roles=admin;
2017-12-11 11:26:35.471 event=eval; expr=fn:collection()/qconsole:workspace[qconsole:security/qconsole:userid = xs:unsignedLong("4745866157390971071")]; database=App-Services; success=true; user=admin2; roles=admin;
2017-12-11 11:26:35.471 event=eval; expr=fn:collection()/qconsole:workspace[qconsole:security/qconsole:userid = xs:unsignedLong("4745866157390971071")]; database=App-Services; success=true; user=admin2; roles=admin;
2017-12-11 11:26:35.523 event=search; expr=fn:collection()/root; database=checkDataSize; success=true; user=admin2; roles=admin;
2017-12-11 11:26:35.867 event=eval; expr=fn:doc("/queries/863336884117240855.txt"); database=App-Services; success=true; user=admin2; roles=admin;
2017-12-11 11:26:35.867 event=eval; expr=fn:collection()/qconsole:workspace[qconsole:security/qconsole:userid = xs:unsignedLong("4745866157390971071")]; database=App-Services; success=true; user=admin2; roles=admin;
2017-12-11 11:26:35.867 event=eval; expr=fn:collection()/qconsole:workspace[qconsole:security/qconsole:userid = xs:unsignedLong("4745866157390971071")]; database=App-Services; success=true; user=admin2; roles=admin;
2017-12-11 11:26:35.867 event=eval; expr=fn:doc("/queries/863336884117240855.txt"); database=App-Services; success=true; user=admin2; roles=admin;
2017-12-11 11:26:35.867 event=eval; expr=fn:collection()/qconsole:history[qconsole:security/qconsole:userid = xs:unsignedLong("4745866157390971071")]; database=App-Services; success=true; user=admin2; roles=admin;
2017-12-11 11:26:35.875 event=eval; expr=fn:doc("/histories/11042616841168179085.xml"); database=App-Services; success=true; user=admin2; roles=admin;
2017-12-11 11:26:35.875 event=eval; expr=fn:doc("/histories/11042616841168179085.xml")/qconsole:history[qconsole:security/qconsole:userid = xs:unsignedLong("4745866157390971071")]; database=App-Services; success=true; user=admin2; roles=admin;
```

あまりに長くて分かりづらいですが、「fn:doc("/root/100/2/2017-02/10.xml"); 」という記述から、このXMLファイルが読み取られたようです。

ログ出力関数
========
XQuery内でxdmp:log()関数を使えば、任意のタイミングで[ポート番号]_ErrorLog.txtにメッセージを出力することができます。クエリコンソール(ポート8000番)を開いてみて、実際に出力してみましょう。第１引数は出力メッセージ、第２引数(任意)はログのレベルです。

```
xdmp:log("sample output!", "info")
```

8000_ErrorLog.txt(ver8以前ではErrorLog.txt)はこんな感じの出力になりました。

```
2017-12-11 11:32:49.099 Info: App-Services: sample output!
```

ちょっとしたデバッグに使えそうですね。

おわりに
========
何らかのトラブルが発生した場合に、ログテキストは解決のための重要なヒントを与えてくれることが多々あります。「トラブルが起きたら、まずはErrorLog.txtを見る」を心がけておきましょう。


```math
\def\textsmall#1{%
  {\rm\scriptsize #1}
}
```

------------------------------------------------------------------------

**免責事項**

​​​​​$\textsmall{当ユーザ会は本文書及びその内容に関して、いかなる保証もするものではありません。}$
​​​​​$\textsmall{万一、本文書の内容に誤りがあった場合でも当ユーザ会は一切責任を負いかねます。}$
​​​​​$\textsmall{また、本文書に記載されている事項は予告なしに変更または削除されることがありますので、予めご了承ください。}$