Giter VIP home page Giter VIP logo

log4swift's Introduction

Log4Swift

License Platform Language Cocoapod Carthage compatible Travis-ci Build Status

Log4Swift is a logging library for swift projects, that will allow you to log in a very flexible way.

Its ultimate goal is to be the tool you need to make your logs as valuable as possible, both in your developpment environment and in production.

Compatibility

Current version requires Xcode 9 and swift 4.1.

It can be used in projects targetting either OS X (>= 10.10), iOS (>= iOS 8) or appleTV, and written either in swift or objective-C (or a mix of those two).

How to use

Manually

Clone the repo on your machine, and compile the target that feets your need (OS X, iOS, ...). It will produce a library that you can use in your project. As long as the swift ABI is not stable, you will need to recompile the library if you change the version of the compiler used for your project. Because of that, you should rather consider one of the other methods (see bellow).

CocoaPod

Add those lines to your Podfile to embed this library in an iOS project (with the versions you want for the lib and the target):

platform :ios, '8'
pod 'Log4swift', '1.2.0'
use_frameworks!

And in an OS X project :

platform :osx, '10.10'
pod 'Log4swift', '1.2.0'
use_frameworks!

Carthage

Add this line to your Cartfile (with the version you want):

github "jduquennoy/Log4swift" ~> 1.2.0

Features

Here are the main features you can expect from Log4swift :

  • straightforward to use for simple cases : default configuration should just work, one-line configuration for typical uses like logging to IDE console or to system logs
  • flexible for more complexe cases, with multi-destination logging, hierarchic loggers configuration, ...
  • multiple destinations available, including network logging, using NSLogger
    • file logging
    • network logging using NSLogger
    • Xcode console logging, including colorized logs (with the XcodeColors plugin installed)
  • dynamically configurable by code
  • configurable by file, with auto-reload on update possibility (opt-in feature)
  • asynchronous logging, performed on a secondary thread (opt-in feature). Async behavior can be activated per logger.

Another goal, that I think we all share, is to have readable and tested code.

  • The code coverage of Log4swift's code (excluding third party code) is 100% for most of the source files, and very close to it for others.
  • Feel free to send feedbacks or contribute if you find the code not readable enough, or if you have ideas to highen the quality of that code !

Concepts

The three main concepts of this library are borrowed from log4j :

Loggers

Loggers are the objects to which logs are send at the first place. They are identified by a UTI identifier (like "project.module.function") that are hierachical. When a log message is sent, the logger with the longest matching UTI will be responsible for dealing the log. A root logger will deal with logs that matches no specific logger.

A logger defines a threshold level. Logs bellow this level will be ignored. Non ignored levels are sent to the appenders associated to the logger.

Appenders

Appenders are attached to loggers. They are responsible for writing the logs to their destination. They are identified by an identifier, that is used when loading configuration to attache appenders to their loggers. One appender might be attached to multiple loggers.

Appenders also have a threshold to filter out messages.

Formatters

Formatters are attached to appenders. Their job is to modify the message to apply it a specific formatting before it is sent to its final destination. One formatter might be attached to multiple appenders.

Some more details on features

Mutliple appenders per logger

One logger can have multiple appenders. You can for exemple define a logger that will log everything to the console, but that will also log error messages to a file for latter use.

let logger = Logger.getLogger("test.logger");
let stdOutAppender = StdOutAppender("console");
let fileAppender = FileAppender(identifier: "errorFile", filePath: "/var/log/error.log");

stdOutAppender.thresholdLevel = .Debug;
fileAppender.thresholdLevel = .Error;
logger.appenders = [stdOutAppender, fileAppender];

logger.debug ("This message will go to the console");
logger.error ("This message will go to the console and the error log file");  }

(this code compiles on Xcode 7.3, using swift 2.2)

Formatters associated to appenders

Formatters allows you to apply a specific formatting to your log message, either adding information to the logged message or modifying the message to have it complying to some constraintes.

Formatters are associated to appenders. This way, you can log human readable logs to Xcode's console, while logging with more info regexp friendly format in a file.

Log with closures

Providing a closure instead of a string is pretty handy if the code that generates the message is heavy : the closure will only be executed if the logs are to be issued. No need to encapsulate the code in an if structure.

Logger.debug { someHeavyCodeThatGeneratesTheLogMessage() }

Note that creating the bloc is not completely free (some magic happen behind the scene, like variable capture). But for most uses, the cost should be negligible.

Log asynchronously

