Skip to content

Commit

Permalink
LogScope.Item inherits from Log.Item
Browse files Browse the repository at this point in the history
  • Loading branch information
ikhvorost committed Oct 8, 2024
1 parent 2ac5d81 commit 8dacea9
Show file tree
Hide file tree
Showing 12 changed files with 305 additions and 262 deletions.
6 changes: 3 additions & 3 deletions Sources/DLog/File.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,12 @@ public class File: LogOutput {
write("\(item)")
}

override func begin(interval: LogInterval) {
override func begin(interval: LogInterval.Item) {
super.begin(interval: interval)
}

override func end(interval: LogInterval) {
override func end(interval: LogInterval.Item) {
super.end(interval: interval)
write(interval.text())
write("\(interval)")
}
}
16 changes: 9 additions & 7 deletions Sources/DLog/Filter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import Foundation
public class Filter: LogOutput {

private let itemHandler: ((LogItem) -> Bool)?
private let intervalHandler: ((LogInterval.Item) -> Bool)?
private let scopeHandler: ((LogScope.Item) -> Bool)?

/// Initializes a filter output that evaluates using a specified block object.
Expand All @@ -42,9 +43,10 @@ public class Filter: LogOutput {
/// - Parameters:
/// - block: The block is applied to the object to be evaluated.
///
public init(itemHandler: ((LogItem) -> Bool)?, scopeHandler: ((LogScope.Item) -> Bool)?) {
self.itemHandler = itemHandler
self.scopeHandler = scopeHandler
public init(item: ((LogItem) -> Bool)? = nil, interval: ((LogInterval.Item) -> Bool)? = nil, scope: ((LogScope.Item) -> Bool)? = nil) {
self.itemHandler = item
self.intervalHandler = interval
self.scopeHandler = scope
}

// MARK: - LogOutput
Expand All @@ -70,15 +72,15 @@ public class Filter: LogOutput {
super.enter(item: item)
}

override func begin(interval: LogInterval) {
guard itemHandler == nil || itemHandler?(interval) == true else {
override func begin(interval: LogInterval.Item) {
guard intervalHandler == nil || intervalHandler?(interval) == true else {
return
}
super.begin(interval: interval)
}

override func end(interval: LogInterval) {
guard itemHandler == nil || itemHandler?(interval) == true else {
override func end(interval: LogInterval.Item) {
guard intervalHandler == nil || intervalHandler?(interval) == true else {
return
}
super.end(interval: interval)
Expand Down
116 changes: 107 additions & 9 deletions Sources/DLog/Log.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import Foundation
///
@objcMembers
public class Log: NSObject {
var logger: DLog!
weak var logger: DLog!
let category: String
let config: LogConfig

Expand All @@ -43,9 +43,9 @@ public class Log: NSObject {
self.metadata = LogMetadata(data: metadata)
}

private func scope() -> LogScope.Item? {
private func stack() -> [Bool]? {
if let scope = self as? LogScope {
return scope.item
return scope.stack
}
return nil
}
Expand All @@ -54,7 +54,7 @@ public class Log: NSObject {
guard let output = logger.output else {
return nil
}
let item = LogItem(message: message.text, type: type, category: category, config: config, scope: scope(), metadata: metadata, location: location)
let item = LogItem(message: message.text, type: type, category: category, config: config, stack: stack(), metadata: metadata, location: location)
output.log(item: item)
return item
}
Expand Down Expand Up @@ -277,7 +277,7 @@ public class Log: NSObject {
return scope
}

private func interval(name: String, staticName: StaticString?, intervalConfig: IntervalConfig?, location: LogLocation, closure: (() -> Void)?) -> LogInterval? {
private func interval(message: String, staticName: StaticString?, intervalConfig: IntervalConfig?, location: LogLocation, closure: (() -> Void)?) -> LogInterval? {
guard logger.output != nil else {
return nil
}
Expand All @@ -287,7 +287,7 @@ public class Log: NSObject {
config.intervalConfig = intervalConfig
}

let interval = LogInterval(logger: logger, name: name, staticName: staticName, category: category, config: config, scope: scope(), metadata: metadata.data, location: location)
let interval = LogInterval(logger: logger, message: message, staticName: staticName, category: category, config: config, stack: stack(), metadata: metadata.data, location: location)
if let block = closure {
interval.begin()
block()
Expand Down Expand Up @@ -316,12 +316,110 @@ public class Log: NSObject {
///
@discardableResult
public func interval(_ name: StaticString = "", config: IntervalConfig? = nil, fileID: String = #fileID, file: String = #file, function: String = #function, line: UInt = #line, closure: (() -> Void)? = nil) -> LogInterval? {
interval(name: "\(name)", staticName: name, intervalConfig: config, location: LogLocation(fileID, file, function, line), closure: closure)
interval(message: "\(name)", staticName: name, intervalConfig: config, location: LogLocation(fileID, file, function, line), closure: closure)
}

/// Creates an interval object that logs a detailed message with accumulated statistics.
@discardableResult
public func interval(name: String, fileID: String, file: String, function: String, line: UInt, closure: (() -> Void)?) -> LogInterval? {
interval(name: name, staticName: nil, intervalConfig: nil, location: LogLocation(fileID, file, function, line), closure: closure)
public func interval(message: String, fileID: String, file: String, function: String, line: UInt, closure: (() -> Void)?) -> LogInterval? {
interval(message: message, staticName: nil, intervalConfig: nil, location: LogLocation(fileID, file, function, line), closure: closure)
}
}

extension Log {

public class Item: CustomStringConvertible {
public let time: Date
public let category: String
public let stack: [Bool]?
public let type: LogType
public let location: LogLocation
public let metadata: Metadata
public let message: String
public let config: LogConfig

init(time: Date, category: String, stack: [Bool]?, type: LogType, location: LogLocation, metadata: Metadata, message: String, config: LogConfig) {
self.time = time
self.category = category
self.stack = stack
self.type = type
self.location = location
self.metadata = metadata
self.message = message
self.config = config
}

func padding() -> String {
guard let stack else {
return ""
}
return stack
.map { $0 ? "| " : " " }
.joined()
.appending("")
}

func typeText() -> String {
let tag = LogItem.tags[self.type]!
return switch config.style {
case .plain:
"[\(type.title)]"

case .colored:
"[\(type.title)]".color(tag.colors)

case .emoji:
"\(type.icon) [\(type.title)]"
}
}

func messageText() -> String {
let tag = LogItem.tags[self.type]!
return switch config.style {
case .plain, .emoji:
message

case .colored:
message.color(tag.textColor)
}
}

public var description: String {
var sign = "\(config.sign)"
var time = LogItem.dateFormatter.string(from: self.time)
var level = String(format: "[%02d]", self.stack?.count ?? 0)
var category = "[\(self.category)]"
var location = "<\(self.location.fileName):\(self.location.line)>"
var metadata = self.metadata.json()

switch config.style {
case .plain, .emoji:
break

case .colored:
let tag = LogItem.tags[self.type]!

sign = sign.color(.dim)
time = time.color(.dim)
level = level.color(.dim)
category = category.color(.textBlue)
location = location.color([.dim, tag.textColor])
metadata = metadata.color(.dim)
}

let items: [(LogOptions, String)] = [
(.sign, sign),
(.time, time),
(.level, level),
(.category, category),
(.padding, padding()),
(.type, typeText()),
(.location, location),
(.metadata, metadata),
(.message, messageText()),
]

return LogItem.logPrefix(items: items, options: config.options)
}
}
}
2 changes: 1 addition & 1 deletion Sources/DLog/LogConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public struct LogOptions: OptionSet {
self.rawValue = rawValue
}

static let scope = Self(-1)
static let message = Self(-1)

/// Start sign
public static let sign = Self(0)
Expand Down
69 changes: 29 additions & 40 deletions Sources/DLog/LogItem+Text.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ extension String {
}
}

private extension LogType {
extension LogType {
static let icons: [LogType : String] = [
.log : "💬",
.trace : "#️⃣",
Expand All @@ -88,6 +88,8 @@ private extension LogType {
.assert : "🅰️",
.fault : "🆘",
.interval : "🕒",
.scopeEnter: "⬇️",
.scopeLeave: "⬆️",
]

var icon: String {
Expand All @@ -104,6 +106,8 @@ private extension LogType {
.assert : "ASSERT",
.fault : "FAULT",
.interval : "INTERVAL",
.scopeEnter : "SCOPE",
.scopeLeave : "SCOPE",
]

var title: String {
Expand All @@ -113,12 +117,12 @@ private extension LogType {

extension LogItem {

private struct Tag {
struct Tag {
let textColor: ANSIEscapeCode
let colors: [ANSIEscapeCode]
}

private static let tags: [LogType : Tag] = [
static let tags: [LogType : Tag] = [
.log : Tag(textColor: .textWhite, colors: [.backgroundWhite, .textBlack]),
.info : Tag(textColor: .textGreen, colors: [.backgroundGreen, .textWhite]),
.trace : Tag(textColor: .textCyan, colors: [.backgroundCyan, .textBlack]),
Expand All @@ -128,6 +132,8 @@ extension LogItem {
.fault : Tag(textColor: .textRed, colors: [.backgroundRed, .textWhite, .blink]),
.assert : Tag(textColor: .textRed, colors: [.backgroundRed, .textWhite]),
.interval : Tag(textColor: .textGreen, colors: [.backgroundGreen, .textBlack]),
.scopeEnter : Tag(textColor: .textMagenta, colors: [.backgroundMagenta, .textBlack]),
.scopeLeave : Tag(textColor: .textMagenta, colors: [.backgroundMagenta, .textBlack]),
]

static let dateFormatter: DateFormatter = {
Expand All @@ -136,40 +142,34 @@ extension LogItem {
return dateFormatter
}()

static func logPrefix(items: [(type: LogOptions, text:() -> String)], options: LogOptions) -> String {
static func logPrefix(items: [(type: LogOptions, text: String)], options: LogOptions) -> String {
items.compactMap {
guard options.contains($0.type) || $0.type == .scope else {
guard options.contains($0.type) || $0.type == .message else {
return nil
}
let text = $0.text()
return text.trimTrailingWhitespace()
return $0.text.trimTrailingWhitespace()
}
.joinedCompact()
}

func text() -> String {
var sign = { "\(self.config.sign)" }
var time = { Self.dateFormatter.string(from: self.time) }
var level = { String(format: "[%02d]", self.scope?.level ?? 0) }
var category = { "[\(self.category)]" }
let padding = {
self.scope?.stack
var sign = "\(config.sign)"
var time = Self.dateFormatter.string(from: self.time)
var level = String(format: "[%02d]", self.stack?.count ?? "")
var category = "[\(self.category)]"
let padding = self.stack?
.map { $0 ? "| " : " " }
.joined()
.appending("") ?? ""
}
var type = { "[\(self.type.title)]" }
var location = { "<\(self.location.fileName):\(self.location.line)>" }
var metadata = {
self.metadata
var type = "[\(self.type.title)]"
var location = "<\(self.location.fileName):\(self.location.line)>"
var metadata = self.metadata
.filter { $0.isEmpty == false }
.map {
let pretty = self.type == .trace && self.config.traceConfig.style == .pretty
return $0.json(pretty: pretty)
}
.joined(separator: " ")
}

var message = message

switch config.style {
Expand All @@ -180,31 +180,20 @@ extension LogItem {
assert(Self.tags[self.type] != nil)
let tag = Self.tags[self.type]!

let s = sign
sign = { s().color(.dim) }

let t = time
time = { t().color(.dim) }

let l = level
level = { l().color(.dim) }

category = { self.category.color(.textBlue) }
type = { " \(self.type.title) ".color(tag.colors) }

let loc = location
location = { loc().color([.dim, tag.textColor]) }

let m = metadata
metadata = { m().color(.dim) }

sign = sign.color(.dim)
time = time.color(.dim)
level = level.color(.dim)
category = category.color(.textBlue)
type = " \(self.type.title) ".color(tag.colors)
location = location.color([.dim, tag.textColor])
metadata = metadata.color(.dim)
message = message.color(tag.textColor)

case .emoji:
type = { "\(self.type.icon) [\(self.type.title)]" }
type = "\(self.type.icon) [\(self.type.title)]"
}

let items: [(LogOptions, () -> String)] = [
let items: [(LogOptions, String)] = [
(.sign, sign),
(.time, time),
(.level, level),
Expand Down
Loading

0 comments on commit 8dacea9

Please sign in to comment.