# Логирование ## Навигация - [🏠 Главная страница курса](../../../README.md) - [📚 Модуль 5](../README.md) --- ## Принципы логирования ### 1. Structured Logging **Определение:** Логирование в структурированном формате (JSON). **Технический пример - Advanced Structured Logging:** ```java @Slf4j @RestController public class OrderController { @Autowired private OrderService orderService; @Autowired private MetricsService metricsService; @PostMapping("/orders") public ResponseEntity createOrder(@RequestBody CreateOrderRequest request) { String correlationId = MDC.get("correlationId"); String userId = MDC.get("userId"); // Structured logging with business context log.info("Order creation started", StructuredLogging.builder() .correlationId(correlationId) .userId(userId) .customerId(request.getCustomerId()) .orderValue(request.getTotalValue()) .itemsCount(request.getItems().size()) .currency(request.getCurrency()) .paymentMethod(request.getPaymentMethod()) .build() ); Timer.Sample sample = Timer.start(); try { Order order = orderService.createOrder(request); // Success logging with performance metrics Duration duration = Duration.ofNanos(sample.stop()); log.info("Order created successfully", StructuredLogging.builder() .correlationId(correlationId) .userId(userId) .orderId(order.getId()) .customerId(request.getCustomerId()) .status(order.getStatus()) .processingTimeMs(duration.toMillis()) .build() ); // Record business metrics metricsService.recordBusinessEvent("order_created", userId); metricsService.recordOrderValue(request.getTotalValue(), request.getCurrency()); return ResponseEntity.ok(order); } catch (ValidationException e) { log.warn("Order validation failed", StructuredLogging.builder() .correlationId(correlationId) .userId(userId) .customerId(request.getCustomerId()) .errorType("validation_error") .errorMessage(e.getMessage()) .validationErrors(e.getValidationErrors()) .build() ); return ResponseEntity.badRequest().body(new ErrorResponse(e.getMessage())); } catch (PaymentException e) { log.error("Payment processing failed", StructuredLogging.builder() .correlationId(correlationId) .userId(userId) .customerId(request.getCustomerId()) .errorType("payment_error") .errorMessage(e.getMessage()) .paymentMethod(request.getPaymentMethod()) .orderValue(request.getTotalValue()) .build() ); return ResponseEntity.status(HttpStatus.PAYMENT_REQUIRED) .body(new ErrorResponse("Payment processing failed")); } catch (Exception e) { log.error("Unexpected error during order creation", StructuredLogging.builder() .correlationId(correlationId) .userId(userId) .customerId(request.getCustomerId()) .errorType("system_error") .errorMessage(e.getMessage()) .stackTrace(getStackTrace(e)) .build() ); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body(new ErrorResponse("Internal server error")); } } } ``` ### 2. Log Levels - **ERROR** — критические ошибки - **WARN** — предупреждения - **INFO** — информационные сообщения - **DEBUG** — отладочная информация - **TRACE** — детальная трассировка ### 3. Correlation ID ```java @Component public class CorrelationIdFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; String correlationId = httpRequest.getHeader("X-Correlation-ID"); if (correlationId == null) { correlationId = UUID.randomUUID().toString(); } MDC.put("correlationId", correlationId); try { chain.doFilter(request, response); } finally { MDC.clear(); } } } ``` ## ELK Stack (Elasticsearch, Logstash, Kibana) ### Конфигурация Logstash ```ruby # logstash.conf input { beats { port => 5044 } } filter { if [fields][service] == "order-service" { grok { match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} %{GREEDYDATA:message}" } } date { match => [ "timestamp", "ISO8601" ] } } } output { elasticsearch { hosts => ["elasticsearch:9200"] index => "logs-%{+YYYY.MM.dd}" } } ``` ### Шаблон индекса Elasticsearch ```json { "index_patterns": ["logs-*"], "template": { "settings": { "number_of_shards": 1, "number_of_replicas": 1 }, "mappings": { "properties": { "@timestamp": { "type": "date" }, "level": { "type": "keyword" }, "message": { "type": "text" }, "correlationId": { "type": "keyword" }, "service": { "type": "keyword" } } } } } ``` ## Fluentd ```ruby # fluent.conf @type tail path /var/log/application.log pos_file /var/log/fluentd.log.pos tag application.logs format json @type record_transformer service "order-service" environment "production" @type elasticsearch host elasticsearch port 9200 index_name logs type_name _doc ```