3 // alamofire_activity_logger
5 // Created by Manuel García-Estañ on 14/9/16.
6 // Copyright © 2016 manuege. All rights reserved.
11 private let nullString = "(null)"
12 private let separatorString = "*******************************"
15 A set of static methods which logs request and responses
17 internal struct Logger {
19 internal static func logRequest(request: URLRequest?, level: LogLevel, options: [LogOption], printer: Printer) {
21 guard let request = request else {
25 let method = request.httpMethod!
26 let url = request.url?.absoluteString ?? nullString
27 let headers = prettyPrintedString(from: request.allHTTPHeaderFields) ?? nullString
30 let openSeparator = options.contains(.includeSeparator) ? "\(separatorString)\n" : ""
31 let closeSeparator = options.contains(.includeSeparator) ? "\n\(separatorString)" : ""
35 let prettyPrint = options.contains(.jsonPrettyPrint)
36 let body = string(from: request.httpBody, prettyPrint: prettyPrint) ?? nullString
37 printer.print("\(openSeparator)[Request] \(method) '\(url)':\n\n[Headers]\n\(headers)\n\n[Body]\n\(body)\(closeSeparator)", phase: .request)
40 printer.print("\(openSeparator)[Request] \(method) '\(url)'\(closeSeparator)", phase: .request)
47 internal static func logResponse(request: URLRequest?, response: ResponseInfo, level: LogLevel, options: [LogOption], printer: Printer) {
49 guard level != .none else {
53 let httpResponse = response.httpResponse
54 let data = response.data
55 let elapsedTime = response.elapsedTime
56 let error = response.error
58 if request == nil && response.httpResponse == nil {
63 let prettyPrint = options.contains(.jsonPrettyPrint)
66 let requestMethod = request?.httpMethod ?? nullString
67 let requestUrl = request?.url?.absoluteString ?? nullString
70 let responseStatusCode = httpResponse?.statusCode ?? 0
71 let responseHeaders = prettyPrintedString(from: httpResponse?.allHeaderFields) ?? nullString
72 let responseData = string(from: data, prettyPrint: prettyPrint) ?? nullString
75 let elapsedTimeString = String(format: "[%.4f s]", elapsedTime)
78 let openSeparator = options.contains(.includeSeparator) ? "\(separatorString)\n" : ""
79 let closeSeparator = options.contains(.includeSeparator) ? "\n\(separatorString)" : ""
82 let success = (error == nil)
83 let responseTitle = success ? "Response" : "Response Error"
86 printer.print("\(openSeparator)[\(responseTitle)] \(responseStatusCode) '\(requestUrl)' \(elapsedTimeString):\n\n[Headers]:\n\(responseHeaders)\n\n[Body]\n\(responseData)\(closeSeparator)", phase: .response(success: success))
88 printer.print("\(openSeparator)[\(responseTitle)] \(responseStatusCode) '\(requestUrl)' \(elapsedTimeString)\(closeSeparator)", phase: .response(success: success))
90 if let error = error {
91 printer.print("\(openSeparator)[\(responseTitle)] \(requestMethod) '\(requestUrl)' \(elapsedTimeString) s: \(error)\(closeSeparator)", phase: .response(success: success))
98 // MARK: - Private helpers
99 private static func string(from data: Data?, prettyPrint: Bool) -> String? {
101 guard let data = data else {
105 var response: String? = nil
108 let json = try? JSONSerialization.jsonObject(with: data, options: []),
109 let prettyString = prettyPrintedString(from: json) {
110 response = prettyString
113 else if let dataString = String.init(data: data, encoding: .utf8) {
114 response = dataString
120 private static func prettyPrintedString(from json: Any?) -> String? {
121 guard let json = json else {
125 var response: String? = nil
127 if let data = try? JSONSerialization.data(withJSONObject: json, options: .prettyPrinted),
128 let dataString = String.init(data: data, encoding: .utf8) {
129 response = dataString