   import UIKit
 #endif
 
-public enum LogLevel: Int {
-  case Verbose = 1
-  case Info    = 2
-  case Debug   = 3
-  case Warn    = 4
-  case Error   = 5
+public enum LogLevel {
+  case Verbose, Debug, Info, Warn, Error
 }
 
-extension LogLevel: CustomStringConvertible {
-  public var description: String {
-    switch self {
-    case .Verbose:
-      return "VERBOSE"
-    case .Info:
-      return "INFO"
-    case .Debug:
-      return "DEBUG"
-    case .Warn:
-      return "WARN"
-    case .Error:
-      return "ERROR"
-    }
+extension LogLevel: Comparable {
+  var description: String {
+    return String(self).uppercaseString
   }
 }
+
+public func ==(x: LogLevel, y: LogLevel) -> Bool {
+  return x.hashValue == y.hashValue
+}
+
+public func <(x: LogLevel, y: LogLevel) -> Bool {
+  return x.hashValue < y.hashValue
+}
+
 
 public protocol Logger {
   func log(level: LogLevel, msg: String, funcName: String, lineNum: Int, fileName: String)
 }
 
+
 public class FYLog: Logger {
+  /// The logger state
   public var debug: Bool = true
+  
+  /// The details
   public var details: Bool = true
+  
+  /// The minimum level of severity
+  public var minLevel: LogLevel = .Verbose
   
   public init() {}
   
-  public init(debug: Bool, details: Bool) {
+  /**
+   Create and return a new logger.
+   
+   - parameter debug:    The formatter.
+   - parameter details:  The details.
+   - parameter minLevel: The minimum level of severity.
+   
+   - returns: A new logger instance.
+   */
+  public init(debug: Bool, details: Bool, minLevel: LogLevel = .Verbose) {
     self.debug = debug
     self.details = details
+    self.minLevel = minLevel
   }
   
   public func log(level: LogLevel, msg: String, funcName: String, lineNum: Int, fileName: String) {
-    guard debug else {
+    guard debug && level >= minLevel else {
       return
     }
-    // Debug model
+    
+    var result = "\(now()) [\(level.description)] \(msg)"
     if details {
-      print("\(now()) [\(level.description)] \(funcName) \((fileName as NSString).lastPathComponent) [line:\(lineNum)] --- \(msg)")
-    } else {
-      print("\(now()) [\(level.description)] \(msg)")
+      result = "\(now()) [\(level.description)] \(funcName) \(fileName.lastPathComponent) [line:\(lineNum)] --- \(msg)"
+    }
+    
+    dispatch_async(dispatch_queue_create("FYLogger", DISPATCH_QUEUE_SERIAL)) {
+      Swift.print(result)
     }
   }
 }

  // MARK: - Helper
  
  /// Get current date
  func now() -> String {
    let date: NSDate = NSDate()
    let fmt: NSDateFormatter = NSDateFormatter()
    fmt.dateFormat = "yyyy-MM-dd HH:mm:ss"

    log(.Verbose, msg: msg, funcName: funcName, lineNum: lineNum, fileName: fileName)
  }
  
  /// Debug
  public func debug(msg: String, funcName: String = #function, lineNum: Int = #line, fileName: String = #file) {
    log(.Debug, msg: msg, funcName: funcName, lineNum: lineNum, fileName: fileName)
  }
  
  /// Info
  public func info(msg: String, funcName: String = #function, lineNum: Int = #line, fileName: String = #file) {
    log(.Info, msg: msg, funcName: funcName, lineNum: lineNum, fileName: fileName)
  }
  
  /// Warn
