A powerful input-agnostic swift logging framework made to speed up development with maximum readability.

Related tags

Logging Atlantis
Overview

alt tag

The Swift logging framework.

Atlantis is an extremely powerful logging framework that I've created for everyday use, including enterprise development for aspiring start-ups or for rapid prototyping API's. It is type agnostic, meaning you can pass in anything from strings to customobjects that you yourself made... and it will basically pretty print all the values within that object or literally anything in general. It is made with exceptional readability and ease of use.

Installation

Add this to your podfile...

# for Swift 4.0
pod 'Atlantis', :git => 'https://github.com/aaronjsutton/Atlantis.git', :branch => 'swift-4-patch'
# for Swift 3.0
pod 'Atlantis'
# for Swift 2.3
pod 'Atlantis', :git => 'https://github.com/DrewKiino/Atlantis.git', :branch => 'swift2.3'

Then do a pod install, and voila!

Unique Logs

This includes the stamp trace of the log's date, source, function, line number, as well as the actual type of the value.

Note: The date's format goes by month, date, year, hour, then time of day.

// You do not need to initialize this, the variable is initialized in file.
let log = Atlantis.Logger()

// Let's log some stuff
log.verbose("Hello, World!")
log.info("Hello, World!")
log.warning("Hello, World!")
log.debug("Hello, World!")
log.error("Hello, World!")

Which prints the following...

alt tag

Powerful Printing

Atlantis is built to pretty print literally everything.

- proper text alignment

alt tag

Atlantis automatically aligns its logs based on it's previous alignments. However you can change this configuration by setting this variable,

Atlantis.Configuration.alignmentThreshold

which defaults to 5.

- optionals

Atlantis will safely unwrap any optionals.

let doIExist: String? = nil

log.warning(doIExist)

// prints 'nil'

- empty strings

Atlantis will visually print empty strings.

let emptyString: String = ""

log.warning(emptyString)

// prints ""

- native types

let string = "Hello, World"
let int = 123
let double = 12.3
let float = 12.3
let bool = true

// you can either log one value
log.debug(string)

// or all of them like so,
log.debug(string, int, double, float, bool)

// prints
"Hello, World" // first one

"Hello, World" // prints each with a new line
123
12.3
12.3
true

- arrays

// array of ints
let numbers = [123, 1234, 12345]

log.debug(numbers)

// prints
[
	123,
	1234,
	12345
]
// lets try arrays of arrays
let numberArray = [[1, 2, 3], [4, 5]]

log.debug(numberArray)

// prints
[
	[
		1,
		2,
		3
	],
	[
		4,
		5
	]
]

- dictionaries

// on to dictionaries...
let dictionary: [String: AnyObject] = [
	"quote": "It is better to have loved, than to have never loved at all?"
]

log.debug(dictionary)

// prints
[
	"quote": "It is better to have loved, than to have never loved at all?"
]
// how about NSDictionary types?
var dictionary = NSDictionary()
dictionary.updateValue("will this work?", key: "question")

log.debug(dictionary)

// prints
[
	"question": "will  this work?"
]
// say we got two response objects from the server,
// now both objects are the same but one of them has missing data...

responses.map { log.debug($0) }

// prints
{
	"response": "Here is some data!",
	"success" 200
},
{
	"response": null,
	"success" 200
}

// Atlantis will print all of the object's keys regardless of missing
// or empty values and will print null if need be.

- objects

// now let's get to the fun part,
// native Foundation (ex: UIView, UIColor, etc.)

log.debug(UIColor())

// prints
<UIPlaceholderColor: 0x7ff1fb517ab0>
// native NSObjects

public class Dog: NSObject {
  var name = "Doug"
}

let dog = Dog()

log.debug(dog)

// prints
{
	"name": "Doug"
}
// But what about objects you created with no native subclasses?

public class CustomObject {
	var id: Int = 123
	var name: String = "Ben"
}

let customObject = CustomObject()

log.debug(customObject)

