- 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
239 lines
6.6 KiB
Markdown
239 lines
6.6 KiB
Markdown
# Логирование
|
|
|
|
## Навигация
|
|
- [🏠 Главная страница курса](../../../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<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
|
|
```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
|
|
<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>
|
|
```
|