Loggers can be configured individualy to log asynchronously. Asynchronous logging will return almost immediately when a log is requested, while the real log will be issued in background on a low priority thread.

Order of messages logged to asynchronous loggers is guaranteed.

Note that if asychronous loggers will execute logged closures later in time, and on an external thread.

Flexible configuration

Loggers can be configured from a file, or using the library's API.

Using the API, you can use a dictionary, that can be stored and loaded from anywhere you want (a web service, a database, a preference file, ...).

Using a configuration file, you can request the configuration to be auto-reloaded each time the file is modified:

LoggerFactory.sharedInstance.readConfiguration(fromPlistFile: "/some/file.plist", autoReload: true)

Configuration can be modified at run time.

Provided appenders

The stdout appender

This appender will write log messages to stdout or stderr. It has two thresholds : the regular threshold, available on all appenders, and an error threshold.

  • If the log level is bellow the general threshold, the message is ignored
  • If the log level is above the general threshold but bellow the error threshold, the message is issued on stdout
  • If the log level is above both the general and the error threshold, the message is issued on stderr

By default, the stdout appender is configured to send Error and Fatal messages to stderr, and all other levers to stdout.

This appender is a good choice for CLI tools.

The file appender

This appender will write log messages to a file, specified by its path. It will create the file if needed (and possible), and will re-create it if it disapears. This allows log rotation scripts to avoid having to restart the process to ensure logs are recorded in a new file after rotation.

The NSLogger appender

This appender uses NSLogger (https://github.com/fpillet/NSLogger) to send log messages over the network. Not all capabilities of NSLogger are accessibles yet : only text messages can be logged.

The ASL appender

The ASL appender sends log messages to the system logging service, provided by Apple. Your messages will we visible in the Console.app application if the ASL configuration has not been customized.

This appender is a good choice for release versions of softwares targetting exclusively systems that does not have the Unified Logging System.

Note: ASL has been deprecated by Apple starting with MacOS 10.12. The unified logger appender should be used instead of ASL for those platforms.

The Unified Logging System appender

The unified logging system is the replacement of ASL starting with MacOS 10.12. This logger will log messages to this facility. Your messages will be visible in the Console.app application.

This appender is a good choice for release versions of software targetting 10.12 and latter.

The system appender

This meta-appender will use the most appropriate system appender for the current system.

  • for MacOS < 10.12, it will use the ASLAppender
  • for MacOS >= 10.12, it will use the Unified Logging System appender.

This appender is the best choice for release versions of software targetting multiple versions of the system (most common case).

Provided formatters

The PatternFormatter

The PatternFormatter uses a simple textual pattern with marker identified by a '%' prefix to render the log messages.

As an exemple, this pattern :

[%d][%l][%n] %m

will produce this kind of log:

[2015-02-02 12:45:23 +0000][Debug][logger.name] The message that was sent to the logger

See this page for more details, including a full list of available markers.

log4swift's People

Contributors

darkdah avatar igor-makarov avatar jduquennoy avatar pulcheri avatar readmecritic avatar regalmedia avatar sshirokov-mwb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

log4swift's Issues

`AppleUnifiedLoggerAppender` isn't thread-safe

While os_log is supposed to be thread-safe, access to AppleUnifiedLoggerAppender.loggerToOSLogCache instance variable can happen on multiple threads and causes crashes due to memory access errors.

Can't build for iOS with Carthage

With Carthage 25 and 26 both Log4Swift does not build for me with 9A235.
Simply states :

*** Building scheme "log4swift-iOS" in Log4swift.xcodeproj
Failed to write to /Users/codemonkey/workspace/Poll-Pad-3/Carthage/Build/iOS/Log4swift.framework: Error Domain=NSCocoaErrorDomain Code=260 "The file “Log4swift.framework” couldn’t be opened because there is no such file." UserInfo={NSURL=file:///Users/codemonkey/workspace/Poll-Pad-3/Carthage/Checkouts/Log4swift/build/ArchiveIntermediates/log4swift-iOS/BuildProductsPath/Release-iphoneos/Log4swift.framework, NSFilePath=/Users/codemonkey/workspace/Poll-Pad-3/Carthage/Checkouts/Log4swift/build/ArchiveIntermediates/log4swift-iOS/BuildProductsPath/Release-iphoneos/Log4swift.framework, NSUnderlyingError=0x7fc8aedfc000 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}

Im in the "my project. won't build due to a million dependencies" situation. Never had issues with XCGLogger.

Build Issues while using pod

Hi,
I am using your library in my project, I am facing the following issue as described below.
FYI
Platform: iOS
Compiler Version : Swift 4.1

Screenshot of the issue
screen shot 2018-07-10 at 5 49 19 pm

I can manually fix this issue by suggestion as shown below
screen shot 2018-07-10 at 5 57 07 pm

But if used above suggestion the following screen pops over
screen shot 2018-07-10 at 5 57 24 pm

If I gave unlock permission the issue is fixed. For all issues same steps as has to be followed

I am using pod method to install this library, So I will not keep my pod libraries in my source.
Single pod file with dependency list will be available in source, So that pod libraries can be retrieved using pod install command.

If am sharing the code with developers in my team.
The developer have to repeat those steps specified above to fix the issue every time while installing pod libraries.

If the issue is resolved in your build, It will be helpful to developer community.

Regards,
Santhosh

Project maintenance?

Hi @jduquennoy and thank you for developing and maintaining Log4swift!

I've been a user of it for years and have contributed several times to it.

I've recently come across two issues (#31 & #32) that have been randomly occurring in debug, but due to recent code changes I've made in the app, have begun occurring for users.

I have noticed that the repo hasn't received much maintenance, and I'll be happy to take it off your hands.

No matter what your decision is, I'll open a PR that fixes the two issues I've found in a short while.

Use of unresolved identifier 'NSString'

Hello,
I spent last two days on this issue and still believe it must be something simple. I made a tvOS target and added all needed files into it and still getting bunch of errors while building the framework.
`Showing All Messages
/Users/rcerny/Developer/Projects/Net/Log4swift/Log4swift/Utilities/String+utilities.swift:25:56: Use of unresolved identifier 'NSString'

/Users/rcerny/Developer/Projects/Net/Log4swift/Log4swift/Utilities/String+utilities.swift:42:7: Use of unresolved identifier 'NSString'

/Users/rcerny/Developer/Projects/Net/Log4swift/Log4swift/Utilities/String+utilities.swift:88:22: Use of undeclared type 'NSString'

/Users/rcerny/Developer/Projects/Net/Log4swift/Log4swift/Utilities/String+utilities.swift:92:16: Use of unresolved identifier 'JSONSerialization'

/Users/rcerny/Developer/Projects/Net/Log4swift/Log4swift/Utilities/String+utilities.swift:92:66: Use of unresolved identifier 'JSONSerialization'`

Does anyone have any idea what could be wrong?

error: include of non-modular header inside framework module 'Log4swift.log4swift'

:1:9: note: in file included from :1:

import "/Users/liorshalev01/heylo/heylo-ios/Pods/Target Support Files/Log4swift/Log4swift-umbrella.h"

    ^

/Users/liorshalev01/heylo/heylo-ios/Pods/Target Support Files/Log4swift/Log4swift-umbrella.h:3:9: note: in file included from /Users/liorshalev01/heylo/heylo-ios/Pods/Target Support Files/Log4swift/Log4swift-umbrella.h:3:

import "log4swift.h"

    ^

/Users/liorshalev01/heylo/heylo-ios/Pods/Log4swift/Log4swift/log4swift.h:30:9: error: include of non-modular header inside framework module 'Log4swift.log4swift'

import <Log4swift/NSLogger.h>

    ^

:1:9: note: in file included from :1:

import "/Users/liorshalev01/heylo/heylo-ios/Pods/Target Support Files/Log4swift/Log4swift-umbrella.h"

    ^

/Users/liorshalev01/heylo/heylo-ios/Pods/Target Support Files/Log4swift/Log4swift-umbrella.h:3:9: note: in file included from /Users/liorshalev01/heylo/heylo-ios/Pods/Target Support Files/Log4swift/Log4swift-umbrella.h:3:

import "log4swift.h"

    ^

/Users/liorshalev01/heylo/heylo-ios/Pods/Log4swift/Log4swift/log4swift.h:31:9: error: include of non-modular header inside framework module 'Log4swift.log4swift'

import <Log4swift/LoggerClient.h>

    ^

Hi,

Xcode 7.1

Podfile:
use_frameworks!
target 'Heylo' do
pod 'Log4swift', '1.0.0b4'
pod 'AWSCore', '> 2.3'
pod 'AWSCognito', '
> 2.3'
pod 'Fabric', '> 1.6'
pod 'TwitterCore', '
> 1.14'
pod 'TwitterKit', '> 1.14'
pod 'PromiseKit', '
> 3.0'
pod 'AFNetworking', '3.0.0-beta.3'
end

:1:9: note: in file included from :1:

import "/Users/liorshalev01/heylo/heylo-ios/Pods/Target Support Files/Log4swift/Log4swift-umbrella.h"

    ^

/Users/liorshalev01/heylo/heylo-ios/Pods/Target Support Files/Log4swift/Log4swift-umbrella.h:3:9: note: in file included from /Users/liorshalev01/heylo/heylo-ios/Pods/Target Support Files/Log4swift/Log4swift-umbrella.h:3:

import "log4swift.h"

    ^

/Users/liorshalev01/heylo/heylo-ios/Pods/Log4swift/Log4swift/log4swift.h:32:9: error: include of non-modular header inside framework module 'Log4swift.log4swift'

import <Log4swift/LoggerCommon.h>

    ^

:1:9: note: in file included from :1:

import "/Users/liorshalev01/heylo/heylo-ios/Pods/Target Support Files/Log4swift/Log4swift-umbrella.h"

    ^

/Users/liorshalev01/heylo/heylo-ios/Pods/Target Support Files/Log4swift/Log4swift-umbrella.h:3:9: note: in file included from /Users/liorshalev01/heylo/heylo-ios/Pods/Target Support Files/Log4swift/Log4swift-umbrella.h:3:

import "log4swift.h"

    ^

/Users/liorshalev01/heylo/heylo-ios/Pods/Log4swift/Log4swift/log4swift.h:34:9: error: include of non-modular header inside framework module 'Log4swift.log4swift'

import <Log4swift/ASLWrapper.h>

    ^

:0: error: could not build Objective-C module 'Log4swift'

Versioned File Appender

I Jerome, I have created a pull request with a patch of the file appender in which we avoid the log file to be overwritten every time the logger is launched. But with this patch the log file will grow forever. There is multiple solution to this small problem:

  1. We check the size of the file and when it reach a value we add the date to the name of the log file and create a new one. We also only keep some of them. The number of files to keep and the size could be parameters one the appender configuration.
    Parameter could be:
    versionable: BOOL
    maxFileSize: 2Mb
    numberOfHistoryFiles: 10
  2. We do the same as in 1 but create a new file on every run, keeping the las n ones with the creation date attached.
    Parameter could be:
    versionable: BOOL
    numberOfHistoryFiles: 10

What do you think?

CocoaPods integration

I added Log4swift in my project using cocoapods and throw me this errors when is building the project:

MyProject/Pods/Log4swift/Log4swift/log4swift.h:32:9: error: include of non-modular header inside framework module 'Log4swift.log4swift'

import <Log4swift/NSLogger.h>

MyProject/Pods/Log4swift/Log4swift/log4swift.h:33:9: error: include of non-modular header inside framework module 'Log4swift.log4swift'

import <Log4swift/LoggerClient.h>

MyProject/Pods/Log4swift/Log4swift/log4swift.h:34:9: error: include of non-modular header inside framework module 'Log4swift.log4swift'

import <Log4swift/LoggerCommon.h>

MYProject/Pods/Log4swift/Log4swift/log4swift.h:36:9: error: include of non-modular header inside framework module 'Log4swift.log4swift'

import <Log4swift/ASLWrapper.h>

:0: error: could not build Objective-C module 'Log4swift'

Use of unresolved identifier "ConsoleAppender"

I am using the following code from the examples. On the first line I am getting Use of unresolved identifier "ConsoleAppender"

let consoleAppender = ConsoleAppender("consoleAppender");
consoleAppender.formatter = defaultFormatter;

I am importing Log4swift on my AppDelegate. Am I missing something? Here is my full configureLogging method called from the onAppLoaded() method:

func configureLogging() {
    let sharedFactory = LoggerFactory.sharedInstance;

    let defaultFormatter = try! PatternFormatter(identifier: "default formatter", pattern: "%d - %m");

    let consoleAppender = ConsoleAppender("consoleAppender");
    consoleAppender.formatter = defaultFormatter;

    let fileAppender = FileAppender(identifier: "fileAppender", filePath: "/var/log/errors.log");
    fileAppender.formatter = defaultFormatter;
    fileAppender.thresholdLevel = .Error;

    sharedFactory.rootLogger.appenders = [consoleAppender, fileAppender];
    sharedFactory.rootLogger.thresholdLevel = .Info;

    let debugLogger = sharedFactory.getLogger("application.feature");
    debugLogger.thresholdLevel = .Debug;
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.