[iOS 10] os_logを使ったLoggerを作ってみた

2016.10.14

はじめに

こんにちは!モバイルアプリサービス部の加藤 潤です。
iOS 10から使えるos_logですが以下のような形でそのまま使うとコンソールにログタイプが出力されないことに気がつきました。

let myOSLog = OSLog(subsystem: "jp.classmethod.OSLogSample", category: "UI")
os_log("os_logをそのまま使ったログ", log: myOSLog, type: .debug)

上記で出力した結果(コンソール)

2016-10-14 18:56:59.231021 OSLogSample[7979:1076185] [UI] os_logをそのまま使ったログ

ということでログタイプを出力するようなロガークラスを作ってみました。

開発環境

  • Xcode Version 8.0 (8A218a)
  • Swift 3.0

まずはOSLogTypeを拡張する

OSLogTypeにログタイプの文字列を取得するようなプロパティ等はなさそうなので、ログタイプに応じた文字列を取得できるようOSLogTypeを拡張しました。

extension OSLogType: CustomStringConvertible {
    public var description: String {
        switch self {
        case OSLogType.info:
            return "INFO"
        case OSLogType.debug:
            return "DEBUG"
        case OSLogType.error:
            return "ERROR"
        case OSLogType.fault:
            return "FAULT"
        default:
            return "DEFAULT"
        }
    }
}

CustomStringConvertibleに準拠しただけです。

ロガークラスを作る

次にロガークラスを作ってみました。

public class Logger {

    private init() {}

    static var osLog: OSLog = OSLog.default

    public static func info(message: String, osLog: OSLog = osLog) {
        doLog(message: message, osLog: osLog, logType: .info)
    }

    public static func debug(message: String, osLog: OSLog = osLog) {
        doLog(message: message, osLog: osLog, logType: .debug)
    }

    public static func error(message: String, osLog: OSLog = osLog) {
        doLog(message: message, osLog: osLog, logType: .error)
    }

    public static func fault(message: String, osLog: OSLog = osLog) {
        doLog(message: message, osLog: osLog, logType: .fault)
    }

    public static func `default`(message: String, osLog: OSLog = osLog) {
        doLog(message: message, osLog: osLog)
    }

    private static func doLog(message: String, osLog: OSLog, logType: OSLogType = .default) {
        os_log("[%@] %@", log: osLog, type: logType, String(describing: logType), message)
    }
}

ログタイプ毎のメソッドを作りました。 最終的にはos_logを実行しています。

ロガーの使い方

使い方は簡単です。 必要に応じてカスタムのOSLogを作ってLoggerにセット(指定しない場合はOSLog.defaultが使われます)し、ログタイプに応じたログ出力メソッドを実行するだけです。

// カスタムのOSLogを作る
let myOSLog = OSLog(subsystem: "jp.classmethod.OSLogSample", category: "UI")

// カスタムのOSLogをLoggerにセット
Logger.osLog = myOSLog

// あとは出力するだけ
Logger.info(message: "info message")
Logger.debug(message: "debug message")
Logger.error(message: "error message")
Logger.fault(message: "fault message")
Logger.default(message: "default message")

実行結果(コンソール)は以下の通りです。 ちょっぴり便利になりましたね!

2016-10-14 19:14:35.510910 OSLogSample[8720:1101836] [UI] [INFO] info message
2016-10-14 19:14:35.511130 OSLogSample[8720:1101836] [UI] [DEBUG] debug message
2016-10-14 19:14:35.511459 OSLogSample[8720:1101836] [UI] [ERROR] error message
2016-10-14 19:14:35.511909 OSLogSample[8720:1101836] [UI] [FAULT] fault message
2016-10-14 19:14:35.512284 OSLogSample[8720:1101836] [UI] [DEFAULT] default message

おわりに

今回は簡単なos_logのラッパークラスを作ってログタイプを出力できるようにしてみました。
ログのカテゴリを複数持たせたい場合も拡張すればなんとかなりそうです。

参考記事