更新时延计算
This commit is contained in:
@@ -31,13 +31,14 @@ type Summary struct {
|
||||
BodySize int `json:"body_size"` //消息体大小(字节数)
|
||||
Timestamps map[string]int64 `json:"timestamps"` //事件时间戳,key 是事件名称,value 是 UnixNano 时间戳
|
||||
|
||||
AProcessingLatencyNS *int64 `json:"a_processing_latency_ns,omitempty"` // A 处理时延:A_TX_SCHED - A_APP_PREP_BEGIN
|
||||
AQueueLatencyNS *int64 `json:"a_queue_latency_ns,omitempty"` // A 排队时延:A_TX_SOFTWARE - A_TX_SCHED
|
||||
ABTransportPropagationBQueueLatencyNS *int64 `json:"a_b_transport_propagation_b_queue_latency_ns,omitempty"` // A-B 传输时延 + B 排队时延:B_APP_RECV - A_TX_SOFTWARE
|
||||
BKernelReceivePathLatencyNS *int64 `json:"b_kernel_receive_path_latency_ns,omitempty"` // B 内核接收路径近似:B_APP_RECV - B_RX_SOFTWARE
|
||||
BProcessingLatencyNS *int64 `json:"b_processing_latency_ns,omitempty"` // B 处理时延:B_PERSIST_END - B_APP_RECV
|
||||
EndToEndLatencyNS *int64 `json:"end_to_end_latency_ns,omitempty"` // 端到端时延:B_PERSIST_END - A_APP_PREP_BEGIN
|
||||
MissingTimestamps []string `json:"missing_timestamps,omitempty"` // 缺失的时间戳列表,包含 requiredTimestampNames 中但在原始事件中没有的事件名称
|
||||
AProcessingLatencyNS *int64 `json:"a_processing_latency_ns,omitempty"` // A 处理时延:A_TX_SCHED - A_APP_PREP_BEGIN
|
||||
AQueueLatencyNS *int64 `json:"a_queue_latency_ns,omitempty"` // A 排队时延:A_TX_SOFTWARE - A_TX_SCHED
|
||||
ABTransportPropagationNS *int64 `json:"a_b_transport_propagation_ns,omitempty"` // A-B 传输+传播时延近似:B_APP_RECV - A_TX_SOFTWARE
|
||||
BKernelReceivePathLatencyNS *int64 `json:"b_kernel_receive_path_latency_ns,omitempty"` // B 内核接收路径近似:B_APP_RECV - B_RX_SOFTWARE
|
||||
BProcessingLatencyNS *int64 `json:"b_processing_latency_ns,omitempty"` // B 处理时延:B_PERSIST_END - B_APP_RECV
|
||||
EndToEndLatencyNS *int64 `json:"end_to_end_latency_ns,omitempty"` // 端到端时延:B_PERSIST_END - A_APP_PREP_BEGIN
|
||||
ApproxRTTNS *int64 `json:"approx_rtt_ns,omitempty"` // 近似 RTT:首条反向应答的 B_APP_RECV - 当前请求的 A_TX_SOFTWARE
|
||||
MissingTimestamps []string `json:"missing_timestamps,omitempty"` // 缺失的时间戳列表,包含 requiredTimestampNames 中但在原始事件中没有的事件名称
|
||||
}
|
||||
|
||||
// LoadEventsFromFiles 从JSONL 原始日志文件中加载事件。
|
||||
@@ -132,9 +133,15 @@ func SummarizeEvents(events []Event) []Summary {
|
||||
}
|
||||
}
|
||||
|
||||
summaries := make([]Summary, 0, len(grouped))
|
||||
summaryPointers := make([]*Summary, 0, len(grouped))
|
||||
for _, summary := range grouped {
|
||||
completeSummary(summary) //补全时延指标和缺失时间戳信息
|
||||
summaryPointers = append(summaryPointers, summary)
|
||||
}
|
||||
assignApproxRTTs(summaryPointers)
|
||||
|
||||
summaries := make([]Summary, 0, len(summaryPointers))
|
||||
for _, summary := range summaryPointers {
|
||||
summaries = append(summaries, *summary)
|
||||
}
|
||||
//对整理结果进行排序,先按发送方、再按接收方、再按消息 ID、最后按消息类型排序,保证输出的稳定性和可读性。
|
||||
@@ -195,7 +202,7 @@ func completeSummary(summary *Summary) {
|
||||
summary.AQueueLatencyNS = value
|
||||
}
|
||||
if value := subtractIfPresent(summary.Timestamps, EventBAppRecv, EventATXSoftware); value != nil {
|
||||
summary.ABTransportPropagationBQueueLatencyNS = value
|
||||
summary.ABTransportPropagationNS = value
|
||||
}
|
||||
if value := subtractIfPresent(summary.Timestamps, EventBAppRecv, EventBRXSoftware); value != nil {
|
||||
summary.BKernelReceivePathLatencyNS = value
|
||||
@@ -208,6 +215,90 @@ func completeSummary(summary *Summary) {
|
||||
}
|
||||
}
|
||||
|
||||
type routeKey struct {
|
||||
From string
|
||||
To string
|
||||
}
|
||||
|
||||
func assignApproxRTTs(summaries []*Summary) {
|
||||
grouped := make(map[routeKey][]*Summary)
|
||||
for _, summary := range summaries {
|
||||
grouped[routeKey{From: summary.From, To: summary.To}] = append(grouped[routeKey{From: summary.From, To: summary.To}], summary)
|
||||
}
|
||||
|
||||
for key, requests := range grouped {
|
||||
replies := grouped[routeKey{From: key.To, To: key.From}]
|
||||
if len(replies) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
assignApproxRTTsForRoute(
|
||||
sortSummariesByTimestamp(requests, EventBAppRecv),
|
||||
sortSummariesByTimestamp(replies, EventATXSoftware),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func assignApproxRTTsForRoute(requests, replies []*Summary) {
|
||||
replyIndex := 0
|
||||
for _, request := range requests {
|
||||
requestReceivedAtResponder, ok := request.Timestamps[EventBAppRecv]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
for replyIndex < len(replies) {
|
||||
reply := replies[replyIndex]
|
||||
replySentAtResponder, ok := reply.Timestamps[EventATXSoftware]
|
||||
if !ok {
|
||||
replyIndex++
|
||||
continue
|
||||
}
|
||||
if replySentAtResponder < requestReceivedAtResponder {
|
||||
replyIndex++
|
||||
continue
|
||||
}
|
||||
|
||||
if value := subtractSummaryTimestamps(reply, EventBAppRecv, request, EventATXSoftware); value != nil {
|
||||
request.ApproxRTTNS = value
|
||||
}
|
||||
replyIndex++
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func sortSummariesByTimestamp(summaries []*Summary, eventName string) []*Summary {
|
||||
sorted := append([]*Summary(nil), summaries...)
|
||||
sort.SliceStable(sorted, func(i, j int) bool {
|
||||
leftTS, leftOK := sorted[i].Timestamps[eventName]
|
||||
rightTS, rightOK := sorted[j].Timestamps[eventName]
|
||||
switch {
|
||||
case leftOK && rightOK:
|
||||
if leftTS != rightTS {
|
||||
return leftTS < rightTS
|
||||
}
|
||||
case leftOK:
|
||||
return true
|
||||
case rightOK:
|
||||
return false
|
||||
}
|
||||
|
||||
if sorted[i].MessageID != sorted[j].MessageID {
|
||||
return sorted[i].MessageID < sorted[j].MessageID
|
||||
}
|
||||
if sorted[i].From != sorted[j].From {
|
||||
return sorted[i].From < sorted[j].From
|
||||
}
|
||||
if sorted[i].To != sorted[j].To {
|
||||
return sorted[i].To < sorted[j].To
|
||||
}
|
||||
|
||||
return sorted[i].MessageType < sorted[j].MessageType
|
||||
})
|
||||
return sorted
|
||||
}
|
||||
|
||||
// 返回 requiredTimestampNames 中哪些在给定的 timestamps 中缺失。
|
||||
func missingTimestampNames(timestamps map[string]int64) []string {
|
||||
var missing []string
|
||||
@@ -235,6 +326,20 @@ func subtractIfPresent(timestamps map[string]int64, endName, beginName string) *
|
||||
return &value
|
||||
}
|
||||
|
||||
func subtractSummaryTimestamps(endSummary *Summary, endName string, beginSummary *Summary, beginName string) *int64 {
|
||||
end, ok := endSummary.Timestamps[endName]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
begin, ok := beginSummary.Timestamps[beginName]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
value := end - begin
|
||||
return &value
|
||||
}
|
||||
|
||||
// 判断事件是否是业务相关的时延事件(其中一项)
|
||||
func IsBusinessEvent(event Event) bool {
|
||||
switch event.Event {
|
||||
|
||||
Reference in New Issue
Block a user