macOSのError,FaultログをCSVファイルに出力する

# 概要

本書ではlogコマンドを利用してmacOSのError,Faultログを抽出し、CSVファイルにログを出力するコマンドを作成します。また当日に発生したError,FaultログのみをCSVに出力するシェルスクリプトを作成します。

## 動作環境

macOS Catalina (MacBookAir2019)

## 1.error,Faultログの出力

* ログを出力するにはターミナルを開き、`log show`と入力しEnterを押下します。コマンドを実行すると全てのログが出力されます。

```
% log show | more
Timestamp                       Thread     Type        Activity             PID    TTL
2020-05-05 19:16:40.063938-0700 0x0        Timesync    0x0                  0      0    === system boot: 571DA786-615F-4413-944B-1D34B63BA616
2020-05-05 19:16:40.063938-0700 0x0        Timesync    0x0                  0      0    === log class: TTL more than 14 days begins
2020-05-05 19:16:40.063938-0700 0x0        Timesync    0x0                  0      0    === log class: persist begins
2020-05-05 19:16:40.063980-0700 0x0        Default     0x0                  0      0    kernel: mem_actual: 0x400000000
(非常に長いため省略)
```

* Errorログのみを出力するには`log show --predicate 'messageType == "error"'`と入力しEnterを押下します。

```
% log show --predicate 'messageType == "error"' | more
Timestamp                       Thread     Type        Activity             PID    TTL
2020-05-05 19:16:42.931110-0700 0x26a      Error       0x0                  72     0    opendirectoryd: [com.apple.opendirectoryd:default] Failed to open file <private> [2: No such file or directory]
2020-05-05 19:16:42.949256-0700 0x2bc      Error       0x0                  72     0    opendirectoryd: [com.apple.opendirectoryd:default] Failed to open file <private> [2: No such file or directory]
2020-05-05 19:16:42.976184-0700 0x2c1      Error       0x0                  72     0    opendirectoryd: [com.apple.opendirectoryd:default] Failed to open file <private> [2: No such file or directory]
2020-05-05 19:16:42.977242-0700 0x2bf      Error       0x20                 102    0    tccd: (libsqlite3.dylib) [com.apple.libsqlite3:logging-persist] cannot open file at line 43353 of [378230ae7f]
(非常に長いため省略)
```

* Faultログのみを出力するには`log show --predicate 'messageType == "fault"'`と入力しEnterを押下します。

```
% log show --predicate 'messageType == "fault"' | more
Timestamp                       Thread     Type        Activity             PID    TTL
2020-05-05 19:17:29.320269-0700 0x394      Fault       0x0                  0      0    kernel: (IOAcceleratorFamily2) bool IOAccelDisplayPipe::init_framebuffer_resource(IOAccelResource2 *): getPixelInformation for framebuffer 0 failed
2020-05-05 19:17:29.559630-0700 0x394      Fault       0x0                  0      0    kernel: (IOAcceleratorFamily2) virtual IOReturn IOAccelLegacySurface::set_id_mode(uint32_t, uint32_t): Surface mode contains bad bits
2020-05-05 19:17:29.559788-0700 0x394      Fault       0x0                  0      0    kernel: (IOAcceleratorFamily2) virtual IOReturn IOAccelLegacySurface::set_id_mode(uint32_t, uint32_t): Surface mode contains bad bits
2020-05-05 19:17:29.559875-0700 0x394      Fault       0x0                  0      0    kernel: (IOAcceleratorFamily2) virtual IOReturn IOAccelLegacySurface::set_id_mode(uint32_t, uint32_t): Surface mode contains bad bits
(非常に長いため省略)
```

## 2.Error,FaultログをCSVに出力する

* リダイレクトを使用してError,FaultログをCSVに出力します。

```
% log show --predicate 'messageType == "error"'>/tmp/test2/errorlog.csv
% log show --predicate 'messageType == "fault"'>/tmp/test2/faultlog.csv
% ls -la /tmp/test2
total 57360
drwxr-xr-x   4 yuichiwest  wheel       128  5 24 19:46 .
drwxrwxrwt  15 root        wheel       480  5 24 19:47 ..
-rw-r--r--   1 yuichiwest  wheel  26946597  5 24 19:45 errorlog.csv
-rw-r--r--   1 yuichiwest  wheel   1497197  5 24 19:46 faultlog.csv
% cat /tmp/test2/errorlog.csv | more
Timestamp                       Thread     Type        Activity             PID    TTL
2020-05-05 19:16:42.931110-0700 0x26a      Error       0x0                  72     0    opendirectoryd: [com.apple.opendirectoryd:default] Failed to open file <private> [2: No such file or directory]
2020-05-05 19:16:42.949256-0700 0x2bc      Error       0x0                  72     0    opendirectoryd: [com.apple.opendirectoryd:default] Failed to open file <private> [2: No such file or directory]
2020-05-05 19:16:42.976184-0700 0x2c1      Error       0x0                  72     0    opendirectoryd: [com.apple.opendirectoryd:default] Failed to open file <private> [2: No such file or directory]
2020-05-05 19:16:42.977242-0700 0x2bf      Error       0x20                 102    0    tccd: (libsqlite3.dylib) [com.apple.libsqlite3:logging-persist] cannot open file at line 43353 of [378230ae7f]
(省略)
% cat /tmp/test2/faultlog.csv | more
Timestamp                       Thread     Type        Activity             PID    TTL
2020-05-05 19:17:29.320269-0700 0x394      Fault       0x0                  0      0    kernel: (IOAcceleratorFamily2) bool IOAccelDisplayPipe::init_framebuffer_resource(IOAccelResource2 *): getPixelInformation for framebuffer 0 failed
2020-05-05 19:17:29.559630-0700 0x394      Fault       0x0                  0      0    kernel: (IOAcceleratorFamily2) virtual IOReturn IOAccelLegacySurface::set_id_mode(uint32_t, uint32_t): Surface mode contains bad bits
2020-05-05 19:17:29.559788-0700 0x394      Fault       0x0                  0      0    kernel: (IOAcceleratorFamily2) virtual IOReturn IOAccelLegacySurface::set_id_mode(uint32_t, uint32_t): Surface mode contains bad bits
2020-05-05 19:17:29.559875-0700 0x394      Fault       0x0                  0      0    kernel: (IOAcceleratorFamily2) virtual IOReturn IOAccelLegacySurface::set_id_mode(uint32_t, uint32_t): Surface mode contains bad bits
(省略)
```