// prints
{
	"id": 123,
	"name": "Doug"
}

// Haha, no way?
// Alright, well how about custom objects with custom objects in them?

public class ParentObject {
	var id: Int = 456
	var name: String = "Tammy"
	var customObject: CustomObject = CustomObject()
}

let parentObject = ParentObject()

log.debug(parentObject)

// prints
{
	"id": 456,
	"name": "Tammy"
	"customObject": {
		"id": 123,
		"name": "Doug"
	}
}

// That's right.
// Okay, custom objects with an array of custom objects. ;)

public class ParentObject {
	var id: Int = 456
	var name: String = "Tammy"
	var customObjects: [CustomObject] = [CustomObject(), CustomObject()]
}

let parentObject = ParentObject()

log.debug(parentObject)

// prints
{
	"id": 456,
	"name": "Tammy"
	"customObjects": [
		{
			"id": 123,
			"name": "Doug"
		},
		{
			"id": 123,
			"name": "Doug"
		}
	]
}
// Not impressed?

let parentObject1 = ParentObject()
let parentObject2 = ParentObject() // one of its child has a dictionary

let parents: [ParentObject] = [parentObject1, parentObject2]

log.debug(parents)

// prints
[
	{
		"id": 456,
		"name": "Tammy"
		"customObjects": [
			{
				"id": 123,
				"name": "Doug"
			},
			{
				"id": 123,
				"name": "Doug"
			}
		]
	},
	{
		"id": 456,
		"name": "Tammy"
		"customObjects": [
			{
				"id": 123,
				"name": "Doug"
			},
			{
				"id": 123,
				"name": "Doug"
				"dictionary": [
					"likes": "baseball",
					"dislikes": "pad thai"
				]
			}
		]
	}
]

// Atlantis' logging is infinitely and ambiguously recursive,
// it supports almost all data types including arrays, dictionaries,
// and any objects within any objects. 👍🏼

- Structs

// Great!! Now on to some more stand-alone but much needed types.

struct Struct {
  var name: String = "Bob the Builder"
  var skills: [String] = ["structures, buildings"]
}

log.debug(Struct())

// prints
{
  "skills" : [
    "structures, buildings"
  ],
  "name" : "Bob the Builder"
}

- Enum

enum ErrorType {
	case Severe
	case Moderate
	case Casual
}

let type: ErrorType = .Severe

log.debug(type)

// prints
Severe
// one more example.

log.debug(ErrorType.Moderate)
log.debug(ErrorType.Casual)

// prints
Moderate
Casual

Error Handling

Atlantis will print all errors like so,

Error: [ViewController.swift/viewDidLoad()/line:98]
{
  "code" : 404,
  "localizedDescription" : "The operation couldn’t be completed. (Hello, World! error 404.)",
  "domain" : "Hello, World!",
  "userInfo" : {
  	"error": "found"
  	"note": "syntax"
  }
}

It will automatically parse the localized description, error code, domain, and user info from the NSError object.

Atlantis.Configuration.highlightsErrors // default false

By default, Atlantis will print all logs equally in white or in color if colored logging is enabled. However, if you enable error highlighting it will always highlight errors regardless of any set parameters.

Atlantis.Configuration.filteredErrorCodes

Atlantis has the ability to filter out errors based on their error code. For example, you have a method that sends requests to the network and you made it so it can only make one request at a time so it will always cancel the last request made. However, some APIs are out of our control and will send out errors without your permission.

Say you want to filter out error code -1099 // offline error,

Atlantis.Configuration.filteredErrorCodes.append(-1099)

// let's call a method that throws errors, however one of the
// errors is something we want to filter out.
method() { error in
	log.error(error) // can either be error 404 or -1099?
}

// will only print the error if the error code is 404

Now, if the method throws a -1099 error, Atlantis will will skip over it!

.Tap

Tap is an Atlantis extension that allows you to print like how you would regularly do, but will return the value of the input.

func add(x: Int, _ y: Int) -> Int { return x + y }

