DEV Community

Mustafa ERBAY
Mustafa ERBAY

Posted on • Originally published at mustafaerbay.com.tr

Application Log Levels: When to Use DEBUG and INFO?

Application Log Levels and Their Importance

One of the most fundamental issues we encounter while developing an application or managing an existing system is the logging mechanism that allows us to understand the application's operational status. Logs are vital for debugging errors, identifying performance issues, and monitoring the overall health of the system. However, making the right decisions about how detailed logs should be and what information should be recorded directly affects the efficiency of the system.

In particular, frequently used log levels like DEBUG and INFO are the ones developers encounter most and sometimes confuse. While the DEBUG level shows the most detailed internal workings of the application, the INFO level contains more general operational information. Using these two levels correctly both speeds up the development process and prevents performance loss by avoiding unnecessary log overhead in the production environment. In this post, I will explain when and how we should use DEBUG and INFO log levels, based on concrete examples and my real-world field experience.

DEBUG Log Level: Diving into the Details

The DEBUG log level is used to track the finest details of an application, variable values, function calls, and the flow of code step-by-step. This level is typically active during the development and debugging phases. Keeping the DEBUG level constantly open in a production environment can generate a massive amount of log data, quickly consuming disk space and significantly degrading I/O performance.

For example, during a user registration process, the DEBUG level might record the following information: the email address entered by the user, the pre-hashed version of the password (this should never be recorded!), the full text of the SQL query sent to the database, details of the response returned from the database, the execution times of the functions used, and even instantaneous changes in memory usage. Such detailed information is invaluable for understanding exactly where and how an error occurred. A DEBUG log example might look like this:

2026-05-16 03:15:22.123 DEBUG [com.example.user.service.UserService:registerUser] - Entering registerUser method with email: user@example.com
2026-05-16 03:15:22.125 DEBUG [com.example.user.service.UserService:hashPassword] - Hashing password for user: user@example.com
2026-05-16 03:15:22.130 DEBUG [com.example.user.repository.UserRepository:saveUser] - Executing SQL: INSERT INTO users (email, password_hash, created_at) VALUES (?, ?, ?) with params: ['user@example.com', 'hashed_password_string', '2026-05-16 03:15:22.130']
2026-05-16 03:15:22.150 DEBUG [com.example.user.repository.UserRepository:saveUser] - User saved successfully. User ID: 12345
2026-05-16 03:15:22.155 DEBUG [com.example.user.service.UserService:registerUser] - Exiting registerUser method. User ID: 12345
Enter fullscreen mode Exit fullscreen mode

This level of detail is necessary to find the root cause of an error, especially in applications with complex business logic. For instance, in an error encountered during the "add to cart" process on an e-commerce site, thanks to DEBUG logs, we can access information such as which product ID was attempted to be added to which user's cart and at what stage the stock check failed. This allows us to identify the source of the problem directly from the logs instead of manually searching through lines of code.

💡 When to Use the DEBUG Level?

The DEBUG level should be preferred especially in the following situations:

  • Monitoring code flow and variable values during the development phase.
  • While trying to find the root cause of a complex error that cannot be resolved in the production environment (temporarily).
  • When you want to understand the behavior of a specific module or function in detail.

It should not be forgotten that DEBUG logs can lead to serious performance problems if left open continuously in the production environment. Therefore, they should only be enabled when needed and turned off after debugging.

INFO Log Level: Operational Logs

The INFO log level provides meaningful information about the normal operational status of the application. This level is used to record events that indicate the application is working as expected. Unlike the DEBUG level, INFO logs are usually left on in the production environment because they provide valuable information about the general health and workflows of the system and generally produce a reasonable amount of data.

An INFO log example might include events such as a user successfully logging in, a transaction being completed, or a service being restarted. This information is used to understand the general state of the application, verify whether a specific workflow has been successfully completed, and detect anomalies in the system early.

For example, in a financial transaction application, INFO logs might look like this:

2026-05-16 03:17:05.500 INFO [com.example.transaction.service.TransactionService:processPayment] - Payment processed successfully for transaction ID: TXN789012. Amount: 150.75 USD. Customer: John Doe.
2026-05-16 03:17:06.100 INFO [com.example.user.auth.AuthenticationService:login] - User 'admin' logged in successfully from IP address: 192.168.1.100.
2026-05-16 03:18:30.000 INFO [com.example.scheduler.JobScheduler:startJob] - Scheduled job 'daily_report_generator' started at 03:18:30.
Enter fullscreen mode Exit fullscreen mode

