chore(logging): 降噪 PDD 同步与发单消费者常态日志

将无新单/全跳过的处理完成日志降到 debug,并压缩 decisions 详情,避免 app 日志被按日切碎。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
yml2213
2026-09-15 13:48:30 +08:00
co-authored by Cursor
parent 40c51e1d8e
commit 40278a68fc
5 changed files with 111 additions and 48 deletions
@@ -17,7 +17,7 @@ import {
publishWorkOrderRealtimeChange,
} from '../realtime/realtime-event-service.js'
import { nowIso } from '../../utils/time.js'
import { logInfo, logIntegration, logWarn } from '../../utils/logger.js'
import { logDebug, logInfo, logIntegration, logWarn } from '../../utils/logger.js'
import { createHttpError } from '../../utils/http.js'
import type { OrderItemRow, OrderRow, TaskRow } from '../../types/repository/rows.js'
@@ -211,21 +211,14 @@ export async function upsertOrderFromSource(
source: `${sourceLabel}_order_upsert`,
autoOnly: true,
})
logInfo('[order-consumer-router]', '来源订单消费者分流完成', {
logDebug('[order-consumer-router]', '来源订单消费者分流完成(履约未就绪)', {
source: sourceLabel,
orderId: order.id,
platformOrderId: order.platform_order_id,
fulfillment: {
result: 'blocked',
reason: readiness.blockReason,
detail: readiness.reason,
orderItemIds: configuredOrderItems.map((item) => item.id),
},
workerPlatform: {
createdCount: workOrderSync.createdCount,
skippedCount: workOrderSync.skippedCount,
decisions: workOrderSync.decisions,
},
fulfillmentResult: 'blocked',
fulfillmentReason: readiness.blockReason || readiness.reason,
workerCreatedCount: workOrderSync.createdCount,
workerSkippedCount: workOrderSync.skippedCount,
})
publishSourceOrderRealtimeChanges(order.id, workOrderSync.created)
return {
@@ -353,33 +346,61 @@ function logOrderConsumerOutcome({
source: sourceLabel,
orderId: order.id,
platformOrderId: order.platform_order_id,
fulfillment: {
configuredOrderItemIds: Array.from(configuredItemIds),
taskIds: tasks.map((task) => task.id),
taskCount: tasks.length,
missingItems: missingFulfillmentItems,
},
workerPlatform: {
createdCount: workerCreatedCount,
skippedCount: workerSkippedCount,
decisions: workerDecisions,
},
dualConsumedOrderItemIds,
unhandledOrderItems,
fulfillmentTaskCount: tasks.length,
fulfillmentConfiguredCount: configuredItemIds.size,
fulfillmentMissingCount: missingFulfillmentItems.length,
workerCreatedCount,
workerSkippedCount,
workerSkipReasons: summarizeWorkerDecisionReasons(workerDecisions),
dualConsumedCount: dualConsumedOrderItemIds.length,
unhandledCount: unhandledOrderItems.length,
}
const hasSignal =
workerCreatedCount > 0 ||
tasks.length > 0 ||
missingFulfillmentItems.length > 0 ||
dualConsumedOrderItemIds.length > 0
// 常态 PDD 重拉:无履约任务、工单全跳过,仅 debug;避免 decisions 大对象撑爆日志文件。
if (hasSignal) {
logInfo('[order-consumer-router]', '来源订单消费者分流完成', detail)
} else {
logDebug('[order-consumer-router]', '来源订单消费者分流完成', detail)
}
logInfo('[order-consumer-router]', '来源订单消费者分流完成', detail)
if (missingFulfillmentItems.length > 0) {
logWarn('[order-consumer-router]', '已配置履约的订单项存在任务缺口', detail)
logWarn('[order-consumer-router]', '已配置履约的订单项存在任务缺口', {
...detail,
missingItems: missingFulfillmentItems.slice(0, 5),
})
}
if (dualConsumedOrderItemIds.length > 0) {
logWarn('[order-consumer-router]', '同一订单项被履约与发单平台消费者同时接收', detail)
logWarn('[order-consumer-router]', '同一订单项被履约与发单平台消费者同时接收', {
...detail,
dualConsumedOrderItemIds: dualConsumedOrderItemIds.slice(0, 20),
})
}
// 「未匹配接单规则」对大量 PDD 商品是常态,降到 debug;真正的缺口用上面的 missing 告警。
if (unhandledOrderItems.length > 0) {
logWarn('[order-consumer-router]', '订单项未被履约或发单平台消费者接收', detail)
logDebug('[order-consumer-router]', '订单项未被履约或发单平台消费者接收', {
...detail,
unhandledSkuCodes: unhandledOrderItems
.slice(0, 10)
.map((item) => String(item.skuCode || item.skuName || item.orderItemId)),
})
}
}
function summarizeWorkerDecisionReasons(decisions: Array<Record<string, unknown>>) {
const counts: Record<string, number> = {}
for (const decision of decisions) {
const reason = String(decision.reason || decision.result || 'unknown').trim() || 'unknown'
counts[reason] = (counts[reason] || 0) + 1
}
return Object.keys(counts).length > 0 ? JSON.stringify(counts) : ''
}
function resolveOrderItemRouteDiagnostic(item: OrderItemRow) {
const snapshot = parseOrderItemSnapshot(item.item_snapshot_json) || {}
const sendCode =