iOSやmacOSでのログ出力はASL API

Software Design 2016年9月号の特集のログ出力を読んでいて、iOSやmacOSでsyslogでどうなっていたかなぁと思ったので、確認しました。

iOSやmacOSでもsyslog()関数を使ったログ出力が出来ます。アップルの推奨している方法は、syslog()を使うのではなく、ASL (Apple System Logger) APIを使う方法です。「Daemons and Services Programming Guide」の「Logging Errors and Warnings」の所に概要が載っています。ASL APIの詳細はmanページを参照と書かれていました。

書かれている中で目を引いたのは、ASLはスレッドセーフであることです。libdispatchのおかげで簡単にスレッドを作って、サブスレッドで処理を行わせることが出来るようになり、サブスレッドで動作していることを忘れがちです。気軽にログ出力を行ったら、それが原因で落ちてしまったなんてことになったら、目が当てられないです。

NSLog関数はsyslogにも出力します。Swiftネイティブで同様の関数があったか検索してみると、そのものずばりは無いようですね。素直にASL APIをSwiftから使えば良いようです。しかし、ログ出力をしたいところで、直接ASL APIを使っていると、後々、変更するときに面倒になるのと、出力先や出力フォーマットを変更したいなども考えると、ラッパー関数を作って、それを使うのが良いのでは無いでしょうか。

Swiftから使ってみる

とりあえず、Swiftから使って見ます。Swiftから使うにはブリッジヘッダファイルを作って、ブリッジヘッダファイルで「asl.h」をインクルードします。

C++やObjective-Cからは「asl_log_message」関数で手軽に出力できますが、Swiftからだと直接は呼べないようです。そのため、他の関数を使って実装します。次の例は、「log」という関数を実装しています。

import Foundation

func log(format: String, _ items: CVarArgType...) {
    let logClient = asl_open(nil, "com.rk-k.MacLog", UInt32(ASL_OPT_STDERR))
    asl_vlog(logClient, nil, ASL_LEVEL_WARNING, format, getVaList(items))
    asl_close(logClient)
}

log("Debug Log Test")

ログレベルは「ASL_LEVEL_NOTICE」以上のレベル(数値としては以下ですが)を指定すると、コンソールにも表示されます。

[PR] 著書をちょっと宣伝です。

シェアする

  • このエントリーをはてなブックマークに追加
  • Evernoteに保存Evernoteに保存

フォローする