- Added comprehensive course structure with 11 modules - Included theoretical content, practical examples, and tasks - Multi-language code examples (Java, Rust, Node.js, Python) - Detailed analysis of architectural approaches and trade-offs - Complete caching strategies documentation - Architecture examples from real-world systems (Twitter, Netflix, Uber) - Structured navigation and learning path - Ready for educational use
6.6 KiB
6.6 KiB
Логирование
Навигация
Принципы логирования
1. Structured Logging
Определение: Логирование в структурированном формате (JSON).
Технический пример - Advanced Structured Logging:
@Slf4j
@RestController
public class OrderController {
@Autowired
private OrderService orderService;
@Autowired
private MetricsService metricsService;
@PostMapping("/orders")
public ResponseEntity<Order> 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
@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
# 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
{
"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
# fluent.conf
<source>
@type tail
path /var/log/application.log
pos_file /var/log/fluentd.log.pos
tag application.logs
format json
</source>
<filter application.logs>
@type record_transformer
<record>
service "order-service"
environment "production"
</record>
</filter>
<match application.logs>
@type elasticsearch
host elasticsearch
port 9200
index_name logs
type_name _doc
</match>