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

[skywalking-rover] branch main updated: Support upload slow trace (#57)

This is an automated email from the ASF dual-hosted git repository.

liuhan 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 dbefcc5  Support upload slow trace (#57)
dbefcc5 is described below

commit dbefcc5fbaef3c9d1d3820b8f9f4079216a41a66
Author: mrproliu <74...@qq.com>
AuthorDate: Tue Nov 1 17:18:04 2022 +0800

    Support upload slow trace (#57)
---
 .github/workflows/rover.yaml                       |  16 +-
 docs/en/setup/configuration/profiling.md           |  73 +++---
 pkg/profiling/task/network/analyze/base/metrics.go |  53 +++-
 .../task/network/analyze/layer7/protocols/http1.go | 270 +++++++++++++++------
 .../analyze/layer7/protocols/metrics/base.go       |  15 +-
 .../analyze/layer7/protocols/metrics/topn.go       |  99 ++++++++
 .../network/analyze/layer7/protocols/tracing.go    | 124 ++++++++++
 pkg/profiling/task/network/runner.go               |  65 ++++-
 test/e2e/base/env                                  |   4 +-
 .../profiling/network/base/docker-compose.yml      |   6 +
 .../profiling/network/base/network-profiling.yaml  |   1 +
 test/e2e/cases/profiling/network/base/nginx.conf   |   5 +
 .../profiling/network/base/slow-trace-lal.yaml     |  64 +++++
 .../cases/profiling/network/c_plus_plus/e2e.yaml   |   2 +-
 .../network/expected/skywalking-trace.yml}         |  26 +-
 .../profiling/network/expected/slow-traces.yml}    |  15 +-
 .../profiling/network/expected/zipkin-trace.yml}   |  21 +-
 test/e2e/cases/profiling/network/golang/Dockerfile |   8 +-
 .../profiling/network/golang/docker-compose.yml    |   5 +
 test/e2e/cases/profiling/network/golang/e2e.yaml   |   3 +-
 test/e2e/cases/profiling/network/golang/go.mod     |  18 ++
 test/e2e/cases/profiling/network/golang/go.sum     | 170 +++++++++++++
 test/e2e/cases/profiling/network/golang/service.go |  77 +++++-
 .../{http1-cases.yaml => http1-metrics-cases.yaml} |   0
 .../profiling/network/http1-slow-traces-cases.yaml |  38 +++
 test/e2e/cases/profiling/network/nodejs/e2e.yaml   |   2 +-
 test/e2e/cases/profiling/network/python/e2e.yaml   |   2 +-
 27 files changed, 1005 insertions(+), 177 deletions(-)

diff --git a/.github/workflows/rover.yaml b/.github/workflows/rover.yaml
index 6011c4c..8ac40f4 100644
--- a/.github/workflows/rover.yaml
+++ b/.github/workflows/rover.yaml
@@ -115,7 +115,7 @@ jobs:
             config: test/e2e/cases/process/istio/e2e.yaml
             env: ISTIO_VERSION=1.13.1
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
         with:
           submodules: true
       - uses: actions/download-artifact@v2
@@ -125,14 +125,10 @@ jobs:
           path: docker-images
       - name: Load docker images
         run: find docker-images -name "*.tar" -exec docker load -i {} \;
-      - name: Setup Go
-        uses: actions/setup-go@v2
-        with:
-          go-version: '1.16'
       - name: Set env var
         run: echo "${{ matrix.test.env }}"  >> $GITHUB_ENV
       - name: ${{ matrix.test.name }}
-        uses: apache/skywalking-infra-e2e@main
+        uses: apache/skywalking-infra-e2e@c3eb3241f649289465eda12af8214ca60aaaaa5f
         with:
           e2e-file: $GITHUB_WORKSPACE/${{ matrix.test.config }}
       - uses: actions/upload-artifact@v2
@@ -166,7 +162,7 @@ jobs:
           - name: HTTP2 Profiling
             config: test/e2e/cases/profiling/network/http2/e2e.yaml
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
         with:
           submodules: true
       - uses: actions/download-artifact@v2
@@ -176,10 +172,6 @@ jobs:
           path: docker-images
       - name: Load docker images
         run: find docker-images -name "*.tar" -exec docker load -i {} \;
-      - name: Setup Go
-        uses: actions/setup-go@v2
-        with:
-          go-version: '1.16'
       - name: Set env var
         run: echo "${{ matrix.test.env }}"  >> $GITHUB_ENV
       - name: Setup SSL Certs
@@ -187,7 +179,7 @@ jobs:
           bash test/e2e/cases/profiling/network/base/ssl/gen-selfsigned-ssl.sh service
           bash test/e2e/cases/profiling/network/base/ssl/gen-selfsigned-ssl.sh proxy
       - name: ${{ matrix.test.name }}
-        uses: apache/skywalking-infra-e2e@main
+        uses: apache/skywalking-infra-e2e@c3eb3241f649289465eda12af8214ca60aaaaa5f
         with:
           e2e-file: $GITHUB_WORKSPACE/${{ matrix.test.config }}
       - uses: actions/upload-artifact@v2
diff --git a/docs/en/setup/configuration/profiling.md b/docs/en/setup/configuration/profiling.md
index 1004209..5811306 100644
--- a/docs/en/setup/configuration/profiling.md
+++ b/docs/en/setup/configuration/profiling.md
@@ -43,9 +43,9 @@ Also, the following protocol are supported for analyzing using OpenSSL library,
 6. Kafka
 7. DNS
 
-#### Metrics
+#### Collecting data
 
-Network profiling uses metrics send data to the backend service.
+Network profiling uses metrics, logs send to the backend service.
 
 ##### Data Type
 
@@ -55,46 +55,55 @@ The network profiling has customized the following two types of metrics to repre
    2. **Bytes**: The package size of the execution.
    3. **Exe Time**: The consumed time(nanosecond) of the execution. 
 2. **Histogram**: Records the distribution of the data in the bucket.
+3. **TopN**: Record the highest latency data in a certain period of time.
 
 ##### Labels
 
 Each metric contains the following labels to identify the process relationship:
 
-| Name | Type | Description |
-|------|------|-------------|
-|client_process_id or server_process_id| string | The ID of the current process, which is determined by the role of the current process in the connection as server or client. |
-|client_local or server_local| boolean | The remote process is a local process. |
-|client_address or server_address| string | The remote process address. ex: `IP:port`. |
-|side| enum | The current process is either "client" or "server" in this connection. |
-|protocol| string | Identification the protocol based on the package data content. |
-|is_ssl| bool | Is the current connection using SSL. |
+| Name                                     | Type    | Description                                                                                                                  |
+|------------------------------------------|---------|------------------------------------------------------------------------------------------------------------------------------|
+| client_process_id or server_process_id   | string  | The ID of the current process, which is determined by the role of the current process in the connection as server or client. |
+| client_local or server_local             | boolean | The remote process is a local process.                                                                                       |
+| client_address or server_address         | string  | The remote process address. ex: `IP:port`.                                                                                   |
+| side                                     | enum    | The current process is either "client" or "server" in this connection.                                                       |
+| protocol                                 | string  | Identification the protocol based on the package data content.                                                               |
+| is_ssl                                   | bool    | Is the current connection using SSL.                                                                                         |
 
 ##### Layer-4 Data
 
 Based on the above two data types, the following metrics are provided. 
 
-| Name | Type| Unit | Description |
-|------|-----|------|-------------|
-|write|Counter|nanosecond|The socket write counter|
-|read|Counter|nanosecond|The socket read counter|
-|write RTT|Counter|microsecond|The socket write RTT counter|
-|connect|Counter|nanosecond|The socket connect/accept with other server/client counter|
-|close|Counter|nanosecond|The socket close counter|
-|retransmit|Counter|nanosecond|The socket retransmit package counter|
-|drop|Counter|nanosecond|The socket drop package counter|
-|write RTT|Histogram|microsecond|The socket write RTT execute time histogram|
-|write execute time|Histogram|nanosecond|The socket write data execute time histogram|
-|read execute time|Histogram|nanosecond|The socket read data execute time histogram|
-|connect execute time|Histogram|nanosecond|The socket connect/accept with other server/client execute time histogram|
-|close execute time|Histogram|nanosecond|The socket close execute time histogram|
+| Name                  | Type      | Unit         | Description                                                               |
+|-----------------------|-----------|--------------|---------------------------------------------------------------------------|
+| write                 | Counter   | nanosecond   | The socket write counter                                                  |
+| read                  | Counter   | nanosecond   | The socket read counter                                                   |
+| write RTT             | Counter   | microsecond  | The socket write RTT counter                                              |
+| connect               | Counter   | nanosecond   | The socket connect/accept with other server/client counter                |
+| close                 | Counter   | nanosecond   | The socket close counter                                                  |
+| retransmit            | Counter   | nanosecond   | The socket retransmit package counter                                     |
+| drop                  | Counter   | nanosecond   | The socket drop package counter                                           |
+| write RTT             | Histogram | microsecond  | The socket write RTT execute time histogram                               |
+| write execute time    | Histogram | nanosecond   | The socket write data execute time histogram                              |
+| read execute time     | Histogram | nanosecond   | The socket read data execute time histogram                               |
+| connect execute time  | Histogram | nanosecond   | The socket connect/accept with other server/client execute time histogram |
+| close execute time    | Histogram | nanosecond   | The socket close execute time histogram                                   |
 
 ##### HTTP/1.x Data
 
