SwiftyBeaver でアプリケーションログをメール送信しデバッグしやすい環境を作る

SwiftyBeaver

SwiftyBeaver というログ集計プラットフォームがあり、これを利用するとアプリケーションのログをクラウドに保存することができます。
それ以外にも普通にコンソールにログを吐いたりローカルのファイルに保存してくれる機能があります。

ログをメールで送れる

今回はローカルにログを保存する機能を使って、そのログファイルをメールで送信できるようにします。

テスターさんが「アプリクラッシュしたんだが」と言ってきた場合に、メールでアプリケーションログを送信できるようにすれば手順やデータなどが再現できるようになりますね。

ログを送信できるようにする手順

Getting Started - SwiftyBeaver Docs
途中までここに載っている内容です。

まずログを出力する

Install SwiftyBeaver

Carthage や Cocoapods などで SwiftyBeaver を install します。
github "SwiftyBeaver/SwiftyBeaver" or pod 'SwiftyBeaver' などですね。

AppDelegate で import

AppDelegate のトップレベルで log の設定を書きます。
Release では利用しない前提なので、私は以下のように書いています。

import SwiftyBeaver

let log: SwiftyBeaver.Type? = {
    #if DEBUG
        let logger = SwiftyBeaver.self
        let console = ConsoleDestination()
        console.asynchronously = false
        let file = FileDestination()
        logger.addDestination(console) // コンソールにログを出力する
        logger.addDestination(file)    // ファイルにログを出力する

        return logger
    #else
        return nil
    #endif
}()

コンソールログを確認する

log?.debug("\(a), \(b)") と書きました。ちゃんとログが出ていますね。

SwiftyBeaver でアプリケーションログをメール送信しデバッグしやすい環境を作る

ログファイルの取得

SwiftyBeaver では Library/Cache ディレクトリにログが吐き出されます。
Cache は OS 側が容量などに合わせて自動で削除するものなので、ログが肥大化しても OS 側がよしなにやってくれそうですね。

以下のコードでログファイルにアクセスし、ファイルのデータを取得できます。

let path: String = NSHomeDirectory() + "/Library/Caches/swiftybeaver.log"
if FileManager().fileExists(atPath: path) {
    let url = URL(fileURLWithPath: path)
    let data = try? Data(contentsOf: url)
}

MessageUI.framework の import

今回はログファイルをメールで送信したいので、 MessageUI.framwork を利用します。
【Swift】アプリからメーラーを起動する方法 - Qiita にわかりやすい導入方法が書いてあります。

ログファイルをメールで送る

以下のようなコードでメールを送るようにしました。
sendMail() を実行するボタンは #if DEBUG の時だけ表示するようにしています。

import MessageUI

extension HogeViewController {
    fileprivate func sendMail() {
        let path: String = NSHomeDirectory() + "/Library/Caches/swiftybeaver.log"
        if FileManager().fileExists(atPath: path) {
            if MFMailComposeViewController.canSendMail() {
                let url = URL(fileURLWithPath: path)
                let data = try? Data(contentsOf: url)
                let mail = MFMailComposeViewController()
                mail.mailComposeDelegate = self
                mail.setToRecipients(["送信先メールアドレス"])
                mail.setSubject("アプリログ")
                mail.setMessageBody("問題の事象などを書いてください", isHTML: false)
                mail.addAttachmentData(data!, mimeType: "text/plain", fileName: "log.txt")
                present(mail, animated: true, completion: nil)
            } else {
                log?.warning("メールが利用できない設定になっています。")
            }
        } else {
            log?.warning("ログファイルが見つかりませんでした。")
        }
    }
}

extension SettingViewController: MFMailComposeViewControllerDelegate {
    func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
        log?.info(result.rawValue)
        dismiss(animated: true, completion: { [weak self] _ in
            switch result {
            case .sent:
                log?.info("送信成功")
            case .failed:
                log?.error("失敗")
            default:
                break
            }
        })
    }
}

メール送信画面

こんな感じで表示されます。

SwiftyBeaver でアプリケーションログをメール送信しデバッグしやすい環境を作る

受信したメール

このようにメールが受信できました。
添付ファイルを開くと、アプリケーションのログを見ることができます。

SwiftyBeaver でアプリケーションログをメール送信しデバッグしやすい環境を作る

おわり

アプリの内部だけでログを集計し、それを外部に送れる仕組みを作りました。
手順や状況などが把握しやすいため、デバッグに非常に役立つと思います。

ただし、これは綺麗にログを吐いていないと意味がないため、ログレベルや何をログとして送信するかなどをちゃんと考えないといけませんね :relaxed:

SwiftyBeaver のクラウドログ機能もめちゃくちゃ便利そうなので、クラウド版の導入も考えていきたいです :moneybag:

2017/03/23 23:39 追記

ログのサイズがメール送信可能ファイルサイズを超える気がしてきたのでその事象に当たったらまた更新します。

カテゴリ:Default 時間:2017-03-23 人気:36
この記事では、 iOS swift3 SwiftyBeaver

関連記事

Copyright (C) socapnw.com, All Rights Reserved.

Socapnw All Rights Reserved.

processed in 1.063 (s). 12 q(s)