Upgrade to Pro — share decks privately, control downloads, hide ads and more …

サポート効率を上げるためのロギング環境構築

503b1ca28b167b0d94a5992aad1a57b1?s=47 horimislime
September 17, 2017

 サポート効率を上げるためのロギング環境構築

iOSDC Japan 2017 2017/9/17 (日)
https://iosdc.jp/2017/node/1422

503b1ca28b167b0d94a5992aad1a57b1?s=128

horimislime

September 17, 2017
Tweet

Transcript

  1. αϙʔτޮ཰Λ্͛ΔͨΊͷ ϩΪϯά؀ڥߏங 2017/09/17 (೔) ງݟ फҰ࿠ @horimislime iOSDC Japan 2017

  2. ࣗݾ঺հ • ງݟ फҰ࿠ (@horimislime) • ! גࣜձࣾτϨλ • "

    iPad޲͚ͷ༧໿୆ாΞϓϦ։ൃ • # ϞόΠϧΞϓϦͷΤϥʔϩάऩूʹ͍ͭͯ iOSDC Japan 2017
  3. ฐࣾʹ͍ͭͯ • 2013೥ϩʔϯνɺࠃ಺8000ళͰಋೖ • ଟݴޠԽͰΞδΞݍʹ΋ల։ ! • ࠷ۙ͸BLEΛ࢖ͬͨϋʔυ΢ΣΞ΋ iOSDC Japan

    2017
  4. Կ͕ى͖͔ͨ • ࠶ݱੑͷͳ͍ෆ۩߹໰͍߹Θ͕ͤ • ίϛϡχέʔγϣϯίετͷ૿େ • ϋʔυ΢ΣΞ΋བྷΜͰ͞ΒʹෳࡶԽ iOSDC Japan 2017

  5. Ξϓϩʔν 1. ΫϥογϡҎ֎ͷΤϥʔΛݕ஌Ͱ͖Δମ੍࡞Γ 2. ௐࠪʹඞཁͳώϯτ͸ͳΔ΂͘૿΍͢ 3. ໰͍߹Θͤ࣌ͷίετΛݮΒ͢ iOSDC Japan 2017

  6. Ξϓϩʔν 1. ΫϥογϡҎ֎ͷΤϥʔΛݕ஌Ͱ͖Δମ੍࡞Γ 2. ௐࠪʹඞཁͳώϯτ͸ͳΔ΂͘૿΍͢ 3. ໰͍߹Θͤ࣌ͷίετΛݮΒ͢ iOSDC Japan 2017

  7. ฐࣾͷ͜Ε·Ͱ • HockeyAppͰΫϥογϡऩूʢ഑෍͸ݱ໾ʣ • Ϋϥογϡ৘ใҎ֎ʹϩάϑΝΠϧͷૹ৴ػೳ • ϩάૹ৴ͷλΠϛϯά͸Ϋϥογϡ࣌ͷΈ • Ϋϥογϡ࣌ͷ৘ใ͕গͳ͍ iOSDC

    Japan 2017
  8. Ҡߦܭը • ΫϥογϡҎ֎ͷΤϥʔΛݕ஌Ͱ͖Δମ੍࡞Γ • ΫϥογϡɾΤϥʔૹ৴࣌ͷঢ়ଶΛৄ͘͠஌Γ͍ͨ • BugsnagΛ࠾༻͢Δࣄʹ iOSDC Japan 2017

  9. αʔϏεબఆ • େखͩͱ3αʔϏε͕΄΅ಉ౳ͷػೳ • • • • ʮύϯͣ͘ϩάʯΛ࢖͑Δͷ͕ศར iOSDC Japan

    2017
  10. ύϯͣ͘ϩά • Τϥʔൃੜ·Ͱͷಓ͠Δ΂ • ΞϓϦͷ৭Μͳॴʹ࢓ࠐΉ͚ͩ • ΤϥʔͱҰॹʹ࣌ܥྻͰϩάදࣔ func buttonTapped(sender: UIButton)

    { Bugsnag.leaveBreadcrumb("\(sender.title) tapped!") } iOSDC Japan 2017
  11. Logger.swift struct Logger { func info(message: String) { debugPrint(message) Bugsnag.leaveBreadcrumb(message)

    } func error(message: String) { debugPrint(message) Bugsnag.notifyError(...) } } iOSDC Japan 2017
  12. ࣮͸iOSඪ४ػೳͱͯ͠΋ଘࡏ iOSDC Japan 2017

  13. Activity Tracing iOSDC Japan 2017

  14. 1. ΫϥογϡҎ֎ͷΤϥʔΛݕ஌Ͱ͖Δମ੍࡞Γ 2. ௐࠪʹඞཁͳώϯτ͸ͳΔ΂͘૿΍͢ 3. ໰͍߹Θͤ࣌ͷίετΛݮΒ͢ iOSDC Japan 2017

  15. 1. ΫϥογϡҎ֎ͷΤϥʔΛݕ஌Ͱ͖Δମ੍࡞Γ 2. ௐࠪʹඞཁͳώϯτ͸ͳΔ΂͘૿΍͢ 3. ໰͍߹Θͤ࣌ͷίετΛݮΒ͢ iOSDC Japan 2017

  16. ௐ͕ࠪḿΔ৘ใͱ͸ • Ϣʔβ͕Ͳ͏͍ͬͨૢ࡞Λߦ͔ͬͨ • ໰୊͕ىͬͨ͜ͷ͸Ͳ͏͍͏ঢ়ଶɾ؀ڥ͔ iOSDC Japan 2017

  17. Ϣʔβͷߦಈϩά • ViewControllerͷભҠϩά • ݩʑHockeyApp࣌୅͔Βऩू • ύϯͣ͘ʹͦͷ··ೖΕΔΑ͏ʹ iOSDC Japan 2017

  18. UIͷૢ࡞ཤྺ • UITextFieldͷϑΥʔΧεɾUIButtonͷλοϓ౳ • AnalyticsͰर͍ͬͯΔΠϕϯτͱॏෳ͢Δ͕ • accessibilityIdentifierΛૹ࣮ͬͯ૷Λ࠷খ޻਺ʹ iOSDC Japan 2017

  19. Ϣʔβ୺຤ͷঢ়ଶ • ࠷ۙͷαʔϏε͸ࣗಈऩू • Bugsnag΋΄ͱΜͲͷঢ়ଶΛऩू iOSDC Japan 2017

  20. ωοτϫʔΫ઀ଓঢ়گ • ReachabilityͷΠϕϯτΛߪಡ • ࣮͸"ϧʔλʹܨ͕͍ͬͯΔ͔"͔͠൑ அ͕͔ͭͳ͍ • Πϯλʔωοτʹग़ΒΕͳ͍৔߹΋ iOSDC Japan

    2017
  21. ͦͷଞͷίϯιʔϧϩά • γεςϜ͕ు͖ग़ͯ͠Δϩά (AutoLayout่ΕͳͲ) • ϩάอଘઌΛ೚ҙͷσΟϨΫτϦԼʹมߋͰ͖Δ • Ϋϥογϡʹhookͯ͠ϑΝΠϧͷத਎Λૹ৴͢Δ͜ͱ΋Մೳ var paths

    = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) let directory = paths[0] let logFilePath = (directory as NSString).appendingPathComponent("\(Date()).log") freopen(logFilePath.cString(using: String.Encoding.ascii)!, "a+", stderr) iOSDC Japan 2017
  22. 1. ΫϥογϡҎ֎ͷΤϥʔΛݕ஌Ͱ͖Δମ੍࡞Γ 2. ௐࠪʹඞཁͳώϯτ͸ͳΔ΂͘૿΍͢ 3. ໰͍߹Θͤ࣌ͷίετΛݮΒ͢ iOSDC Japan 2017

  23. 1. ΫϥογϡҎ֎ͷΤϥʔΛݕ஌Ͱ͖Δମ੍࡞Γ 2. ௐࠪʹඞཁͳώϯτ͸ͳΔ΂͘૿΍͢ 3. ໰͍߹Θͤ࣌ͷίετΛݮΒ͢ iOSDC Japan 2017

  24. ໰͍߹Θͤ࣌ͷίετ͸ͳͥ૿͑Δ͔ • ௐࠪʹඞཁͳϩά͕ͦ΋ͦ΋ݟΕͳ͍ • ೔ຊޠͰత֬ʹ఻ୡ͢Δͷ͕೉͍͠ iOSDC Japan 2017

  25. struct Service { func connectToDevice(completion: Result<Response, NSError>) { // ॲཧ

    if notReady { completion(.failure(NSError(domain: "in.toreta", code: 0, userInfo: nil))) } else { completion(.success(response)) } } } override func viewDidLoad() { super.viewDidLoad() service.connectToDevice { result in switch result { case .success(let data): ... case .failure(let _): HUD.show("Τϥʔ͕ൃੜ͠·ͨ͠ɻ઀ଓ؀ڥΛ֬ೝ͍ͩ͘͞ɻ") } } } iOSDC Japan 2017
  26. ϩδοΫΤϥʔ΋ৄࡉʹྻڍ enum ApplicationError: Error { case bleNotAvailable case hardwareNotReady ...

    } struct Service { func connectToDevice(completion: Result<Response, ApplicationError>) { // ॲཧ if notReady { completion(.failure(.hardwareNotReady)) } else { completion(.success(response)) } } } iOSDC Japan 2017
  27. Error Code • Ϣʔβ͔Βͷ໰͍߹ΘͤΛޮ཰Խ͢Δཁ • ώΞϦϯάࣄ߲͔ΒݪҼಛఆ·ͰΛ௚݁ͤ͞Δ iOSDC Japan 2017

  28. iOSDC Japan 2017

  29. iOSDC Japan 2017

  30. enum ApplicationError: Error { ... case hardwareNotReady var errorCode: Int

    { switch self { ... case hardwareNotReady: return -3000 } } var localizedDescription: String { ... case hardwareNotReady: return "Τϥʔίʔυ: \(errorCode)" } var localizedFailureReason: String { ... case hardwareNotReady: return "઀ଓʹࣦഊ͠·ͨ͠ɻBLEσόΠεͷిݯΛ֬͝ೝ͍ͩ͘͞ɻ" } } iOSDC Japan 2017
  31. Error Codeͷར఺1 • ໰͍߹ΘͤͷແݴޠԽʹܨ͕Δ override func viewDidLoad() { ... service.connectToDevice

    { result in switch result { case .success(let data): ... case .failure(let error): Logger.shared.error(error) self.showAlert(withTitle: error.localizedDescription, message: error.localizedFailureReason) } } } iOSDC Japan 2017
  32. Error Codeͷར఺2 • ϩάૹ৴͓͖ͯ͠ௐࠪΛޮ཰Խ • ໰͍߹ΘͤΛݩʹDashboardͰҰൃ ݕࡧ iOSDC Japan 2017

  33. ϙΠϯτ • Τϥʔίʔυ͸ΞϓϦଆͰҰׅఆٛɾ؅ཧ͢Δͱྑͦ͞͏ • localizedFailureReasonͳͲ΋SDK͕ฦ͢΋ͷΛ࢖Θͳ͍ • 3rd party FWͰ͸nilΛฦͯ͠Δ͜ͱ͕ී௨ʹ͋Δ iOSDC

    Japan 2017
  34. 1. ΫϥογϡҎ֎ͷΤϥʔΛݕ஌Ͱ͖Δମ੍࡞Γ 2. ௐࠪʹඞཁͳώϯτ͸ͳΔ΂͘૿΍͢ 3. ໰͍߹Θͤ࣌ͷίετΛݮΒ͢ iOSDC Japan 2017

  35. ·ͱΊ • ෆ۩߹͕ൃੜ͢Δͱଟ͘ͷਓʹίετ͕͔͔Δ • ؆୯ͳ੔஍࡞ۀͰେ͖ͳϝϦοτ • ແବͳ΍ΓͱΓΛݮΒ͠շదͳτϥϒϧγϡʔςΟϯάΛ iOSDC Japan 2017