LogDog is designed to work out of the box, you can use the pre-configured logger anytime, anywhere

Related tags

Logging LogDog
Overview

LogDog



user-friendly logging

apple/swift-log api compatible

Usage

LogDog is designed to work out of the box, you can use the pre-configured logger anytime, anywhere:

sugar.debug("hi")

sugar.error("somethings went wrong")

Or, make a local copy and do some changes:

var logger = suggar
logger["path"] = "/me"

logger.debug("hi")

You can quickly create a logger with just a label, it will use the predefined log handler:

var logger = Logger.sugar("worker:a")
logger.level = .info

logger.info("hi")

SugarLogHandler

The core component that makes this all work is SugarLogHandler.

The following code snippet shows how to create a SugarLogHandler and use it to bootstrap the logging system.

LoggingSystem.bootstrap { label in

    // ! to create your own `SugarLogHandler`, you need a `sink`, an `appender` and an optional `errorHandler`. 
    let sink = LogSinks.Builtin.short
    let appender = TextLogAppender.stdout
    let errorHandler = { error: Error in
        print("LogError: \(error)")
    }

    var handler = SugarLogHandler(label: label, sink: sink, appender: appender, errorHandler: errorHandler)

    // ! use dynamicMetadata to register values that are evaluted on logging.
    handler.dynamicMetadata["currentUserId"] = {
        AuthService.shared.userId
    }   
    
    return handler
}

let logger = Logger(label: "app")
logger.error("Something went wrong")

Sink

Sinks process log records.

A sink can be a formatter, or a filter, a hook, or a chain of other sinks.

Formatter

You can create a formatter sink with just a closure.

let sink = LogSinks.firstly
    .format {
        "\($0.entry.level.uppercased) \($0.entry.message)\n"
    }
    
// Output:
//
//     DEBUG hello

Or use the built-in neat formatters directly.

let short = LogSinks.BuiltIn.short

// Output:
//
//     E: bad response
//     C: can not connect to db


let medium = LogSinks.BuiltIn.medium  // default sink for sugar loggers

// Output:
//
//     20:40:56.850 E/App main.swift.39: bad response url=/me, status_code=404
//     20:40:56.850 C/App main.swift.41: can not connect to db


let long = LogSinks.BuiltIn.long

// Output:
//
//     ╔════════════════════════════════════════════════════════════════════════════════
//     ║ 2020-11-15 20:46:31.157  App  ERROR     (main.swift:39  run(_:))
//     ╟────────────────────────────────────────────────────────────────────────────────
//     ║ bad response
//     ╟────────────────────────────────────────────────────────────────────────────────
//     ║ url=/me
//     ║ status_code=404
//     ╚════════════════════════════════════════════════════════════════════════════════

Filter

You can create a filter sink with just a closure.

let sink = LogSinks.firstly
    .filter {
        $0.entry.source != "LogDog"
    }
    
// logs from `LogDog` will not be output.

DSL

Or use the built-in expressive dsl to create one.

let sink = LogSinks.BuiltIn.short
    .when(.path)
    .contains("private")
    .deny
    
let sink = LogSinks.BuiltIn.short
    .when(.level)
    .greaterThanOrEqualTo(.error)
    .allow

Concat

Sinks are chainable, a sink can concatenate another sink.

let sink = sinkA + sinkB + sinkC // + sinkD + ...

// or
let sink = sinkA
    .concat(sinkB)
    .concat(sinkC)
    // .concat(sinkD) ...

LogDog ships with many commonly used operators.

Prefix & Suffix

let sink = LogSinks.BuiltIn.short
    .prefix("🎈 ")
    
// Output:
//
//     🎈 E: bad response


let sink = LogSinks.BuiltIn.short
    .suffix(" 🎈")
    
// Output:
//
//     E: bad response 🎈

Encode

let sink = LogSinks.firstly
    .encode(JSONEncoder())

Crypto

let sink = LogSinks.firstly
    .encode(JSONEncoder())
    .encrypt(using: key, cipher: .ChaChaPoly)

Compress

