openreplay/backend/pkg/handlers/custom/pageEventBuilder.go
Alexander d2a5f42e37
Dynatrace mock (#2745)
* feat(web): small changes in dynatrace + mock for testing

* feat(backend): undo dynatrace mock

* feat(backend): removed commented code from page builder

* feat(backend): added 404 for not found sql response in integrations
2024-11-14 16:06:17 +01:00

112 lines
2.7 KiB
Go

package custom
import (
"encoding/json"
"fmt"
. "openreplay/backend/pkg/messages"
)
const PageEventTimeout = 1 * 60 * 1000
type pageEventBuilder struct {
pageEvent *PageEvent
firstTimingHandled bool
webVitals map[string]string
}
func NewPageEventBuilder() *pageEventBuilder {
ieBuilder := &pageEventBuilder{}
return ieBuilder
}
func (b *pageEventBuilder) Handle(message Message, timestamp uint64) Message {
switch msg := message.(type) {
case *SetPageLocation:
if msg.NavigationStart == 0 { // routing without new page loading
return &PageEvent{
URL: msg.URL,
Referrer: msg.Referrer,
Loaded: false,
MessageID: message.MsgID(),
Timestamp: timestamp,
}
} else {
pageEvent := b.Build()
b.pageEvent = &PageEvent{
URL: msg.URL,
Referrer: msg.Referrer,
Loaded: true,
MessageID: message.MsgID(),
Timestamp: timestamp,
}
return pageEvent
}
case *PageLoadTiming:
if b.pageEvent == nil {
break
}
if msg.RequestStart <= 30000 {
b.pageEvent.RequestStart = msg.RequestStart
}
if msg.ResponseStart <= 30000 {
b.pageEvent.ResponseStart = msg.ResponseStart
}
if msg.ResponseEnd <= 30000 {
b.pageEvent.ResponseEnd = msg.ResponseEnd
}
if msg.DomContentLoadedEventStart <= 30000 {
b.pageEvent.DomContentLoadedEventStart = msg.DomContentLoadedEventStart
}
if msg.DomContentLoadedEventEnd <= 30000 {
b.pageEvent.DomContentLoadedEventEnd = msg.DomContentLoadedEventEnd
}
if msg.LoadEventStart <= 30000 {
b.pageEvent.LoadEventStart = msg.LoadEventStart
}
if msg.LoadEventEnd <= 30000 {
b.pageEvent.LoadEventEnd = msg.LoadEventEnd
}
if msg.FirstPaint <= 30000 {
b.pageEvent.FirstPaint = msg.FirstPaint
}
if msg.FirstContentfulPaint <= 30000 {
b.pageEvent.FirstContentfulPaint = msg.FirstContentfulPaint
}
return nil
case *PageRenderTiming:
if b.pageEvent == nil {
break
}
b.pageEvent.SpeedIndex = msg.SpeedIndex
b.pageEvent.VisuallyComplete = msg.VisuallyComplete
b.pageEvent.TimeToInteractive = msg.TimeToInteractive
return nil
case *WebVitals:
if b.webVitals == nil {
b.webVitals = make(map[string]string)
}
b.webVitals[msg.Name] = msg.Value
}
if b.pageEvent != nil && b.pageEvent.Timestamp+PageEventTimeout < timestamp {
return b.Build()
}
return nil
}
func (b *pageEventBuilder) Build() Message {
if b.pageEvent == nil {
return nil
}
pageEvent := b.pageEvent
b.pageEvent = nil
b.firstTimingHandled = false
if b.webVitals != nil {
if vitals, err := json.Marshal(b.webVitals); err == nil {
pageEvent.WebVitals = string(vitals)
} else {
fmt.Printf("Error marshalling web vitals: %v\n", err)
}
}
return pageEvent
}