-| Name                        | Type      | Unit        | Description                                                               |
-|-----------------------------|-----------|-------------|---------------------------------------------------------------------------|
-| http1_request_cpm           | Counter   | count       | The HTTP request counter                                                  |
-| http1_response_status_cpm   | Counter   | count       | The count of per HTTP response code                                       |
-| http1_request_package_size  | Histogram | Byte size   | The request package size                                                  |
-| http1_response_package_size | Histogram | Byte size   | The response package size                                                 |
-| http1_client_duration       | Histogram | millisecond | The duration of single HTTP response on the client side                   |
-| http1_server_duration       | Histogram | millisecond | The duration of single HTTP response on the server side                   |
\ No newline at end of file
+##### Metrics
+
+| Name                        | Type      | Unit        | Description                                             |
+|-----------------------------|-----------|-------------|---------------------------------------------------------|
+| http1_request_cpm           | Counter   | count       | The HTTP request counter                                |
+| http1_response_status_cpm   | Counter   | count       | The count of per HTTP response code                     |
+| http1_request_package_size  | Histogram | Byte size   | The request package size                                |
+| http1_response_package_size | Histogram | Byte size   | The response package size                               |
+| http1_client_duration       | Histogram | millisecond | The duration of single HTTP response on the client side |
+| http1_server_duration       | Histogram | millisecond | The duration of single HTTP response on the server side |
+
+##### Logs 
+
+| Name         | Type  | Unit        | Description                |
+|--------------|-------|-------------|----------------------------|
+| slow_traces  | TopN  | millisecond | The Top N slow trace(id)s  |
\ No newline at end of file
diff --git a/pkg/profiling/task/network/analyze/base/metrics.go b/pkg/profiling/task/network/analyze/base/metrics.go
index bc0a176..15a1438 100644
--- a/pkg/profiling/task/network/analyze/base/metrics.go
+++ b/pkg/profiling/task/network/analyze/base/metrics.go
@@ -24,7 +24,8 @@ import (
 	"github.com/apache/skywalking-rover/pkg/process/api"
 	"github.com/apache/skywalking-rover/pkg/tools"
 
-	v3 "skywalking.apache.org/repo/goapi/collect/language/agent/v3"
+	agentv3 "skywalking.apache.org/repo/goapi/collect/language/agent/v3"
+	logv3 "skywalking.apache.org/repo/goapi/collect/logging/v3"
 )
 
 // ConnectionMetrics The Metrics in each listener
