include db for gitea build
This commit is contained in:
1 parent
8de4a2e010
commit
645f923175
33 files changed
+1490
-150
No files matched your search
@@ -7,6 +7,8 @@ package features
|
||||
import (
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"git.tornberg.me/go-otel/internal/uaclass"
|
||||
)
|
||||
|
||||
// Event is the subset of a normalized event used by the detector. Text fields
|
||||
@@ -31,6 +33,14 @@ type Event struct {
|
||||
Route string
|
||||
StatusCode int
|
||||
ExceptionType string
|
||||
|
||||
// Trace-resolved context (see internal/tracectx). All optional: zero
|
||||
// values mean "not resolved", which behaves like the pre-resolution data.
|
||||
ClientIP string // real client behind proxy hops, when known
|
||||
UAClass string // internal/uaclass class of the User-Agent
|
||||
IsDuplicate bool // repeats an ancestor span's failure; not a new request
|
||||
IsRootCause bool // error span with no erroring child
|
||||
HasUpstream bool // an ingress span that had a child in another service
|
||||
}
|
||||
|
||||
// Config controls feature and label windows. A zero Config receives the
|
||||
@@ -94,6 +104,18 @@ type Row struct {
|
||||
TimeoutCount int `json:"timeoutCount"`
|
||||
CancellationCount int `json:"cancellationCount"`
|
||||
|
||||
// Logical-request view: DuplicateErrors are hops repeating an ancestor's
|
||||
// failure, so LogicalErrors = ErrorCount - DuplicateErrors is the number of
|
||||
// failed requests. DistinctClients / TopClientShare separate one noisy
|
||||
// client from broad impact; BotErrorShare is the share of errors whose
|
||||
// User-Agent classifies as a self-declared non-human client.
|
||||
LogicalErrors int `json:"logicalErrors"`
|
||||
DuplicateErrors int `json:"duplicateErrors"`
|
||||
RootCauseErrors int `json:"rootCauseErrors"`
|
||||
DistinctClients int `json:"distinctClients"`
|
||||
TopClientShare float64 `json:"topClientShare"`
|
||||
BotErrorShare float64 `json:"botErrorShare"`
|
||||
|
||||
BaselineErrorRate float64 `json:"baselineErrorRate"`
|
||||
BaselineSamples int `json:"baselineSamples"`
|
||||
FutureEventCount int `json:"futureEventCount"`
|
||||
@@ -189,10 +211,13 @@ type accumulator struct {
|
||||
durations []float64
|
||||
traces map[string]struct{}
|
||||
issues map[string]struct{}
|
||||
clients map[string]int
|
||||
botErrors int
|
||||
classed int
|
||||
}
|
||||
|
||||
func newAccumulator(start, end time.Time, service, release string) *accumulator {
|
||||
return &accumulator{value: Row{WindowStart: start, WindowEnd: end, Service: service, Release: release}, traces: map[string]struct{}{}, issues: map[string]struct{}{}}
|
||||
return &accumulator{value: Row{WindowStart: start, WindowEnd: end, Service: service, Release: release}, traces: map[string]struct{}{}, issues: map[string]struct{}{}, clients: map[string]int{}}
|
||||
}
|
||||
|
||||
func (a *accumulator) add(e Event) {
|
||||
@@ -223,6 +248,20 @@ func (a *accumulator) add(e Event) {
|
||||
return
|
||||
}
|
||||
a.value.ErrorCount++
|
||||
if e.IsDuplicate {
|
||||
a.value.DuplicateErrors++
|
||||
} else if e.ClientIP != "" {
|
||||
a.clients[e.ClientIP]++
|
||||
}
|
||||
if e.IsRootCause {
|
||||
a.value.RootCauseErrors++
|
||||
}
|
||||
if e.UAClass != "" && !e.IsDuplicate {
|
||||
a.classed++
|
||||
if uaclass.IsBot(e.UAClass) {
|
||||
a.botErrors++
|
||||
}
|
||||
}
|
||||
if e.Source == "frontend" {
|
||||
a.value.FrontendErrors++
|
||||
} else {
|
||||
@@ -252,6 +291,17 @@ func issueKey(e Event) string {
|
||||
func (a *accumulator) row() Row {
|
||||
a.value.ErrorRate = rate(a.value.ErrorCount, a.value.TotalEvents)
|
||||
a.value.UniqueTraceCount, a.value.UniqueIssueCount = len(a.traces), len(a.issues)
|
||||
a.value.LogicalErrors = a.value.ErrorCount - a.value.DuplicateErrors
|
||||
a.value.DistinctClients = len(a.clients)
|
||||
top, known := 0, 0
|
||||
for _, n := range a.clients {
|
||||
known += n
|
||||
if n > top {
|
||||
top = n
|
||||
}
|
||||
}
|
||||
a.value.TopClientShare = rate(top, known)
|
||||
a.value.BotErrorShare = rate(a.botErrors, a.classed)
|
||||
if len(a.durations) != 0 {
|
||||
sort.Float64s(a.durations)
|
||||
a.value.P50Duration = percentile(a.durations, .50)
|
||||
|
||||
Reference in new issue
Block a user