These types of logs indicate that a report was successfully generated, a user accessed the system, or a transaction was completed. In a production ERP system, INFO logs might specify that an order was approved, a shipment was made, or an invoice was issued. This information is critical for tracking and auditing business processes. Although the INFO level is not detailed enough for debugging, it provides a fundamental dataset for understanding the general operation of the application.

ℹ️ When to Use the INFO Level?

The INFO level is ideal for documenting the normal operation of the application. It should be preferred in the following situations:

  • Recording the successful completion of important workflows (e.g., user registration, order processing).
  • Indicating significant state changes in the application (e.g., service start/stop, configuration changes).
  • Recording events to be used for monitoring the general operational status.

INFO logs are usually left on as standard in production environments and take on the task of providing information about the general health of the system.

Trade-offs: DETAIL vs. PERFORMANCE

The choice between DEBUG and INFO log levels is essentially a matter of trade-off: more detail means more performance cost. The DEBUG level offers incredible detail by recording every step of an event, but these detailed records generate high volumes of data. This situation increases disk I/O operations, keeps the processor busier, and can ultimately lower the overall performance of the application.

For example, in a web application, dozens or even hundreds of DEBUG log lines can be generated during the processing of each request. If this application receives millions of requests per day, the size of the log files can quickly reach terabytes. This makes it difficult to analyze logs, increases storage costs, and can strain the log collection/processing infrastructure (e.g., ELK Stack, Grafana Loki). In one study, it was observed that a service where DEBUG logs were left on in production experienced a performance drop of up to 30% compared to the INFO level.

In contrast, the INFO level contains more limited information. This means less data is produced and therefore brings less performance cost. While INFO logs provide enough information to understand the general operation of the application, they create an acceptable load on the system. For this reason, higher levels like INFO, WARN, and ERROR are generally used in production environments, while the DEBUG level is only temporarily enabled for a specific debugging scenario.

⚠️ Risks of DEBUG Logs in Production

Leaving DEBUG logs continuously on in a production environment brings the following risks:

  • Performance Degradation: The application slowing down or becoming unresponsive due to excessive I/O and CPU usage.
  • Disk Space Exhaustion: Log files growing rapidly and filling up the disk space on the server.
  • Increased Costs: Rising costs for more storage space, more powerful servers, and log processing infrastructure.
  • Security Vulnerabilities: The risk of sensitive information (e.g., passwords, personal data) being accidentally recorded in `DEBUG` logs and falling into the hands of unauthorized persons.

Due to these risks, the DEBUG level should be used in production environments only in a controlled manner, for a specific period, and only when necessary.

Which Level in Which Situation? Real-Life Scenarios

The choice of log level varies according to the type of application, the development stage, and current operational requirements. Here are a few real-life scenarios:

Scenario 1: Developing a New Feature

I am developing a new payment gateway integration. This feature is complex and sensitive. During development, I want to see every step of the integration, the data sent and received, timeout situations, and error codes in detail. Keeping the DEBUG level active at this stage allows me to find the source of the problem quickly.

// Hypothetical DEBUG log example:
2026-05-16 04:05:10.100 DEBUG [com.example.payment.gateway.StripeAdapter:processPayment] - Sending payment request to Stripe: { "amount": 10000, "currency": "USD", "card_token": "tok_..." }
2026-05-16 04:05:11.500 DEBUG [com.example.payment.gateway.StripeAdapter:processPayment] - Received response from Stripe: { "status": "succeeded", "transaction_id": "pi_..." }
Enter fullscreen mode Exit fullscreen mode

However, when this feature first goes live in production, I will turn off the DEBUG level and pull it back to the INFO level. Seeing only that the payment was successfully processed or that an error occurred will be enough for me.

Scenario 2: Intermittent Error in a Production Service

For a few days, I've noticed that an application we use for customer service occasionally stops responding. No obvious error appears in the WARN and ERROR logs. In this case, to understand the source of the problem, I will temporarily turn on the DEBUG level and try to capture the moment the problem occurs. Maybe a database query is taking longer than expected, or maybe a call to an external API is hanging. DEBUG logs can reveal these kinds of hidden problems.

// Hypothetical DEBUG log example:
2026-05-16 04:10:00.000 DEBUG [com.example.crm.service.TicketService:getTicketDetails] - Fetching ticket details for ticket ID: 98765
2026-05-16 04:10:15.500 DEBUG [com.example.crm.service.TicketService:getTicketDetails] - Database query for ticket 98765 took 15.5 seconds.
Enter fullscreen mode Exit fullscreen mode

