* feat(backend): try a new approach for logs formatting (http) * feat(backend): added logger module * feat(backend): added project/session info to /i endpoint * feat(backend): found a solution for correct caller information * feat(backend): finished logs for http handlers * feat(backend): finished logs for mobile http handlers * feat(backend): finished ender * feat(backend): finished assets * feat(backend): finished heuristics * feat(backend): finished image-storage * feat(backend): finished sink * feat(backend): finished storage * feat(backend): formatted logs in all services * feat(backend): finished foss part * feat(backend): added missed foss part * feat(backend): fixed panic in memory manager and sink service * feat(backend): connectors
88 lines
1.9 KiB
Go
88 lines
1.9 KiB
Go
package web
|
|
|
|
import (
|
|
"encoding/json"
|
|
|
|
. "openreplay/backend/pkg/messages"
|
|
"openreplay/backend/pkg/messages/performance"
|
|
)
|
|
|
|
/*
|
|
Handler name: CpuIssue
|
|
Input events: PerformanceTrack,
|
|
SetPageLocation
|
|
Output event: IssueEvent
|
|
*/
|
|
|
|
const CpuThreshold = 70 // % out of 100
|
|
const CpuMinDurationTrigger = 6 * 1000
|
|
|
|
type CpuIssueDetector struct {
|
|
startTimestamp uint64
|
|
startMessageID uint64
|
|
lastTimestamp uint64
|
|
maxRate uint64
|
|
contextString string
|
|
}
|
|
|
|
func (f *CpuIssueDetector) createPayload() string {
|
|
p, err := json.Marshal(struct {
|
|
Duration uint64
|
|
Rate uint64
|
|
}{f.duration(), f.maxRate})
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
return string(p)
|
|
}
|
|
|
|
func (f *CpuIssueDetector) duration() uint64 {
|
|
return f.lastTimestamp - f.startTimestamp
|
|
}
|
|
|
|
func (f *CpuIssueDetector) reset() {
|
|
f.startTimestamp = 0
|
|
f.startMessageID = 0
|
|
f.maxRate = 0
|
|
}
|
|
|
|
func (f *CpuIssueDetector) Build() Message {
|
|
defer f.reset()
|
|
if f.startTimestamp == 0 || f.duration() < CpuMinDurationTrigger {
|
|
return nil
|
|
}
|
|
return &IssueEvent{
|
|
Type: "cpu",
|
|
Timestamp: f.startTimestamp,
|
|
MessageID: f.startMessageID,
|
|
ContextString: f.contextString,
|
|
Payload: f.createPayload(),
|
|
}
|
|
}
|
|
|
|
func (f *CpuIssueDetector) Handle(message Message, timestamp uint64) Message {
|
|
switch msg := message.(type) {
|
|
case *PerformanceTrack:
|
|
// Ignore if it's a wrong message order
|
|
if timestamp < f.lastTimestamp {
|
|
return nil
|
|
}
|
|
f.lastTimestamp = timestamp
|
|
cpuRate := performance.CPURate(msg.Ticks, performance.TimeDiff(timestamp, f.lastTimestamp))
|
|
// Build event if cpu issue have gone
|
|
if msg.Frames == -1 || msg.Ticks == -1 || cpuRate < CpuThreshold {
|
|
return f.Build()
|
|
}
|
|
// Update values
|
|
if f.startTimestamp == 0 {
|
|
f.startTimestamp = timestamp
|
|
f.startMessageID = message.MsgID()
|
|
}
|
|
if f.maxRate < cpuRate {
|
|
f.maxRate = cpuRate
|
|
}
|
|
case *SetPageLocation:
|
|
f.contextString = msg.URL
|
|
}
|
|
return nil
|
|
}
|