let addXY = log.tap.debug(add(3, 5))

// prints 8 and assigns the value to addXY

Normal extensions such as .Verbose etc. are also under .Tap

Compatible with Promises

using PromiseKit more specifically...

func promise() -> Promise<String> {
  return Promise { fulfill, reject in
    // blah blah
    fulfill("Hello from server!")
  }
}

promise()
.then { log.tap($0) }
.then { reply in
  // blah blah
}
.catch { log.error($0) }

// prints "Hello from server!" while completing the promise.

Note that .Tap can only take in single inputs.

Configuration

Levels

Atlantis.Configuration.logLevel // default .Verbose

The five log levels are: Verbose, Info, Warning, Debug, Error, and None, ordered by priority.

For example, if you set the log level to Debug, Atlantis will only print logs whose levels are Debug and Error.

Setting the log level to .None means Atlantis will skip all log execution. I recommend using this when the app is shift off to production.

Source Information

Atlantis.Configuration.showExtraInfo // default true

You can also hide the source details by setting this parameter to false.

Coloring

Atlantis is able to provide full color customization,

// colors
Atlantis.Configuration.hasColoredLogs // default false
Atlantis.Configuration.hasWhiteBackground // default false
Atlantis.Configuration.coloredLogLevels // default [.Verbose, .Info, .Warning, .Debug, .Error]

// using a Tuple initializer

Atlantis.Configuration.logColors.info = Atlantis.XCodeColor(fg: (Int, Int, Int)>, bg: <(Int, Int, Int)>)

// using UIColor setting only the foreground

Atlantis.Configuration.logColors.info = Atlantis.XCodeColor(fg: UIColor)

// or using UIColor setting both the foreground and background

Atlantis.Configuration.logColors.debug = Atlantis.XCodeColor(fg: UIColor, bg: UIColor)

By default, Atlantis doesn't print its logs in colors. if you want colors, you will need to set the configuration during launch.

However, for you to enable log colors you will have to first download the xcode package manager Alcatraz and enable it inside xcode. Pull up the package manager afterwards and install XCodeColors.

Afterword

To Do

  1. create a logging framework
  2. add color customization
  3. print to a text file when used on a device
  4. pretty print json types from server responses

License

The MIT License (MIT)

Copyright (c) 2015 Andrew Aquino http://drewkiino.github.io/

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

You might also like...
Swift Logging Utility for Xcode & Google Docs
Swift Logging Utility for Xcode & Google Docs

QorumLogs Swift Logging Utility in Xcode & Google Docs

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

A flexible logging library written in Swift

Puppy Puppy is a flexible logging library written in Swift 🐶 It supports multiple transports(console, file, syslog, and oslog) as loggers. It not onl

Logging utility for Swift and Objective C
Logging utility for Swift and Objective C

Swell - Swift Logging A logging utility for Swift and Objective C. ##Features Turn on logging during development, turn them off when building for the

Most natural Swift logging

Evergreen Most natural Swift logging Evergreen is a logging framework written in Swift. It is designed to work just as you would expect, yet so versat

Spy is a flexible, lightweight, multiplatform logging utility written in pure Swift.
Spy is a flexible, lightweight, multiplatform logging utility written in pure Swift.

Spy is a flexible, lightweight, multiplatform logging utility written in pure Swift. It allows to log with different levels and on different channels. You can define what levels and channels actually are.

A simple logging package for Swift

OhMyLog OhMyLog is a simple logging package for Swift. It supports the following features: Six logging levels ( 👣 , 🔍 , 💡 , ⚠️ , 🚨 , 💊 ) Display

Simple logging for simples needs.

Simple logging for simples needs.

Class for logging excessive blocking on the main thread
Class for logging excessive blocking on the main thread

Watchdog Class for logging excessive blocking on the main thread. It watches the main thread and checks if it doesn’t get blocked for more than define

