7

I have a kotlin file with a couple of package-level functions and without any class. I would like to add logging to this class but struggle to find an elegant way to give the logger an identifier.

This is an example

package com.example.myproject.my_package

import org.slf4j.LoggerFactory


private val log = LoggerFactory.getLogger("com.example.myproject.my_package")

fun bla(term: String) {
   log.info("invoked with $term")
}

There are very good best practices to use classes to find a good identifier: link 1 link 2. What's the approach if there are no classes?

I would like to avoid writing the identifier by hand and adjust it when the package name changes. Is there a way to get the package name in kotlin?

5
  • Top-level functions are good when they are utility functions. But logic should be located in a class (or object). Commented Jul 27, 2017 at 10:00
  • 1
    why that? object oriented programming is only one way to develop your code, there are other paradigm that kotlin perfectly is suited for. Commented Jul 27, 2017 at 10:28
  • 3
    Have you tried github.com/MicroUtils/kotlin-logging ? Commented Jul 27, 2017 at 11:25
  • That's not because of OOP paradigm. (By the way, Singleton, which object stands for, is a procedural pattern.) That's because your functions are gathered in a file, which is not a fully-functional scope — it has no representation in a programming language. Commented Jul 27, 2017 at 11:55
  • @FrankSchmitt perfect, works like a charm! Commented Jul 28, 2017 at 10:28

2 Answers 2

13

This line should do the job:

private val log = LoggerFactory.getLogger(object{}::class.java.`package`.name)

The object is doing nothing but nevertheless kotlin will create a class to hold the code. You can then access the class, the package, the package name.

Note the usage of backtick because package is a reserved keyword. In java it is not a problem because the real method is getPackage(). The shorter syntax of kotlin transform this method call by a direct access to the property which name now collides with reserved keywords.

Sign up to request clarification or add additional context in comments.

2 Comments

Great answer, thanks. Finally I went with the solution given by Frank's comment. If you are fine with this extra dependency his solution is even more elegant.
Of course, I was more focused on your precise question "Is there a way to get the package name in kotlin?" than what I would do myself.
5

You can create a top-level logger for the generated class like this:

private val logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass())

Or for the package like this:

private val logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass().`package`.name)

This has the benefit of not creating an additional class file but it requires atleast Java 7. I have created a library which assists with this and more at https://github.com/kxtra/kxtra-slf4j.

1 Comment

better answer. good info, should be set as the accepted.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.