-
Notifications
You must be signed in to change notification settings - Fork 21
Expand file tree
/
Copy pathsummary_settings.go
More file actions
108 lines (92 loc) · 3.74 KB
/
summary_settings.go
File metadata and controls
108 lines (92 loc) · 3.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package trace2receiver
import (
"fmt"
)
// SummarySettings describes the configuration for summary
// metrics that should be aggregated from trace2 events and emitted as
// a single JSON object in the OTEL process span.
type SummarySettings struct {
MessagePatterns []MessagePatternRule `mapstructure:"message_patterns"`
RegionTimers []RegionTimerRule `mapstructure:"region_timers"`
}
// MessagePatternRule defines a rule for counting messages that match
// a specific prefix. When a message (from error, data, or other events)
// starts with the specified prefix, a counter is incremented and emitted
// in the summary using the specified field name.
type MessagePatternRule struct {
// Prefix is the string prefix to match at the beginning of messages
Prefix string `mapstructure:"prefix"`
// FieldName is the name of the field in the summary object
// where the count will be stored
FieldName string `mapstructure:"field_name"`
}
// RegionTimerRule defines a rule for aggregating time spent in regions
// that match a specific (category, label) pair. The count and/or total
// time can be emitted in the summary using the specified field names.
type RegionTimerRule struct {
// Category is the region category to match (exact match)
Category string `mapstructure:"category"`
// Label is the region label to match (exact match)
Label string `mapstructure:"label"`
// CountField is the optional name of the field in the summary
// object where the count of matching regions will be stored.
// If empty, count will not be tracked.
CountField string `mapstructure:"count_field"`
// TimeField is the optional name of the field in the summary
// object where the total time (in seconds) will be stored.
// If empty, time will not be tracked.
TimeField string `mapstructure:"time_field"`
}
// parseSummarySettings parses a summary configuration
// from a YML file and validates the configuration.
func parseSummarySettings(path string) (*SummarySettings, error) {
return parseYmlFile[SummarySettings](path, parseSummarySettingsFromBuffer)
}
// parseSummarySettingsFromBuffer parses and validates
// summary settings from a YAML byte buffer.
func parseSummarySettingsFromBuffer(data []byte, path string) (*SummarySettings, error) {
css, err := parseYmlBuffer[SummarySettings](data, path)
if err != nil {
return nil, err
}
// Track all field names to detect duplicates
fieldNames := make(map[string]bool)
// Validate message pattern rules
for i, rule := range css.MessagePatterns {
if len(rule.Prefix) == 0 {
return nil, fmt.Errorf("message_patterns[%d]: prefix cannot be empty", i)
}
if len(rule.FieldName) == 0 {
return nil, fmt.Errorf("message_patterns[%d]: field_name cannot be empty", i)
}
if fieldNames[rule.FieldName] {
return nil, fmt.Errorf("message_patterns[%d]: duplicate field_name '%s'", i, rule.FieldName)
}
fieldNames[rule.FieldName] = true
}
// Validate region timer rules
for i, rule := range css.RegionTimers {
if len(rule.Category) == 0 {
return nil, fmt.Errorf("region_timers[%d]: category cannot be empty", i)
}
if len(rule.Label) == 0 {
return nil, fmt.Errorf("region_timers[%d]: label cannot be empty", i)
}
if len(rule.CountField) == 0 && len(rule.TimeField) == 0 {
return nil, fmt.Errorf("region_timers[%d]: at least one of count_field or time_field must be specified", i)
}
if len(rule.CountField) > 0 {
if fieldNames[rule.CountField] {
return nil, fmt.Errorf("region_timers[%d]: duplicate field_name '%s'", i, rule.CountField)
}
fieldNames[rule.CountField] = true
}
if len(rule.TimeField) > 0 {
if fieldNames[rule.TimeField] {
return nil, fmt.Errorf("region_timers[%d]: duplicate field_name '%s'", i, rule.TimeField)
}
fieldNames[rule.TimeField] = true
}
}
return css, nil
}