You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2024/03/22 01:23:57 UTC
(skywalking-go) branch main updated: Add support trace ignore (#177)
This is an automated email from the ASF dual-hosted git repository.
wusheng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-go.git
The following commit(s) were added to refs/heads/main by this push:
new e427c3e Add support trace ignore (#177)
e427c3e is described below
commit e427c3e53a7fda57ebd85b9784e58db352d77a53
Author: Starry <co...@163.com>
AuthorDate: Fri Mar 22 09:23:52 2024 +0800
Add support trace ignore (#177)
---
CHANGES.md | 5 +-
docs/en/agent/tracing-metrics-logging.md | 9 +-
plugins/core/tracer.go | 4 +-
plugins/core/tracer_ignore.go | 135 ++++++++++++++++++++++
plugins/core/tracer_ignore_test.go | 81 +++++++++++++
plugins/core/tracing.go | 16 +--
tools/go-agent/config/agent.default.yaml | 8 +-
tools/go-agent/config/loader.go | 1 +
tools/go-agent/instrument/agentcore/instrument.go | 3 +-
9 files changed, 239 insertions(+), 23 deletions(-)
diff --git a/CHANGES.md b/CHANGES.md
index f823c49..fe3da3b 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -4,6 +4,9 @@ Release Notes.
0.5.0
------------------
+#### Features
+* Add support trace ignore.
+
#### Plugins
* Support [Pulsar](https://github.com/apache/pulsar-client-go) MQ.
* Support [Segmentio-Kafka](https://github.com/segmentio/kafka-go) MQ.
@@ -111,7 +114,7 @@ Release Notes.
* Support [Kratos](github.com/go-kratos/kratos) v2 server and client framework.
* Support [Go-Micro](https://github.com/go-micro/go-micro) v4 server and client framework.
* Support [GORM](https://github.com/go-gorm/gorm) v2 database client framework.
- * Support [MySQL Driver](https://github.com/go-gorm/mysql) detection.
+* Support [MySQL Driver](https://github.com/go-gorm/mysql) detection.
#### Documentation
* Initialize the documentation.
diff --git a/docs/en/agent/tracing-metrics-logging.md b/docs/en/agent/tracing-metrics-logging.md
index 07ccf8d..ec6e263 100644
--- a/docs/en/agent/tracing-metrics-logging.md
+++ b/docs/en/agent/tracing-metrics-logging.md
@@ -22,10 +22,11 @@ If you wish to disable a particular plugin to prevent enhancements related to th
The basic configuration is as follows:
-| Name | Environment Key | Default Value | Description |
-|---------------------|------------------------|--------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------|
-| agent.sampler | SW_AGENT_SAMPLER | 1 | Sampling rate of tracing data, which is a floating-point value that must be between 0 and 1. |
-| agent.ignore_suffix | SW_AGENT_IGNORE_SUFFIX | .jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico,.mp3,.mp4,.html,.svg | If the operation name of the first span is included in this set, this segment should be ignored.(multiple split by ","). |
+| Name | Environment Key | Default Value | Description |
+|-------------------------|----------------------------|--------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|
+| agent.sampler | SW_AGENT_SAMPLER | 1 | Sampling rate of tracing data, which is a floating-point value that must be between 0 and 1. |
+| agent.ignore_suffix | SW_AGENT_IGNORE_SUFFIX | .jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico,.mp3,.mp4,.html,.svg | If the suffix obtained by splitting the operation name by the last index of "." in this set, this segment should be ignored.(multiple split by ","). |
+| agent.trace_ignore_path | SW_AGENT_TRACE_IGNORE_PATH | | If the operation name of the first span is matching, this segment should be ignored.(multiple split by ","). |
## Metrics
diff --git a/plugins/core/tracer.go b/plugins/core/tracer.go
index e10a56b..53a5eff 100644
--- a/plugins/core/tracer.go
+++ b/plugins/core/tracer.go
@@ -54,10 +54,11 @@ type Tracer struct {
meterMap *sync.Map
meterCollectListeners []func()
ignoreSuffix []string
+ traceIgnorePath []string
}
func (t *Tracer) Init(entity *reporter.Entity, rep reporter.Reporter, samp Sampler, logger operator.LogOperator,
- meterCollectSecond int, correlation *CorrelationConfig, ignoreSuffixStr string) error {
+ meterCollectSecond int, correlation *CorrelationConfig, ignoreSuffixStr string, ignorePath string) error {
t.ServiceEntity = entity
t.Reporter = rep
t.Sampler = samp
@@ -69,6 +70,7 @@ func (t *Tracer) Init(entity *reporter.Entity, rep reporter.Reporter, samp Sampl
t.initMetricsCollect(meterCollectSecond)
t.correlation = correlation
t.ignoreSuffix = strings.Split(ignoreSuffixStr, ",")
+ t.traceIgnorePath = strings.Split(ignorePath, ",")
// notify the tracer been init success
if len(GetInitNotify()) > 0 {
for _, fun := range GetInitNotify() {
diff --git a/plugins/core/tracer_ignore.go b/plugins/core/tracer_ignore.go
new file mode 100644
index 0000000..ae4212b
--- /dev/null
+++ b/plugins/core/tracer_ignore.go
@@ -0,0 +1,135 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you under
+// the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package core
+
+import (
+ "strings"
+)
+
+func tracerIgnore(operationName string, ignoreSuffixList, ignorePath []string) bool {
+ return ignoreSuffix(operationName, ignoreSuffixList) || traceIgnorePath(operationName, ignorePath)
+}
+
+func ignoreSuffix(operationName string, ignoreSuffix []string) bool {
+ suffixIdx := strings.LastIndex(operationName, ".")
+ if suffixIdx == -1 {
+ return false
+ }
+ for _, suffix := range ignoreSuffix {
+ if suffix == operationName[suffixIdx:] {
+ return true
+ }
+ }
+ return false
+}
+
+func traceIgnorePath(operationName string, ignorePath []string) bool {
+ for _, pattern := range ignorePath {
+ if normalMatch(pattern, 0, operationName, 0) {
+ return true
+ }
+ }
+ return false
+}
+
+// normalMatch determines whether the operation name matches the wildcard pattern.
+// The parameters `p` and `s` represent the current index in pattern and operationName respectively.
+func normalMatch(pattern string, p int, operationName string, s int) bool {
+ for p < len(pattern) {
+ pc := pattern[p]
+ sc := safeCharAt(operationName, s)
+
+ if pc == '*' {
+ p++
+ if safeCharAt(pattern, p) == '*' {
+ p++
+ return multiWildcardMatch(pattern, p, operationName, s)
+ }
+ return wildcardMatch(pattern, p, operationName, s)
+ }
+
+ if (pc == '?' && sc != 0 && sc != '/') || pc == sc {
+ s++
+ p++
+ continue
+ }
+ return false
+ }
+ return s == len(operationName)
+}
+
+func wildcardMatch(pattern string, p int, operationName string, s int) bool {
+ pc := safeCharAt(pattern, p)
+
+ if pc == 0 {
+ for {
+ sc := safeCharAt(operationName, s)
+ if sc == 0 {
+ return true
+ }
+ if sc == '/' {
+ return s == len(operationName)-1
+ }
+ s++
+ }
+ }
+
+ for {
+ sc := safeCharAt(operationName, s)
+ if sc == '/' {
+ if pc == sc {
+ return normalMatch(pattern, p+1, operationName, s+1)
+ }
+ return false
+ }
+ if !normalMatch(pattern, p, operationName, s) {
+ if s >= len(operationName) {
+ return false
+ }
+ s++
+ continue
+ }
+ return true
+ }
+}
+
+func multiWildcardMatch(pattern string, p int, operationName string, s int) bool {
+ switch safeCharAt(pattern, p) {
+ case 0:
+ return true
+ case '/':
+ p++
+ }
+ for {
+ if !normalMatch(pattern, p, operationName, s) {
+ if s >= len(operationName) {
+ return false
+ }
+ s++
+ continue
+ }
+ return true
+ }
+}
+
+func safeCharAt(value string, index int) byte {
+ if index >= len(value) {
+ return 0
+ }
+ return value[index]
+}
diff --git a/plugins/core/tracer_ignore_test.go b/plugins/core/tracer_ignore_test.go
new file mode 100644
index 0000000..9bd3bf3
--- /dev/null
+++ b/plugins/core/tracer_ignore_test.go
@@ -0,0 +1,81 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you under
+// the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package core
+
+import (
+ "strings"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestIgnoreSuffix(t *testing.T) {
+ ignoreSuffixStr := ".jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico,.mp3,.mp4,.html,.svg"
+ ignoreSuffixList := strings.Split(ignoreSuffixStr, ",")
+ assert.True(t, ignoreSuffix("GET:/favicon.ico", ignoreSuffixList))
+}
+
+func TestTraceIgnorePath(t *testing.T) {
+ ignorePath := []string{"/health/*"}
+ assert.False(t, traceIgnorePath("", ignorePath))
+ assert.True(t, traceIgnorePath("/health/apps", ignorePath))
+ assert.True(t, traceIgnorePath("/health/", ignorePath))
+ assert.True(t, traceIgnorePath("/health/apps/", ignorePath))
+
+ ignorePath = []string{"/health/**"}
+ assert.True(t, traceIgnorePath("/health/apps/", ignorePath))
+
+ ignorePath = []string{"/health/?"}
+ assert.True(t, traceIgnorePath("/health/a", ignorePath))
+ assert.False(t, traceIgnorePath("/health/ab", ignorePath))
+
+ ignorePath = []string{"/health/*/"}
+ assert.True(t, traceIgnorePath("/health/apps/", ignorePath))
+ assert.False(t, traceIgnorePath("/health/", ignorePath))
+ assert.False(t, traceIgnorePath("/health/apps/list", ignorePath))
+ assert.False(t, traceIgnorePath("/health/test", ignorePath))
+
+ ignorePath = []string{"/health/**"}
+ assert.True(t, traceIgnorePath("/health/", ignorePath))
+ assert.True(t, traceIgnorePath("/health/apps/test", ignorePath))
+ assert.True(t, traceIgnorePath("/health/apps/test/", ignorePath))
+
+ ignorePath = []string{"health/apps/?"}
+ assert.False(t, traceIgnorePath("health/apps/list", ignorePath))
+ assert.False(t, traceIgnorePath("health/apps/", ignorePath))
+ assert.True(t, traceIgnorePath("health/apps/a", ignorePath))
+
+ ignorePath = []string{"health/**/lists"}
+ assert.True(t, traceIgnorePath("health/apps/lists", ignorePath))
+ assert.True(t, traceIgnorePath("health/apps/test/lists", ignorePath))
+ assert.False(t, traceIgnorePath("health/apps/test/", ignorePath))
+ assert.False(t, traceIgnorePath("health/apps/test", ignorePath))
+
+ ignorePath = []string{"health/**/test/**"}
+ assert.True(t, traceIgnorePath("health/apps/test/list", ignorePath))
+ assert.True(t, traceIgnorePath("health/apps/foo/test/list/bar", ignorePath))
+ assert.True(t, traceIgnorePath("health/apps/foo/test/list/bar/", ignorePath))
+ assert.True(t, traceIgnorePath("health/apps/test/list", ignorePath))
+ assert.True(t, traceIgnorePath("health/test/list", ignorePath))
+
+ ignorePath = []string{"/health/**/b/**/*.txt", "abc/*"}
+ assert.True(t, traceIgnorePath("/health/a/aa/aaa/b/bb/bbb/xxxxxx.txt", ignorePath))
+ assert.False(t, traceIgnorePath("/health/a/aa/aaa/b/bb/bbb/xxxxxx", ignorePath))
+ assert.False(t, traceIgnorePath("abc/foo/bar", ignorePath))
+ assert.True(t, traceIgnorePath("abc/foo", ignorePath))
+}
diff --git a/plugins/core/tracing.go b/plugins/core/tracing.go
index 8fac32f..1f73c89 100644
--- a/plugins/core/tracing.go
+++ b/plugins/core/tracing.go
@@ -20,7 +20,6 @@ package core
import (
"reflect"
"runtime/debug"
- "strings"
"github.com/pkg/errors"
@@ -230,7 +229,7 @@ func (t *Tracer) createNoop(operationName string) (*TracingContext, TracingSpan,
if !t.InitSuccess() || t.Reporter.ConnectionStatus() == reporter.ConnectionStatusDisconnect {
return nil, newNoopSpan(), true
}
- if ignoreSuffixFilter(operationName, t.ignoreSuffix) {
+ if tracerIgnore(operationName, t.ignoreSuffix, t.traceIgnorePath) {
return nil, newNoopSpan(), true
}
ctx := getTracingContext()
@@ -341,16 +340,3 @@ func saveSpanToActiveIfNotError(ctx *TracingContext, span interface{}, err error
ctx.SaveActiveSpan(span.(TracingSpan))
SetGLS(ctx)
}
-
-func ignoreSuffixFilter(operationName string, ignoreSuffix []string) bool {
- suffixIdx := strings.LastIndex(operationName, ".")
- if suffixIdx == -1 {
- return false
- }
- for _, suffix := range ignoreSuffix {
- if suffix == operationName[suffixIdx:] {
- return true
- }
- }
- return false
-}
diff --git a/tools/go-agent/config/agent.default.yaml b/tools/go-agent/config/agent.default.yaml
index 0af4207..ee1e5cd 100644
--- a/tools/go-agent/config/agent.default.yaml
+++ b/tools/go-agent/config/agent.default.yaml
@@ -30,8 +30,14 @@ agent:
correlation:
max_key_count: ${SW_AGENT_CORRELATION_MAX_KEY_COUNT:3}
max_value_size: ${SW_AGENT_CORRELATION_MAX_VALUE_SIZE:128}
- # If the operation name of the first span is included in this set, this segment should be ignored.(multiple split by ",")
+ # If the suffix obtained by splitting the operation name by the last index of "." in this set, this segment should be ignored.(multiple split by ",").
ignore_suffix: ${SW_AGENT_IGNORE_SUFFIX:.jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico,.mp3,.mp4,.html,.svg}
+ # If the operation name of the first span is matching, this segment should be ignored.(multiple split by ",").
+ # Matching rules follow Ant Path match style, like /path/*, /path/**, /path/?.
+ # "/path/*" means matching any path that starts with "/path/".
+ # "/path/**" means matching any path that starts with "/path/" and includes its subpaths.
+ # "/path/?" means matching any path that starts with "/path/" and has any single character as a wildcard.
+ trace_ignore_path: ${SW_AGENT_TRACE_IGNORE_PATH:}
reporter:
discard: ${SW_AGENT_REPORTER_DISCARD:false}
diff --git a/tools/go-agent/config/loader.go b/tools/go-agent/config/loader.go
index e42420d..466626a 100644
--- a/tools/go-agent/config/loader.go
+++ b/tools/go-agent/config/loader.go
@@ -51,6 +51,7 @@ type Agent struct {
Meter Meter `yaml:"meter"`
Correlation Correlation `yaml:"correlation"`
IgnoreSuffix StringValue `yaml:"ignore_suffix"`
+ TraceIgnorePath StringValue `yaml:"trace_ignore_path"`
}
type Reporter struct {
diff --git a/tools/go-agent/instrument/agentcore/instrument.go b/tools/go-agent/instrument/agentcore/instrument.go
index 83dcbb6..b46abec 100644
--- a/tools/go-agent/instrument/agentcore/instrument.go
+++ b/tools/go-agent/instrument/agentcore/instrument.go
@@ -163,7 +163,8 @@ func (t *Tracer) InitTracer(extend map[string]interface{}) {
MaxValueSize : {{.Config.Agent.Correlation.MaxValueSize.ToGoIntValue "loading the agent correlation maxValueSize error"}},
}
ignoreSuffixStr := {{.Config.Agent.IgnoreSuffix.ToGoStringValue}}
- if err := t.Init(entity, rep, samp, logger, meterCollectInterval, correlation, ignoreSuffixStr); err != nil {
+ ignorePath := {{.Config.Agent.TraceIgnorePath.ToGoStringValue}}
+ if err := t.Init(entity, rep, samp, logger, meterCollectInterval, correlation, ignoreSuffixStr, ignorePath); err != nil {
t.Log.Errorf("cannot initialize the SkyWalking Tracer: %v", err)
}
}`, struct {