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

# [SwiftyBeaver](http://swiftybeaver.com/)

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

## ログをメールで送れる

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

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

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

[Getting Started \- SwiftyBeaver Docs](http://docs.swiftybeaver.com/category/4-getting-started)
途中までここに載っている内容です。

## まずログを出力する

### Install SwiftyBeaver

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

### AppDelegate で import

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

```swift
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)")` と書きました。ちゃんとログが出ていますね。

<img width="636" alt="スクリーンショット 2017-03-23 20.19.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/5678/ce207627-bf6d-0c23-73e0-09a383ac4973.png">

### ログファイルの取得

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

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

```swift
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](http://qiita.com/The_Shimon/items/24735d2211d67cf668f7) にわかりやすい導入方法が書いてあります。

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

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

```swift
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
            }
        })
    }
}
```

### メール送信画面

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

<img width="375" alt="2017-03-23 20.45.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/5678/df4185f0-544e-d2c5-6302-64c320607951.png">

### 受信したメール

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

<img width="408" alt="スクリーンショット 2017-03-23 20.47.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/5678/ba6fd7e0-eab6-e940-8cdb-39bd9536e372.png">


# おわり

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

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

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

# 2017/03/23 23:39 追記

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