0

I am trying to make a generic Logger for a project, but I am unable of getting the name of the calling class in the log traces.

I have tried to get the name of the calling class using super.getClass, but it doesn't seem to work the way I'd like to. Right now, this is where I am at:

object GeneralLogger {

    val newLogger = LoggerFactory.getLogger(super.getClass)
    val configFile: Config = ConfigFactory.load()

    def SparkLogger(event: ErrorEvent) : Unit = {

      val sparkAppName: String = configFile.getString("spark.appName")
      val sparkMaster: String = configFile.getString("spark.master")
      val sparkCrossJoin: String = configFile.getString("spark.crossJoin")
      val sparkSqlWarehouse: String = configFile.getString("spark.sqlWarehouse")
      val sparkExecutorMemory: String = configFile.getString("spark.sparkExecutorMemory")

      newLogger.info("--- Spark Parameters ---")
      newLogger.info("sparkAppName: " + sparkAppName.toString)
      newLogger.info("sparkMaster: " + sparkMaster.toString)
      newLogger.info("sparkCrossJoin: " + sparkCrossJoin.toString)
      newLogger.info("sparkSqlWarehouse: " + sparkSqlWarehouse.toString)
      newLogger.info("sparkExecutorMemory: " + sparkExecutorMemory.toString)

    }

    def CassandraLogger() : Unit = {

      val cassandraHost: util.List[String] = configFile.getStringList("cassandra.host")
      val cassandraUser: String = configFile.getString("cassandra.username")
      val cassandraKeyspace: String = configFile.getString("cassandra.keyspaces.test")
      val cassandraPassword: String = configFile.getString("cassandra.password")

      newLogger.info("--- Cassandra Parameters ---")
      newLogger.info("cassandraHost: " + cassandraHost.toString)
      newLogger.info("cassandraUser: " + cassandraUser.toString)
      newLogger.info("cassandraKeyspace: " + cassandraKeyspace.toString)
      newLogger.info("cassandraPassword: " + cassandraPassword.toString)

    }

So this solution makes my logs look like the following:

2375 [main] INFO  c.g.bank.core.utils.GeneralLogger$ - --- Spark Parameters --- 
2449 [main] INFO  c.g.bank.core.utils.GeneralLogger$ - sparkAppName: Flap

What I want to accomplish is to have the logs named by the calling class, so if I implement GeneralLogger inside a class named IncomeNotifier I would get the logs this way:

2375 [main] INFO  c.g.bank.core.utils.IncomeNotifier$ - --- Spark Parameters --- 
2449 [main] INFO  c.g.bank.core.utils.IncomeNotifier$ - sparkAppName: Flap 

Thank you for your help in advance

1 Answers1

0

super.getClass just calls supertype's implementation of getClass, which is the same as calling your object's getClass because you don't (and can't) override it.

GeneralLogger as written is a singleton, so you have exactly one GeneralLogger and all logs will have the same logger name, so it isn't clear what you mean by

I implement GeneralLogger inside a class named IncomeNotifier

One option would be

class GeneralLogger(clazz: Class[_]) {
  val newLogger = LoggerFactory.getLogger(clazz)
}

In IncomeNotifier:

val logger = new GeneralLogger(getClass)
logger.CassandraLogger()

or define SparkLogger and CassandraLogger to take the calling class as a parameter.

You can get the calling class name without passing it: How do I find the caller of a method using stacktrace or reflection? In most cases you shouldn't.

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487