@@ -38,15 +38,24 @@ func V2ToRuntime(src *schema.Extension) (*obi.Config, error) {
3838 if err := schema .ValidateStandalone (src ); err != nil {
3939 return nil , err
4040 }
41+ if err := validateV2MatchOrder (src .Capture .Policy .MatchOrder , src .Capture .Rules ); err != nil {
42+ return nil , err
43+ }
4144 if err := validateV2RulePatterns (src .Capture .Rules ); err != nil {
4245 return nil , err
4346 }
47+ if err := validateV2RuleSelectorFamilies (src .Capture .Rules ); err != nil {
48+ return nil , err
49+ }
4450 if err := validateV2HTTPFilters (src .Capture .Instrumentation .HTTP .Filters ); err != nil {
4551 return nil , err
4652 }
4753 if err := validateV2HTTPPayloadExtraction (src .Capture .Instrumentation .HTTP .PayloadExtraction ); err != nil {
4854 return nil , err
4955 }
56+ if err := validateUnsupportedV2Fields (src ); err != nil {
57+ return nil , err
58+ }
5059
5160 cfg := runtimeConfigDefaults ()
5261 applyV2Capture (& cfg , src )
@@ -57,6 +66,57 @@ func V2ToRuntime(src *schema.Extension) (*obi.Config, error) {
5766 return & cfg , nil
5867}
5968
69+ func validateUnsupportedV2Fields (src * schema.Extension ) error {
70+ runtimeFilters := []struct {
71+ path string
72+ filters schema.AttributeFilters
73+ }{
74+ {path : "capture.runtimes.go.filter" , filters : src .Capture .Runtimes .Go .Filter },
75+ {path : "capture.runtimes.nodejs.filter" , filters : src .Capture .Runtimes .NodeJS .Filter },
76+ {path : "capture.runtimes.java.filter" , filters : src .Capture .Runtimes .Java .Filter },
77+ }
78+ for _ , runtimeFilter := range runtimeFilters {
79+ if len (runtimeFilter .filters ) != 0 {
80+ return fmt .Errorf ("%s is not supported" , runtimeFilter .path )
81+ }
82+ }
83+
84+ if src .Enrich != nil {
85+ for _ , enrichmentProperties := range []struct {
86+ path string
87+ properties map [string ]any
88+ }{
89+ {path : "enrich" , properties : src .Enrich .AdditionalProperties },
90+ {path : "enrich.enrichers" , properties : src .Enrich .Enrichers .AdditionalProperties },
91+ {path : "enrich.enrichers.kubernetes" , properties : src .Enrich .Enrichers .Kubernetes .AdditionalProperties },
92+ {path : "enrich.service_name" , properties : src .Enrich .ServiceName .AdditionalProperties },
93+ {path : "enrich.attributes" , properties : src .Enrich .Attributes .AdditionalProperties },
94+ } {
95+ if err := rejectUnsupportedProperties (enrichmentProperties .path , enrichmentProperties .properties ); err != nil {
96+ return err
97+ }
98+ }
99+ }
100+
101+ if src .Correlation != nil && len (src .Correlation .LogTraceAnnotation .Filter ) != 0 {
102+ return errors .New ("correlation.log_trace_annotation.filter is not supported" )
103+ }
104+ return nil
105+ }
106+
107+ func rejectUnsupportedProperties (path string , properties map [string ]any ) error {
108+ if len (properties ) == 0 {
109+ return nil
110+ }
111+
112+ keys := make ([]string , 0 , len (properties ))
113+ for key := range properties {
114+ keys = append (keys , key )
115+ }
116+ slices .Sort (keys )
117+ return fmt .Errorf ("%s.%s is not supported" , path , keys [0 ])
118+ }
119+
60120func runtimeConfigDefaults () obi.Config {
61121 cfg := obi .DefaultConfig
62122 if cfg .Routes != nil {
@@ -72,7 +132,7 @@ func runtimeConfigDefaults() obi.Config {
72132
73133func applyV2Capture (cfg * obi.Config , src * schema.Extension ) {
74134 applyV2Policy (cfg , src .Capture .Policy , completePolicy (src .Capture .Policy ))
75- applyV2Rules (cfg , src .Capture .Rules )
135+ applyV2Rules (cfg , src .Capture .Rules , src . Capture . Policy . DefaultAction )
76136 applyV2Limits (cfg , src .Capture .Limits , completeLimits (src .Capture .Limits ))
77137 applyV2Safety (cfg , src .Capture .Safety , ! zeroValue (src .Capture .Safety ))
78138 applyV2Channels (cfg , src .Capture .Channels , completeChannels (src .Capture .Channels ))
@@ -112,12 +172,30 @@ type runtimeDiscoveryRules struct {
112172 defaultOTLPGRPCPort int
113173}
114174
115- func applyV2Rules (cfg * obi.Config , rules []schema.Rule ) {
175+ func applyV2Rules (cfg * obi.Config , rules []schema.Rule , defaultAction schema.CaptureAction ) {
176+ includeByDefault := defaultAction != schema .CaptureActionExclude
116177 if rules == nil {
178+ if includeByDefault {
179+ cfg .Discovery .Instrument = services.GlobDefinitionCriteria {
180+ {Path : services .NewGlob ("*" )},
181+ }
182+ }
117183 return
118184 }
119185
120- applyRuntimeDiscoveryRules (cfg , runtimeDiscoveryRulesFromV2 (rules ))
186+ converted := runtimeDiscoveryRulesFromV2 (rules )
187+ if includeByDefault {
188+ if len (converted .includeRegex ) > 0 || len (converted .excludeRegex ) > 0 {
189+ converted .includeRegex = append (converted .includeRegex , services.RegexSelector {
190+ Path : services .NewRegexp (".*" ),
191+ })
192+ } else {
193+ converted .includeGlobs = append (converted .includeGlobs , services.GlobAttributes {
194+ Path : services .NewGlob ("*" ),
195+ })
196+ }
197+ }
198+ applyRuntimeDiscoveryRules (cfg , converted )
121199}
122200
123201func runtimeDiscoveryRulesFromV2 (rules []schema.Rule ) runtimeDiscoveryRules {
@@ -195,6 +273,69 @@ func validateV2RulePatterns(rules []schema.Rule) error {
195273 return nil
196274}
197275
276+ func validateV2RuleSelectorFamilies (rules []schema.Rule ) error {
277+ selectorFamily := ""
278+ for i , rule := range rules {
279+ if rule .Match .Process .ExportsOTLP != nil || ruleMatchEmpty (rule .Match ) {
280+ continue
281+ }
282+
283+ ruleSelectorFamily := "glob"
284+ if ruleUsesRegex (rule .Match ) {
285+ if ruleUsesGlob (rule .Match ) {
286+ return fmt .Errorf (
287+ "capture.rules[%d].match: mixing glob and regex selectors is not supported" ,
288+ i ,
289+ )
290+ }
291+ ruleSelectorFamily = "regex"
292+ }
293+
294+ if selectorFamily != "" && selectorFamily != ruleSelectorFamily {
295+ return fmt .Errorf (
296+ "capture.rules[%d].match: mixing glob and regex selectors is not supported" ,
297+ i ,
298+ )
299+ }
300+ selectorFamily = ruleSelectorFamily
301+ }
302+ return nil
303+ }
304+
305+ func validateV2MatchOrder (matchOrder schema.MatchOrder , rules []schema.Rule ) error {
306+ if matchOrder == schema .MatchOrderLastMatchWins {
307+ return errors .New ("capture.policy.match_order: last_match_wins is not supported" )
308+ }
309+
310+ includeSeen := false
311+ for i , rule := range rules {
312+ if ! ruleAffectsV2Selection (rule ) {
313+ continue
314+ }
315+
316+ switch rule .Action {
317+ case schema .CaptureActionInclude :
318+ includeSeen = true
319+ case schema .CaptureActionExclude :
320+ if includeSeen {
321+ return fmt .Errorf (
322+ "capture.rules[%d]: exclude rules must precede include rules for first_match_wins" ,
323+ i ,
324+ )
325+ }
326+ }
327+ }
328+
329+ return nil
330+ }
331+
332+ func ruleAffectsV2Selection (rule schema.Rule ) bool {
333+ if rule .Match .Process .ExportsOTLP != nil || ruleMatchEmpty (rule .Match ) {
334+ return false
335+ }
336+ return ! ruleUsesRegex (rule .Match ) || ! ruleUsesGlob (rule .Match )
337+ }
338+
198339func validateV2HTTPFilters (filters schema.SignalFilters ) error {
199340 if len (filters .Traces ) == 0 || len (filters .Metrics ) == 0 {
200341 return nil
0 commit comments