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.