let sink = LogSinks.firstly
    .encode(JSONEncoder())
    .compress(.COMPRESSION_LZFSE)

Schedule

Sinks's processing can be time-consuming, if you don't want it to slow down your work, you can using Scheduler to make logging asynchronous.

let sink = LogSinks.firstly
    .sink(on: dispatchQueue) // or an operationQueue, or some other custom schedulers, for example, an eventLoop.
    .encode(JSONEncoder()) // time-consuming processing begins.
    .encrypt(using: key, cipher: .ChaChaPoly)
    .compress(.COMPRESSION_LZFSE)

Hook

Because of Scheduler, the logging may be asynchronous.

It means that the sinking may be in a different context,

You can use hook with entry.parameters to capture and pass the context.

private struct CustomSinkContext: LogParameterKey {
    typealias Value = CustomSinkContext

    let date = Date()
    let thread = LogHelper.thread
}

let customSink: AnyLogSink<Void, String> = AnyLogSink {

    // ! beforeSink: in the same context as the log generation.
    
    $0.parameters[CustomSinkContext.self] = .init()
} sink: { record, next in

    // ! sink: may not be in the same context as the log generation.

    record.sink(next: next) { (record) -> String? in
        guard let context = record.entry.parameters[CustomSinkContext.self] else {
            return nil
        }

        let time = LogHelper.format(context.date, using: "HH:mm:ss.SSS")
        let thread = context.thread
        
        // ...
    }
}

Please note, when using encode, parameters with string as key will also be encoded.

LogSinks.firstly
  .hook { 
     $0.parameters["currentUserId"] = AuthService.shared.userId
  }
  .hook(.appName, .appVersion, .date) /* , ..., a lot of built-in hooks */
  .encode(JSONEncoder())
  
/*
{
  "label": "app",
  "level": "debug",
  "metadata": {
    // ...
  }
  // ...
  "currentUserId": "1",
  "appName": "LogDog",
  "appVersion": "0.0.1",
  "date": "2020-11-19T01:12:37.001Z"
}
 */

Appender

Appenders are destinations of log records.

Built-in Appenders

OSLogAppender

Append strings to the underlying OSLog.

let appender = OSLogAppender(osLog)

TextLogAppender

Append strings to the underlying TextOutputStream.

let appender = TextLogAppender(stream)

let stdout = TextLogAppender.stdout
let stderr = TextLogAppender.stderr

MultiplexLogAppender

Append outputs to the underlying appenders.

// when `concurrent` is `true`, a dispatch group is used to make the appending of all appenders parallel. 
let appender = MultiplexLogAppender(concurrent: true, a, b, c, d/*, ...*/)

FileLogAppender

WIP

  • async
  • auto rotate
  • ...

Community

In addition to the sinks/appenders mentioned above, you can also find more integrations at LogDogCommunity!

LogDogChalk

Color the output of LogDog.

LogDogCryptoSwift

Encrypt the output of LogDog.

LogDogCocoaLumberjack

Append the output of LogDog to CocoaLumberjack.

Don't have the sink/appender you want? Contributions are welcome!

Installation

Swift Package Manager

.package(url: "https://github.com/luoxiu/LogDog.git", from: "0.2.0"),

CocoaPods

pod 'LogDog', '~> 0.2.0'
You might also like...
A simple logger for your swift applications.

AHQSLogger A simple logging system. Usage import AHQSLogger Use the following methods for loggging. Logging an information / debug You can log a simp

Tracker - A simple location logger app written in Swift and MVVM architecture
Tracker - A simple location logger app written in Swift and MVVM architecture

Tracker - A simple location logger app written in Swift and MVVM architecture

An Alamofire network activity logger view
An Alamofire network activity logger view

📒 AlamofireLogbook An Alamofire network activity logger view Installation AlamofireLogbook is available through CocoaPods. To install it, simply add

Tap to swap out words with emojis. Inspired by Messages.app on iOS 10.
Tap to swap out words with emojis. Inspired by Messages.app on iOS 10.

