CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-quarkus--quarkus-core

Quarkus core components - runtime library for the Cloud Native, Container First Java framework

Pending
Overview
Eval results
Files

logging.mddocs/

Logging System

The Logging System provides a simplified static logging facade with build-time optimization and multiple log levels for Quarkus applications.

Static Logging Facade

Log Class

public final class Log {
    
    // Level checking methods
    /**
     * Check if TRACE level is enabled.
     * @return true if TRACE logging is enabled
     */
    public static boolean isTraceEnabled();
    
    /**
     * Check if DEBUG level is enabled.
     * @return true if DEBUG logging is enabled
     */
    public static boolean isDebugEnabled();
    
    /**
     * Check if INFO level is enabled.
     * @return true if INFO logging is enabled
     */
    public static boolean isInfoEnabled();
    
    /**
     * Check if WARN level is enabled.
     * @return true if WARN logging is enabled
     */
    public static boolean isWarnEnabled();
    
    /**
     * Check if ERROR level is enabled.
     * @return true if ERROR logging is enabled
     */
    public static boolean isErrorEnabled();
    
    /**
     * Check if FATAL level is enabled.
     * @return true if FATAL logging is enabled
     */
    public static boolean isFatalEnabled();
    
    /**
     * Check if specific log level is enabled.
     * @param level The log level to check
     * @return true if the specified level is enabled
     */
    public static boolean isEnabled(Logger.Level level);
    
    // TRACE level logging
    /**
     * Log a message at TRACE level.
     * @param message The message to log
     */
    public static void trace(Object message);
    
    /**
     * Log a message at TRACE level with throwable.
     * @param message The message to log
     * @param t The throwable to log
     */
    public static void trace(Object message, Throwable t);
    
    /**
     * Log a formatted message at TRACE level.
     * @param format The message format string
     * @param params The parameters for formatting
     */
    public static void tracef(String format, Object... params);
    
    /**
     * Log a formatted message at TRACE level using MessageFormat.
     * @param format The MessageFormat pattern
     * @param params The parameters for formatting
     */
    public static void tracev(String format, Object... params);
    
    // DEBUG level logging
    /**
     * Log a message at DEBUG level.
     * @param message The message to log
     */
    public static void debug(Object message);
    
    /**
     * Log a message at DEBUG level with throwable.
     * @param message The message to log
     * @param t The throwable to log
     */
    public static void debug(Object message, Throwable t);
    
    /**
     * Log a formatted message at DEBUG level.
     * @param format The message format string
     * @param params The parameters for formatting
     */
    public static void debugf(String format, Object... params);
    
    /**
     * Log a formatted message at DEBUG level using MessageFormat.
     * @param format The MessageFormat pattern
     * @param params The parameters for formatting
     */
    public static void debugv(String format, Object... params);
    
    // INFO level logging
    /**
     * Log a message at INFO level.
     * @param message The message to log
     */
    public static void info(Object message);
    
    /**
     * Log a message at INFO level with throwable.
     * @param message The message to log
     * @param t The throwable to log
     */
    public static void info(Object message, Throwable t);
    
    /**
     * Log a formatted message at INFO level.
     * @param format The message format string
     * @param params The parameters for formatting
     */
    public static void infof(String format, Object... params);
    
    /**
     * Log a formatted message at INFO level using MessageFormat.
     * @param format The MessageFormat pattern
     * @param params The parameters for formatting
     */
    public static void infov(String format, Object... params);
    
    // WARN level logging
    /**
     * Log a message at WARN level.
     * @param message The message to log
     */
    public static void warn(Object message);
    
    /**
     * Log a message at WARN level with throwable.
     * @param message The message to log
     * @param t The throwable to log
     */
    public static void warn(Object message, Throwable t);
    
    /**
     * Log a formatted message at WARN level.
     * @param format The message format string
     * @param params The parameters for formatting
     */
    public static void warnf(String format, Object... params);
    
    /**
     * Log a formatted message at WARN level using MessageFormat.
     * @param format The MessageFormat pattern
     * @param params The parameters for formatting
     */
    public static void warnv(String format, Object... params);
    
    // ERROR level logging
    /**
     * Log a message at ERROR level.
     * @param message The message to log
     */
    public static void error(Object message);
    
    /**
     * Log a message at ERROR level with throwable.
     * @param message The message to log
     * @param t The throwable to log
     */
    public static void error(Object message, Throwable t);
    
