Невозможно исправить то, чего не видишь. В современной распределенной системе электронной коммерции процесс оформления заказа затрагивает множество сервисов: от интерфейсного пользовательского интерфейса до серверных API, платежных шлюзов и систем инвентаризации. Сбои, проблемы с производительностью или непредвиденные задержки часто скрываются в промежутках между этими компонентами.
Вот где оперативная наблюдаемость становится критическим. Используя Аналитика приложений Azure Используя существующую структурированную регистрацию, вы можете обеспечить полезную и сквозную прозрачность каждой транзакции оформления заказа.
Что отслеживать
- Действия страницы/контроллера: вход/выход, сбои проверки.
- Оркестрация платежей: вызов шлюза, результат, задержка, таймауты.
- Деловые события: создана корзина, сохранена информация о бронировании, создан заказ.
- Ключи корреляции: CartReference, PaymentMethod, атрибуты пользователя/устройства.
Давайте настроим и закодируем
- Application Insights настроен:
ApplicationInsights":{
"ConnectionString": "InstrumentationKey={my_key};IngestionEndpoint= {applicationinsights_endpoint}"
}
- Checkout регистрирует ключевые хлебные крошки со ссылкой на корзину (отлично подходит для корреляции)
Примечание: В этой реализации carsReference используется в качестве мета-ключа для идентификации и отслеживания каждого сеанса корзины/оформления заказа с помощью телеметрии. Вы можете заменить его любым пользовательским ключом/значением, соответствующим модели вашего домена (например, orderId, sessionId, checkoutId).
Вход:
_fluentLogger
.Data(("CartReference", cart.GetCartReference()),
("BookingInfo", model.BookingInfo))
.LogInfo("Booking calendar");
return View(GetViewPath(currentPage), model);
Выход:
_fluentLogger
.Data((nameof(checkoutBookingInfo), checkoutBookingInfo),
("CartReference", cart.GetCartReference()))
.LogInfo("Booking POST");
Добавьте расширенную телеметрию с корреляцией
Используйте carReference в качестве основного свойства корреляции между журналами, трассировками и метриками. Если вы уже используете ILogger (или Serilog) с экспортом AI, расширьте область применения; в противном случае отправьте пользовательские события через код TelemetryClient.New (пример шаблона):
using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.DataContracts;
public class CheckoutTelemetryService
{
private readonly TelemetryClient _telemetryClient;
public CheckoutTelemetryService(TelemetryClient telemetryClient)
{
_telemetryClient = telemetryClient ?? throw new ArgumentNullException(nameof(telemetryClient));
}
///
/// Tracks a specific step in the checkout process.
///
/// Name of the checkout step (e.g., "cartValidation").
/// Unique identifier for the cart.
/// Optional custom properties.
/// Optional duration of the step in milliseconds.
public void TrackCheckoutStep(
string stepName,
string cartReference,
IDictionary? properties = null,
double? durationMs = null)
{
var telemetryEvent = new EventTelemetry($"checkout_{stepName}");
telemetryEvent.Properties["cartReference"] = cartReference;
if (properties != null)
{
foreach (var kvp in properties)
{
telemetryEvent.Properties[kvp.Key] = kvp.Value;
}
}
if (durationMs.HasValue)
{
telemetryEvent.Metrics["duration_ms"] = durationMs.Value;
}
_telemetryClient.TrackEvent(telemetryEvent);
}
///
/// Starts a dependency telemetry operation, such as payment or inventory check.
///
/// Name of the dependency operation.
/// Cart reference ID.
/// Outputs the created DependencyTelemetry object.
/// IDisposable to stop the operation when disposed.
public IDisposable StartDependencyOperation(
string dependencyName,
string cartReference,
out DependencyTelemetry dependency)
{
dependency = new DependencyTelemetry("checkoutDependency", dependencyName, DateTimeOffset.UtcNow, TimeSpan.Zero, success: true);
dependency.Properties["cartReference"] = cartReference;
return new TelemetryOperation(_telemetryClient, dependency);
}
///
/// Helper class to manage the lifetime of telemetry operations.
///
private sealed class TelemetryOperation : IDisposable
{
private readonly TelemetryClient _telemetryClient;
private readonly IOperationHolder _operationHolder;
public TelemetryOperation(TelemetryClient telemetryClient, DependencyTelemetry telemetry)
{
_telemetryClient = telemetryClient ?? throw new ArgumentNullException(nameof(telemetryClient));
_operationHolder = _telemetryClient.StartOperation(telemetry);
}
public void Dispose()
{
_telemetryClient.StopOperation(_operationHolder);
}
}
}
Используйте его в путях оформления заказа/оплаты:
var cartRef = cart.GetCartReference();
_checkoutTelemetry.TrackCheckoutStep("shipping_viewed", cartRef, new Dictionary {
["device"] = Request.Headers["User-Agent"].ToString().Contains("Mobile") ? "mobile" : "desktop"
});
Вокруг платежного звонка
using (_checkoutTelemetry.StartDependencyOperation("bank_charge", cartRef, out var dep))
{
var sw = Stopwatch.StartNew();
var result = await _paymentService.ProcessBankCheckoutAsync(chargeId, transactionId, cartRef);
sw.Stop();
dep.Duration = sw.Elapsed;
dep.Success = result.Success;
dep.Properties["paymentMethod"] = "CreditCard";
dep.Properties["timeout"] = result.Timeout.ToString();
_checkoutTelemetry.TrackStep("payment_processed", cartRef, new Dictionary{
["paymentMethod"] = "CreditCard",
["errorType"] = result.ErrorType.ToString()
}, sw.Elapsed.TotalMilliseconds);
}
Примеры запросов Kusto (копипаста в журналах):
- Комплексное решение для одной тележки:
union traces, customEvents, dependencies, requests
| extend cartReference = tostring(customDimensions.cartReference)
| where isnotempty(cartReference) and cartReference == ""
| project timestamp, itemType = itemType, name, message, resultCode, success, duration, cartReference, customDimensions
| order by timestamp asc
dependencies
| where type == "payment"
| summarize count(), failures = countif(success == false), p95=percentile(duration,95) by name, bin(timestamp, 5m)
| extend failureRate = todouble(failures) / todouble(count())
- Узкие места при оформлении заказа по шагам:
customEvents
| where name startswith "checkout_"
| summarize p95=percentile(todouble(tostring(customMeasurements["duration_ms"])),95)
, count() by name
| order by p95 desc
Ограждения
- Не регистрируйте личные данные и свойства белого списка. Рассматривайте carReference как не-PII.
- При необходимости выбирайте массовые мероприятия; никогда не отбрасывайте пути ошибок.
- Защитите строку подключения AI с помощью секретов/Key Vault; избегайте обычного текста в конфигурации.
Результаты
- Быстрая основная причина: сопоставьте неудачный платеж клиента с помощью контроллера, зависимостей и пользовательских событий.
- Анализ тенденций: выявляйте деградацию шлюза и тайм-ауты до падения конверсии.
- Измеримые улучшения: сокращение MTTR (среднего времени решения/восстановления) и отказов от платежей, связанных с целевыми исправлениями.
19 ноября 2025 г.
По теме

