diff --git a/Sources/AKLogger/AKLogger.swift b/Sources/AKLogger/AKLogger.swift deleted file mode 100644 index 97d3326..0000000 --- a/Sources/AKLogger/AKLogger.swift +++ /dev/null @@ -1,59 +0,0 @@ -// The Swift Programming Language -// https://docs.swift.org/swift-book -import Foundation - -protocol AKLoggerProtocol { - func trace(_ message: @autoclosure () -> T, filename: String, line: Int, function: String) - func debug(_ message: @autoclosure () -> T, filename: String, line: Int, function: String) - func info(_ message: @autoclosure () -> T, filename: String, line: Int, function: String) - func warn(_ message: @autoclosure () -> T, filename: String, line: Int, function: String) - func error(_ message: @autoclosure () -> T, filename: String, line: Int, function: String) - func fatal(_ message: @autoclosure () -> T, filename: String, line: Int, function: String) -} - -public struct AKLogger: AKLoggerProtocol { - - enum LogLevel: String { - case trace = "TRACE" - case debug = "DEBUG" - case info = "INFO " - case warn = "WARN " - case error = "ERROR" - case fatal = "FATAL" - } - - private let dateFormatter: DateFormatter = { - let formatter = DateFormatter() - formatter.dateFormat = "HH:mm:ss" - return formatter - }() - - func trace(_ message: @autoclosure () -> T, filename: String = #file, line: Int = #line, function: String = #function) { - log(message(), level: .trace, filename: filename, line: line, function: function) - } - - func debug(_ message: @autoclosure () -> T, filename: String = #file, line: Int = #line, function: String = #function) { - log(message(), level: .debug, filename: filename, line: line, function: function) - } - - func info(_ message: @autoclosure () -> T, filename: String = #file, line: Int = #line, function: String = #function) { - log(message(), level: .info, filename: filename, line: line, function: function) - } - - func warn(_ message: @autoclosure () -> T, filename: String = #file, line: Int = #line, function: String = #function) { - log(message(), level: .warn, filename: filename, line: line, function: function) - } - - func error(_ message: @autoclosure () -> T, filename: String = #file, line: Int = #line, function: String = #function) { - log(message(), level: .error, filename: filename, line: line, function: function) - } - - func fatal(_ message: @autoclosure () -> T, filename: String = #file, line: Int = #line, function: String = #function) { - log(message(), level: .fatal, filename: filename, line: line, function: function) - } - - private func log(_ message: @autoclosure () -> T, level: LogLevel, filename: String, line: Int, function: String) { - let msg = message() - print("\(dateFormatter.string(from: Date())):\(level.rawValue):\(filename):\(line) - \(msg)") - } -} diff --git a/Sources/Logging/Logging.swift b/Sources/Logging/Logging.swift new file mode 100644 index 0000000..dd81da2 --- /dev/null +++ b/Sources/Logging/Logging.swift @@ -0,0 +1,110 @@ +import Foundation + +protocol AKLoggerProtocol { + func trace(_ message: @autoclosure () -> T, filename: String, line: Int, function: String) + func debug(_ message: @autoclosure () -> T, filename: String, line: Int, function: String) + func info(_ message: @autoclosure () -> T, filename: String, line: Int, function: String) + func notice(_ message: @autoclosure () -> T, filename: String, line: Int, function: String) + func warn(_ message: @autoclosure () -> T, filename: String, line: Int, function: String) + func error(_ message: @autoclosure () -> T, filename: String, line: Int, function: String) + func criti(_ message: @autoclosure () -> T, filename: String, line: Int, function: String) +} + +public struct AKLogger: AKLoggerProtocol { + + internal var logHandler: (String) -> Void = { message in + print(message) + } + + private enum LogLevel: Int { + case trace = 100 + case debug = 200 + case info = 300 + case notice = 400 + case warn = 500 + case error = 600 + case criti = 700 + + func stringValue() -> String { + switch self { + case .trace: return "TRACE" + case .debug: return "DEBUG" + case .info: return "INFO" + case .notice: return "NOTICE" + case .warn: return "WARN" + case .error: return "ERROR" + case .criti: return "CRITI" + } + } + } + + private func log(_ message: @autoclosure () -> T, + level: LogLevel, filename: String, line: Int, function: String) { + let cleanedfile = cleanedFilename(filename) + + let msg = message() + var logMessage = "" + + logMessage = "\(dateFormatter.string(from: Date())) [\(level.stringValue())] \(cleanedfile):\(line) - \(msg)" + logHandler(logMessage) + } + + private let dateFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.dateFormat = "HH:mm:ss" + return formatter + }() + + private var cleanedFilenamesCache: NSCache = NSCache() + private func cleanedFilename(_ filename: String) -> String { + if let cleanedfile:String = cleanedFilenamesCache.object(forKey: filename as AnyObject) as? String { + return cleanedfile + } else { + var retval = "" + let items = filename.split{$0 == "/"}.map(String.init) + + if items.count > 0 { + retval = items.last! + } + cleanedFilenamesCache.setObject(retval as AnyObject, forKey: filename as AnyObject) + return retval + } + } +} + +extension AKLogger { + public func trace(_ message: @autoclosure () -> T, + filename: String = #file, line: Int = #line, function: String = #function) { + log(message(), level: .trace, filename: filename, line: line, function: function) + } + + public func debug(_ message: @autoclosure () -> T, + filename: String = #file, line: Int = #line, function: String = #function) { + log(message(), level: .debug, filename: filename, line: line, function: function) + } + + public func info(_ message: @autoclosure () -> T, + filename: String = #file, line: Int = #line, function: String = #function) { + log(message(), level: .info, filename: filename, line: line, function: function) + } + + public func notice(_ message: @autoclosure () -> T, + filename: String = #file, line: Int = #line, function: String = #function) { + log(message(), level: .notice, filename: filename, line: line, function: function) + } + + public func warn(_ message: @autoclosure () -> T, + filename: String = #file, line: Int = #line, function: String = #function) { + log(message(), level: .warn, filename: filename, line: line, function: function) + } + + public func error(_ message: @autoclosure () -> T, + filename: String = #file, line: Int = #line, function: String = #function) { + log(message(), level: .error, filename: filename, line: line, function: function) + } + + public func criti(_ message: @autoclosure () -> T, + filename: String = #file, line: Int = #line, function: String = #function) { + log(message(), level: .criti, filename: filename, line: line, function: function) + } +} diff --git a/Tests/AKLoggerTests/AKLoggerTests.swift b/Tests/AKLoggerTests/AKLoggerTests.swift deleted file mode 100644 index fb457a7..0000000 --- a/Tests/AKLoggerTests/AKLoggerTests.swift +++ /dev/null @@ -1,12 +0,0 @@ -import XCTest -@testable import AKLogger - -final class AKLoggerTests: XCTestCase { - func testExample() throws { - // XCTest Documentation - // https://developer.apple.com/documentation/xctest - - // Defining Test Cases and Test Methods - // https://developer.apple.com/documentation/xctest/defining_test_cases_and_test_methods - } -} diff --git a/Tests/LoggingTests/LoggingTests.swift b/Tests/LoggingTests/LoggingTests.swift new file mode 100644 index 0000000..d32099c --- /dev/null +++ b/Tests/LoggingTests/LoggingTests.swift @@ -0,0 +1,36 @@ +import XCTest +@testable import AKLogger + +final class AKLoggerTests: XCTestCase { + func testLogOutput() { + var loggedMessages: [String] = [] + var logger = AKLogger() + logger.logHandler = { message in + loggedMessages.append(message) + } + + logger.trace("traceメッセージ") + XCTAssertTrue(loggedMessages[0].contains("traceメッセージ")) + + logger.debug("debugメッセージ") + XCTAssertTrue(loggedMessages[1].contains("debugメッセージ")) + + logger.info("infoメッセージ") + XCTAssertTrue(loggedMessages[2].contains("infoメッセージ")) + + logger.notice("noticeメッセージ") + XCTAssertTrue(loggedMessages[3].contains("noticeメッセージ")) + + logger.warn("warnメッセージ") + XCTAssertTrue(loggedMessages[4].contains("warnメッセージ")) + + logger.error("errorメッセージ") + XCTAssertTrue(loggedMessages[5].contains("errorメッセージ")) + + logger.criti("critiメッセージ") + XCTAssertTrue(loggedMessages[6].contains("critiメッセージ")) + + print(loggedMessages) + + } +}