1
0
Fork 0
mirror of https://github.com/anyproto/anytype-heart.git synced 2025-06-10 18:10:49 +09:00
anytype-heart/metrics/events.go
2023-04-25 18:17:59 +02:00

476 lines
11 KiB
Go

package metrics
import (
"fmt"
)
const CtxKeyRequest = "request"
type RecordAcceptEventAggregated struct {
IsNAT bool
RecordType string
Count int
}
func (r RecordAcceptEventAggregated) ToEvent() *Event {
return &Event{
EventType: "thread_record_accepted",
EventData: map[string]interface{}{
"record_type": r.RecordType,
"is_nat": r.IsNAT,
"count": r.Count,
},
}
}
func (r RecordAcceptEventAggregated) Key() string {
return fmt.Sprintf("RecordAcceptEventAggregated%s%v", r.RecordType, r.IsNAT)
}
func (r RecordAcceptEventAggregated) Aggregate(other EventAggregatable) EventAggregatable {
ev, ok := other.(RecordAcceptEventAggregated)
// going here we already check the keys, so let's not do this another time
if !ok {
return r
}
r.Count += ev.Count
return r
}
type ChangesetEvent struct {
Diff int64
}
func (c ChangesetEvent) ToEvent() *Event {
return &Event{
EventType: "changeset_applied",
EventData: map[string]interface{}{
// we send diff, and not timestamps of records, because we cannot filter
// them in Amplitude (unless we will have access to SQL there)
"diff_current_time_vs_first": c.Diff,
},
}
}
type ReindexType int
const (
ReindexTypeThreads ReindexType = iota
ReindexTypeFiles
ReindexTypeBundledRelations
ReindexTypeBundledTypes
ReindexTypeBundledObjects
ReindexTypeBundledTemplates
ReindexTypeOutdatedHeads
)
func (t ReindexType) String() string {
switch t {
case ReindexTypeThreads:
return "threads"
case ReindexTypeFiles:
return "files"
case ReindexTypeBundledRelations:
return "bundled_relations"
case ReindexTypeBundledTypes:
return "bundled_types"
case ReindexTypeBundledObjects:
return "bundled_objects"
case ReindexTypeBundledTemplates:
return "bundled_templates"
case ReindexTypeOutdatedHeads:
return "outdated_heads"
}
return "unknown"
}
const IndexEventThresholdMs = 10
type IndexEvent struct {
ObjectId string
IndexLinksTimeMs int64
IndexDetailsTimeMs int64
IndexSetRelationsTimeMs int64
RelationsCount int
DetailsCount int
SetRelationsCount int
}
func (c IndexEvent) ToEvent() *Event {
if c.IndexLinksTimeMs+c.IndexDetailsTimeMs+c.IndexSetRelationsTimeMs < IndexEventThresholdMs {
return nil
}
return &Event{
EventType: "index",
EventData: map[string]interface{}{
"object_id": c.ObjectId,
"links_ms": c.IndexLinksTimeMs,
"details_ms": c.IndexDetailsTimeMs,
"set_ms": c.IndexSetRelationsTimeMs,
"rel_count": c.RelationsCount,
"det_count": c.DetailsCount,
"set_rel_count": c.SetRelationsCount,
"total_ms": c.IndexLinksTimeMs + c.IndexDetailsTimeMs + c.IndexSetRelationsTimeMs,
},
}
}
const ReindexEventThresholdsMs = 100
type ReindexEvent struct {
ReindexType ReindexType
Total int
Success int
SpentMs int
IndexesRemoved bool
}
func (c ReindexEvent) ToEvent() *Event {
if c.SpentMs < ReindexEventThresholdsMs {
return nil
}
return &Event{
EventType: "store_reindex",
EventData: map[string]interface{}{
"spent_ms": c.SpentMs,
"total": c.Total,
"failed": c.Total - c.Success,
"type": c.ReindexType,
"ix_removed": c.IndexesRemoved,
},
}
}
const RecordCreateEventThresholdMs = 30
type RecordCreateEvent struct {
PrepareMs int64
NewRecordMs int64
LocalEventBusMs int64
PushMs int64
ThreadId string
}
func (c RecordCreateEvent) ToEvent() *Event {
if c.PrepareMs+c.NewRecordMs+c.LocalEventBusMs+c.PushMs < RecordCreateEventThresholdMs {
return nil
}
return &Event{
EventType: "record_create",
EventData: map[string]interface{}{
"thread_id": c.ThreadId,
"prepare_ms": c.PrepareMs,
"new_record_ms": c.NewRecordMs,
"local_ms": c.LocalEventBusMs,
"push_ms": c.PushMs,
"total_ms": c.PrepareMs + c.NewRecordMs + c.LocalEventBusMs + c.PushMs,
},
}
}
type DifferentAddresses struct {
LocalEdge uint64
RemoteEdge uint64
PeerId string
ThreadId string
}
func (c DifferentAddresses) ToEvent() *Event {
return nil // TODO: temporary disabled. Need to accumulate statistic on client
}
type DifferentHeads struct {
LocalEdge uint64
RemoteEdge uint64
PeerId string
ThreadId string
}
func (c DifferentHeads) ToEvent() *Event {
return nil // TODO: temporary disabled. Need to accumulate statistic on client
}
type BlockSplit struct {
AlgorithmMs int64
ApplyMs int64
ObjectId string
}
func (c BlockSplit) ToEvent() *Event {
return &Event{
EventType: "block_merge",
EventData: map[string]interface{}{
"object_id": c.ObjectId,
"algorithm_ms": c.AlgorithmMs,
"apply_ms": c.ApplyMs,
"total_ms": c.AlgorithmMs + c.ApplyMs,
},
}
}
type TreeBuild struct {
SbType uint64
TimeMs int64
ObjectId string
Logs int
Request string
RecordsLoaded int
RecordsMissing int
RecordsFailed int
InProgress bool
}
func (c TreeBuild) ToEvent() *Event {
return &Event{
EventType: "tree_build",
EventData: map[string]interface{}{
"object_id": c.ObjectId,
"logs": c.Logs,
"request": c.Request,
"records_loaded": c.RecordsLoaded,
"records_missing": c.RecordsMissing,
"records_failed": c.RecordsFailed,
"time_ms": c.TimeMs,
"sb_type": c.SbType,
"in_progress": c.InProgress,
},
}
}
const StateApplyThresholdMs = 100
type StateApply struct {
BeforeApplyMs int64
StateApplyMs int64
PushChangeMs int64
ReportChangeMs int64
ApplyHookMs int64
ObjectId string
}
func (c StateApply) ToEvent() *Event {
total := c.StateApplyMs + c.PushChangeMs + c.BeforeApplyMs + c.ApplyHookMs + c.ReportChangeMs
if total <= StateApplyThresholdMs {
return nil
}
return &Event{
EventType: "state_apply",
EventData: map[string]interface{}{
"before_ms": c.BeforeApplyMs,
"apply_ms": c.StateApplyMs,
"push_ms": c.PushChangeMs,
"report_ms": c.ReportChangeMs,
"hook_ms": c.ApplyHookMs,
"object_id": c.ObjectId,
"total_ms": c.StateApplyMs + c.PushChangeMs + c.BeforeApplyMs + c.ApplyHookMs + c.ReportChangeMs,
},
}
}
type AppStart struct {
Request string
TotalMs int64
PerCompMs map[string]int64
}
func (c AppStart) ToEvent() *Event {
return &Event{
EventType: "app_start",
EventData: map[string]interface{}{
"request": c.Request,
"time_ms": c.TotalMs,
"per_comp": c.PerCompMs,
},
}
}
type InitPredefinedBlocks struct {
TimeMs int64
}
func (c InitPredefinedBlocks) ToEvent() *Event {
return &Event{
EventType: "init_predefined_blocks",
EventData: map[string]interface{}{
"time_ms": c.TimeMs,
},
}
}
type InitPredefinedBlock struct {
SbType int
TimeMs int64
ObjectId string
}
func (c InitPredefinedBlock) ToEvent() *Event {
return &Event{
EventType: "init_predefined_block",
EventData: map[string]interface{}{
"time_ms": c.TimeMs,
"sb_type": c.SbType,
"object_id": c.ObjectId,
},
}
}
type BlockMerge struct {
AlgorithmMs int64
ApplyMs int64
ObjectId string
}
func (c BlockMerge) ToEvent() *Event {
return &Event{
EventType: "block_split",
EventData: map[string]interface{}{
"object_id": c.ObjectId,
"algorithm_ms": c.AlgorithmMs,
"apply_ms": c.ApplyMs,
"total_ms": c.AlgorithmMs + c.ApplyMs,
},
}
}
type CreateObjectEvent struct {
SetDetailsMs int64
GetWorkspaceBlockWaitMs int64
WorkspaceCreateMs int64
SmartblockCreateMs int64
SmartblockType int
ObjectId string
}
func (c CreateObjectEvent) ToEvent() *Event {
return &Event{
EventType: "create_object",
EventData: map[string]interface{}{
"set_details_ms": c.SetDetailsMs,
"get_workspace_block_wait_ms": c.GetWorkspaceBlockWaitMs,
"workspace_create_ms": c.WorkspaceCreateMs,
"smartblock_create_ms": c.SmartblockCreateMs,
"total_ms": c.SetDetailsMs + c.GetWorkspaceBlockWaitMs + c.WorkspaceCreateMs + c.SmartblockCreateMs,
"smartblock_type": c.SmartblockType,
"object_id": c.ObjectId,
},
}
}
type OpenBlockEvent struct {
GetBlockMs int64
DataviewMs int64
ApplyMs int64
ShowMs int64
FileWatcherMs int64
SmartblockType int
ObjectId string
}
func (c OpenBlockEvent) ToEvent() *Event {
return &Event{
EventType: "open_block",
EventData: map[string]interface{}{
"object_id": c.ObjectId,
"get_block_ms": c.GetBlockMs,
"dataview_notify_ms": c.DataviewMs,
"apply_ms": c.ApplyMs,
"show_ms": c.ShowMs,
"file_watchers_ms": c.FileWatcherMs,
"total_ms": c.GetBlockMs + c.DataviewMs + c.ApplyMs + c.ShowMs + c.FileWatcherMs,
"smartblock_type": c.SmartblockType,
},
}
}
type ProcessThreadsEvent struct {
WaitTimeMs int64
}
func (c ProcessThreadsEvent) ToEvent() *Event {
return &Event{
EventType: "process_threads",
EventData: map[string]interface{}{
"wait_time_ms": c.WaitTimeMs,
},
}
}
type AccountRecoverEvent struct {
SpentMs int
TotalThreads int
SimultaneousRequests int
}
func (c AccountRecoverEvent) ToEvent() *Event {
return &Event{
EventType: "account_recover",
EventData: map[string]interface{}{
"spent_ms": c.SpentMs,
"total_threads": c.TotalThreads,
"simultaneous_requests": c.SimultaneousRequests,
},
}
}
type CafeP2PConnectStateChanged struct {
AfterMs int64
PrevState int
NewState int
NetCheckSuccess bool
NetCheckError string
GrpcConnected bool
}
func (c CafeP2PConnectStateChanged) ToEvent() *Event {
return &Event{
EventType: "cafe_p2p_connect_state_changed",
EventData: map[string]interface{}{
"after_ms": c.AfterMs,
"state": c.NewState,
"prev_state": c.PrevState,
"net_check_success": c.NetCheckSuccess,
"net_check_error": c.NetCheckError,
"grpc_connected": c.GrpcConnected,
},
}
}
type CafeGrpcConnectStateChanged struct {
AfterMs int64
Connected bool
ConnectedBefore bool
}
func (c CafeGrpcConnectStateChanged) ToEvent() *Event {
return &Event{
EventType: "cafe_grpc_connect_state_changed",
EventData: map[string]interface{}{
"after_ms": c.AfterMs,
"connected": c.Connected,
"connected_before": c.ConnectedBefore,
},
}
}
type ThreadDownloaded struct {
Success bool
Downloaded int
DownloadedSinceStart int
Total int
TimeMs int64
}
func (c ThreadDownloaded) ToEvent() *Event {
return &Event{
EventType: "thread_downloaded",
EventData: map[string]interface{}{
"success": c.Success,
"time_ms": c.TimeMs,
"downloaded": c.Downloaded,
"downloaded_since_start": c.DownloadedSinceStart,
"total": c.Total,
},
}
}