Skip to content

Instantly share code, notes, and snippets.

@zirinisp
Created July 1, 2017 12:17
Show Gist options
  • Save zirinisp/4217dae76d6ccc42810ddbf1ab6f7feb to your computer and use it in GitHub Desktop.
Save zirinisp/4217dae76d6ccc42810ddbf1ab6f7feb to your computer and use it in GitHub Desktop.
Slack Logger for Swift Kitura
import Foundation
import LoggerAPI
import KituraRequest
import SwiftyJSON
struct SlackField {
var title: String
var value: String
var short: Bool = false
var json: JSON {
return JSON(["title": title, "value": value])
}
}
class SlackController {
static var shared = SlackController()
var slackWebhook: String?
var slackErrorWebhook: String?
var serverUrl: String?
func log(_ type: LoggerMessageType, msg: String,
functionName: String, lineNum: Int, fileName: String) {
let fileNameWithoutPath = fileName.components(separatedBy: "/").last ?? fileName
let completeFunction = fileNameWithoutPath+"/"+functionName+":"+"\(lineNum)"
let fields: [SlackField] = [SlackField(title: "Timestamp", value: self.formatDate(), short: false), SlackField(title: "Function", value: completeFunction, short: false), SlackField(title: "Type", value: type.description, short: false)]
var json = JSON([:])
json["username"].stringValue = self.serverUrl ?? "Unknown Server"
json["text"].stringValue = msg
let jsonFields = fields.map({$0.json})
json["fields"] = JSON(jsonFields)
json["color"].stringValue = type.colorHex
//json["fallback"].string = type.description + " " + msg
let jsonString = json.rawString() ?? ""
if let slackWebhook = self.slackWebhook {
let _ = KituraRequest.request(.post,
slackWebhook,
parameters: ["payload":jsonString],
encoding: URLEncoding.default)
}
if let slackErrorWebhook = self.slackErrorWebhook {
if type.rawValue >= LoggerMessageType.warning.rawValue {
let _ = KituraRequest.request(.post,
slackErrorWebhook,
parameters: ["payload":jsonString],
encoding: URLEncoding.default)
}
}
}
/// If not nil, specifies the format used when adding the date and the time to the
/// logged messages
public var dateFormat: String? {
didSet {
dateFormatter = SlackController.getDateFormatter(format: dateFormat, timeZone: timeZone)
}
}
/// If not nil, specifies the timezone used in the date time format
public var timeZone: TimeZone? {
didSet {
dateFormatter = SlackController.getDateFormatter(format: dateFormat, timeZone: timeZone)
}
}
/// default date format - ISO 8601
public static let defaultDateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
fileprivate var dateFormatter: DateFormatter = SlackController.getDateFormatter()
static func getDateFormatter(format: String? = nil, timeZone: TimeZone? = nil) -> DateFormatter {
let formatter = DateFormatter()
if let dateFormat = format {
formatter.dateFormat = dateFormat
} else {
formatter.dateFormat = defaultDateFormat
}
if let timeZone = timeZone {
formatter.timeZone = timeZone
}
return formatter
}
func formatDate(_ date: Date = Date()) -> String {
return dateFormatter.string(from: date)
}
}
class SlackLogger: Logger {
var localLogger: Logger?
/// Create a `HeliumLogger` instance and set it up as the logger used by the `LoggerAPI`
/// protocol.
/// - Parameter type: The most detailed message type (`LoggerMessageType`) to see in the
/// output of the logger. Defaults to `verbose`.
public class func use(_ type: LoggerMessageType = .verbose, localLogger: Logger?) {
Log.logger = SlackLogger(type, localLogger: localLogger)
}
var type: LoggerMessageType
/// Create a `HeliumLogger` instance
///
/// - Parameter type: The most detailed message type (`LoggerMessageType`) to see in the
/// output of the logger.
public init (_ type: LoggerMessageType = .verbose, localLogger: Logger?) {
self.type = type
self.localLogger = localLogger
}
func log(_ type: LoggerMessageType, msg: String, functionName: String, lineNum: Int, fileName: String) {
self.localLogger?.log(type, msg: msg, functionName: functionName, lineNum: lineNum, fileName: fileName)
guard isLogging(type) else {
return
}
guard !fileName.endsWith("ClientRequest.swift") else {
return
}
SlackController.shared.log(type, msg: msg, functionName: functionName, lineNum: lineNum, fileName: fileName)
}
/// A function that will indicate if a message with a specified type (`LoggerMessageType`)
/// will be outputed in the log (i.e. will not be filtered out).
///
/// -Parameter type: The type of message that one wants to know if it will be output in the log.
///
/// - Returns: A Bool indicating whether, if true, or not a message of the specified type
/// (`LoggerMessageType`) would be output.
public func isLogging(_ type: LoggerMessageType) -> Bool {
return type.rawValue >= self.type.rawValue
}
}
extension LoggerMessageType {
var colorHex: String {
switch self {
case .debug:
return "666666"
case .error:
return "CC0000"
case .info:
return "0000CC"
case .verbose:
return "999999"
case .warning:
return "DD7722"
case .entry:
return "666666"
case .exit:
return "CC0000"
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment