✏️ Cabret ✏️

jCenter
PRs Welcome
jCenter

Introduction 🙋‍♂️ 🙋‍

This is an Kotlin Library that enables Annotation-triggered method call logging for Kotlin Multiplatform. Inspired by Hugo, Hunter-Debug and the blog posts by bnorm .

Simply add @DebugLog to your methods and it will automatically log all arguments that are passed to the function the return value and the time the function needed to excecute.

When the following function gets called:

@DebugLog
fun exampleFun(
    first: String,
    last: String,
    age: Int = 31,
    isLoggedIn: Boolean = false
): String = "$first $last"

fun main(){
  exampleFun("Jens","Klingenberg")
}

It will automatically log:

Example -> exampleFun( first= Jens, last= Klingenberg, age= 31, isLoggedIn= false)
Example <- exampleFun() [2.63ms] =  Jens Klingenberg

Show some ❤️ and star the repo to support the project

GitHub stars GitHub forks GitHub watchers Twitter Follow

Setup

You can take a look at DemoProject as an example

1) Gradle Plugin

Add the dependency to your buildscript

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath "de.jensklingenberg.cabret:cabret-gradle:1.0.3"
    }
}

2) Apply the plugin

Kotlin DSL:

plugins {
     id("de.jensklingenberg.cabret")
}

configure<de.jensklingenberg.gradle.CabretGradleExtension> {
    enabled = true
    version = "1.0.4"
}

Groovy DSL:

plugins {
    id 'de.jensklingenberg.cabret'
}

cabret {
    enabled = true
    version = 1.0.4
}

The plugin will only be active when enabled is set to true

3) Log Library

To be able to use the DebugLog annotation, you also need add the dependecies on cabret-log.

Multiplatform (Common, JS, Native)

You can add dependency to the right to the common source set:

commonMain {
    dependencies {
        implementation "de.jensklingenberg.cabret:cabret-log:1.0.4"
    }
}

Platform-specific

You can also add platform-specific dependecies

sourceSets {
    jvmMain {
            dependencies {
                 implementation "de.jensklingenberg.cabret:cabret-log-jvm:1.0.4"
            }
   }
}

Here’s a list of all available targets:

def cabretVersion = "1.0.4"

implementation "de.jensklingenberg.cabret:cabret-log-jvm:$cabretVersion"
implementation "de.jensklingenberg.cabret:cabret-log-js:$cabretVersion"
implementation "de.jensklingenberg.cabret:cabret-log-android:$cabretVersion"
implementation "de.jensklingenberg.cabret:cabret-log-iosx64:$cabretVersion"
implementation "de.jensklingenberg.cabret:cabret-log-iosarm64:$cabretVersion"
implementation "de.jensklingenberg.cabret:cabret-log-linux:$cabretVersion"
implementation "de.jensklingenberg.cabret:cabret-log-macos:$cabretVersion"
implementation "de.jensklingenberg.cabret:cabret-log-watchosarm32:$cabretVersion"
implementation "de.jensklingenberg.cabret:cabret-log-watchosarm64:$cabretVersion"
implementation "de.jensklingenberg.cabret:cabret-log-tvosarm32:$cabretVersion"
implementation "de.jensklingenberg.cabret:cabret-log-tvosarm64:$cabretVersion"

4) Enable IR

Cabret is using a Kotlin Compiler Plugin that is using the IR Backend. For Native targets it’s already enabled, but you need to activate it in your build.gradle for Kotlin JVM/JS

Kotlin/JVM

tasks.withType<KotlinCompile>().configureEach {
  kotlinOptions {
    useIR = true
  }
}
Kotlin/JS

target {
  js(IR) {
  }
}

Logging

Tag

@DebugLog( tag = "MyTag")

You can add a tag to the DebugLog annotation under which you can find your logged data. When you don’t add a custom tag, Cabret will use the file name for top level function and the class name for class functions as the tag.

LogLevel

@DebugLog(logLevel = Cabret.LogLevel.ERROR)

You can set a LogLevel to the DebugLog Annotation. You can choose between VERBOSE, DEBUG, INFO, WARN or ERROR. By default DEBUG is selected.

Custom Logger

By default Cabret will log the data with printLn() or on Android with android.util.Log and the selected LogLevel. E.g. LogLevel.ERROR will be logged with Log.e(), LogLevel.INFO will be logged with Log.i(), etc.

You can add your own Logger. All you need to do is to add your object of Cabret.Logger to Cabret.addLogger() somewhere at the beginning of your programm.

Cabret.addLogger(object : Cabret.Logger {
            override fun log(data: LogData) {
                //Add your logger here
                println(data.tag + " " + data.msg)
            }
})

👷 Project Structure

  • cabret-compiler-plugin – This module contains the Kotlin Compiler Plugin for JVM/JS targets
  • cabret-compiler-native-plugin – This module contains the Kotlin Compiler Plugin for native targets
  • cabret-compiler-runtime – This module contains the shared Kotlin Compiler Plugin Logic for JVM/JS/Native compiler
  • cabret-gradle – This module contains the gradle plugin which triggers the two compiler plugins
  • cabret-log – A Kotlin Multiplatform project with the DebugLog annotation and the default loggers
  • DemoProject – A Kotlin Multiplatform project that is using the debuglog compiler plugin

✍️ Feedback

Feel free to send feedback on Twitter or file an issue. Feature requests are always welcome.

📜 License


This project is licensed under Apache License, Version 2.0

Copyright 2020 Jens Klingenberg

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

GitHub

https://github.com/Foso/Cabret-Log