SimpleLogReporter.swift 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import Foundation
  2. import SwiftDate
  3. final class SimpleLogReporter: IssueReporter {
  4. private let fileManager = FileManager.default
  5. private var dateFormatter: DateFormatter {
  6. let dateFormatter = DateFormatter()
  7. dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
  8. return dateFormatter
  9. }
  10. func setup() {}
  11. func setUserIdentifier(_: String?) {}
  12. func reportNonFatalIssue(withName _: String, attributes _: [String: String]) {}
  13. func reportNonFatalIssue(withError _: NSError) {}
  14. func log(_ category: String, _ message: String, file: String, function: String, line: UInt) {
  15. let now = Date()
  16. let startOfDay = Calendar.current.startOfDay(for: now)
  17. if !fileManager.fileExists(atPath: SimpleLogReporter.logDir) {
  18. try? fileManager.createDirectory(
  19. atPath: SimpleLogReporter.logDir,
  20. withIntermediateDirectories: false,
  21. attributes: nil
  22. )
  23. }
  24. if !fileManager.fileExists(atPath: SimpleLogReporter.logFile) {
  25. createFile(at: startOfDay)
  26. } else {
  27. if let attributes = try? fileManager.attributesOfItem(atPath: SimpleLogReporter.logFile),
  28. let creationDate = attributes[.creationDate] as? Date, creationDate < startOfDay
  29. {
  30. try? fileManager.removeItem(atPath: SimpleLogReporter.logFilePrev)
  31. try? fileManager.moveItem(atPath: SimpleLogReporter.logFile, toPath: SimpleLogReporter.logFilePrev)
  32. createFile(at: startOfDay)
  33. }
  34. }
  35. let logEntry = "\(dateFormatter.string(from: now)) [\(category)] \(file.file) - \(function) - \(line) - \(message)\n"
  36. let data = logEntry.data(using: .utf8)!
  37. try? data.append(fileURL: URL(fileURLWithPath: SimpleLogReporter.logFile))
  38. }
  39. private func createFile(at date: Date) {
  40. fileManager.createFile(atPath: SimpleLogReporter.logFile, contents: nil, attributes: [.creationDate: date])
  41. }
  42. static var logFile: String {
  43. getDocumentsDirectory().appendingPathComponent("logs/log.txt").path
  44. }
  45. static var logDir: String {
  46. getDocumentsDirectory().appendingPathComponent("logs").path
  47. }
  48. static var logFilePrev: String {
  49. getDocumentsDirectory().appendingPathComponent("logs/log_prev.txt").path
  50. }
  51. static func getDocumentsDirectory() -> URL {
  52. let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
  53. let documentsDirectory = paths[0]
  54. return documentsDirectory
  55. }
  56. }
  57. private extension Data {
  58. func append(fileURL: URL) throws {
  59. if let fileHandle = FileHandle(forWritingAtPath: fileURL.path) {
  60. defer {
  61. fileHandle.closeFile()
  62. }
  63. fileHandle.seekToEndOfFile()
  64. fileHandle.write(self)
  65. } else {
  66. try write(to: fileURL, options: .atomic)
  67. }
  68. }
  69. }
  70. private extension String {
  71. var file: String { components(separatedBy: "/").last ?? "" }
  72. }