    /**
     * Log a formatted message at ERROR level.
     * @param format The message format string
     * @param params The parameters for formatting
     */
    public static void errorf(String format, Object... params);
    
    /**
     * Log a formatted message at ERROR level using MessageFormat.
     * @param format The MessageFormat pattern
     * @param params The parameters for formatting
     */
    public static void errorv(String format, Object... params);
    
    // FATAL level logging
    /**
     * Log a message at FATAL level.
     * @param message The message to log
     */
    public static void fatal(Object message);
    
    /**
     * Log a message at FATAL level with throwable.
     * @param message The message to log
     * @param t The throwable to log
     */
    public static void fatal(Object message, Throwable t);
    
    /**
     * Log a formatted message at FATAL level.
     * @param format The message format string
     * @param params The parameters for formatting
     */
    public static void fatalf(String format, Object... params);
    
    /**
     * Log a formatted message at FATAL level using MessageFormat.
     * @param format The MessageFormat pattern
     * @param params The parameters for formatting
     */
    public static void fatalv(String format, Object... params);
    
    // Generic logging methods
    /**
     * Log a message at the specified level.
     * @param level The log level
     * @param message The message to log
     */
    public static void log(Logger.Level level, Object message);
    
    /**
     * Log a message at the specified level with throwable.
     * @param level The log level
     * @param message The message to log
     * @param t The throwable to log
     */
    public static void log(Logger.Level level, Object message, Throwable t);
    
    /**
     * Log a formatted message at the specified level.
     * @param level The log level
     * @param format The message format string
     * @param params The parameters for formatting
     */
    public static void logf(Logger.Level level, String format, Object... params);
    
    /**
     * Log a formatted message at the specified level using MessageFormat.
     * @param level The log level
     * @param format The MessageFormat pattern
     * @param params The parameters for formatting
     */
    public static void logv(Logger.Level level, String format, Object... params);
}

Usage Examples

Basic Logging

import io.quarkus.logging.Log;
import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class UserService {
    
    public User findUser(Long id) {
        Log.info("Finding user with ID: " + id);
        
        try {
            User user = userRepository.findById(id);
            if (user != null) {
                Log.debug("Found user: " + user.getName());
                return user;
            } else {
                Log.warn("User not found with ID: " + id);
                return null;
            }
        } catch (Exception e) {
            Log.error("Error finding user with ID: " + id, e);
            throw new UserNotFoundException("Failed to find user", e);
        }
    }
    
    public void deleteUser(Long id) {
        Log.info("Attempting to delete user with ID: " + id);
        
        try {
            userRepository.deleteById(id);
            Log.info("Successfully deleted user with ID: " + id);
        } catch (Exception e) {
            Log.fatal("Critical error deleting user with ID: " + id, e);
            throw new RuntimeException("Failed to delete user", e);
        }
    }
}

Formatted Logging

import io.quarkus.logging.Log;
import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class OrderService {
    
    public void processOrder(Order order) {
        // Using printf-style formatting
        Log.infof("Processing order %d for customer %s with total $%.2f", 
                  order.getId(), order.getCustomerName(), order.getTotal());
        
        try {
            validateOrder(order);
            Log.debugf("Order %d validation successful", order.getId());
            
            chargePayment(order);
            Log.infof("Payment charged successfully for order %d: $%.2f", 
                      order.getId(), order.getTotal());
            
            fulfillOrder(order);
            Log.infof("Order %d fulfilled successfully", order.getId());
            
        } catch (ValidationException e) {
            Log.warnf("Order %d validation failed: %s", order.getId(), e.getMessage());
            throw e;
        } catch (PaymentException e) {
            Log.errorf("Payment failed for order %d: %s", order.getId(), e.getMessage());
            throw e;
        } catch (Exception e) {
            Log.fatalf("Critical error processing order %d", order.getId(), e);
            throw new RuntimeException("Order processing failed", e);
        }
    }
    
    private void validateOrder(Order order) {
        Log.tracef("Validating order %d with %d items", order.getId(), order.getItems().size());
        // Validation logic
    }
    
    private void chargePayment(Order order) {
        Log.debugf("Charging payment for order %d using method %s", 
                   order.getId(), order.getPaymentMethod());
        // Payment logic
    }
    
    private void fulfillOrder(Order order) {
        Log.debugf("Fulfilling order %d to address: %s", 
                   order.getId(), order.getShippingAddress());
        // Fulfillment logic
    }
}

