まずはここから！Linuxサーバでカジュアルに作業ログを取得する方法

はじめに
---
Linuxサーバ上で直接SSHで作業をする際に、その作業ログを取得する方法についてまとめてみます。

スクリプトを自前で書く、専用のツールを利用するなど様々な方法が考えられますが、ここではLinuxの標準的なコマンドでの作業ログ取得について記載します。

今回は以下のコマンドを利用します。
> - **history**
- **script**

各コマンドの基本的な使い方や、覚えておくと役に立つちょっとした設定方法、最後に自動で作業ログを取得する方法について記載しました。

history
---
現在の作業ユーザがコマンドライン上で実行したコマンド履歴を表示するコマンドです。

```shell-session
$ history
    1  ls
    2  env
    3  history
    4  ls -la
    5  ls -la
    6  vim .bashrc
    7  zsh
    8  exit
    9  lsblk
   10  hostname
   …
```

数値を引数にとり、直近の履歴を指定して確認することもできます。
下記の例は直近からさかのぼって5個履歴を表示するものです。

```shell-session
$ history 5
  349  cat hoge.log
  350  ls
  351  hostname
  352  history
  353  history 5
```

保存できる履歴数は.bash_profileや.bashrcに以下の変数を追加することで調整可能です。
下記例では1000件の履歴を残すように設定しています。
(.bash_profile,.bashrcの違いについては[本当に正しい .bashrc と .bash_profile の使ひ分け](http://qiita.com/magicant/items/d3bb7ea1192e63fba850)をご参照ください。) 

```shell-session
#コマンド履歴を1000件残す
HISTSIZE=1000
```

デフォルトだとhistoryコマンドを実行しても、実行された順にコマンドが表示されるだけです。
しかし**HISTTIMEFORMAT**で表示フォーマットを変更できます。
以下の設定を同様に.bash_profileや.bashrcに設定すると日付・時刻も表示されるようになるのでぜひ設定をお勧めします。

```shell-session
#表示に日時をつける
HISTTIMEFORMAT=%Y/%m/%d %H:%M:%S
```

再度historyを実行すると、日付と時刻が表示されます。

```
$ history
    1  2015/06/24 09:45:26 ls
    2  2015/06/24 09:45:26 env
    3  2015/06/24 09:45:26 history
    4  2015/06/24 09:45:26 ls -la
    5  2015/06/24 09:45:26 ls -la
    6  2015/06/24 09:45:26 vim .bashrc
    7  2015/06/24 09:45:26 zsh
    8  2015/06/24 09:45:26 exit
    9  2015/06/24 09:45:26 lsblk
   10  2015/06/24 09:45:26 hostname
   …
```

またHISTIGNOREを設定することで特定のコマンドを履歴を残す対象から除外することができます。
下記の設定例はhostnameとlsコマンドを履歴対象から除外するものです。
複数コマンドを記載する際は**:**区切りで記載します。

```
#hostname,lsコマンドを履歴に残さない
HISTIGNORE=hostname:ls
```

script
---
historyはあくまで実行したコマンドの履歴なので、その実行結果の出力までは確認することはできません。
そこで出力結果までを保存することができるのが**script**コマンドです。

scriptコマンドは引数に出力格納先のファイル名を指定して利用します。
scriptコマンドを実行した以降のコマンドとその出力結果を指定したファイルに書き込んでいきます。
ログ出力を終了するときはexitコマンドを実行してください。

```
$ script /tmp/test.log
スクリプトを開始しました。ファイルは /tmp/test.log です
$ hostname
server01
$ pwd
/home/user01
$ history | grep hostname
  309  2015/06/24 11:51:52 hostname
  415  2015/06/24 11:23:52 hostname
  428  2015/06/24 11:52:05 history | grep hostname
$ date
2015年  6月 24日 水曜日 11:52:13 JST
$ exit
exit
スクリプトを終了しました。ファイルは /tmp/test.log です
```

scriptコマンド実行時に指定したファイルの中を確認すると、先ほどの実行コマンドと出力結果が確認できます。

```
$ cat /tmp/test.log
スクリプトは 2015年06月24日 11時51分52秒に開始しました
$ hostname
server01
$ pwd
/home/user01
$ history | grep hostname
  309  2015/06/24 11:51:52 hostname
  415  2015/06/24 11:23:52 hostname
  428  2015/06/24 11:52:05 history | grep hostname
$ date
2015年  6月 24日 水曜日 11:52:13 JST
$ exit
exit

スクリプトは 2015年06月24日 11時52分18秒に終了しました
```

同じファイルに追記して出力したい場合は**-a**オプションを利用します。

```
$ script -a /tmp/test.log
```

自動で作業ログを取得
----
.bash_profileにユーザのログイン時にscriptコマンドを実行するように設定することで、いちいちscriptコマンドを実行せせずとも作業ログを保存することができます。

.bash_profileに下記を追加します。

```
#ユーザのログイン時に特定のディレクトリへログファイルを保存
#${log_archive_directory}は任意のディレクトリを指定
#ログファイル名はログイン時の日時とログインユーザ名を付与

script ${log_archive_directory}/$(date +%Y%m%d_%H%M%S)_$(whoami).log
```

例えばこのファイルをfluentdでリアルタイムに連携したり、NASなどの共通ストレージをマウントした先に複数サーバから操作ログを保存したりといったことが可能となります。

ファイル出力にあたって一点留意していただきたのは、scriptコマンドはデフォルトでのファイル出力は非同期です。
なのでバッファからファイルへ出力されるまでにタイムラグがあります。
もしリアルタイムにファイルへ出力したい場合は**-f**オプションをつけてください。

```
#即時にファイルへ結果を出力

script -f ${log_archive_directory}/$(date +%Y%m%d_%H%M%S)_$(whoami).log
```