Scala Lesson 52 – Logging | Dataplexa

Logging in Scala Applications

In this lesson, you will learn about logging in Scala. Logging is a critical part of real-world software development and helps developers understand what an application is doing internally.

Unlike simple println statements, logging provides structured, configurable, and production-ready information about program execution.


What Is Logging?

Logging is the process of recording messages about an application’s behavior during execution.

Logs help developers:

  • Debug errors and unexpected behavior
  • Monitor application health
  • Analyze performance issues
  • Track user actions and system events

Why Not Use println?

While println is useful for learning, it is not suitable for production systems.

Problems with println:

  • No log levels (info, error, warning)
  • No timestamps
  • No log files
  • Hard to disable or filter

Logging frameworks solve these issues.


Common Logging Levels

Most logging systems support different severity levels.

  • DEBUG – Detailed internal information
  • INFO – General application flow
  • WARN – Potential problems
  • ERROR – Errors that affect execution
  • FATAL – Severe system failures

Popular Logging Libraries for Scala

Scala commonly uses Java logging frameworks.

  • SLF4J (Simple Logging Facade for Java)
  • Logback
  • Log4j

In this lesson, we will focus on SLF4J with Logback, which is widely used and recommended.


Adding Logging Dependency (Concept)

In a real Scala project using SBT, logging dependencies are added to build.sbt.

libraryDependencies += "ch.qos.logback" % "logback-classic" % "1.4.11"

This enables structured logging in your application.


Creating a Logger

A logger is usually created once per class or object.

import org.slf4j.LoggerFactory

object LoggerExample {
  val logger = LoggerFactory.getLogger("LoggerExample")

  def main(args: Array[String]): Unit = {
    logger.info("Application started")
  }
}

This creates a logger that can log messages at different levels.


Using Different Log Levels

You can log messages at various severity levels depending on the situation.

logger.debug("Debugging details")
logger.info("Application is running")
logger.warn("This might cause an issue")
logger.error("An error occurred")

This makes logs more meaningful and easier to filter.


Logging with Variables

Log messages often include dynamic data.

val user = "Alice"
logger.info(s"User logged in: $user")

This helps track runtime values during execution.


Logging Errors with Exceptions

Logging exceptions is crucial for debugging failures.

try {
  val result = 10 / 0
} catch {
  case e: Exception =>
    logger.error("Computation failed", e)
}

This records both the error message and stack trace.


Logging in CLI Applications

Logging is especially useful in CLI tools where output must be controlled.

object CLILogger {
  val logger = LoggerFactory.getLogger("CLI")

  def main(args: Array[String]): Unit = {
    logger.info("CLI started")
    if (args.isEmpty) {
      logger.warn("No arguments provided")
    }
  }
}

Logs can be redirected to files instead of cluttering the terminal.


Best Practices for Logging

To write effective logs:

  • Use appropriate log levels
  • Avoid logging sensitive data
  • Do not overuse DEBUG logs in production
  • Log meaningful events, not everything

📝 Practice Exercises


Exercise 1

Create a logger and log an INFO message when the program starts.

Exercise 2

Log a warning if no command-line arguments are provided.

Exercise 3

Log an error message when an exception occurs.


✅ Practice Answers


Answer 1

logger.info("Program started")

Answer 2

if (args.isEmpty) logger.warn("No arguments")

Answer 3

catch {
  case e: Exception => logger.error("Error occurred", e)
}

What’s Next?

In the next lesson, you will learn about Serialization in Scala, which allows you to convert objects into formats like JSON for storage and communication.