* Excelの区切り位置を設定することでログを見やすく表示することができます。

<img width="1417" alt="スクリーンショット 2020-05-24 20.02.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307261/2b83c9b8-60ff-9610-b5ce-4ff534a2b5ac.png">


## 3.当日に発生したError,Faultログのみを出力するシェルスクリプトを作成する

* シェルスクリプトの動作内容

1. 当日の日付を変数に出力する

2. 保存先を変数に出力する

3. Error,Faultログを指定した日付、保存先にCSVとして出力する

* シェルスクリプトの内容

```
#!/bin/sh

<< COMMENTOUT
logsearch(macOS)
Copyright (c) 2020 yuichi1992_west
This software is released under the MIT License.
http://opensource.org/licenses/mit-license.php
COMMENTOUT

# Get today's date
log_date=`date +"%Y-%m-%d"`

# Specify the log storage location
log_space='/tmp/test3'

# Output error log
log show --predicate 'messageType == "error"' | grep "${log_date}" > "${log_space}"/error_log_"${log_date}".csv

# Output fault log
log show --predicate 'messageType == "fault"' | grep "${log_date}" > "${log_space}"/fault_log_"${log_date}".csv

exit 0
```

* 動作結果

```
% bash logsearch.sh
% ls -la /tmp/test3
total 6656
drwxr-xr-x   4 yuichiwest  wheel      128  5 24 20:09 .
drwxrwxrwt  18 root        wheel      576  5 24 20:15 ..
-rw-r--r--   1 yuichiwest  wheel  2928838  5 24 20:09 error_log_2020-05-24.csv
-rw-r--r--   1 yuichiwest  wheel   137697  5 24 20:10 fault_log_2020-05-24.csv
% cat /tmp/test3/error_log_2020-05-24.csv | more
2020-05-24 10:08:52.588855+0900 0x31a      Error       0x0                  139    0    opendirectoryd: [com.apple.opendirectoryd:default] Failed to open file <private> [2: No such file or directory]
2020-05-24 10:08:52.742746+0900 0x32f      Error       0x0                  139    0    opendirectoryd: [com.apple.opendirectoryd:default] Failed to open file <private> [2: No such file or directory]
2020-05-24 10:08:52.744104+0900 0x2c4      Error       0x0                  151    0    displaypolicyd: (CoreFoundation) [com.apple.defaults:User Defaults] All kCFPreferencesCurrentUser domains in this process will be volatile, because homeDirPath starts with /var/empty
2020-05-24 10:08:52.745015+0900 0x32f      Error       0x0                  139    0    opendirectoryd: [com.apple.opendirectoryd:default] Failed to open file <private> [2: No such file or directory]
(省略)
% cat /tmp/test3/fault_log_2020-05-24.csv | more
2020-05-24 10:08:53.089823+0900 0x3a3      Fault       0x190                183    14   contextstored: (CoreFoundation) [com.apple.defaults:User Defaults] Couldn't read values in CFPrefsPlistSource<0x7fe9b7707ce0> (Domain: kCFPreferencesAnyApplication, User: kCFPreferencesCurrentUser, ByHost: No, Container: (null), Contents Need Refresh: No): accessing preferences outside an application's container requires user-preference-read or file-read-data sandbox access
2020-05-24 10:08:53.090168+0900 0x3a3      Fault       0x191                183    14   contextstored: (CoreFoundation) [com.apple.defaults:User Defaults] Couldn't read values in CFPrefsPlistSource<0x7fe9b7707fb0> (Domain: kCFPreferencesAnyApplication, User: kCFPreferencesAnyUser, ByHost: Yes, Container: (null), Contents Need Refresh: No): accessing preferences outside an application's container requires user-preference-read or file-read-data sandbox access
2020-05-24 10:08:53.277770+0900 0x43c      Fault       0x1f2                183    14   contextstored: (KnowledgeMonitor) [com.apple.coreduet.knowledge:] Requested the previousEvent from instantState in setCurrentEvent, but received nil in stream: Backlight.
2020-05-24 10:08:53.278484+0900 0x43b      Fault       0x1f5                183    14   contextstored: (KnowledgeMonitor) [com.apple.coreduet.knowledge:] Requested the previousEvent from instantState in setCurrentEvent, but received nil in stream: ChargerPluggedInState.
(省略)
```

## 最後に
macOSのError,Faultログを出力することで、ハードウェアやアプリケーションの不具合を調査するのに役立つと思います。またCSVに出力することでExcelを利用してログデータを加工でき、ログデータによる不具合の調査がやりやすくなると思います。