MessageFormat-style Logging

import io.quarkus.logging.Log;
import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class ReportService {
    
    public void generateReport(String reportType, Date startDate, Date endDate) {
        // Using MessageFormat-style formatting
        Log.infov("Generating {0} report from {1,date,short} to {2,date,short}", 
                  reportType, startDate, endDate);
        
        try {
            int recordCount = countRecords(startDate, endDate);
            Log.debugv("Found {0,number,integer} records for report {1}", 
                       recordCount, reportType);
            
            if (recordCount == 0) {
                Log.warnv("No data found for {0} report between {1,date} and {2,date}", 
                          reportType, startDate, endDate);
                return;
            }
            
            generateReportFile(reportType, startDate, endDate, recordCount);
            Log.infov("Successfully generated {0} report with {1,number,integer} records", 
                      reportType, recordCount);
            
        } catch (Exception e) {
            Log.errorv("Failed to generate {0} report: {1}", reportType, e.getMessage(), e);
            throw new ReportGenerationException("Report generation failed", e);
        }
    }
    
    private int countRecords(Date startDate, Date endDate) {
        // Count records logic
        return 0;
    }
    
    private void generateReportFile(String reportType, Date startDate, Date endDate, int recordCount) {
        // Report generation logic
    }
}

Conditional Logging

import io.quarkus.logging.Log;
import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class DataProcessor {
    
    public void processLargeDataset(List<DataRecord> records) {
        Log.infof("Starting processing of %d records", records.size());
        
        int processedCount = 0;
        int errorCount = 0;
        
        for (DataRecord record : records) {
            try {
                // Only log debug info if debug is enabled (performance optimization)
                if (Log.isDebugEnabled()) {
                    Log.debugf("Processing record ID: %s, type: %s", 
                               record.getId(), record.getType());
                }
                
                processRecord(record);
                processedCount++;
                
                // Log progress every 1000 records
                if (processedCount % 1000 == 0) {
                    Log.infof("Processed %d/%d records", processedCount, records.size());
                }
                
            } catch (Exception e) {
                errorCount++;
                
                // Only log full stack trace for trace level
                if (Log.isTraceEnabled()) {
                    Log.trace("Detailed error processing record: " + record.getId(), e);
                } else {
                    Log.warnf("Error processing record %s: %s", record.getId(), e.getMessage());
                }
                
                // Stop processing if too many errors
                if (errorCount > 100) {
                    Log.errorf("Too many errors (%d), stopping processing", errorCount);
                    break;
                }
            }
        }
        
        Log.infof("Processing completed. Processed: %d, Errors: %d", processedCount, errorCount);
    }
    
    private void processRecord(DataRecord record) {
        // Record processing logic
        
        // Trace level for very detailed logging
        if (Log.isTraceEnabled()) {
            Log.tracef("Record %s validation: passed=%b, score=%.2f", 
                       record.getId(), record.isValid(), record.getQualityScore());
        }
    }
}

Generic Level Logging

import io.quarkus.logging.Log;
import org.jboss.logging.Logger;
import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class ConfigurableLogger {
    
    public void logMessage(String message, String levelName) {
        Logger.Level level = parseLogLevel(levelName);
        
        if (Log.isEnabled(level)) {
            Log.log(level, message);
        }
    }
    
    public void logFormattedMessage(String levelName, String format, Object... params) {
        Logger.Level level = parseLogLevel(levelName);
        
        if (Log.isEnabled(level)) {
            Log.logf(level, format, params);
        }
    }
    
    public void logWithException(String levelName, String message, Throwable throwable) {
        Logger.Level level = parseLogLevel(levelName);
        
        if (Log.isEnabled(level)) {
            Log.log(level, message, throwable);
        }
    }
    
    private Logger.Level parseLogLevel(String levelName) {
        try {
            return Logger.Level.valueOf(levelName.toUpperCase());
        } catch (IllegalArgumentException e) {
            Log.warnf("Invalid log level '%s', defaulting to INFO", levelName);
            return Logger.Level.INFO;
        }
    }
}

Application Lifecycle Logging

import io.quarkus.logging.Log;
import io.quarkus.runtime.StartupEvent;
import io.quarkus.runtime.ShutdownEvent;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.event.Observes;

