← Назад к вопросам
Как реализовать логирование сервиса на Spring Boot?
1.6 Junior🔥 211 комментариев
#Spring Boot и Spring Data
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Как реализовать логирование сервиса на Spring Boot?
Логирование — это критическая часть любого production приложения. Оно помогает отслеживать события, ошибки и процессы выполнения. В Spring Boot используется SLF4J с Logback.
1. Встроенная конфигурация Spring Boot
Spring Boot автоматически настраивает Logback при добавлении зависимости.
// spring-boot-starter включает logging автоматически
2. Основные уровни логирования
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
@Service
public class UserService {
private static final Logger logger = LoggerFactory.getLogger(UserService.class);
public void processUser(String userId) {
logger.debug("Processing user: {}", userId);
try {
logger.info("User started processing", userId);
if (userId == null || userId.isEmpty()) {
logger.warn("User ID is empty");
}
} catch (Exception e) {
logger.error("Error processing user: {}", e.getMessage(), e);
}
}
}
Уровни (от менее к более серьезным):
- TRACE — наиболее детальная информация
- DEBUG — информация для отладки
- INFO — информационные сообщения
- WARN — предупреждения
- ERROR — ошибки
3. Конфигурация через application.yml
spring:
application:
name: myapp
logging:
level:
root: INFO
com.mycompany: DEBUG
org.springframework: WARN
pattern:
console: %d{yyyy-MM-dd HH:mm:ss} - %msg%n
file: %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
file:
name: logs/application.log
logback:
rollingpolicy:
max-file-size: 10MB
max-history: 30
4. Кастомная конфигурация logback-spring.xml
Создайте файл src/main/resources/logback-spring.xml для гибкой конфигурации:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n" />
<property name="LOG_PATH" value="logs" />
<property name="LOG_FILE" value="${LOG_PATH}/application.log" />
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${LOG_PATTERN}</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_FILE}</file>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/archived/application-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>1GB</totalSizeCap>
</rollingPolicy>
</appender>
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/error.log</file>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/archived/error-%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<logger name="com.mycompany" level="DEBUG" />
<logger name="org.springframework" level="INFO" />
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
<appender-ref ref="ERROR_FILE" />
</root>
</configuration>
5. Логирование с контекстом (MDC)
import org.springframework.stereotype.Component;
import org.slf4j.MDC;
import javax.servlet.Filter;
import java.util.UUID;
@Component
public class RequestLoggingFilter implements Filter {
private static final Logger logger = LoggerFactory.getLogger(RequestLoggingFilter.class);
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
String requestId = UUID.randomUUID().toString();
MDC.put("requestId", requestId);
try {
logger.info("Request started");
chain.doFilter(request, response);
} finally {
MDC.clear();
}
}
}
Обновите pattern: %d{yyyy-MM-dd HH:mm:ss} [%X{requestId}] %-5level %msg%n
6. Логирование в контроллере
@RestController
@RequestMapping("/api/users")
public class UserController {
private static final Logger logger = LoggerFactory.getLogger(UserController.class);
private final UserService userService;
@GetMapping("/{id}")
public ResponseEntity<UserDTO> getUser(@PathVariable Long id) {
logger.debug("Getting user by id: {}", id);
try {
UserDTO user = userService.findById(id);
logger.info("User found", id);
return ResponseEntity.ok(user);
} catch (UserNotFoundException e) {
logger.warn("User not found", id);
return ResponseEntity.notFound().build();
}
}
@PostMapping
public ResponseEntity<UserDTO> createUser(@RequestBody CreateUserRequest request) {
logger.info("Creating user");
try {
UserDTO user = userService.create(request);
logger.info("User created successfully");
return ResponseEntity.status(HttpStatus.CREATED).body(user);
} catch (Exception e) {
logger.error("Failed to create user", e);
throw e;
}
}
}
7. Логирование исключений
@Service
public class PaymentService {
private static final Logger logger = LoggerFactory.getLogger(PaymentService.class);
public void processPayment(String orderId, BigDecimal amount) {
try {
logger.info("Processing payment for order {}", orderId);
} catch (PaymentException e) {
logger.error("Payment processing failed: {}", e.getMessage(), e);
throw e;
} catch (Exception e) {
logger.error("Unexpected error during payment", e);
throw new PaymentException("Payment failed", e);
}
}
}
8. Async логирование для производительности
<appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender">
<queueSize>512</queueSize>
<discardingThreshold>0</discardingThreshold>
<appender-ref ref="FILE" />
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="ASYNC_FILE" />
</root>
9. Логирование в разные файлы
<logger name="com.mycompany.payment" level="DEBUG" additivity="false">
<appender-ref ref="PAYMENT_FILE" />
</logger>
<logger name="com.mycompany.user" level="DEBUG" additivity="false">
<appender-ref ref="USER_FILE" />
</logger>
Лучшие практики
- Используйте SLF4J — стандартная абстракция в Java
- Логируйте значимые события — старты, ошибки, завершения
- Не логируйте sensitive данные — пароли, токены, номера карт
- Используйте разные уровни — DEBUG для разработки, INFO для production
- Включайте контекст — requestId, userId для трассировки
- Логируйте исключения полностью — с stack trace для отладки
- Используйте ротацию логов — не заполняйте диск
- Параметризуйте логи — используйте {} плейсхолдеры вместо конкатенации
Таким образом, правильное логирование — это фундамент успешного мониторинга и отладки production приложений.