πŸ‘¨β€πŸ’» Bulk is pipeline based powerful & flexible logging framework
Clone or download
Latest commit da71824 Jan 12, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
Bulk-Carthage.xcodeproj Rename LogData Jan 12, 2019
Sources Rename LogData Jan 12, 2019
Tests/BulkTests Rename LogData Jan 12, 2019
.gitignore Carthage compatible May 3, 2017
.swift-version Swift4 Sep 17, 2017
.travis.yml Update travis Oct 17, 2017
Bulk.podspec Update Podspec Jan 12, 2019
LICENSE Update LICENSE May 14, 2017
Makefile Update Makefile May 6, 2017
Package.swift [skip ci] Ignore demo from Package.swift May 4, 2017
README.md Update README.md Jul 23, 2018
arch.png Update Readme May 7, 2017
header@2x.jpg Update header image May 7, 2017

README.md

Bulk

Travis Version Carthage compatible platforms

forthebadge forthebadge

Bulk is a pipeline based powerful & flexible logging framework.
It has basic functions as a Logger.
In addition, it can output logs in bulk.
This is useful when sending logs to a server.

Usage

✨Very Simple Usage

import Bulk

// Create Logger instance.
// Define on global scope.

let Log = Logger()

// Add pipeline to Logger

Log.add(pipeline:
  Pipeline(
    plugins: [],  
    targetConfiguration: .init(
      formatter: BasicFormatter(), 
      target: ConsoleTarget()
    )
  )
)

// Simple logging

Log.verbose("Something log")
Log.debug("Something log")
Log.info("Something log")
Log.warn("Something log")
Log.error("Something log")

// And more
// We can use this like Swift.print()
Log.verbose("a", "b", 1, 2, 3, ["a", "b"]) // => a b 1 2 3 ["a", "b"]

Advanced Settings

let Log = Logger()

// Setup output targets

// Logging synchronously
Log.add(pipeline:
  Pipeline(
    plugins: [
      /* Some plugins */
      /* MyPlugin() */
    ],  
    targetConfiguration: .init(formatter: BasicFormatter(), target: ConsoleTarget())
  )
)

// Logging asynchronously

Log.add(pipeline:
  AsyncPipeline( // <-- 😎< asynchronously
    plugins: [
      /* Some plugins */
      /* MyPlugin() */
    ],  
    targetConfiguration: .init(formatter: BasicFormatter(), target: ConsoleTarget()),
    queue: .global() // <-- πŸ€“< Specify DispatchQueue
  )
)

Pipeline

Pipeline perform sending Log from Logger to Target.

Sequence πŸ“„ => Logger => [Plugin] => BulkBuffer? => WriteBuffer? => Formatter => Target => πŸ“„

Pipeline

Pipeline is basic class.

Sequence perform on the queue that called Logger's method.

AsyncPipeline

AsyncPipeline perform sequence on specified queue.

πŸ“„ => Logger => Dispatch to specified queue => [Plugin] => BulkBuffer? => WriteBuffer? => Formatter => Target => πŸ“„

Buffer

  • NoBuffer
  • MemoryBuffer
  • FileBuffer

Bulk Buffer

For send formatted strings to Target.

Write Buffer

For waiting for processing Target.

If Target is sending logs to the server, You may not be able to send all of them. Write Buffer will be useful in the case.

In the case of FileBuffer, if the process ends due to an exception, it will be sent to the Target at the next timing.

Set Buffer

let Log = Logger()

Log.add(pipeline:
  Pipeline(
    plugins: [],  
    bulkConfiguration: .init(
      buffer: MemoryBuffer(size: 10),
      timeout: .seconds(10)
    ), // Send to Target every 10 Logs.
    targetConfiguration: .init(
      formatter: BasicFormatter(),
      target: ConsoleTarget(),
      buffer: FileBuffer(size: 40, filePath: "/path/to/bulk-buffer.log")
    ) // Wait for writing up to 40 Logs.  
  )
)

if we don't need Buffer?

It's ok. Use NoBuffer

Customization

Plugins

class MyPlugin: Plugin {
  func map(log: Log) -> Log {
    var log = log
    log.body = "Tweaked:: " + log.body
    return log
  }
}

Example: Create Log.Level based filter.

public struct LevelFilterPlugin: Plugin {
  
  public let ignoreLevels: [Log.Level]
  
  public init(ignoreLevels: [Log.Level]) {
    self.ignoreLevels = ignoreLevels
  }
  
  public func apply(log: Log) -> Log {
    if ignoreLevels.contains(log.level) {
      var log = log
      log.isActive = false
      return log
    }
    return log
  }
}

Custom Formatter

Step of Log -> any type

Create customized formatter using Formatter protocol

public protocol Formatter {
  
  associatedtype FormatType
  
  func format(log: Log) -> FormatType
}

Custom Target

Create customized target using Target protocol.

public protocol Target {
  
  associatedtype FormatType
  
  func write(formatted items: [FormatType], completion: @escaping () -> Void)
}

Example

open class ConsoleTarget: Target {
    
  public init() {
    
  }
  
  open func write(formatted strings: [String], completion: @escaping () -> Void) {
    strings.forEach {
      print($0)
    }
    
    completion() // Important
  }
}

Custom Buffer

We can create customized Buffer.

Example,

Use Realm or CoreData instead of FileBuffer It will be faster than FileBuffer (maybe)

// TODO:

Built-in Libraries

  • Formatters

    • BasicFormatter
    • RawFormatter
  • Targets

    • ConsoleTarget
    • FileTarget
    • NSLogTarget
  • Buffers

    • NoBuffer
    • MemoryBuffer
    • FileBuffer (Using SeparatorBasedLogSerializer)

Installation

CocoaPods

pod "Bulk"

Carthage

github "muukii/Bulk"

SwiftPackageManager

import PackageDescription

let package = Package(
  name: "MyApp",
  dependencies: [
    .Package(url: "https://github.com/muukii/Bulk.git", majorVersion: 0),
  ]
)

Development

Ubuntu

Use docker

$ cd /path/to/Bulk
$ docker run --rm -it --name swift -v $PWD:/local/dev --workdir "/local/dev" swift:3.1 /bin/bash
$ swift build

LICENSE

Bulk Framework is released under the MIT License.