EmojiTextView Tap to swap out words with emojis. Works with any UITextView. Heavily inspired by Messages.app on iOS 10. Created by Arkadiusz Holko (@a

A debug log framework for use in Swift projects. Allows you to log details to the console (and optionally a file), just like you would have with NSLog() or print(), but with additional information, such as the date, function name, filename and line number. 📱💬🚦 TinyConsole is a micro-console that can help you log and display information inside an iOS application, where having a connection to a development computer is not possible.
📱💬🚦 TinyConsole is a micro-console that can help you log and display information inside an iOS application, where having a connection to a development computer is not possible.

TinyConsole TinyConsole is a tiny log console to display information while using your iOS app and written in Swift. Usage Wrap your Main ViewControlle

This is how you can manage and share logs in iOS application.

Logging in Swift In this example, you can find how to print all the logs effciently in iOS application. Along with, you will find how to share logs fo

Simple Design for Swift bridge with Javascript. Also can get javascript console.log.
Simple Design for Swift bridge with Javascript. Also can get javascript console.log.

SDBridgeOC is here. If your h5 partner confused about how to deal with iOS and Android. This Demo maybe help. YouTube video is here. bilibili Video is

TraceLog is a highly configurable, flexible, portable, and simple to use debug logging system for Swift and Objective-C applications running on Linux, macOS, iOS, watchOS, and tvOS.

Please star this github repository to stay up to date. TraceLog Introduction TraceLog is a highly configurable, flexible, portable, and simple to use

Releases(0.3.0)
Owner
Luo Xiu
iOS Developer, occasionally write web, server and cli apps.
Luo Xiu
Easy to use and lightweight logger for iOS, macOS, tvOS, watchOS and Linux in Swift.

Lighty Easy to use and lightweight logger for iOS, macOS, tvOS, watchOS and Linux in Swift. Screenshots Requirements Lighty Version Minimum iOS Target

Abdullah Selek 51 Dec 21, 2022
Automate box any value! Print log without any format control symbol! Change debug habit thoroughly!

LxDBAnything Automate box any value! Print log without any format control symbol! Change debug habit thoroughly! Installation You only need drag LxD

DeveloperLx 433 Sep 7, 2022
A fancy logger yet lightweight, and configurable. 🖨

?? ?? Important: Printer can only print console logs if you're running an app in the Simulator. If you're running in a real device it will not print a

Hemang 66 Dec 7, 2022
Bugfender SDK for iOS, a remote logger tailor-made for mobile

Bugfender SDK for iOS Bugfender is a cloud service to collect mobile application logs. Developers can control log sending programmatically and manuall

Bugfender 69 Dec 4, 2022
Logger for Xcode

CSwiftLog Usage Log.log("Message text without category") Log.my.log("Message text with custom category") Log.network.log("Message text with network ca

Andrew Firsenko 2 Nov 29, 2021
A custom logger implementation and Task Local helper for swift-log

LGNLog A custom logger implementation and TaskLocal helper for Swift-Log. Why and how This package provides two and a half things (and a small bonus):

17:11 Games 0 Oct 26, 2021
A lightweight Swift logger, uses `print` in development and `NSLog` in production. Support colourful and formatted output.

Loggerithm A lightweight Swift logger, uses print in Debug and NSLog in Production with colourful output. Why In Swift, we usually use print to log in

HongHao Zhang 270 Oct 8, 2022
Simple network activity logger for iOS

Reqres is a simple library for logging all requests and responses in your app. It supports Alamofire and also requests made via native NSURLSession. ⬆

Ackee 85 Aug 21, 2022
A network logger for iOS and macOS projects.

OkLog for iOS and macOS OkLog-Swift is a network logger written in Swift highly inspired by simonpercic's original OkLog implementation to be used in

Diego Trevisan Lara 18 Dec 24, 2021
Stock tradings Logger app for iOS

Stock Logger Contributor: Name: Prof. Darren Takaki Author: Name: Ibrahim (Wusiman Yibulayin) Student ID: 0728356 Table of contents Description Gettin

null 2 Jul 28, 2022