Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom logger #6

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,15 @@ Timberjack has two modes: Verbose and Light. The default style is `Verbose`. To
Timberjack.logStyle = .Verbose //Either .Verbose, or .Light
````

It is also possible to filtered which URL you want to log.
2 modes exist: *Black list mode* and *White list mode*. The default mode is *Black list*

````swift
Timberjack.filteredMode = .Black
let urlFiltered = NSURL(string: "http://www.example.com")
Timberjack.blackListUrl = [urlFiltered!] // All requests going and coming from example.com will be ignored
````

##License

MIT, see LICENSE for details.
Expand Down
84 changes: 69 additions & 15 deletions Source/Timberjack.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,27 @@ public enum Style {
case Light
}

public typealias TimberjackPrint = ((String) -> Void)

public class Timberjack: NSURLProtocol {
var connection: NSURLConnection?
var data: NSMutableData?
var response: NSURLResponse?
var newRequest: NSMutableURLRequest?


public enum FilterListMode {
case Black
case White
}

public static var printLog: TimberjackPrint = { log in
print(log)
}
public static var logStyle: Style = .Verbose

public static var filteredMode: FilterListMode = .Black
public static var whiteListUrl: [NSURL]?
public static var blackListUrl: [NSURL]?

public class func register() {
NSURLProtocol.registerClass(self)
}
Expand Down Expand Up @@ -117,30 +130,34 @@ public class Timberjack: NSURLProtocol {
//MARK: - Logging

public func logDivider() {
print("---------------------")
Timberjack.printLog("---------------------")
}

public func logError(error: NSError) {
logDivider()

print("Error: \(error.localizedDescription)")
Timberjack.printLog("Error: \(error.localizedDescription)")

if Timberjack.logStyle == .Verbose {
if let reason = error.localizedFailureReason {
print("Reason: \(reason)")
Timberjack.printLog("Reason: \(reason)")
}

if let suggestion = error.localizedRecoverySuggestion {
print("Suggestion: \(suggestion)")
Timberjack.printLog("Suggestion: \(suggestion)")
}
}
}

public func logRequest(request: NSURLRequest) {
if !shouldLog(request.URL) {
return
}

logDivider()

if let url = request.URL?.absoluteString {
print("Request: \(request.HTTPMethod!) \(url)")
Timberjack.printLog("Request: \(request.HTTPMethod!) \(url)")
}

if Timberjack.logStyle == .Verbose {
Expand All @@ -151,15 +168,19 @@ public class Timberjack: NSURLProtocol {
}

public func logResponse(response: NSURLResponse, data: NSData? = nil) {
if !shouldLog(response.URL) {
return
}

logDivider()

if let url = response.URL?.absoluteString {
print("Response: \(url)")
Timberjack.printLog("Response: \(url)")
}

if let httpResponse = response as? NSHTTPURLResponse {
let localisedStatus = NSHTTPURLResponse.localizedStringForStatusCode(httpResponse.statusCode).capitalizedString
print("Status: \(httpResponse.statusCode) - \(localisedStatus)")
Timberjack.printLog("Status: \(httpResponse.statusCode) - \(localisedStatus)")
}

if Timberjack.logStyle == .Verbose {
Expand All @@ -169,7 +190,7 @@ public class Timberjack: NSURLProtocol {

if let startDate = Timberjack.propertyForKey(TimberjackRequestTimeKey, inRequest: newRequest!) as? NSDate {
let difference = fabs(startDate.timeIntervalSinceNow)
print("Duration: \(difference)s")
Timberjack.printLog("Duration: \(difference)s")
}

guard let data = data else { return }
Expand All @@ -179,23 +200,56 @@ public class Timberjack: NSURLProtocol {
let pretty = try NSJSONSerialization.dataWithJSONObject(json, options: .PrettyPrinted)

if let string = NSString(data: pretty, encoding: NSUTF8StringEncoding) {
print("JSON: \(string)")
Timberjack.printLog("JSON: \(string)")
}
}

catch {
if let string = NSString(data: data, encoding: NSUTF8StringEncoding) {
print("Data: \(string)")
Timberjack.printLog("Data: \(string)")
}
}
}
}

public func logHeaders(headers: [String: AnyObject]) {
print("Headers: [")
Timberjack.printLog("Headers: [")
for (key, value) in headers {
print(" \(key) : \(value)")
Timberjack.printLog(" \(key) : \(value)")
}
print("]")
Timberjack.printLog("]")
}

func shouldLog(url: NSURL?) -> Bool {
let filteredList = Timberjack.filteredMode == .Black ? Timberjack.blackListUrl : Timberjack.whiteListUrl

switch (Timberjack.filteredMode, url, filteredList) {
case (.Black, let url?, let list?):
return !list.contains(url)
case (.Black, _, _):
return true
case (.White, let url?, let list?):
return list.contains(url)
case (.White, _, _):
return false
}
}
}

extension String {
func contains(aString: String) -> Bool {
return self.rangeOfString(aString) != nil
}
}

extension NSURL {
func contains(url: NSURL) -> Bool {
return self.absoluteString.contains(url.absoluteString)
}
}

extension SequenceType where Generator.Element == NSURL {
func contains(element: NSURL) -> Bool {
return self.reduce(false) { return $0 || element.contains($1) }
}
}
95 changes: 80 additions & 15 deletions Tests/TimberjackTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,93 @@
import UIKit
import XCTest

@testable import Timberjack

class TimberjackTests: XCTestCase {


private var buffer: [String] = []

override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
buffer = []
Timberjack.printLog = { log in
self.buffer.append(log)
}
}

override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()

func testLogDefaultBehavior() {
// Given
let urlRequested = NSURL(string: "http://www.example.com/sample")
let request = NSURLRequest(URL: urlRequested!)

// When
let instance = Timberjack()
instance.logRequest(request)

// Then
XCTAssert(buffer.count != 0)
}

func testExample() {
// This is an example of a functional test case.
XCTAssert(true, "Pass")
func testLogDisableWithBlackList() {
// Given
let urlFiltered = NSURL(string: "http://www.example.com")
let urlRequested = NSURL(string: "http://www.example.com/sample")
Timberjack.filteredMode = .Black
Timberjack.blackListUrl = [urlFiltered!]
let request = NSURLRequest(URL: urlRequested!)

// When
let instance = Timberjack()
instance.logRequest(request)

// Then
XCTAssert(buffer.count == 0)
}

func testPerformanceExample() {
// This is an example of a performance test case.
self.measureBlock() {
// Put the code you want to measure the time of here.
}
func testLogEnableWithBlackList() {
// Given
let urlFiltered = NSURL(string: "http://www.example.com")
let urlRequested = NSURL(string: "http://www.example2.com")
Timberjack.filteredMode = .Black
Timberjack.blackListUrl = [urlFiltered!]
let request = NSURLRequest(URL: urlRequested!)

// When
let instance = Timberjack()
instance.logRequest(request)

// Then
XCTAssert(buffer.count != 0)
}

func testLogEnableWithWhiteList() {
// Given
let urlFiltered = NSURL(string: "http://www.example.com")
let urlRequested = NSURL(string: "http://www.example.com/sample")
Timberjack.filteredMode = .White
Timberjack.whiteListUrl = [urlFiltered!]
let request = NSURLRequest(URL: urlRequested!)

// When
let instance = Timberjack()
instance.logRequest(request)

// Then
XCTAssert(buffer.count != 0)
}

func testLogDisableWithWhiteList() {
// Given
let urlFiltered = NSURL(string: "http://www.example.com")
let urlRequested = NSURL(string: "http://www.example2.com")
Timberjack.filteredMode = .White
Timberjack.whiteListUrl = [urlFiltered!]
let request = NSURLRequest(URL: urlRequested!)

// When
let instance = Timberjack()
instance.logRequest(request)

// Then
XCTAssert(buffer.count == 0)
}
}