@@ -57,18 +58,20 @@ func (c *ConnectionMetricsContext) MergeMetricsFromConnection(connection *Connec
 
 type MetricsBuilder struct {
 	prefix  string
-	metrics map[metadata][]*v3.MeterData
+	metrics map[metadata][]*agentv3.MeterData
+	logs    map[metadata][]*logv3.LogData
 }
 
 func NewMetricsBuilder(prefix string) *MetricsBuilder {
 	return &MetricsBuilder{
 		prefix:  prefix,
-		metrics: make(map[metadata][]*v3.MeterData),
+		metrics: make(map[metadata][]*agentv3.MeterData),
+		logs:    make(map[metadata][]*logv3.LogData),
 	}
 }
 
-func (m *MetricsBuilder) AppendMetrics(service, instance string, metrics []*v3.MeterData) {
-	meta := metadata{ServiceName: service, InstanceName: instance}
+func (m *MetricsBuilder) AppendMetrics(service, instance string, metrics []*agentv3.MeterData) {
+	meta := metadata{Layer: "", ServiceName: service, InstanceName: instance}
 	existingMetrics := m.metrics[meta]
 	if len(existingMetrics) == 0 {
 		m.metrics[meta] = metrics
@@ -77,17 +80,22 @@ func (m *MetricsBuilder) AppendMetrics(service, instance string, metrics []*v3.M
 	m.metrics[meta] = append(existingMetrics, metrics...)
 }
 
+func (m *MetricsBuilder) AppendLogs(service string, log *logv3.LogData) {
+	meta := metadata{ServiceName: service}
+	m.logs[meta] = append(m.logs[meta], log)
+}
+
 func (m *MetricsBuilder) MetricPrefix() string {
 	return m.prefix
 }
 
-func (m *MetricsBuilder) BuildBasicMeterLabels(traffic *ProcessTraffic, local api.ProcessInterface) (ConnectionRole, []*v3.Label) {
+func (m *MetricsBuilder) BuildBasicMeterLabels(traffic *ProcessTraffic, local api.ProcessInterface) (ConnectionRole, []*agentv3.Label) {
 	curRole := traffic.Role
 	// add the default role
 	if curRole == ConnectionRoleUnknown {
 		curRole = ConnectionRoleClient
 	}
-	labels := make([]*v3.Label, 0)
+	labels := make([]*agentv3.Label, 0)
 
 	// two pair process/address info
 	labels = m.appendMeterValue(labels, fmt.Sprintf("%s_process_id", curRole.String()), local.ID())
@@ -101,8 +109,8 @@ func (m *MetricsBuilder) BuildBasicMeterLabels(traffic *ProcessTraffic, local ap
 	return curRole, labels
 }
 
-func (m *MetricsBuilder) Build() []*v3.MeterDataCollection {
-	collections := make([]*v3.MeterDataCollection, 0)
+func (m *MetricsBuilder) BuildMetrics() []*agentv3.MeterDataCollection {
+	collections := make([]*agentv3.MeterDataCollection, 0)
 	now := time.Now().UnixMilli()
 	for meta, meters := range m.metrics {
 		if len(meters) == 0 {
@@ -111,17 +119,36 @@ func (m *MetricsBuilder) Build() []*v3.MeterDataCollection {
 		meters[0].Service = meta.ServiceName
 		meters[0].ServiceInstance = meta.InstanceName
 		meters[0].Timestamp = now
-		collections = append(collections, &v3.MeterDataCollection{MeterData: meters})
+		collections = append(collections, &agentv3.MeterDataCollection{MeterData: meters})
 	}
 	return collections
 }
 
+func (m *MetricsBuilder) BuildLogs() [][]*logv3.LogData {
+	result := make([][]*logv3.LogData, 0)
+	now := time.Now().UnixMilli()
+	for meta, logs := range m.logs {
+		if len(logs) == 0 {
+			continue
+		}
+		logs[0].Service = meta.ServiceName
+		// update the timestamp
+		for _, l := range logs {
+			l.Timestamp = now
+		}
+		result = append(result, logs)
+	}
+	return result
+}
+
 type metadata struct {
+	Layer        string
 	ServiceName  string
 	InstanceName string
 }
 
-func (m *MetricsBuilder) appendRemoteAddressInfo(labels []*v3.Label, traffic *ProcessTraffic, prefix string, local api.ProcessInterface) []*v3.Label {
+func (m *MetricsBuilder) appendRemoteAddressInfo(labels []*agentv3.Label, traffic *ProcessTraffic, prefix string,
+	local api.ProcessInterface) []*agentv3.Label {
 	if len(traffic.RemoteProcesses) != 0 {
 		for _, p := range traffic.RemoteProcesses {
 			// only match with same service instance
@@ -139,8 +166,8 @@ func (m *MetricsBuilder) appendRemoteAddressInfo(labels []*v3.Label, traffic *Pr
 	return m.appendMeterValue(labels, prefix+"_address", fmt.Sprintf("%s:%d", traffic.RemoteIP, traffic.RemotePort))
 }
 
-func (m *MetricsBuilder) appendMeterValue(labels []*v3.Label, name, value string) []*v3.Label {
-	return append(labels, &v3.Label{
+func (m *MetricsBuilder) appendMeterValue(labels []*agentv3.Label, name, value string) []*agentv3.Label {
+	return append(labels, &agentv3.Label{
 		Name:  name,
 		Value: value,
 	})
diff --git a/pkg/profiling/task/network/analyze/layer7/protocols/http1.go b/pkg/profiling/task/network/analyze/layer7/protocols/http1.go
index 15b49cc..2c88cbc 100644
--- a/pkg/profiling/task/network/analyze/layer7/protocols/http1.go
+++ b/pkg/profiling/task/network/analyze/layer7/protocols/http1.go
@@ -31,13 +31,16 @@ import (
 	"sync"
 	"time"
 
-	"github.com/sirupsen/logrus"
-
+	commonv3 "skywalking.apache.org/repo/goapi/collect/common/v3"
 	v3 "skywalking.apache.org/repo/goapi/collect/language/agent/v3"
+	logv3 "skywalking.apache.org/repo/goapi/collect/logging/v3"
+
+	"github.com/sirupsen/logrus"
 
 	"github.com/apache/skywalking-rover/pkg/process/api"
 	"github.com/apache/skywalking-rover/pkg/profiling/task/network/analyze/base"
 	"github.com/apache/skywalking-rover/pkg/profiling/task/network/analyze/layer7/protocols/metrics"
+	"github.com/apache/skywalking-rover/pkg/tools"
 )
 
 var HTTP1ProtocolName = "http1"
@@ -55,6 +58,8 @@ var HTTP1DurationHistogramBuckets = []float64{
 	330, 380, 430, 480, 500, 600, 700, 800, 900, 1000, 1100, 1300, 1500, 1800, 2000, 5000, 10000, 15000, 20000, 30000,
 }
 
+var SlowTraceTopNSize = 10
+
 type HTTP1Analyzer struct {
 	// cache connection metrics if the connect event not receive or process
 	cache map[string]*HTTP1ConnectionMetrics
@@ -64,8 +69,9 @@ type HTTP1ConnectionMetrics struct {
 	// halfData all data event(request/response) not finished
 	halfData *list.List
 
-	combinedMetrics *HTTP1URIMetrics
-	metricsLocker   sync.RWMutex
+	clientMetrics *HTTP1URIMetrics
+	serverMetrics *HTTP1URIMetrics
+	metricsLocker sync.RWMutex
 }
 
 type HTTP1URIMetrics struct {
@@ -77,10 +83,10 @@ type HTTP1URIMetrics struct {
 	ReqPackageSizeHistogram  *metrics.Histogram
 	RespPackageSizeHistogram *metrics.Histogram
 
-	ClientAvgDuration       *metrics.AvgCounter
-	ServerAvgDuration       *metrics.AvgCounter
-	ClientDurationHistogram *metrics.Histogram
-	ServerDurationHistogram *metrics.Histogram
+	avgDuration       *metrics.AvgCounter
+	durationHistogram *metrics.Histogram
+
+	slowTraces *metrics.TopN
 }
 
 func NewHTTP1URIMetrics() *HTTP1URIMetrics {
@@ -91,10 +97,9 @@ func NewHTTP1URIMetrics() *HTTP1URIMetrics {
 		AvgResponsePackageSize:   metrics.NewAvgCounter(),
 		ReqPackageSizeHistogram:  metrics.NewHistogram(HTTP1PackageSizeHistogramBuckets),
 		RespPackageSizeHistogram: metrics.NewHistogram(HTTP1PackageSizeHistogramBuckets),
-		ClientAvgDuration:        metrics.NewAvgCounter(),
-		ServerAvgDuration:        metrics.NewAvgCounter(),
-		ClientDurationHistogram:  metrics.NewHistogram(HTTP1DurationHistogramBuckets),
-		ServerDurationHistogram:  metrics.NewHistogram(HTTP1DurationHistogramBuckets),
+		avgDuration:              metrics.NewAvgCounter(),
+		durationHistogram:        metrics.NewHistogram(HTTP1DurationHistogramBuckets),
+		slowTraces:               metrics.NewTopN(SlowTraceTopNSize),
 	}
 }
 
@@ -112,7 +117,8 @@ func (h *HTTP1Analyzer) GenerateMetrics() Metrics {
 	return &HTTP1ConnectionMetrics{
 		halfData: list.New(),
 
-		combinedMetrics: NewHTTP1URIMetrics(),
+		clientMetrics: NewHTTP1URIMetrics(),
+		serverMetrics: NewHTTP1URIMetrics(),
 	}
 }
 
@@ -286,12 +292,18 @@ func (h *HTTP1Analyzer) analyze(_ Context, connectionID string, connectionMetric
 	defer connectionMetrics.metricsLocker.RUnlock()
 
 	// append metrics
-	combinedMetrics := connectionMetrics.combinedMetrics
-	h.appendToMetrics(combinedMetrics, request, requestBuffer, response, responseBuffer)
+	data := connectionMetrics.clientMetrics
+	side := base.ConnectionRoleClient
+	if requestBuffer.Direction() == base.SocketDataDirectionIngress {
+		// if receive the request, that's mean is server side
+		data = connectionMetrics.serverMetrics
+		side = base.ConnectionRoleServer
+	}
+	h.appendToMetrics(data, request, requestBuffer, response, responseBuffer)
 
 	if log.Enable(logrus.DebugLevel) {
-		metricsJSON, _ := json.Marshal(combinedMetrics)
-		log.Debugf("generated metrics, connection id: %s, metrisc: %s", connectionID, string(metricsJSON))
+		metricsJSON, _ := json.Marshal(data)
+		log.Debugf("generated metrics, connection id: %s, side: %s, metrisc: %s", connectionID, side.String(), string(metricsJSON))
 	}
 	return nil
 }
@@ -334,7 +346,7 @@ func (h *HTTP1Analyzer) tryingToReadResponseWithoutHeaders(reader *bufio.Reader,
 	return resp, nil
 }
 
-func (h *HTTP1Analyzer) appendToMetrics(data *HTTP1URIMetrics, _ *http.Request, reqBuffer SocketDataBuffer,
+func (h *HTTP1Analyzer) appendToMetrics(data *HTTP1URIMetrics, req *http.Request, reqBuffer SocketDataBuffer,
 	resp *http.Response, respBuffer SocketDataBuffer) {
 	data.RequestCounter.Increase()
 	statusCounter := data.StatusCounter[resp.StatusCode]
@@ -349,18 +361,34 @@ func (h *HTTP1Analyzer) appendToMetrics(data *HTTP1URIMetrics, _ *http.Request,
 	data.ReqPackageSizeHistogram.Increase(float64(reqBuffer.TotalSize()))
 	data.RespPackageSizeHistogram.Increase(float64(respBuffer.TotalSize()))
 
-	// duration data need client and server side
-	avgDuration := data.ClientAvgDuration
-	durationHistogram := data.ClientDurationHistogram
-	if reqBuffer.Direction() == base.SocketDataDirectionIngress {
-		// if the request is ingress, that's mean current is server side
-		avgDuration = data.ServerAvgDuration
-		durationHistogram = data.ServerDurationHistogram
-	}
 	duration := time.Duration(respBuffer.Time() - reqBuffer.Time())
 	durationInMS := float64(duration.Milliseconds())
-	avgDuration.Increase(durationInMS)
-	durationHistogram.Increase(durationInMS)
+	data.avgDuration.Increase(durationInMS)
+	data.durationHistogram.Increase(durationInMS)
+
+	h.increaseSlowTraceTopN(data.slowTraces, duration, req, resp, reqBuffer, respBuffer)
+}
+
+func (h *HTTP1Analyzer) increaseSlowTraceTopN(slowTraceTopN *metrics.TopN, duration time.Duration,
+	request *http.Request, _ *http.Response, reqBuffer, respBuffer SocketDataBuffer) {
+	tracingContext, err := AnalyzeTracingContext(func(key string) string {
+		return request.Header.Get(key)
+	})
+	if err != nil {
+		log.Warnf("analyze tracing context error: %v", err)
+		return
+	}
+	if tracingContext == nil {
+		return
+	}
+
+	// remove the query parameters
+	uri := request.RequestURI
+	if i := strings.Index(uri, "?"); i > 0 {
+		uri = uri[0:i]
+	}
+	trace := &HTTP1Trace{Trace: tracingContext, RequestURI: uri, RequestBuffer: reqBuffer, ResponseBuffer: respBuffer}
+	slowTraceTopN.AddRecord(trace, duration.Milliseconds())
 }
 
 func (h *HTTP1ConnectionMetrics) MergeMetricsFromConnection(connection *base.ConnectionContext) {
@@ -368,84 +396,77 @@ func (h *HTTP1ConnectionMetrics) MergeMetricsFromConnection(connection *base.Con
 	other.metricsLocker.Lock()
 	defer other.metricsLocker.Unlock()
 
-	h.combinedMetrics.MergeAndClean(other.combinedMetrics)
+	h.clientMetrics.MergeAndClean(other.clientMetrics)
+	h.serverMetrics.MergeAndClean(other.serverMetrics)
 	if log.Enable(logrus.DebugLevel) {
-		marshal, _ := json.Marshal(h.combinedMetrics)
-		log.Debugf("combine metrics: conid: %d_%d, metrics: %s", connection.ConnectionID, connection.RandomID, marshal)
+		clientMetrics, _ := json.Marshal(h.clientMetrics)
+		serverMetrics, _ := json.Marshal(h.serverMetrics)
+		log.Debugf("combine metrics: conid: %d_%d, client side metrics: %s, server side metrics: %s",
+			connection.ConnectionID, connection.RandomID, clientMetrics, serverMetrics)
 	}
 }
 
 func (h *HTTP1ConnectionMetrics) FlushMetrics(traffic *base.ProcessTraffic, metricsBuilder *base.MetricsBuilder) {
 	connectionMetrics := QueryProtocolMetrics(traffic.Metrics, HTTP1ProtocolName).(*HTTP1ConnectionMetrics)
 	for _, p := range traffic.LocalProcesses {
-		collection := make([]*v3.MeterData, 0)
-		combinedMetrics := connectionMetrics.combinedMetrics
-		collection = h.appendMetrics(collection, traffic, p, "", combinedMetrics, metricsBuilder)
-		if len(collection) == 0 {
+		// if the remote process is profiling, then used the client side
+		localMetrics := connectionMetrics.clientMetrics
+		remoteMetrics := connectionMetrics.serverMetrics
+		if traffic.Role == base.ConnectionRoleServer {
+			localMetrics = connectionMetrics.serverMetrics
+			remoteMetrics = connectionMetrics.clientMetrics
+		}
+
+		metricsCount := h.appendMetrics(traffic, p, "", localMetrics, metricsBuilder, false)
+		if traffic.RemoteProcessIsProfiling() {
+			metricsCount += h.appendMetrics(traffic, p, "", remoteMetrics, metricsBuilder, true)
+		}
+		if metricsCount <= 0 {
 			continue
 		}
 
 		if log.Enable(logrus.DebugLevel) {
 			// if remote process is profiling, then the metrics data need to be cut half
-			log.Debugf("flush HTTP1 metrics(%s): %s, remote process is profiling: %t, "+
-				"client request count: %d, avg request size: %f, "+
-				"avg response size: %f, client avg duration: %f, server avg duration: %f",
+			log.Debugf("flush HTTP1 metrics(%s): %s, remote process is profiling: %t, client(%s), server(%s)"+
 				traffic.Role.String(), traffic.GenerateConnectionInfo(), traffic.RemoteProcessIsProfiling(),
-				combinedMetrics.RequestCounter.Get(), combinedMetrics.AvgRequestPackageSize.Calculate(),
-				combinedMetrics.AvgResponsePackageSize.Calculate(),
-				combinedMetrics.ClientAvgDuration.Calculate(), combinedMetrics.ServerAvgDuration.Calculate())
+				connectionMetrics.clientMetrics.String(), connectionMetrics.serverMetrics.String())
 		}
-
-		metricsBuilder.AppendMetrics(p.Entity().ServiceName, p.Entity().InstanceName, collection)
 	}
 }
 
-func (h *HTTP1ConnectionMetrics) appendMetrics(collections []*v3.MeterData, traffic *base.ProcessTraffic,
-	local api.ProcessInterface, url string, http1Metrics *HTTP1URIMetrics, metricsBuilder *base.MetricsBuilder) []*v3.MeterData {
+func (h *HTTP1ConnectionMetrics) appendMetrics(traffic *base.ProcessTraffic,
+	local api.ProcessInterface, url string, http1Metrics *HTTP1URIMetrics, metricsBuilder *base.MetricsBuilder, durationOnly bool) int {
+	collections := make([]*v3.MeterData, 0)
 	role, labels := metricsBuilder.BuildBasicMeterLabels(traffic, local)
 	prefix := metricsBuilder.MetricPrefix()
 
-	collections = h.buildMetrics(collections, prefix, "request_counter", labels, url, traffic,
-		h.cutHalfMetricsIfNeed(traffic, http1Metrics.RequestCounter))
+	collections = h.buildMetrics(collections, prefix, fmt.Sprintf("%s_duration_avg", role.String()), labels, url,
+		traffic, http1Metrics.avgDuration)
+	collections = h.buildMetrics(collections, prefix, fmt.Sprintf("%s_duration_histogram", role.String()), labels, url,
+		traffic, http1Metrics.durationHistogram)
+	if durationOnly {
+		return len(collections)
+	}
+
+	collections = h.buildMetrics(collections, prefix, "request_counter", labels, url, traffic, http1Metrics.RequestCounter)
 	for status, counter := range http1Metrics.StatusCounter {
 		statusLabels := append(labels, &v3.Label{Name: "code", Value: fmt.Sprintf("%d", status)})
-		collections = h.buildMetrics(collections, prefix, "response_status_counter", statusLabels, url, traffic,
-			h.cutHalfMetricsIfNeed(traffic, counter))
+		collections = h.buildMetrics(collections, prefix, "response_status_counter", statusLabels, url, traffic, counter)
 	}
 
 	collections = h.buildMetrics(collections, prefix, "request_package_size_avg", labels, url, traffic, http1Metrics.AvgRequestPackageSize)
 	collections = h.buildMetrics(collections, prefix, "response_package_size_avg", labels, url, traffic, http1Metrics.AvgResponsePackageSize)
-	collections = h.buildMetrics(collections, prefix, "request_package_size_histogram", labels, url, traffic,
-		h.cutHalfMetricsIfNeed(traffic, http1Metrics.ReqPackageSizeHistogram))
-	collections = h.buildMetrics(collections, prefix, "response_package_size_histogram", labels, url, traffic,
-		h.cutHalfMetricsIfNeed(traffic, http1Metrics.RespPackageSizeHistogram))
-
-	avgDuration := http1Metrics.ClientAvgDuration
-	durationHistogram := http1Metrics.ClientDurationHistogram
-	if role == base.ConnectionRoleServer {
-		avgDuration = http1Metrics.ServerAvgDuration
-		durationHistogram = http1Metrics.ServerDurationHistogram
-	}
-	collections = h.buildMetrics(collections, prefix, fmt.Sprintf("%s_duration_avg", role.String()), labels, url,
-		traffic, avgDuration)
-	collections = h.buildMetrics(collections, prefix, fmt.Sprintf("%s_duration_histogram", role.String()), labels, url,
-		traffic, durationHistogram)
-	return collections
-}
+	collections = h.buildMetrics(collections, prefix, "request_package_size_histogram", labels, url, traffic, http1Metrics.ReqPackageSizeHistogram)
+	collections = h.buildMetrics(collections, prefix, "response_package_size_histogram", labels, url, traffic, http1Metrics.RespPackageSizeHistogram)
 
-func (h *HTTP1ConnectionMetrics) cutHalfMetricsIfNeed(traffic *base.ProcessTraffic, data metrics.Metrics) metrics.Metrics {
-	if traffic.RemoteProcessIsProfiling() {
-		return data.CusHalfOfMetrics()
-	}
-	return data
+	metricsBuilder.AppendMetrics(local.Entity().ServiceName, local.Entity().InstanceName, collections)
+	logsCount := http1Metrics.slowTraces.AppendData(local, traffic, metricsBuilder)
+	return len(collections) + logsCount
 }
 
 func (h *HTTP1ConnectionMetrics) buildMetrics(collection []*v3.MeterData, prefix, name string, basicLabels []*v3.Label,
-	url string, traffic *base.ProcessTraffic, data metrics.Metrics) []*v3.MeterData {
+	url string, _ *base.ProcessTraffic, data metrics.Metrics) []*v3.MeterData {
 	// if remote process is also profiling, then needs to be calculated half of metrics
-	if traffic.RemoteProcessIsProfiling() {
-		data = data.CusHalfOfMetrics()
-	}
 	labels := basicLabels
 	var meterName string
 	if url != "" {
@@ -479,8 +500,99 @@ func (u *HTTP1URIMetrics) MergeAndClean(other *HTTP1URIMetrics) {
 	u.AvgResponsePackageSize.MergeAndClean(other.AvgResponsePackageSize)
 	u.ReqPackageSizeHistogram.MergeAndClean(other.ReqPackageSizeHistogram)
 	u.RespPackageSizeHistogram.MergeAndClean(other.RespPackageSizeHistogram)
-	u.ClientAvgDuration.MergeAndClean(other.ClientAvgDuration)
-	u.ServerAvgDuration.MergeAndClean(other.ServerAvgDuration)
-	u.ClientDurationHistogram.MergeAndClean(other.ClientDurationHistogram)
-	u.ServerDurationHistogram.MergeAndClean(other.ServerDurationHistogram)
+	u.avgDuration.MergeAndClean(other.avgDuration)
+	u.durationHistogram.MergeAndClean(other.durationHistogram)
+	u.slowTraces.MergeAndClean(other.slowTraces)
+}
+
+func (u *HTTP1URIMetrics) String() string {
+	return fmt.Sprintf("request count: %d, avg request size: %f, avg response size: %f, avg duration: %f, slow trace count: %d",
+		u.RequestCounter.Get(), u.AvgRequestPackageSize.Calculate(), u.AvgResponsePackageSize.Calculate(),
+		u.avgDuration.Calculate(), u.slowTraces.List.Len())
+}
+
+type HTTP1Trace struct {
+	Trace          TracingContext
+	RequestURI     string
+	RequestBuffer  SocketDataBuffer
+	ResponseBuffer SocketDataBuffer
+}
+
+func (h *HTTP1Trace) Flush(duration int64, process api.ProcessInterface, traffic *base.ProcessTraffic, metricsBuilder *base.MetricsBuilder) {
+	logData := &logv3.LogData{}
+	logData.Service = process.Entity().ServiceName
+	logData.ServiceInstance = process.Entity().InstanceName
+	logData.Layer = process.Entity().Layer
+
+	logData.Tags = &logv3.LogTags{Data: make([]*commonv3.KeyStringValuePair, 0)}
+	logData.Tags.Data = append(logData.Tags.Data, &commonv3.KeyStringValuePair{Key: "LOG_KIND", Value: "NET_PROFILING_SAMPLED_TRACE"})
+
+	// trace context
+	traceContext := &logv3.TraceContext{}
+	traceContext.TraceId = h.Trace.TraceID()
+	logData.TraceContext = traceContext
+
+	// body
+	logBody := &logv3.LogDataBody{Type: "json"}
+	body := &HTTP1SlowTraceLogBody{
+		Latency:       duration,
+		TraceProvider: h.Trace.Provider(),
+		DetectPoint:   traffic.Role.String(),
+		Component:     traffic.Protocol.String(),
+		SSL:           traffic.IsSSL,
+		URI:           h.RequestURI,
+		Reason:        "slow",
+	}
+	if traffic.Role == base.ConnectionRoleClient {
+		body.ClientProcess = &HTTP1SlowTraceLogProcess{ProcessID: process.ID()}
+		body.ServerProcess = NewHTTP1SlowTRaceLogRemoteProcess(traffic, process)
+	} else {
+		body.ServerProcess = &HTTP1SlowTraceLogProcess{ProcessID: process.ID()}
+		body.ClientProcess = NewHTTP1SlowTRaceLogRemoteProcess(traffic, process)
+	}
+	bodyJSON, err := json.Marshal(body)
+	if err != nil {
+		log.Warnf("format the slow trace log body failure: %v", err)
+		return
+	}
+	logBody.Content = &logv3.LogDataBody_Json{Json: &logv3.JSONLog{Json: string(bodyJSON)}}
+	logData.Body = logBody
+
+	metricsBuilder.AppendLogs(process.Entity().ServiceName, logData)
+}
+
+type HTTP1SlowTraceLogBody struct {
+	URI           string                    `json:"uri"`
+	Reason        string                    `json:"reason"`
+	Latency       int64                     `json:"latency"`
+	TraceProvider string                    `json:"trace_provider"`
+	ClientProcess *HTTP1SlowTraceLogProcess `json:"client_process"`
+	ServerProcess *HTTP1SlowTraceLogProcess `json:"server_process"`
+	DetectPoint   string                    `json:"detect_point"`
+	Component     string                    `json:"component"`
+	SSL           bool                      `json:"ssl"`
+}
+
+type HTTP1SlowTraceLogProcess struct {
+	ProcessID string `json:"process_id"`
+	Local     bool   `json:"local"`
+	Address   string `json:"address"`
+}
+
+func NewHTTP1SlowTRaceLogRemoteProcess(traffic *base.ProcessTraffic, local api.ProcessInterface) *HTTP1SlowTraceLogProcess {
+	if len(traffic.RemoteProcesses) != 0 {
+		for _, p := range traffic.RemoteProcesses {
+			// only match with same service instance
+			if local.Entity().ServiceName == p.Entity().ServiceName &&
+				local.Entity().InstanceName == p.Entity().InstanceName {
+				return &HTTP1SlowTraceLogProcess{ProcessID: p.ID()}
+			}
+		}
+	}
+
+	if tools.IsLocalHostAddress(traffic.RemoteIP) || traffic.Analyzer.IsLocalAddressInCache(traffic.RemoteIP) {
+		return &HTTP1SlowTraceLogProcess{Local: true}
+	}
+
+	return &HTTP1SlowTraceLogProcess{Address: fmt.Sprintf("%s:%d", traffic.RemoteIP, traffic.RemotePort)}
 }
diff --git a/pkg/profiling/task/network/analyze/layer7/protocols/metrics/base.go b/pkg/profiling/task/network/analyze/layer7/protocols/metrics/base.go
index 1ecda6c..ee7c8a3 100644
--- a/pkg/profiling/task/network/analyze/layer7/protocols/metrics/base.go
+++ b/pkg/profiling/task/network/analyze/layer7/protocols/metrics/base.go
@@ -17,12 +17,15 @@
 
 package metrics
 
-import v3 "skywalking.apache.org/repo/goapi/collect/language/agent/v3"
+import (
+	agentv3 "skywalking.apache.org/repo/goapi/collect/language/agent/v3"
+	logv3 "skywalking.apache.org/repo/goapi/collect/logging/v3"
+)
 
 type Metrics interface {
-	// CusHalfOfMetrics used for calculate the half of data
-	// Used on only calculate half of metrics when client or server both profiling
-	// Such as calculate the total request count on the connection
-	CusHalfOfMetrics() Metrics
-	AppendMeter(list []*v3.MeterData, name string, labels []*v3.Label) []*v3.MeterData
+	AppendMeter(list []*agentv3.MeterData, name string, labels []*agentv3.Label) []*agentv3.MeterData
+}
+
+type Records interface {
+	AppendLog(list []*logv3.LogData) []*logv3.LogData
 }
diff --git a/pkg/profiling/task/network/analyze/layer7/protocols/metrics/topn.go b/pkg/profiling/task/network/analyze/layer7/protocols/metrics/topn.go
new file mode 100644
index 0000000..816571f
--- /dev/null
+++ b/pkg/profiling/task/network/analyze/layer7/protocols/metrics/topn.go
@@ -0,0 +1,99 @@
+// 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 metrics
+
+import (
+	"container/list"
+
+	"github.com/apache/skywalking-rover/pkg/process/api"
+	"github.com/apache/skywalking-rover/pkg/profiling/task/network/analyze/base"
+)
+
+type TopN struct {
+	MaxLength int
+	List      *list.List
+}
+
+type TopNData interface {
+	Flush(duration int64, process api.ProcessInterface, traffic *base.ProcessTraffic, metricsBuilder *base.MetricsBuilder)
+}
+
+type TopNRecord struct {
+	Duration int64
+	Data     TopNData
+}
+
+func NewTopN(length int) *TopN {
+	return &TopN{
+		MaxLength: length,
+		List:      list.New(),
+	}
+}
+
+func (t *TopN) AddRecord(data TopNData, duration int64) {
+	// don't need to be added if the duration is lower than the latest value
+	if t.List.Len() >= t.MaxLength && t.List.Back().Value.(*TopNRecord).Duration > duration {
+		return
+	}
+	node := t.createNode(data, duration)
+	if t.List.Len() == 0 {
+		t.List.PushFront(node)
+		return
+	}
+
+	// insert to the list
+	added := false
+	for element := t.List.Back(); element != nil; element = element.Prev() {
+		if element.Value.(*TopNRecord).Duration < duration {
+			t.List.InsertBefore(node, element)
+			added = true
+			break
+		}
+	}
+	if !added {
+		t.List.PushBack(node)
+	}
+
+	// remove latest value
+	if t.List.Len() > t.MaxLength {
+		t.List.Remove(t.List.Back())
+	}
+}
+
+func (t *TopN) MergeAndClean(other *TopN) {
+	for element := other.List.Front(); element != nil; element = element.Next() {
+		record := element.Value.(*TopNRecord)
+		t.AddRecord(record.Data, record.Duration)
+	}
+
+	other.List.Init()
+}
+
+func (t *TopN) AppendData(process api.ProcessInterface, traffic *base.ProcessTraffic, metricsBuilder *base.MetricsBuilder) int {
+	result := 0
+	for element := t.List.Front(); element != nil; element = element.Next() {
+		record := element.Value.(*TopNRecord)
+		record.Data.Flush(record.Duration, process, traffic, metricsBuilder)
+		result++
+	}
+	return result
+}
+
+func (t *TopN) createNode(data TopNData, duration int64) *TopNRecord {
+	return &TopNRecord{Data: data, Duration: duration}
+}
diff --git a/pkg/profiling/task/network/analyze/layer7/protocols/tracing.go b/pkg/profiling/task/network/analyze/layer7/protocols/tracing.go
new file mode 100644
index 0000000..2027674
--- /dev/null
+++ b/pkg/profiling/task/network/analyze/layer7/protocols/tracing.go
@@ -0,0 +1,124 @@
+// 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 protocols
+
+import (
+	"encoding/base64"
+	"fmt"
+	"strings"
+)
+
+type TracingContext interface {
+	TraceID() string
+	Provider() string
+}
+
+type SkyWalkingTracingContext struct {
+	TraceID0              string
+	SegmentID             string
+	SpanID                string
+	ParentService         string
+	ParentServiceInstance string
+	ParentEndpoint        string
+	AddressUsedAtClient   string
+}
+
+type ZipkinTracingContext struct {
+	TraceID0 string
+	SpanID   string
+}
+
+func (w *SkyWalkingTracingContext) TraceID() string {
+	return w.TraceID0
+}
+
+func (w *SkyWalkingTracingContext) Provider() string {
+	return "skywalking"
+}
+
+func AnalyzeTracingContext(fetcher func(key string) string) (TracingContext, error) {
+	// skywalking v3
+	if sw8Header := fetcher("sw8"); sw8Header != "" {
+		return analyzeSkyWalking8TracingContext(sw8Header)
+	}
+
+	// zipkin
+	if zipkinSingleContext := fetcher("b3"); zipkinSingleContext != "" {
+		if ctx := analyzeZipkinTracingContextWithSingleData(zipkinSingleContext); ctx != nil {
+			return ctx, nil
+		}
+	}
+	if zipkinTraceID := fetcher("x-b3-traceid"); zipkinTraceID != "" {
+		if spanID := fetcher("x-b3-spanid"); spanID != "" {
+			return analyzeZipkinTracingContextWithSpecificData(zipkinTraceID, spanID), nil
+		}
+	}
+	return nil, nil
+}
+
+func analyzeSkyWalking8TracingContext(val string) (*SkyWalkingTracingContext, error) {
+	parts := strings.Split(val, "-")
+	if len(parts) != 8 {
+		return nil, fmt.Errorf("sw8 analyze error, value: %s", val)
+	}
+	var err error
+	ctx := &SkyWalkingTracingContext{}
+	ctx.TraceID0, err = decodeBase64StringValue(err, parts[1])
+	ctx.SegmentID, err = decodeBase64StringValue(err, parts[2])
+	ctx.SpanID = parts[3]
+	ctx.ParentService, err = decodeBase64StringValue(err, parts[4])
+	ctx.ParentServiceInstance, err = decodeBase64StringValue(err, parts[5])
+	ctx.ParentEndpoint, err = decodeBase64StringValue(err, parts[6])
+	ctx.AddressUsedAtClient, err = decodeBase64StringValue(err, parts[7])
+
+	if err != nil {
+		return nil, err
+	}
+	return ctx, nil
+}
+
+func analyzeZipkinTracingContextWithSpecificData(traceID, spanID string) *ZipkinTracingContext {
+	return &ZipkinTracingContext{TraceID0: traceID, SpanID: spanID}
+}
+
+func analyzeZipkinTracingContextWithSingleData(singleData string) *ZipkinTracingContext {
+	info := strings.Split(singleData, "-")
+	if len(info) < 2 {
+		return nil
+	}
+	return &ZipkinTracingContext{TraceID0: info[0], SpanID: info[1]}
+}
+
+func (w *ZipkinTracingContext) TraceID() string {
+	return w.TraceID0
+}
+
+func (w *ZipkinTracingContext) Provider() string {
+	return "zipkin"
+}
+
+func decodeBase64StringValue(err error, val string) (string, error) {
+	if err != nil {
+		return "", err
+	}
+	result, err := base64.StdEncoding.DecodeString(val)
+	if err != nil {
+		return "", err
+	}
+	return string(result), nil
+}
diff --git a/pkg/profiling/task/network/runner.go b/pkg/profiling/task/network/runner.go
index c39d690..ac4dbe4 100644
--- a/pkg/profiling/task/network/runner.go
+++ b/pkg/profiling/task/network/runner.go
@@ -40,6 +40,7 @@ import (
 	"github.com/apache/skywalking-rover/pkg/profiling/task/network/bpf"
 
 	v3 "skywalking.apache.org/repo/goapi/collect/language/agent/v3"
+	logv3 "skywalking.apache.org/repo/goapi/collect/logging/v3"
 )
 
 var log = logger.GetLogger("profiling", "task", "network")
@@ -49,6 +50,7 @@ type Runner struct {
 	startLock      sync.Mutex
 	stopOnce       sync.Once
 	meterClient    v3.MeterReportServiceClient
+	logClient      logv3.LogReportServiceClient
 	reportInterval time.Duration
 	meterPrefix    string
 
@@ -182,7 +184,7 @@ func (r *Runner) registerMetricsReport() {
 		for {
 			select {
 			case <-timeTicker.C:
-				if err := r.flushMetrics(); err != nil {
+				if err := r.flushData(); err != nil {
 					log.Errorf("flush network monitoing metrics failure: %v", err)
 				}
 			case <-r.ctx.Done():
@@ -193,18 +195,37 @@ func (r *Runner) registerMetricsReport() {
 	}()
 }
 
-func (r *Runner) flushMetrics() error {
+func (r *Runner) flushData() error {
 	// flush all metrics
 	metricsBuilder, err := r.analyzeContext.FlushAllMetrics(r.bpf, r.meterPrefix)
 	if err != nil {
 		return err
 	}
-	metrics := metricsBuilder.Build()
+
+	if count, err1 := r.flushMetrics(metricsBuilder); err1 != nil {
+		err = multierror.Append(err, err1)
+	} else if count > 0 {
+		log.Infof("total send network topology meter data: %d", count)
+	}
+
+	if count, err1 := r.flushLogs(metricsBuilder); err1 != nil {
+		err = multierror.Append(err, err1)
+	} else if count > 0 {
+		log.Infof("total send network topology logs data: %d", count)
+	}
+	return err
+}
+
+func (r *Runner) flushMetrics(builder *analyzeBase.MetricsBuilder) (int, error) {
+	metrics := builder.BuildMetrics()
+	if len(metrics) == 0 {
+		return 0, nil
+	}
 
 	// send metrics
 	batch, err := r.meterClient.CollectBatch(r.ctx)
 	if err != nil {
-		return err
+		return 0, err
 	}
 	defer func() {
 		if _, e := batch.CloseAndRecv(); e != nil {
@@ -215,13 +236,40 @@ func (r *Runner) flushMetrics() error {
 	for _, m := range metrics {
 		count += len(m.MeterData)
 		if err := batch.Send(m); err != nil {
-			return err
+			return 0, err
 		}
 	}
-	if count > 0 {
-		log.Infof("total send network topology meter data: %d", count)
+	return count, nil
+}
+
+func (r *Runner) flushLogs(builder *analyzeBase.MetricsBuilder) (int, error) {
+	logsCollection := builder.BuildLogs()
+	if len(logsCollection) == 0 {
+		return 0, nil
 	}
-	return nil
+
+	count := 0
+	for _, logs := range logsCollection {
+		collector, err := r.logClient.Collect(r.ctx)
+		if err != nil {
+			return 0, err
+		}
+		count += len(logs)
+		for _, l := range logs {
+			if err := collector.Send(l); err != nil {
+				if _, e := collector.CloseAndRecv(); e != nil {
+					log.Warnf("close the logs stream error: %v", e)
+				}
+				return 0, err
+			}
+		}
+
+		if _, e := collector.CloseAndRecv(); e != nil {
+			log.Warnf("close the logs stream error: %v", e)
+		}
+	}
+
+	return count, nil
 }
 
 func (r *Runner) Stop() error {
@@ -252,6 +300,7 @@ func (r *Runner) init0(config *base.TaskConfig, moduleMgr *module.Manager) error
 	coreOperator := moduleMgr.FindModule(core.ModuleName).(core.Operator)
 	connection := coreOperator.BackendOperator().GetConnection()
 	r.meterClient = v3.NewMeterReportServiceClient(connection)
+	r.logClient = logv3.NewLogReportServiceClient(connection)
 
 	reportInterval, err := time.ParseDuration(config.Network.ReportInterval)
 	if err != nil {
diff --git a/test/e2e/base/env b/test/e2e/base/env
index 833b259..e414f00 100644
--- a/test/e2e/base/env
+++ b/test/e2e/base/env
@@ -13,8 +13,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-SW_CTL_COMMIT=ec85225f3fc0d0d7e8a9513b828d305c7cb399ad
-SW_OAP_COMMIT=9d3982db74dbe7ba9c028aef674ace13fb74cc18
+SW_CTL_COMMIT=521843f963917aa806740a9ad09c65aa59aca179
+SW_OAP_COMMIT=4adc05f89c5506541f6c0817db90238c96e1b5d3
 SW_KUBERNETES_COMMIT_SHA=0f3ec68e5a7e1608cec8688716b848ed15e971e5
 
 SW_AGENT_GO_COMMIT=216f122d942cb683f48578d3014cc5ea83637582
\ No newline at end of file
diff --git a/test/e2e/cases/profiling/network/base/docker-compose.yml b/test/e2e/cases/profiling/network/base/docker-compose.yml
index e51844b..d760ac0 100644
--- a/test/e2e/cases/profiling/network/base/docker-compose.yml
+++ b/test/e2e/cases/profiling/network/base/docker-compose.yml
@@ -55,10 +55,16 @@ services:
       service: oap
     environment:
       SW_METER_ANALYZER_ACTIVE_FILES: network-profiling
+      SW_LOG_LAL_FILES: slow-trace-lal
+      SW_RECEIVER_ZIPKIN: default
+      SW_QUERY_ZIPKIN: default
     volumes:
       - ./network-profiling.yaml:/skywalking/config/meter-analyzer-config/network-profiling.yaml
+      - ./slow-trace-lal.yaml:/skywalking/config/lal/slow-trace-lal.yaml
     ports:
       - 12800:12800
+      - 9411:9411
+      - 9412:9412
 
   rover:
     extends:
diff --git a/test/e2e/cases/profiling/network/base/network-profiling.yaml b/test/e2e/cases/profiling/network/base/network-profiling.yaml
index ce140fa..2e6b3e9 100644
--- a/test/e2e/cases/profiling/network/base/network-profiling.yaml
+++ b/test/e2e/cases/profiling/network/base/network-profiling.yaml
@@ -23,6 +23,7 @@ expPrefix: |-
     // only care about the nginx
     if (tags[prefix + '_local'] == 'true'
       || tags[prefix + '_address'].split(':')[0].endsWith('.1') // local data
+      || tags[prefix + '_address'].split(':')[1] == '11800'     // oap
       || tags[prefix + '_address'].split(':')[1] == '53') {     // dns
       tags[prefix + '_process_id'] = ProcessRegistry.generateVirtualLocalProcess(tags.service, tags.instance)
       return
diff --git a/test/e2e/cases/profiling/network/base/nginx.conf b/test/e2e/cases/profiling/network/base/nginx.conf
index 57acaf5..57d8cfe 100644
--- a/test/e2e/cases/profiling/network/base/nginx.conf
+++ b/test/e2e/cases/profiling/network/base/nginx.conf
@@ -31,6 +31,11 @@ http {
 		    proxy_pass https://service:10443/provider;
 		    proxy_http_version 1.1;
 		}
+
+		location /provider-zipkin {
+		    proxy_pass https://service:10443/provider-zipkin;
+		    proxy_http_version 1.1;
+		}
 	}
 
     server {
diff --git a/test/e2e/cases/profiling/network/base/slow-trace-lal.yaml b/test/e2e/cases/profiling/network/base/slow-trace-lal.yaml
new file mode 100644
index 0000000..3b3fa8f
--- /dev/null
+++ b/test/e2e/cases/profiling/network/base/slow-trace-lal.yaml
@@ -0,0 +1,64 @@
+# Licensed to the 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.
+# The 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.
+
+rules:
+  - name: network-profiling-slow-trace
+    layer: OS_LINUX
+    dsl: |
+      filter {
+        json{
+        }
+        extractor{
+          if (tag("LOG_KIND") == "NET_PROFILING_SAMPLED_TRACE") {
+            sampledTrace {
+              latency parsed.latency as Long
+              uri ((parsed.trace_provider as String) + "-" + (parsed.uri as String))
+              reason parsed.reason as String
+
+              if (parsed.client_process.process_id as String != "") {
+               processId parsed.client_process.process_id as String
+              } else if (parsed.client_process.local as Boolean
+                  || (parsed.client_process.address as String).split(":")[0].endsWith('.1')
+                  || (parsed.client_process.address as String).split(":")[1] == "53") {
+                processId ProcessRegistry.generateVirtualLocalProcess(parsed.service as String, parsed.serviceInstance as String) as String
+              } else {
+                processId ProcessRegistry.generateVirtualProcess(parsed.service as String, parsed.serviceInstance as String, 'UNKNOWN_REMOTE') as String
+              }
+
+              if (parsed.server_process.process_id as String != "") {
+                destProcessId parsed.server_process.process_id as String
+              } else if (parsed.server_process.local as Boolean
+                  || (parsed.server_process.address as String).split(":")[0].endsWith('.1')
+                  || (parsed.server_process.address as String).split(":")[1] == "53") {
+                destProcessId ProcessRegistry.generateVirtualLocalProcess(parsed.service as String, parsed.serviceInstance as String) as String
+              } else {
+                destProcessId ProcessRegistry.generateVirtualProcess(parsed.service as String, parsed.serviceInstance as String, 'UNKNOWN_REMOTE') as String
+              }
+
+              detectPoint parsed.detect_point as String
+
+              if (parsed.component as String == "http" && parsed.ssl as Boolean) {
+                componentId 129
+              } else if (parsed.component as String == "http") {
+                componentId 49
+              } else if (parsed.ssl as Boolean) {
+                componentId 130
+              } else {
+                componentId 110
+              }
+            }
+          }
+        }
+      }
\ No newline at end of file
diff --git a/test/e2e/cases/profiling/network/c_plus_plus/e2e.yaml b/test/e2e/cases/profiling/network/c_plus_plus/e2e.yaml
index 6baa149..72e75bf 100644
--- a/test/e2e/cases/profiling/network/c_plus_plus/e2e.yaml
+++ b/test/e2e/cases/profiling/network/c_plus_plus/e2e.yaml
@@ -43,4 +43,4 @@ verify:
   cases:
     - includes:
         - ../base-cases.yaml
-        - ../http1-cases.yaml
\ No newline at end of file
+        - ../http1-metrics-cases.yaml
\ No newline at end of file
diff --git a/test/e2e/base/env b/test/e2e/cases/profiling/network/expected/skywalking-trace.yml
similarity index 60%
copy from test/e2e/base/env
copy to test/e2e/cases/profiling/network/expected/skywalking-trace.yml
index 833b259..ce30c3a 100644
--- a/test/e2e/base/env
+++ b/test/e2e/cases/profiling/network/expected/skywalking-trace.yml
@@ -13,8 +13,24 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-SW_CTL_COMMIT=ec85225f3fc0d0d7e8a9513b828d305c7cb399ad
-SW_OAP_COMMIT=9d3982db74dbe7ba9c028aef674ace13fb74cc18
-SW_KUBERNETES_COMMIT_SHA=0f3ec68e5a7e1608cec8688716b848ed15e971e5
-
-SW_AGENT_GO_COMMIT=216f122d942cb683f48578d3014cc5ea83637582
\ No newline at end of file
+spans:
+  {{- contains .spans}}
+  - traceid: {{ notEmpty .traceid }}
+    segmentid: {{ notEmpty .segmentid }}
+    spanid: 0
+    parentspanid: -1
+    refs: []
+    servicecode: example
+    serviceinstancename: {{ notEmpty .serviceinstancename }}
+    starttime: {{ gt .starttime 0 }}
+    endtime: {{ gt .endtime 0 }}
+    endpointname: /provider
+    type: Exit
+    peer: https://proxy/provider
+    component: Unknown
+    iserror: false
+    layer: Unknown
+    tags: []
+    logs: []
+    attachedevents: []
+  {{- end }}
\ No newline at end of file
diff --git a/test/e2e/base/env b/test/e2e/cases/profiling/network/expected/slow-traces.yml
similarity index 74%
copy from test/e2e/base/env
copy to test/e2e/cases/profiling/network/expected/slow-traces.yml
index 833b259..4a69821 100644
--- a/test/e2e/base/env
+++ b/test/e2e/cases/profiling/network/expected/slow-traces.yml
@@ -13,8 +13,13 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-SW_CTL_COMMIT=ec85225f3fc0d0d7e8a9513b828d305c7cb399ad
-SW_OAP_COMMIT=9d3982db74dbe7ba9c028aef674ace13fb74cc18
-SW_KUBERNETES_COMMIT_SHA=0f3ec68e5a7e1608cec8688716b848ed15e971e5
-
-SW_AGENT_GO_COMMIT=216f122d942cb683f48578d3014cc5ea83637582
\ No newline at end of file
+{{- contains . }}
+- name: skywalking-/provider
+  id: {{ notEmpty .id }}
+  value: {{ notEmpty .value }}
+  refid: {{ notEmpty .refid }}
+- name: zipkin-/provider-zipkin
+  id: {{ notEmpty .id }}
+  value: {{ notEmpty .value }}
+  refid: {{ notEmpty .refid }}
+{{- end }}
\ No newline at end of file
diff --git a/test/e2e/base/env b/test/e2e/cases/profiling/network/expected/zipkin-trace.yml
similarity index 64%
copy from test/e2e/base/env
copy to test/e2e/cases/profiling/network/expected/zipkin-trace.yml
index 833b259..c16847c 100644
--- a/test/e2e/base/env
+++ b/test/e2e/cases/profiling/network/expected/zipkin-trace.yml
@@ -13,8 +13,19 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-SW_CTL_COMMIT=ec85225f3fc0d0d7e8a9513b828d305c7cb399ad
-SW_OAP_COMMIT=9d3982db74dbe7ba9c028aef674ace13fb74cc18
-SW_KUBERNETES_COMMIT_SHA=0f3ec68e5a7e1608cec8688716b848ed15e971e5
-
-SW_AGENT_GO_COMMIT=216f122d942cb683f48578d3014cc5ea83637582
\ No newline at end of file
+{{- contains . }}
+- traceId: {{ notEmpty .traceId }}
+  id: {{ notEmpty .id }}
+  kind: "CLIENT"
+  name: "https/get"
+  timestamp: {{ gt .timestamp 0 }}
+  duration: {{ gt .duration 0 }}
+  localEndpoint:
+    serviceName: zipkin-service
+    ipv4: {{ notEmpty .localEndpoint.ipv4 }}
+  annotations:
+    {{- contains .annotations }}
+    - value: {{ notEmpty .value }}
+      timestamp: {{ gt .timestamp 0 }}
+    {{- end }}
+{{- end }}
\ No newline at end of file
diff --git a/test/e2e/cases/profiling/network/golang/Dockerfile b/test/e2e/cases/profiling/network/golang/Dockerfile
index c13a395..aabb815 100644
--- a/test/e2e/cases/profiling/network/golang/Dockerfile
+++ b/test/e2e/cases/profiling/network/golang/Dockerfile
@@ -17,10 +17,12 @@
 FROM golang:1.17
 
 WORKDIR /
-COPY golang/service.go /service.go
-RUN go build -o service service.go
+COPY golang/ /service
+
+WORKDIR /service
+RUN go build -o service .
 
 COPY base/ssl /usr/local/share/ca-certificates/ssl
 RUN update-ca-certificates
 
-CMD ["/service"]
\ No newline at end of file
+CMD ["/service/service"]
\ No newline at end of file
diff --git a/test/e2e/cases/profiling/network/golang/docker-compose.yml b/test/e2e/cases/profiling/network/golang/docker-compose.yml
index 592f410..dc154f2 100644
--- a/test/e2e/cases/profiling/network/golang/docker-compose.yml
+++ b/test/e2e/cases/profiling/network/golang/docker-compose.yml
@@ -24,6 +24,9 @@ services:
       - e2e
     volumes:
       - ./../base/ssl:/ssl_data
+    environment:
+      OAP_BACKEND_ADDR: oap:11800
+      ZIPKIN_BACKEND_ADDR: http://oap:9411/api/v2/spans
     ports:
       - 10443:10443
     healthcheck:
@@ -48,6 +51,8 @@ services:
       service: oap
     ports:
       - 12800:12800
+      - 9411:9411
+      - 9412:9412
 
   rover:
     extends:
diff --git a/test/e2e/cases/profiling/network/golang/e2e.yaml b/test/e2e/cases/profiling/network/golang/e2e.yaml
index 6baa149..aa4807b 100644
--- a/test/e2e/cases/profiling/network/golang/e2e.yaml
+++ b/test/e2e/cases/profiling/network/golang/e2e.yaml
@@ -43,4 +43,5 @@ verify:
   cases:
     - includes:
         - ../base-cases.yaml
-        - ../http1-cases.yaml
\ No newline at end of file
+        - ../http1-metrics-cases.yaml
+        - ../http1-slow-traces-cases.yaml
\ No newline at end of file
diff --git a/test/e2e/cases/profiling/network/golang/go.mod b/test/e2e/cases/profiling/network/golang/go.mod
new file mode 100644
index 0000000..e613bf3
--- /dev/null
+++ b/test/e2e/cases/profiling/network/golang/go.mod
@@ -0,0 +1,18 @@
+module test
+
+go 1.17
+
+require (
+	github.com/SkyAPM/go2sky v1.5.0 // indirect
+	github.com/golang/protobuf v1.5.2 // indirect
+	github.com/google/uuid v1.3.0 // indirect
+	github.com/openzipkin/zipkin-go v0.4.1 // indirect
+	github.com/pkg/errors v0.9.1 // indirect
+	golang.org/x/net v0.1.0 // indirect
+	golang.org/x/sys v0.1.0 // indirect
+	golang.org/x/text v0.4.0 // indirect
+	google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71 // indirect
+	google.golang.org/grpc v1.50.1 // indirect
+	google.golang.org/protobuf v1.28.1 // indirect
+	skywalking.apache.org/repo/goapi v0.0.0-20221019074310-53ebda305187 // indirect
+)
diff --git a/test/e2e/cases/profiling/network/golang/go.sum b/test/e2e/cases/profiling/network/golang/go.sum
new file mode 100644
index 0000000..c955a1b
--- /dev/null
+++ b/test/e2e/cases/profiling/network/golang/go.sum
@@ -0,0 +1,170 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
+github.com/SkyAPM/go2sky v1.5.0 h1:TzhKL9IyVCegCUdcqRI7R7g+rQCYNnF6QAzp6IhDy08=
+github.com/SkyAPM/go2sky v1.5.0/go.mod h1:cebzbFtq5oc9VrgJy0Sv7oePj/TjIlXPdj2ntHdCXd0=
+github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
+github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
+github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
+github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
+github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
+github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
+github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
+github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
+github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
+github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
+github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
+github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
+github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
+github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
+github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
+github.com/openzipkin/zipkin-go v0.4.1 h1:kNd/ST2yLLWhaWrkgchya40TJabe8Hioj9udfPcEO5A=
+github.com/openzipkin/zipkin-go v0.4.1/go.mod h1:qY0VqDSN1pOBN94dBc6w2GJlWLiovAyg7Qt6/I9HecM=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
+github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
+golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0=
+golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
+golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
+golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
+google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
+google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71 h1:GEgb2jF5zxsFJpJfg9RoDDWm7tiwc/DDSTE2BtLUkXU=
+google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
+google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
+google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
+google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
+google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
+google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY=
+google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
+google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
+google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
+google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
+google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
+google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
+google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+skywalking.apache.org/repo/goapi v0.0.0-20220401015832-2c9eee9481eb/go.mod h1:uWwwvhcwe2MD/nJCg0c1EE/eL6KzaBosLHDfMFoEJ30=
+skywalking.apache.org/repo/goapi v0.0.0-20221019074310-53ebda305187 h1:6JgAg9aohcHd72VplZUGycZgCNo6iQrz735nmtOTCnE=
+skywalking.apache.org/repo/goapi v0.0.0-20221019074310-53ebda305187/go.mod h1:lxmYWY1uAP5SLVKNymAyDzn7KG6dhPWN+pYHmyt+0vo=
diff --git a/test/e2e/cases/profiling/network/golang/service.go b/test/e2e/cases/profiling/network/golang/service.go
index 8559ca0..6e895ac 100644
--- a/test/e2e/cases/profiling/network/golang/service.go
+++ b/test/e2e/cases/profiling/network/golang/service.go
@@ -21,18 +21,62 @@ import (
 	"io/ioutil"
 	"log"
 	"net/http"
+	"os"
 	"time"
+
+	"github.com/SkyAPM/go2sky"
+	"github.com/SkyAPM/go2sky/reporter"
+
+	"github.com/openzipkin/zipkin-go"
+	zipkinhttp "github.com/openzipkin/zipkin-go/middleware/http"
+	zipkin_reporter "github.com/openzipkin/zipkin-go/reporter/http"
 )
 
+var skyWalkingTracer *go2sky.Tracer
+var zipkinTracer *zipkin.Tracer
+
 func provider(w http.ResponseWriter, req *http.Request) {
 	w.Header().Set("Content-Type", "text/plain")
-	time.Sleep(time.Second * 2)
+	time.Sleep(time.Second * 1)
 	_, _ = w.Write([]byte("service provider\n"))
 }
 
 func consumer(w http.ResponseWriter, req *http.Request) {
 	addr := "https://proxy/provider"
-	get, err := http.Get(addr)
+	request, err := http.NewRequest("GET", addr, nil)
+	exitSpan, err := skyWalkingTracer.CreateExitSpan(req.Context(), "/provider", addr, func(headerKey, headerValue string) error {
+		request.Header.Set(headerKey, headerValue)
+		return nil
+	})
+	get, err := http.DefaultClient.Do(request)
+	if err != nil {
+		log.Printf("send request error: %v", err)
+	}
+	all, err := ioutil.ReadAll(get.Body)
+	_ = get.Body.Close()
+	if err != nil {
+		log.Printf("get response body error: %v", err)
+	}
+
+	w.Header().Set("Content-Type", "text/plain")
+	_, _ = w.Write(all)
+	exitSpan.End()
+}
+
+func providerZipkin(w http.ResponseWriter, req *http.Request) {
+	w.Header().Set("Content-Type", "text/plain")
+	time.Sleep(time.Second * 2)
+	_, _ = w.Write([]byte("service provider zipkin\n"))
+}
+
+func consumerZipkin(w http.ResponseWriter, req *http.Request) {
+	addr := "https://proxy/provider-zipkin"
+	request, err := http.NewRequest("GET", addr, nil)
+	client, err := zipkinhttp.NewClient(zipkinTracer, zipkinhttp.ClientTrace(true))
+	if err != nil {
+		log.Fatalf("unable to create client: %+v\n", err)
+	}
+	get, err := client.Do(request)
 	if err != nil {
 		log.Printf("send request error: %v", err)
 	}
@@ -47,8 +91,35 @@ func consumer(w http.ResponseWriter, req *http.Request) {
 }
 
 func main() {
+	// init skywalking tracer
+	r, err := reporter.NewGRPCReporter(os.Getenv("OAP_BACKEND_ADDR"))
+	if err != nil {
+		log.Fatalf("new reporter error %v \n", err)
+	}
+	defer r.Close()
+	skyWalkingTracer, err = go2sky.NewTracer("example", go2sky.WithReporter(r))
+	if err != nil {
+		log.Fatalf("init skyWalkingTracer failure: %v", err)
+	}
+
+	// init zipkin tracer
+	zipkinReporter := zipkin_reporter.NewReporter(os.Getenv("ZIPKIN_BACKEND_ADDR"))
+	// create our local service endpoint
+	endpoint, err := zipkin.NewEndpoint("zipkin-service", "localhost:0")
+	if err != nil {
+		log.Fatalf("unable to create local endpoint: %+v\n", err)
+	}
+	// initialize our tracer
+	zipkinTracer, err = zipkin.NewTracer(zipkinReporter, zipkin.WithLocalEndpoint(endpoint))
+	if err != nil {
+		log.Fatalf("unable to create tracer: %+v\n", err)
+	}
+
 	http.HandleFunc("/provider", provider)
 	http.HandleFunc("/consumer", consumer)
-	err := http.ListenAndServeTLS(":10443", "/ssl_data/service.crt", "/ssl_data/service.key", nil)
+
+	http.HandleFunc("/consumer-zipkin", consumerZipkin)
+	http.HandleFunc("/provider-zipkin", providerZipkin)
+	err = http.ListenAndServeTLS(":10443", "/ssl_data/service.crt", "/ssl_data/service.key", nil)
 	log.Fatal(err)
 }
diff --git a/test/e2e/cases/profiling/network/http1-cases.yaml b/test/e2e/cases/profiling/network/http1-metrics-cases.yaml
similarity index 100%
rename from test/e2e/cases/profiling/network/http1-cases.yaml
rename to test/e2e/cases/profiling/network/http1-metrics-cases.yaml
diff --git a/test/e2e/cases/profiling/network/http1-slow-traces-cases.yaml b/test/e2e/cases/profiling/network/http1-slow-traces-cases.yaml
new file mode 100644
index 0000000..06ba743
--- /dev/null
+++ b/test/e2e/cases/profiling/network/http1-slow-traces-cases.yaml
@@ -0,0 +1,38 @@
+# Licensed to the 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.
+# The 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.
+
+# HTTP1 verify
+cases:
+  - query: |
+      curl https://${service_host}:${service_10443}/consumer-zipkin > /dev/null;
+      sleep 5;
+      swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql records list \
+        --name=sampled_slow_trace_record --service-name service --instance-name test --process-name service \
+        --dest-service-name service --dest-instance-name test --dest-process-name UNKNOWN_REMOTE 20
+    expected: expected/slow-traces.yml
+  # zipkin trace
+  - query: |
+      traceid=$(swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql records list \
+      --name=sampled_slow_trace_record --service-name service --instance-name test --process-name service \
+      --dest-service-name service --dest-instance-name test --dest-process-name UNKNOWN_REMOTE | yq e '. | map(select(.name == "zipkin-/provider-zipkin")).[0].id' -);
+      curl http://${oap_host}:${oap_9412}/zipkin/api/v2/trace/${traceid} | yq e -| yq e 'del(.[].tags)' -
+    expected: expected/zipkin-trace.yml
+  # skywalking trace
+  - query: |
+      traceid=$(swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql records list \
+      --name=sampled_slow_trace_record --service-name service --instance-name test --process-name service \
+      --dest-service-name service --dest-instance-name test --dest-process-name UNKNOWN_REMOTE | yq e '. | map(select(.name == "skywalking-/provider")).[0].id' -);
+       swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql trace $traceid
+    expected: expected/skywalking-trace.yml
\ No newline at end of file
diff --git a/test/e2e/cases/profiling/network/nodejs/e2e.yaml b/test/e2e/cases/profiling/network/nodejs/e2e.yaml
index 6baa149..72e75bf 100644
--- a/test/e2e/cases/profiling/network/nodejs/e2e.yaml
+++ b/test/e2e/cases/profiling/network/nodejs/e2e.yaml
@@ -43,4 +43,4 @@ verify:
   cases:
     - includes:
         - ../base-cases.yaml
-        - ../http1-cases.yaml
\ No newline at end of file
+        - ../http1-metrics-cases.yaml
\ No newline at end of file
diff --git a/test/e2e/cases/profiling/network/python/e2e.yaml b/test/e2e/cases/profiling/network/python/e2e.yaml
index 6baa149..72e75bf 100644
--- a/test/e2e/cases/profiling/network/python/e2e.yaml
+++ b/test/e2e/cases/profiling/network/python/e2e.yaml
@@ -43,4 +43,4 @@ verify:
   cases:
     - includes:
         - ../base-cases.yaml
-        - ../http1-cases.yaml
\ No newline at end of file
+        - ../http1-metrics-cases.yaml
\ No newline at end of file