This 15.5-second query is an unacceptable situation. Once I have this information, I can focus on database optimization or rewriting the query. When the problem is resolved, I will turn off the DEBUG level again.

Scenario 3: Operational Status Tracking

I am monitoring the daily reporting module of a production ERP system. I need to know if this module runs successfully every day at 05:00. The INFO level is sufficient for this information.

// Hypothetical INFO log example:
2026-05-16 05:00:01.200 INFO [com.example.erp.reporting.ReportGenerator:generateDailySales] - Daily sales report generation started.
2026-05-16 05:05:30.800 INFO [com.example.erp.reporting.ReportGenerator:generateDailySales] - Daily sales report generated successfully. File path: /var/log/erp/reports/daily_sales_20260516.pdf
Enter fullscreen mode Exit fullscreen mode

If this report is not generated or an error occurs, the WARN or ERROR levels will kick in. I don't need the DEBUG level in this scenario.

Logging Configuration and Tools

The tools and configurations used to manage log levels vary according to the programming language and framework used. For example, Logback or Log4j are commonly used in Java, and the logging module is used in Python. These tools generally allow log levels to be set via a configuration file (e.g., logback.xml, logging.conf).

In these configuration files, it is determined which loggers will produce logs at which level. For example, while the default level for the entire application can be set to INFO, the DEBUG level can be enabled for specific packages or classes. This allows us to control the log level in a more granular way.

<!-- Example logback.xml configuration -->
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <logger name="com.example.payment" level="DEBUG"/> <!-- DEBUG level for payment module -->
    <logger name="com.example.user" level="INFO"/>  <!-- INFO level for user module -->

    <root level="INFO"> <!-- Global level INFO -->
        <appender-ref ref="STDOUT" />
    </root>
</configuration>
Enter fullscreen mode Exit fullscreen mode

Thanks to such configurations, it becomes possible to temporarily enable more detailed logging for specific modules even in a production environment. This both protects the overall performance of the system and offers the possibility of in-depth debugging when necessary.

ℹ️ Logging Configuration Tips

  • Default Level: Keep the default log level at higher levels like `INFO` or `WARN` in production.
  • Package-Based Settings: Define more detailed log levels for specific modules or packages.
  • Dynamic Adjustment: If possible, use tools that can change log levels at runtime (e.g., Spring Boot Actuator).
  • Log Format: Use a consistent format (timestamp, level, thread, logger name, message) so that logs are readable and analyzable.

Advanced Logging Techniques and Best Practices

Logging is not just about what we record; it's also about how we structure, collect, and analyze the information. The correct use of DEBUG and INFO levels should be part of a broader logging strategy.

Another important point is the content of the log messages. Even DEBUG messages should provide enough context about what is being recorded. For example, instead of just saying "Database error," more descriptive messages like "PRIMARY KEY violation while inserting data into user table: email 'test@example.com' already exists" should be written. This makes it easier to understand the cause of the error, especially when examining information at the DEBUG level.

Additionally, collecting logs in a central system (e.g., Elasticsearch, Splunk, Loki) and using tools to analyze these logs helps us identify problems faster. These systems offer features like filtering by log level, time series analysis, and anomaly detection. In this way, instead of missing a log at the ERROR level, we can proactively see trends and potential problems across the system.

Finally, the logging strategy should evolve throughout the application's lifecycle. While intensive development is done at the DEBUG level initially, this level should be reduced as it moves to production, but mechanisms should be maintained so that specific DEBUG logs can be enabled under certain conditions for critical modules. As I mentioned before, I touched on this subject more deeply in my [related: my-observability-journey] post. This balanced approach is the key to ensuring both development efficiency and production environment stability.

Conclusion: Logging Smartly

DEBUG and INFO log levels are the vital signs of an application. While DEBUG acts as a microscope to find the root cause of a problem, INFO is a pulse indicating the general health and normal operation of the system. The correct and strategic use of these two levels speeds up the development process, allows us to identify problems in production more easily, and helps us optimize system performance.

It should not be forgotten that excessively detailed logging (especially the DEBUG level being constantly open in production) can negatively affect system performance and increase costs. Therefore, it is essential to always strike a balance: don't hesitate to go into detail during the development phase, but record only the information that is truly necessary in the production environment. By configuring log levels wisely and following best practices, we can develop more robust, more performant, and more manageable applications.

Top comments (0)