@@ -37,8 +37,8 @@ type attributesProcessor struct {
3737// raw format from the configuration.
3838type attributesConfig struct {
3939 actions []attributeAction
40- include * matchingProperties
41- exclude * matchingProperties
40+ include matchingProperties
41+ exclude matchingProperties
4242}
4343
4444type attributeAction struct {
@@ -52,17 +52,38 @@ type attributeAction struct {
5252 AttributeValue * tracepb.AttributeValue
5353}
5454
55- // matchingProperties stores the MatchProperties config in a format that simplifies
56- // and makes property checking faster.
57- type matchingProperties struct {
58- // The list of service names is stored in a map for quick lookup.
59- Services map [string ]bool
55+ // matchingProperties is an interface that allows matching a span against a configuration
56+ // of a match.
57+ type matchingProperties interface {
58+ matchSpan (span * tracepb.Span , serviceName string ) bool
59+ }
60+
61+ type matchAttributes []matchAttribute
62+
63+ // strictMatchingProperties allows matching a span against a "strict" match type
64+ // configuration.
65+ type strictMatchingProperties struct {
66+ // Service names to compare to.
67+ Services []string
68+
69+ // Span names to compare to.
70+ SpanNames []string
71+
72+ // The attribute values are stored in the internal format.
73+ Attributes matchAttributes
74+ }
75+
76+ // strictMatchingProperties allows matching a span against a "regexp" match type
77+ // configuration.
78+ type regexpMatchingProperties struct {
79+ // Precompiled service name regexp-es.
80+ Services []* regexp.Regexp
6081
6182 // Precompiled span name regexp-es.
6283 SpanNames []* regexp.Regexp
6384
6485 // The attribute values are stored in the internal format.
65- Attributes [] matchAttribute
86+ Attributes matchAttributes
6687}
6788
6889// matchAttribute is a attribute key/value pair to match to.
@@ -187,33 +208,86 @@ func (a *attributesProcessor) skipSpan(span *tracepb.Span, serviceName string) b
187208
188209 if a .config .include != nil {
189210 // A false returned in this case means the span should not be processed.
190- if include := matchSpanToProperties ( * a .config .include , span , serviceName ); ! include {
211+ if include := a .config .include . matchSpan ( span , serviceName ); ! include {
191212 return true
192213 }
193214 }
194215
195216 if a .config .exclude != nil {
196217 // A true returned in this case means the span should not be processed.
197- if exclude := matchSpanToProperties ( * a .config .exclude , span , serviceName ); exclude {
218+ if exclude := a .config .exclude . matchSpan ( span , serviceName ); exclude {
198219 return true
199220 }
200221 }
201222
202223 return false
203224}
204225
205- // matchProperties matches a span and service to a set of properties.
206- // There are two sets of properties to match against.
207- // The service name is checked first, if specified. The attributes are checked
208- // afterwards , if specified.
209- // At least one of services or attributes must be specified. It is supported
210- // to have both specified, but both `services` and `attributes` must evaluate
226+ // matchSpan matches a span and service to a set of properties.
227+ // There are 3 sets of properties to match against.
228+ // The service name is checked first, if specified. Then span names are matched, if specified.
229+ // The attributes are checked last , if specified.
230+ // At least one of services, span names or attributes must be specified. It is supported
231+ // to have more than one of these specified, and all specified must evaluate
211232// to true for a match to occur.
212- func matchSpanToProperties (mp matchingProperties , span * tracepb.Span , serviceName string ) bool {
233+ func (mp * strictMatchingProperties ) matchSpan ( span * tracepb.Span , serviceName string ) bool {
213234
214- if len (mp .Services ) != 0 {
215- // Services condition is specified. Check if the service is one the specified.
216- if serviceFound := mp .Services [serviceName ]; ! serviceFound {
235+ if len (mp .Services ) > 0 {
236+ // Verify service name matches at least one of the items.
237+ matched := false
238+ for _ , item := range mp .Services {
239+ if item == serviceName {
240+ matched = true
241+ break
242+ }
243+ }
244+ if ! matched {
245+ return false
246+ }
247+ }
248+
249+ if len (mp .SpanNames ) > 0 {
250+ // SpanNames condition is specified. Check if span name matches the condition.
251+ var spanName string
252+ if span .Name != nil {
253+ spanName = span .Name .Value
254+ }
255+ // Verify span name matches at least one of the items.
256+ matched := false
257+ for _ , item := range mp .SpanNames {
258+ if item == spanName {
259+ matched = true
260+ break
261+ }
262+ }
263+ if ! matched {
264+ return false
265+ }
266+ }
267+
268+ // Service name and span name matched. Now match attributes.
269+ return mp .Attributes .match (span )
270+ }
271+
272+ // matchSpan matches a span and service to a set of properties.
273+ // There are 3 sets of properties to match against.
274+ // The service name is checked first, if specified. Then span names are matched, if specified.
275+ // The attributes are checked last, if specified.
276+ // At least one of services, span names or attributes must be specified. It is supported
277+ // to have more than one of these specified, and all specified must evaluate
278+ // to true for a match to occur.
279+ func (mp * regexpMatchingProperties ) matchSpan (span * tracepb.Span , serviceName string ) bool {
280+
281+ if len (mp .Services ) > 0 {
282+ // Verify service name matches at least one of the regexp patterns.
283+ matched := false
284+ for _ , re := range mp .Services {
285+ if re .MatchString (serviceName ) {
286+ matched = true
287+ break
288+ }
289+ }
290+ if ! matched {
217291 return false
218292 }
219293 }
@@ -237,19 +311,25 @@ func matchSpanToProperties(mp matchingProperties, span *tracepb.Span, serviceNam
237311 }
238312 }
239313
314+ // Service name and span name matched. Now match attributes.
315+ return mp .Attributes .match (span )
316+ }
317+
318+ // match attributes specification against a span.
319+ func (ma matchAttributes ) match (span * tracepb.Span ) bool {
240320 // If there are no attributes to match against, the span matches.
241- if len (mp . Attributes ) == 0 {
321+ if len (ma ) == 0 {
242322 return true
243323 }
244324
245325 // At this point, it is expected of the span to have attributes because of
246- // len (mp.Attributes ) != 0. For spans with no attributes, it does not match.
326+ // len(ma ) != 0. This means for spans with no attributes, it does not match.
247327 if span .Attributes == nil || len (span .Attributes .AttributeMap ) == 0 {
248328 return false
249329 }
250330
251331 // Check that all expected properties are set.
252- for _ , property := range mp . Attributes {
332+ for _ , property := range ma {
253333 val , exist := span .Attributes .AttributeMap [property .Key ]
254334 if ! exist {
255335 return false
@@ -283,7 +363,5 @@ func matchSpanToProperties(mp matchingProperties, span *tracepb.Span, serviceNam
283363 return false
284364 }
285365 }
286-
287- // All properties have been satisfied so the span does match.
288366 return true
289367}
0 commit comments