Comments
  • Print type name when logging custom types

    Print type name when logging custom types

    In the readme, the following example is provided:

    public class CustomObject {
        var id: Int = 123
        var name: String = "Ben"
    }
    
    let customObject = CustomObject()
    
    log.debug(customObject)
    
    // prints
    {
        "id": 123,
        "name": "Doug"
    } 
    

    It would be nice if it instead printed something more like:

    <CustomObject: {
        "id": 123,
        "name": "Doug"
    }>
    

    The actual exact format doesn't exactly matter. But this is closer what I'd expect to see from NSLog in Objective-C for example. Sometimes it's not just the properties that I'm interested in, but also the type itself.

    opened by nhgrif 2
  • Support log output to multiple sources

    Support log output to multiple sources

    From your README's TODO list:

    print to a text file when used on a device

    But competing logging libraries allow me to add different loggers. As an example:

        /**
         Adds CocoaLumberjack loggers to the project.
         */
        static func setUpLogging() {
            #if DEBUG
                setenv("XcodeColors", "YES", 0)
                DDLog.addLogger(xcodeConsoleLogger)
            #endif
            DDLog.addLogger(fileLogger)
            DDLog.addLogger(appleSystemLogger)
        }
    

    I think in an ideal world, I'd be able to not only do this, but also specify the minimum logging level for each logger I attach. So for example, the Xcode console gets all log levels, but the file logger only gets debug and up, and the Apple system logger only gets warning and error.

    opened by nhgrif 1
Releases(1.1.2)
Owner
Andrew Aquino
Andrew Aquino
A logging backend for swift-log that sends logging messages to Logstash (eg. the ELK stack)

LoggingELK LoggingELK is a logging backend library for Apple's swift-log The LoggingELK library provides a logging backend for Apple's apple/swift-log

null 17 Nov 15, 2022
JustLog brings logging on iOS to the next level. It supports console, file and remote Logstash logging via TCP socket with no effort. Support for logz.io available.

JustLog JustLog takes logging on iOS to the next level. It supports console, file and remote Logstash logging via TCP socket with no effort. Support f

Just Eat 509 Dec 10, 2022
A fast & simple, yet powerful & flexible logging framework for Mac and iOS

CocoaLumberjack CocoaLumberjack is a fast & simple, yet powerful & flexible logging framework for macOS, iOS, tvOS and watchOS. How to get started Fir

null 12.9k Jan 9, 2023
Willow is a powerful, yet lightweight logging library written in Swift.

Willow Willow is a powerful, yet lightweight logging library written in Swift. Features Requirements Migration Guides Communication Installation Cocoa

Nike Inc. 1.3k Nov 16, 2022
Convenient & secure logging during development & release in Swift 3, 4 & 5

Colorful, flexible, lightweight logging for Swift 3, Swift 4 & Swift 5. Great for development & release with support for Console, File & cloud platfor

SwiftyBeaver 5.6k Jan 4, 2023
A lightweight logging framework for Swift

HeliumLogger Provides a lightweight logging implementation for Swift which logs to standard output. Features Logs output to stdout by default. You can

Kitura 174 Nov 30, 2022
A lightweight logging framework for Swift

HeliumLogger Provides a lightweight logging implementation for Swift which logs to standard output. Features Logs output to stdout by default. You can

Kitura 174 Nov 30, 2022
An extensible logging framework for Swift

Log is a powerful logging framework that provides built-in themes and formatters, and a nice API to define your owns. Get the most out of Log by insta

Damien 825 Nov 6, 2022
Simple, lightweight and flexible debug logging framework written in Swift

AELog Simple, lightweight and flexible debug logging minion written in Swift If you find yourself in upcoming statements, then you probably want to us

Marko Tadić 28 Jul 6, 2022
CleanroomLogger provides an extensible Swift-based logging API that is simple, lightweight and performant

CleanroomLogger CleanroomLogger provides an extensible Swift-based logging API that is simple, lightweight and performant. The API provided by Cleanro

null 1.3k Dec 8, 2022