@ApplicationScoped
public class ApplicationLifecycleLogger {
    
    void onStart(@Observes StartupEvent event) {
        Log.info("=== Application Starting ===");
        Log.infof("Java version: %s", System.getProperty("java.version"));
        Log.infof("OS: %s %s", System.getProperty("os.name"), System.getProperty("os.version"));
        Log.infof("Memory: Max=%dMB, Total=%dMB, Free=%dMB", 
                  Runtime.getRuntime().maxMemory() / 1024 / 1024,
                  Runtime.getRuntime().totalMemory() / 1024 / 1024,
                  Runtime.getRuntime().freeMemory() / 1024 / 1024);
        Log.info("=== Application Started ===");
    }
    
    void onStop(@Observes ShutdownEvent event) {
        Log.info("=== Application Shutting Down ===");
        
        if (event.isStandardShutdown()) {
            Log.info("Standard shutdown initiated");
        } else {
            Log.warn("Non-standard shutdown (signal received)");
        }
        
        // Log final statistics
        Runtime runtime = Runtime.getRuntime();
        Log.infof("Final memory usage: Used=%dMB, Free=%dMB", 
                  (runtime.totalMemory() - runtime.freeMemory()) / 1024 / 1024,
                  runtime.freeMemory() / 1024 / 1024);
        
        Log.info("=== Application Shutdown Complete ===");
    }
}

Error Handling with Logging

import io.quarkus.logging.Log;
import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class FileProcessor {
    
    public void processFile(String filename) {
        Log.infof("Starting file processing: %s", filename);
        
        try {
            validateFile(filename);
            parseFile(filename);
            processContent(filename);
            Log.infof("Successfully processed file: %s", filename);
            
        } catch (FileNotFoundException e) {
            Log.errorf("File not found: %s", filename, e);
            throw new ProcessingException("File not found: " + filename, e);
            
        } catch (SecurityException e) {
            Log.errorf("Access denied to file: %s", filename, e);
            throw new ProcessingException("Access denied: " + filename, e);
            
        } catch (IOException e) {
            Log.errorf("IO error processing file: %s - %s", filename, e.getMessage(), e);
            throw new ProcessingException("IO error: " + filename, e);
            
        } catch (Exception e) {
            Log.fatalf("Unexpected error processing file: %s", filename, e);
            throw new ProcessingException("Unexpected error: " + filename, e);
        }
    }
    
    private void validateFile(String filename) throws IOException {
        Log.debugf("Validating file: %s", filename);
        // Validation logic
    }
    
    private void parseFile(String filename) throws IOException {
        Log.debugf("Parsing file: %s", filename);
        // Parsing logic
    }
    
    private void processContent(String filename) {
        Log.debugf("Processing content from file: %s", filename);
        // Content processing logic
    }
}

Best Practices

Performance Optimization

  1. Use level checking for expensive log message construction:

    if (Log.isDebugEnabled()) {
        Log.debug("Expensive operation result: " + expensiveCalculation());
    }
  2. Use formatted logging instead of string concatenation:

    // Good
    Log.infof("User %s logged in at %s", username, timestamp);
    
    // Avoid
    Log.info("User " + username + " logged in at " + timestamp);
  3. Avoid logging in hot paths unless necessary

Log Level Guidelines

  • TRACE: Very detailed information, typically only of interest when diagnosing problems
  • DEBUG: Debug information, useful during development and troubleshooting
  • INFO: Informational messages that highlight the progress of the application
  • WARN: Potentially harmful situations that the application can handle
  • ERROR: Error events but the application can continue running
  • FATAL: Very severe error events that will likely lead to application termination

Configuration

Configure logging levels in application.properties:

# Root logger level
quarkus.log.level=INFO

# Package-specific levels
quarkus.log.category."com.mycompany.service".level=DEBUG
quarkus.log.category."io.quarkus.hibernate".level=WARN

# Console logging format
quarkus.log.console.format=%d{HH:mm:ss} %-5p [%c{2.}] (%t) %s%e%n

# File logging
quarkus.log.file.enable=true
quarkus.log.file.path=application.log
quarkus.log.file.level=DEBUG

Install with Tessl CLI

npx tessl i tessl/maven-io-quarkus--quarkus-core

docs

application-lifecycle.md

build-time.md

configuration.md

index.md

logging.md

native-image.md

runtime-context.md

tile.json