Quarkus core components - runtime library for the Cloud Native, Container First Java framework
—
The Logging System provides a simplified static logging facade with build-time optimization and multiple log levels for Quarkus applications.
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);
}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);
}
}
}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
}
}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
}
}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());
}
}
}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;
}
}
}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 ===");
}
}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
}
}Use level checking for expensive log message construction:
if (Log.isDebugEnabled()) {
Log.debug("Expensive operation result: " + expensiveCalculation());
}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);Avoid logging in hot paths unless necessary
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=DEBUGInstall with Tessl CLI
npx tessl i tessl/maven-io-quarkus--quarkus-core