You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@skywalking.apache.org by wu...@apache.org on 2022/11/27 07:18:38 UTC

[skywalking-rover] branch main updated: Support config the default body encoding, Ignore sampling trace when the `MinDuration` is not set (#60)

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-rover.git


The following commit(s) were added to refs/heads/main by this push:
     new 6549362  Support config the default body encoding, Ignore sampling trace when the `MinDuration` is not set (#60)
6549362 is described below

commit 65493623f9fd55ecc9239c2533f4d364a737044e
Author: mrproliu <74...@qq.com>
AuthorDate: Sun Nov 27 15:18:33 2022 +0800

    Support config the default body encoding, Ignore sampling trace when the `MinDuration` is not set (#60)
    
    * Support config the default body encoding, Ignore sampling trace when the MinDuration is not set
---
 configs/rover_configs.yaml                         | 10 ++-
 docs/en/setup/configuration/profiling.md           | 24 +++---
 pkg/profiling/module.go                            |  3 +
 pkg/profiling/task/base/config.go                  | 85 +++++++++++++++++++++-
 pkg/profiling/task/base/task.go                    |  2 +-
 .../task/network/analyze/layer7/events.go          |  8 +-
 .../task/network/analyze/layer7/listener.go        |  2 +-
 .../analyze/layer7/protocols/base/protocol.go      |  1 +
 .../analyze/layer7/protocols/http1/analyzer.go     |  9 ++-
 .../analyze/layer7/protocols/http1/metrics.go      | 55 ++++++++++----
 .../analyze/layer7/protocols/http1/sampling.go     | 40 +++++-----
 .../network/analyze/layer7/protocols/protocols.go  |  6 +-
 .../profiling/network/base/rover_configs.yaml      | 10 ++-
 test/e2e/cases/profiling/network/sampling.yaml     |  3 +-
 14 files changed, 194 insertions(+), 64 deletions(-)

diff --git a/configs/rover_configs.yaml b/configs/rover_configs.yaml
index 557ac5a..695c567 100644
--- a/configs/rover_configs.yaml
+++ b/configs/rover_configs.yaml
@@ -130,4 +130,12 @@ profiling:
         # The count of parallel protocol analyzer
         parallels: ${ROVER_PROFILING_TASK_NETWORK_PROTOCOL_ANALYZE_PARALLELS:2}
         # The size of per paralleled analyzer queue
-        queue_size: ${ROVER_PROFILING_TASK_NETWORK_PROTOCOL_ANALYZE_QUEUE_SIZE:5000}
\ No newline at end of file
+        queue_size: ${ROVER_PROFILING_TASK_NETWORK_PROTOCOL_ANALYZE_QUEUE_SIZE:5000}
+        # The profiling config of the protocols
+        sampling:
+          # The HTTP/1.x and HTTP/2.x profiling config
+          http:
+            # The default body encoding when sampling the request
+            default_request_encoding: ${ROVER_PROFILING_TASK_NETWORK_PROTOCOL_ANALYZE_SAMPLING_HTTP_DEFAULT_REQUEST_ENCODING:UTF-8}
+            # The default body encoding when sampling the response
+            default_response_encoding: ${ROVER_PROFILING_TASK_NETWORK_PROTOCOL_ANALYZE_SAMPLING_HTTP_DEFAULT_RESPONSE_ENCODING:UTF-8}
\ No newline at end of file
diff --git a/docs/en/setup/configuration/profiling.md b/docs/en/setup/configuration/profiling.md
index 95bae91..8a8411c 100644
--- a/docs/en/setup/configuration/profiling.md
+++ b/docs/en/setup/configuration/profiling.md
@@ -5,17 +5,19 @@ and send the snapshot to the backend server.
 
 ## Configuration
 
-| Name                                                   | Default     | Environment Key                                              | Description                                                         |
-|--------------------------------------------------------|-------------|--------------------------------------------------------------|---------------------------------------------------------------------|
-| profiling.active                                       | true        | ROVER_PROFILING_ACTIVE                                       | Is active the process profiling.                                    |
-| profiling.check_interval                               | 10s         | ROVER_PROFILING_CHECK_INTERVAL                               | Check the profiling task interval.                                  |
-| profiling.flush_interval                               | 5s          | ROVER_PROFILING_FLUSH_INTERVAL                               | Combine existing profiling data and report to the backend interval. |
-| profiling.task.on_cpu.dump_period                      | 9ms         | ROVER_PROFILING_TASK_ON_CPU_DUMP_PERIOD                      | The profiling stack dump period.                                    |
-| profiling.task.network.report_interval                 | 2s          | ROVER_PROFILING_TASK_NETWORK_TOPOLOGY_REPORT_INTERVAL        | The interval of send metrics to the backend.                        |
-| profiling.task.network.meter_prefix                    | rover_net_p | ROVER_PROFILING_TASK_NETWORK_TOPOLOGY_METER_PREFIX           | The prefix of network profiling metrics name.                       |
-| profiling.task.network.protocol_analyze.per_cpu_buffer | 400KB       | ROVER_PROFILING_TASK_NETWORK_PROTOCOL_ANALYZE_PER_CPU_BUFFER | The size of socket data buffer on each CPU.                         |
-| profiling.task.network.protocol_analyze.parallels      | 2           | ROVER_PROFILING_TASK_NETWORK_PROTOCOL_ANALYZE_PARALLELS      | The count of parallel protocol analyzer.                            |
-| profiling.task.network.protocol_analyze.queue_size     | 5000        | ROVER_PROFILING_TASK_NETWORK_PROTOCOL_ANALYZE_QUEUE_SIZE     | The size of per paralleled analyzer queue.                          |
+| Name                                                                            | Default     | Environment Key                                                                       | Description                                                         |
+|---------------------------------------------------------------------------------|-------------|---------------------------------------------------------------------------------------|---------------------------------------------------------------------|
+| profiling.active                                                                | true        | ROVER_PROFILING_ACTIVE                                                                | Is active the process profiling.                                    |
+| profiling.check_interval                                                        | 10s         | ROVER_PROFILING_CHECK_INTERVAL                                                        | Check the profiling task interval.                                  |
+| profiling.flush_interval                                                        | 5s          | ROVER_PROFILING_FLUSH_INTERVAL                                                        | Combine existing profiling data and report to the backend interval. |
+| profiling.task.on_cpu.dump_period                                               | 9ms         | ROVER_PROFILING_TASK_ON_CPU_DUMP_PERIOD                                               | The profiling stack dump period.                                    |
+| profiling.task.network.report_interval                                          | 2s          | ROVER_PROFILING_TASK_NETWORK_TOPOLOGY_REPORT_INTERVAL                                 | The interval of send metrics to the backend.                        |
+| profiling.task.network.meter_prefix                                             | rover_net_p | ROVER_PROFILING_TASK_NETWORK_TOPOLOGY_METER_PREFIX                                    | The prefix of network profiling metrics name.                       |
+| profiling.task.network.protocol_analyze.per_cpu_buffer                          | 400KB       | ROVER_PROFILING_TASK_NETWORK_PROTOCOL_ANALYZE_PER_CPU_BUFFER                          | The size of socket data buffer on each CPU.                         |
+| profiling.task.network.protocol_analyze.parallels                               | 2           | ROVER_PROFILING_TASK_NETWORK_PROTOCOL_ANALYZE_PARALLELS                               | The count of parallel protocol analyzer.                            |
+| profiling.task.network.protocol_analyze.queue_size                              | 5000        | ROVER_PROFILING_TASK_NETWORK_PROTOCOL_ANALYZE_QUEUE_SIZE                              | The size of per paralleled analyzer queue.                          |
+| profiling.task.network.protocol_analyze.sampling.http.default_request_encoding  | UTF-8       | ROVER_PROFILING_TASK_NETWORK_PROTOCOL_ANALYZE_SAMPLING_HTTP_DEFAULT_REQUEST_ENCODING  | The default body encoding when sampling the request.                |
+| profiling.task.network.protocol_analyze.sampling.http.default_response_encoding | UTF-8       | ROVER_PROFILING_TASK_NETWORK_PROTOCOL_ANALYZE_SAMPLING_HTTP_DEFAULT_RESPONSE_ENCODING | The default body encoding when sampling the response.               |
 
 ## Profiling Type
 
diff --git a/pkg/profiling/module.go b/pkg/profiling/module.go
index 88b149c..43ccf5f 100644
--- a/pkg/profiling/module.go
+++ b/pkg/profiling/module.go
@@ -59,6 +59,9 @@ func (m *Module) Start(ctx context.Context, mgr *module.Manager) error {
 	if err := rlimit.RemoveMemlock(); err != nil {
 		return err
 	}
+	if err := m.config.TaskConfig.Validate(); err != nil {
+		return err
+	}
 
 	manager, err := NewManager(ctx, mgr, m.config)
 	if err != nil {
diff --git a/pkg/profiling/task/base/config.go b/pkg/profiling/task/base/config.go
index ce369f1..2b89e0d 100644
--- a/pkg/profiling/task/base/config.go
+++ b/pkg/profiling/task/base/config.go
@@ -17,6 +17,13 @@
 
 package base
 
+import (
+	"fmt"
+	"time"
+
+	"golang.org/x/net/html/charset"
+)
+
 type TaskConfig struct {
 	OnCPU   *OnCPUConfig   `mapstructure:"on_cpu"`  // ON_CPU type of profiling task config
 	Network *NetworkConfig `mapstructure:"network"` // NETWORK type of profiling task config
@@ -33,7 +40,79 @@ type NetworkConfig struct {
 }
 
 type ProtocolAnalyzeConfig struct {
-	PerCPUBufferSize string `mapstructure:"per_cpu_buffer"`
-	Parallels        int    `mapstructure:"parallels"`
-	QueueSize        int    `mapstructure:"queue_size"`
+	PerCPUBufferSize string         `mapstructure:"per_cpu_buffer"`
+	Parallels        int            `mapstructure:"parallels"`
+	QueueSize        int            `mapstructure:"queue_size"`
+	Sampling         SamplingConfig `mapstructure:"sampling"`
+}
+
+type SamplingConfig struct {
+	HTTP HTTPSamplingConfig `mapstructure:"http"`
+}
+
+type HTTPSamplingConfig struct {
+	DefaultRequestEncoding  string `mapstructure:"default_request_encoding"`  // default http request body encoding
+	DefaultResponseEncoding string `mapstructure:"default_response_encoding"` // default http response body encoding
+}
+
+func (c *TaskConfig) Validate() error {
+	var err error
+	network := c.Network
+	if network != nil {
+		err = c.durationValidate(err, network.ReportInterval, "parsing report interval failure: %v")
+		err = c.stringNotEmpty(err, network.MeterPrefix, "meter prefix must be set")
+
+		protocolAnalyze := network.ProtocolAnalyze
+		err = c.biggerThan(err, protocolAnalyze.Parallels, 0, "network protocol analyzer parallels must be bigger than 0")
+		err = c.biggerThan(err, protocolAnalyze.QueueSize, 0, "network protocol analyzer queue size must be bigger than 0")
+
+		httpSampling := protocolAnalyze.Sampling.HTTP
+		err = c.validateHTTPEncoding(err, httpSampling.DefaultRequestEncoding, "request")
+		err = c.validateHTTPEncoding(err, httpSampling.DefaultResponseEncoding, "response")
+	}
+	return err
+}
+
+func (c *TaskConfig) durationValidate(err error, value, message string) error {
+	if err != nil {
+		return err
+	}
+	_, err = time.ParseDuration(value)
+	if err != nil {
+		return fmt.Errorf(message, err)
+	}
+	return nil
+}
+
+func (c *TaskConfig) stringNotEmpty(err error, value, message string) error {
+	if err != nil {
+		return err
+	}
+	if value == "" {
+		return fmt.Errorf(message)
+	}
+	return nil
+}
+
+func (c *TaskConfig) biggerThan(err error, value, needs int, message string) error {
+	if err != nil {
+		return err
+	}
+	if value <= needs {
+		return fmt.Errorf(message)
+	}
+	return nil
+}
+
+func (c *TaskConfig) validateHTTPEncoding(err error, encoding, configType string) error {
+	if err != nil {
+		return err
+	}
+	if encoding == "" {
+		return fmt.Errorf("the default HTTP %s encoding must be set", configType)
+	}
+	if e, _ := charset.Lookup(encoding); e == nil {
+		return fmt.Errorf("unknown charset: %s", encoding)
+	}
+	return nil
 }
diff --git a/pkg/profiling/task/base/task.go b/pkg/profiling/task/base/task.go
index 725c77d..dc12577 100644
--- a/pkg/profiling/task/base/task.go
+++ b/pkg/profiling/task/base/task.go
@@ -92,7 +92,7 @@ type ExtensionConfig struct {
 
 type NetworkSamplingRule struct {
 	URIRegex    *string                        `json:"URIRegex"`
-	MinDuration int32                          `json:"MinDuration"`
+	MinDuration *int32                         `json:"MinDuration"`
 	When4XX     bool                           `json:"When4xx"`
 	When5XX     bool                           `json:"When5xx"`
 	Settings    *NetworkDataCollectingSettings `json:"Settings"`
diff --git a/pkg/profiling/task/network/analyze/layer7/events.go b/pkg/profiling/task/network/analyze/layer7/events.go
index e932f4d..9096913 100644
--- a/pkg/profiling/task/network/analyze/layer7/events.go
+++ b/pkg/profiling/task/network/analyze/layer7/events.go
@@ -26,9 +26,9 @@ import (
 	"github.com/apache/skywalking-rover/pkg/profiling/task/network/bpf"
 )
 
-func (l *Listener) initSocketDataQueue(parallels, queueSize int) {
+func (l *Listener) initSocketDataQueue(parallels, queueSize int, config *profiling.TaskConfig) {
 	l.socketDataQueue = NewEventQueue(parallels, queueSize, func() PartitionContext {
-		return NewSocketDataPartitionContext(l)
+		return NewSocketDataPartitionContext(l, config)
 	})
 }
 
@@ -55,9 +55,9 @@ type SocketDataPartitionContext struct {
 	analyzer *protocols.Analyzer
 }
 
-func NewSocketDataPartitionContext(l base.Context) *SocketDataPartitionContext {
+func NewSocketDataPartitionContext(l base.Context, config *profiling.TaskConfig) *SocketDataPartitionContext {
 	return &SocketDataPartitionContext{
-		analyzer: protocols.NewAnalyzer(l),
+		analyzer: protocols.NewAnalyzer(l, config),
 	}
 }
 
diff --git a/pkg/profiling/task/network/analyze/layer7/listener.go b/pkg/profiling/task/network/analyze/layer7/listener.go
index 8d49b3e..8edb532 100644
--- a/pkg/profiling/task/network/analyze/layer7/listener.go
+++ b/pkg/profiling/task/network/analyze/layer7/listener.go
@@ -79,7 +79,7 @@ func (l *Listener) Init(config *profiling.TaskConfig, moduleManager *module.Mana
 	}
 
 	l.protocolPerCPUBuffer = int(perCPUBufferSize)
-	l.initSocketDataQueue(analyzeConfig.Parallels, analyzeConfig.QueueSize)
+	l.initSocketDataQueue(analyzeConfig.Parallels, analyzeConfig.QueueSize, config)
 	return nil
 }
 
diff --git a/pkg/profiling/task/network/analyze/layer7/protocols/base/protocol.go b/pkg/profiling/task/network/analyze/layer7/protocols/base/protocol.go
index 6d54b3b..8afb92e 100644
--- a/pkg/profiling/task/network/analyze/layer7/protocols/base/protocol.go
+++ b/pkg/profiling/task/network/analyze/layer7/protocols/base/protocol.go
@@ -25,6 +25,7 @@ import (
 type Protocol interface {
 	Name() string
 	GenerateMetrics() Metrics
+	Init(config *profiling.TaskConfig)
 
 	ReceiveData(context Context, event *SocketDataUploadEvent) bool
 	UpdateExtensionConfig(config *profiling.ExtensionConfig)
diff --git a/pkg/profiling/task/network/analyze/layer7/protocols/http1/analyzer.go b/pkg/profiling/task/network/analyze/layer7/protocols/http1/analyzer.go
index 0df4242..499f803 100644
--- a/pkg/profiling/task/network/analyze/layer7/protocols/http1/analyzer.go
+++ b/pkg/profiling/task/network/analyze/layer7/protocols/http1/analyzer.go
@@ -90,6 +90,10 @@ func (h *Analyzer) GenerateMetrics() protocol.Metrics {
 	}
 }
 
+func (h *Analyzer) Init(config *profiling.TaskConfig) {
+	h.sampleConfig = NewSamplingConfig(config)
+}
+
 func (h *Analyzer) ReceiveData(context protocol.Context, event *protocol.SocketDataUploadEvent) bool {
 	// only handle the HTTP1 protocol
 	if event.Protocol != base.ConnectionProtocolHTTP {
@@ -138,10 +142,7 @@ func (h *Analyzer) UpdateExtensionConfig(config *profiling.ExtensionConfig) {
 	if config == nil {
 		return
 	}
-	c := NewSamplingConfig(config.NetworkSamplings)
-	if c != nil {
-		h.sampleConfig = c
-	}
+	h.sampleConfig.UpdateRules(config.NetworkSamplings)
 }
 
 func (h *Analyzer) combineAndRemoveEvent(halfConnections *list.List, firstElement *list.Element,
diff --git a/pkg/profiling/task/network/analyze/layer7/protocols/http1/metrics.go b/pkg/profiling/task/network/analyze/layer7/protocols/http1/metrics.go
index 06b1a56..7053216 100644
--- a/pkg/profiling/task/network/analyze/layer7/protocols/http1/metrics.go
+++ b/pkg/profiling/task/network/analyze/layer7/protocols/http1/metrics.go
@@ -32,7 +32,7 @@ import (
 	"golang.org/x/net/html/charset"
 
 	"github.com/apache/skywalking-rover/pkg/process/api"
-	task "github.com/apache/skywalking-rover/pkg/profiling/task/base"
+	profiling "github.com/apache/skywalking-rover/pkg/profiling/task/base"
 	"github.com/apache/skywalking-rover/pkg/profiling/task/network/analyze/base"
 	protocol "github.com/apache/skywalking-rover/pkg/profiling/task/network/analyze/layer7/protocols/base"
 	"github.com/apache/skywalking-rover/pkg/profiling/task/network/analyze/layer7/protocols/metrics"
@@ -182,7 +182,8 @@ type Trace struct {
 	ResponseBuffer protocol.SocketDataBuffer
 	Response       *http.Response
 	Type           string
-	Settings       *task.NetworkDataCollectingSettings
+	Settings       *profiling.NetworkDataCollectingSettings
+	TaskConfig     *profiling.HTTPSamplingConfig
 }
 
 func (h *Trace) Flush(duration int64, process api.ProcessInterface, traffic *base.ProcessTraffic, metricsBuilder *base.MetricsBuilder) {
@@ -248,7 +249,7 @@ func (h *Trace) AppendHTTPEvents(process api.ProcessInterface, traffic *base.Pro
 
 func (h *Trace) appendHTTPEvent(events []*v3.SpanAttachedEvent, process api.ProcessInterface, traffic *base.ProcessTraffic,
 	tp string, header http.Header, body io.Reader, buffer protocol.SocketDataBuffer, maxSize int32) []*v3.SpanAttachedEvent {
-	content, err := h.transformHTTPRequest(header, body, buffer, maxSize)
+	content, err := h.transformHTTPBody(tp, header, body, buffer, maxSize)
 	if err != nil {
 		log.Warnf("transform http %s erorr: %v", tp, err)
 		return events
@@ -289,15 +290,22 @@ func (h *Trace) appendHTTPEvent(events []*v3.SpanAttachedEvent, process api.Proc
 }
 
 // nolint
-func (h *Trace) transformHTTPRequest(header http.Header, body io.Reader, buffer protocol.SocketDataBuffer, maxSize int32) (string, error) {
+func (h *Trace) transformHTTPBody(tp string, header http.Header, _ io.Reader, buffer protocol.SocketDataBuffer, maxSize int32) (string, error) {
 	var needGzip, isPlain, isUtf8 = header.Get("Content-Encoding") == "gzip", true, true
 	contentType := header.Get("Content-Type")
-	if contentType != "" {
-		isPlain = strings.HasPrefix(contentType, "text/") || contentType == "application/json"
-		if _, params, err := mime.ParseMediaType(contentType); err == nil {
-			if cs, ok := params["charset"]; ok {
-				isUtf8 = cs == "utf-8"
-			}
+	if contentType == "" {
+		if tp == transportRequest {
+			contentType = h.TaskConfig.DefaultRequestEncoding
+		} else {
+			contentType = h.TaskConfig.DefaultResponseEncoding
+		}
+		contentType = fmt.Sprintf("text/html; charset=%s", contentType)
+	}
+
+	isPlain = strings.HasPrefix(contentType, "text/") || contentType == "application/json"
+	if _, params, err := mime.ParseMediaType(contentType); err == nil {
+		if cs, ok := params["charset"]; ok {
+			isUtf8 = strings.ToLower(cs) == "utf-8"
 		}
 	}
 
@@ -311,11 +319,21 @@ func (h *Trace) transformHTTPRequest(header http.Header, body io.Reader, buffer
 
 	// re-read the buffer and skip to the body position
 	buf := bufio.NewReaderSize(bytes.NewBuffer(buffer.BufferData()), len(buffer.BufferData()))
-	response, err := http.ReadResponse(buf, nil)
-	if err != nil {
-		return "", err
+	var httpBody io.ReadCloser
+	if tp == transportRequest {
+		req, err := http.ReadRequest(buf)
+		if err != nil {
+			return "", err
+		}
+		httpBody = req.Body
+	} else {
+		response, err := http.ReadResponse(buf, nil)
+		if err != nil {
+			return "", err
+		}
+		httpBody = response.Body
 	}
-	defer response.Body.Close()
+	defer httpBody.Close()
 
 	// no text plain, no need to print the data
 	headerLen := len(buffer.BufferData()) - buf.Buffered()
@@ -326,10 +344,15 @@ func (h *Trace) transformHTTPRequest(header http.Header, body io.Reader, buffer
 	if !isPlain {
 		return fmt.Sprintf("%s[not plain, current content type: %s]", headerString, contentType), nil
 	}
+	// nobody
+	if buf.Buffered() == 0 {
+		return headerString, nil
+	}
 
-	data := response.Body
+	data := httpBody
+	var err error
 	if needGzip {
-		data, err = gzip.NewReader(response.Body)
+		data, err = gzip.NewReader(httpBody)
 		if err != nil {
 			return "", err
 		}
diff --git a/pkg/profiling/task/network/analyze/layer7/protocols/http1/sampling.go b/pkg/profiling/task/network/analyze/layer7/protocols/http1/sampling.go
index 830b271..75f602a 100644
--- a/pkg/profiling/task/network/analyze/layer7/protocols/http1/sampling.go
+++ b/pkg/profiling/task/network/analyze/layer7/protocols/http1/sampling.go
@@ -80,11 +80,6 @@ func (s *Sampler) AppendMetrics(config *SamplingConfig, duration time.Duration,
 		return
 	}
 
-	// if smaller than minimal duration, then ignore
-	if int64(rule.MinDuration) > duration.Milliseconds() {
-		return
-	}
-
 	var traceType string
 	var topN *metrics.TopN
 	if rule.When5XX && response.StatusCode >= 500 && response.StatusCode < 600 {
@@ -93,9 +88,11 @@ func (s *Sampler) AppendMetrics(config *SamplingConfig, duration time.Duration,
 	} else if rule.When4XX && response.StatusCode >= 400 && response.StatusCode < 500 {
 		traceType = "status_4xx"
 		topN = s.Error4xxTraces
-	} else {
+	} else if rule.MinDuration != nil && int64(*rule.MinDuration) <= duration.Milliseconds() {
 		traceType = "slow"
 		topN = s.SlowTraces
+	} else {
+		return
 	}
 
 	trace := &Trace{
@@ -107,6 +104,7 @@ func (s *Sampler) AppendMetrics(config *SamplingConfig, duration time.Duration,
 		Response:       response,
 		Type:           traceType,
 		Settings:       rule.Settings,
+		TaskConfig:     config.ProfilingSampling,
 	}
 	topN.AddRecord(trace, duration.Milliseconds())
 }
@@ -131,9 +129,10 @@ func (s *Sampler) String() string {
 }
 
 type SamplingConfig struct {
-	DefaultRule  *profiling.NetworkSamplingRule
-	URISamplings []*URISampling
-	uriRuleCache *lru.Cache
+	ProfilingSampling *profiling.HTTPSamplingConfig
+	DefaultRule       *profiling.NetworkSamplingRule
+	URISamplings      []*URISampling
+	uriRuleCache      *lru.Cache
 }
 
 type URISampling struct {
@@ -141,24 +140,28 @@ type URISampling struct {
 	Rule       *profiling.NetworkSamplingRule
 }
 
-func NewSamplingConfig(configs []*profiling.NetworkSamplingRule) *SamplingConfig {
-	if len(configs) == 0 {
-		return nil
-	}
+func NewSamplingConfig(config *profiling.TaskConfig) *SamplingConfig {
 	cache, err := lru.New(SamplingRuleCacheSize)
 	if err != nil {
 		log.Warnf("creating sampling cache config failure: %v", err)
 	}
-	result := &SamplingConfig{
-		uriRuleCache: cache,
+	return &SamplingConfig{
+		ProfilingSampling: &config.Network.ProtocolAnalyze.Sampling.HTTP,
+		uriRuleCache:      cache,
+	}
+}
+
+func (s *SamplingConfig) UpdateRules(configs []*profiling.NetworkSamplingRule) {
+	if len(configs) == 0 {
+		return
 	}
 	for _, c := range configs {
 		if c.URIRegex == nil {
-			if result.DefaultRule != nil {
+			if s.DefaultRule != nil {
 				log.Warnf("the default rule is already exists, so ignore it")
 				continue
 			}
-			result.DefaultRule = c
+			s.DefaultRule = c
 			continue
 		}
 
@@ -168,12 +171,11 @@ func NewSamplingConfig(configs []*profiling.NetworkSamplingRule) *SamplingConfig
 			continue
 		}
 
-		result.URISamplings = append(result.URISamplings, &URISampling{
+		s.URISamplings = append(s.URISamplings, &URISampling{
 			URIMatcher: uriPattern,
 			Rule:       c,
 		})
 	}
-	return result
 }
 
 func (s *SamplingConfig) findMatchesRule(uri string) *profiling.NetworkSamplingRule {
diff --git a/pkg/profiling/task/network/analyze/layer7/protocols/protocols.go b/pkg/profiling/task/network/analyze/layer7/protocols/protocols.go
index 743ea30..4028039 100644
--- a/pkg/profiling/task/network/analyze/layer7/protocols/protocols.go
+++ b/pkg/profiling/task/network/analyze/layer7/protocols/protocols.go
@@ -46,10 +46,12 @@ type Analyzer struct {
 	protocols []protocol.Protocol
 }
 
-func NewAnalyzer(ctx protocol.Context) *Analyzer {
+func NewAnalyzer(ctx protocol.Context, config *profiling.TaskConfig) *Analyzer {
 	protocols := make([]protocol.Protocol, 0)
 	for _, r := range registerProtocols {
-		protocols = append(protocols, r())
+		p := r()
+		p.Init(config)
+		protocols = append(protocols, p)
 	}
 	return &Analyzer{
 		ctx:       ctx,
diff --git a/test/e2e/cases/profiling/network/base/rover_configs.yaml b/test/e2e/cases/profiling/network/base/rover_configs.yaml
index d49868b..4d94725 100644
--- a/test/e2e/cases/profiling/network/base/rover_configs.yaml
+++ b/test/e2e/cases/profiling/network/base/rover_configs.yaml
@@ -144,4 +144,12 @@ profiling:
         # The count of parallel protocol analyzer
         parallels: ${ROVER_PROFILING_TASK_NETWORK_PROTOCOL_ANALYZE_PARALLELS:2}
         # The size of per paralleled analyzer queue
-        queue_size: ${ROVER_PROFILING_TASK_NETWORK_PROTOCOL_ANALYZE_QUEUE_SIZE:5000}
\ No newline at end of file
+        queue_size: ${ROVER_PROFILING_TASK_NETWORK_PROTOCOL_ANALYZE_QUEUE_SIZE:5000}
+        # The profiling config of the protocols
+        sampling:
+          # The HTTP/1.x and HTTP/2.x profiling config
+          http:
+            # The default body encoding when sampling the request
+            default_request_encoding: ${ROVER_PROFILING_TASK_NETWORK_PROTOCOL_ANALYZE_SAMPLING_HTTP_DEFAULT_REQUEST_ENCODING:UTF-8}
+            # The default body encoding when sampling the response
+            default_response_encoding: ${ROVER_PROFILING_TASK_NETWORK_PROTOCOL_ANALYZE_SAMPLING_HTTP_DEFAULT_RESPONSE_ENCODING:UTF-8}
\ No newline at end of file
diff --git a/test/e2e/cases/profiling/network/sampling.yaml b/test/e2e/cases/profiling/network/sampling.yaml
index 313c42b..2ed2eab 100644
--- a/test/e2e/cases/profiling/network/sampling.yaml
+++ b/test/e2e/cases/profiling/network/sampling.yaml
@@ -21,7 +21,8 @@
 
 
 samplings:
-  - when_4xx: true
+  - min_duration: 1
+    when_4xx: true
     when_5xx: true
     setting:
       require_request: true