KSLog

Library with aim of simple logging on all platforms and opportunity to setup it with full customization

Setup

Dependency installation

Maven Central

Gradle (Groovy)

implementation "dev.inmo:kslog:$kslog_version"

Gradle (Kotlin Script)

implementation("dev.inmo:kslog:$kslog_version")

Maven (pom)

<dependency>
  <groupId>dev.inmo</groupId>
  <artifactId>kslog</artifactId>
  <version>${kslog_version}</version>
</dependency>

Setup in code

The main point in setup in your code is to setup default logger:

KSLog.default = KSLog("defaultTag")

You may use custom messageFormatter in any of KSLog factory to customize output of KSLog logging. For example:

KSLog(
  "loggingWithCustomFormat",
  messageFormatter = { level, tag, message, throwable ->
    println("[$level] $tag - $message: $throwable")
  }
)

Additionally you may use one of several different settings:

In case you are passing minLoggingLevel, the level and more important levels will be passed to logs. For example, when you are settings up your logger as in next snippet:

val logger = KSLog(
    "exampleTag",
    minLoggingLevel = LogLevel.INFO
)

The next levels will be logged with logger:

Special loggers

CallbackKSLog

It is logger which will call incoming performLogCallback on each logging. This logger can be create simply with one callback:

KSLog { level, tag, message, throwable ->
  println("[$level] $tag - $message: $throwable")
}

TagLogger

It is simple value class which can be used for zero-cost usage of some tag and calling for KSLog.default. For example, if you will create tag logger with next code:

val logger = TagLogger("tagLoggerTag")

The logger will call KSLog.default with the tag tagLoggerTag on each calling of logging.

FilterKSLog

This pretty simple logger will call its fallbackLogger only in cases when incoming messageFilter will return true for logging:

val baseLogger = KSLog("base") // log everything with the tag `base` if not set other
val filtered = baseLogger.filtered { _, t, _ ->
    t == "base"
}

In the example above baseLogger will perform logs in two ways: when it has been called directly or when we call log performing with the tag "base" or null. Besides, you can see there extension filtered which allow to create FilterKSLog logger with simple lambda.

TypedKSLog

This logger accepts map of types with the target loggers. You may build this logger with the special simple DSL:

val baseLogger = KSLog("base") // log everything with the tag `base` if not set other
val typed = buildTypedLogger {
  on<Int>(baseLogger) // log all ints to the baseLogger
  on<Float> { _, _, message, _ ->// log all floats to the passed logger
  	println(message.toString()) // just print all floats
  }
  default { level, tag, message, throwable ->
    KSLog.performLog(level, tag, message, throwable)
  }
}

Automatical loggers

There are two things which can be useful in your code: logger and logTag extensions. logTag is the autocalculated by your object classname tag. logger extension can be used with applying to any object like in the next snippet:

class SomeClass {
  init {
    logger.i("inited")
  }
}

The code above will trigger calling of logging in KSLog.default with level LogLevel.INFO using tag SomeClass and message "inited". As you could have guessed, logger is using TagLogger with logTag underhood and the most expensive operation here is automatical calculation of logTag.

JVM specific setup

For JVM you may setup additionally use java loggers as the second parameter of KSLog factory. For example:

KSLog(
  "yourTag"
  Logger.getLogger("YourJavaLoggerName")
)

Logging

Message type notice
On this page all the messages will be just simple String, but you may pass any object as the message

As has been said in the setup section, this library contains next levels of logging with their default representations on each platform:

Weight (by order) LogLevel name JS JVM Loggers Android
0 DEBUG console.log Level.FINEST Log.d
1 VERBOSE console.info Level.FINE Log.v
2 INFO console.info Level.INFO Log.i
3 WARNING console.warn Level.WARNING Log.w
4 ERROR console.error Level.SEVERE Log.e
5 ASSERT console.error Level.SEVERE Log.wtf

Each of these levels have fullname and shortname shortcat extensions:

And any of these shortcuts may accept one of several arguments combinations:

So, when you want to log some expected exception, there are three common ways to do it:

val logger = KSLog.default

// with callback
logger.info(tag, throwable) {
  "Some your message for this event"
}

// with suspendable callback
logger.infoS(tag, throwable) {
  withContext(Dispatchers.Default) {
    "Some your message for this event"
  }
}

// Just with message
logger.info("Some your message for this event", throwable)

// With message and tag as strings
logger.info(tag, "Some your message for this event", throwable)

Of course, any of this calls can be shortenned:

val logger = KSLog.default

// with callback
logger.i(tag, throwable) {
  "Some your message for this event"
}

// with suspendable callback
logger.iS(tag, throwable) {
  withContext(Dispatchers.Default) {
    "Some your message for this event"
  }
}

// Just with message
logger.i("Some your message for this event", throwable)

// With message and tag as strings
logger.i(tag, "Some your message for this event", throwable)

There is special shortcat - for base performLog. In that case the only change is that you will require to pass the LogLevel more obviously:

val logger = KSLog.default

// with callback
logger.log(LogLevel.INFO, tag, throwable) {
  "Some your message for this event"
}

// with suspendable callback
logger.logS(LogLevel.INFO, tag, throwable) {
  withContext(Dispatchers.Default) {
    "Some your message for this event"
  }
}

// Just with message
logger.log(LogLevel.INFO, "Some your message for this event", throwable)

// With message and tag as strings
logger.log(LogLevel.INFO, tag, "Some your message for this event", throwable)

OR

val logger = KSLog.default

// with callback
logger.l(LogLevel.INFO, tag, throwable) {
  "Some your message for this event"
}

// with suspendable callback
logger.lS(LogLevel.INFO, tag, throwable) {
  withContext(Dispatchers.Default) {
    "Some your message for this event"
  }
}

// Just with message
logger.l(LogLevel.INFO, "Some your message for this event", throwable)

// With message and tag as strings
logger.l(LogLevel.INFO, tag, "Some your message for this event", throwable)