You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ti...@apache.org on 2019/10/24 02:22:59 UTC

[servicecomb-mesher] branch master updated: [SCB-1497]support for skywalking. (#79)

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

tianxiaoliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-mesher.git


The following commit(s) were added to refs/heads/master by this push:
     new dc7ecfd  [SCB-1497]support for skywalking. (#79)
dc7ecfd is described below

commit dc7ecfd69ab510428f4d0cf62da774c6426a34dc
Author: surechen <81...@qq.com>
AuthorDate: Thu Oct 24 10:22:51 2019 +0800

    [SCB-1497]support for skywalking. (#79)
    
    * support for skywalking.
    SCB-1497
    
    Signed-off-by: surechen <ch...@huawei.com>
    
    * fix for gosecure check
    
    * fix
    
    * Solution for compiling error
    
    * fix
    
    * Add go.sum
    
    * remove go.sum
    
    * fix compile problem
    
    * Modify according to code review comments
    
    Signed-off-by: surechen <ch...@huawei.com>
---
 conf/mesher.yaml                                |   5 +
 docs/skywalking/skywalking.md                   |  36 +++++++
 go.mod                                          |  10 +-
 proxy/config/struct.go                          |  17 ++++
 proxy/handler/skywalking_handler.go             | 122 ++++++++++++++++++++++++
 proxy/handler/skywalking_handler_test.go        | 120 +++++++++++++++++++++++
 proxy/pkg/skywalking/skywalking_manager.go      |  79 +++++++++++++++
 proxy/pkg/skywalking/skywalking_manager_test.go | 101 ++++++++++++++++++++
 8 files changed, 487 insertions(+), 3 deletions(-)

diff --git a/conf/mesher.yaml b/conf/mesher.yaml
index 024810c..490844f 100644
--- a/conf/mesher.yaml
+++ b/conf/mesher.yaml
@@ -21,3 +21,8 @@ admin: #admin API
 #    match:
 #      status: 200
 #      body: ok
+#servicecomb:
+#  apm:
+#    tracing:
+#      enable: true
+#      serverUri: 127.0.0.1:11800
\ No newline at end of file
diff --git a/docs/skywalking/skywalking.md b/docs/skywalking/skywalking.md
new file mode 100644
index 0000000..d3b3676
--- /dev/null
+++ b/docs/skywalking/skywalking.md
@@ -0,0 +1,36 @@
+# SkyWalking
+
+Skywalking-manager is a handler plugin of mesher, it reports tracing data to skywalking server.
+
+## Configurations
+**In conf/mesher.conf**
+
+**servicecomb.apm.tracing.enable**
+>  *(optional, bool)* enable application performance manager
+
+**servicecomb.apm.tracing.serverUri**
+>  *(optional, string)* server address of skywalking
+
+## Example
+```yaml
+servicecomb:
+  apm:                              #application performance monitor
+    tracing:
+      enable: true                  #enable tracing ability
+      serverUri: 127.0.0.1:11800    #url of skywalking 
+```
+## Step:
+
+# 1. SkyWawlking-Manager Init
+**You must init skywawlking manager pkg which will manage connection and report msg to skywalking**
+- For example:
+- [1] You can import skywalking manager proxy/pkg/skywalking in file proxy/bootstrap/bootstrap.go.
+- [2] Calling function Init() in proxy/pkg/skywalking manually to init skywalking manager.
+- [3] Adding skywalking's consumer handler name SkyWalkingConsumer defined in proxy/pkg/skywalking to consumerChain.
+- [4] Adding skywalking's provider handler name SkyWalkingProvider defined in proxy/pkg/skywalking to providerChain.
+- more details about handler chains in [go-chassis](https://github.com/go-chassis/go-chassis#readme)
+
+# 2. SkyWalking-Handler Init
+- You must import proxy/handler pkg to init skywalking handler. Not only skywalking handler, all the handlers which are customized for mesher are defined here.
+- For example you can import handler pkg in file cmd/mesher/mesher.go
+
diff --git a/go.mod b/go.mod
index db2168a..89a7514 100644
--- a/go.mod
+++ b/go.mod
@@ -21,14 +21,18 @@ require (
 	github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f
 	github.com/spf13/pflag v1.0.5 // indirect
 	github.com/stretchr/testify v1.3.0
+	github.com/tetratelabs/go2sky v0.1.1-0.20190703154722-1eaab8035277
 	github.com/urfave/cli v1.20.1-0.20181029213200-b67dcf995b6a
 	golang.org/x/net v0.0.0-20190311183353-d8887717615a
 	golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2 // indirect
-	google.golang.org/grpc v1.16.0
+	google.golang.org/grpc v1.19.1
 	gopkg.in/inf.v0 v0.9.1 // indirect
-	gopkg.in/yaml.v2 v2.2.1
+	gopkg.in/yaml.v2 v2.2.2
 	k8s.io/apimachinery v0.0.0-20181022183627-f71dbbc36e12
 	k8s.io/client-go v9.0.0+incompatible
 )
 
-replace github.com/openzipkin-contrib/zipkin-go-opentracing v0.3.5 => github.com/go-chassis/zipkin-go-opentracing v0.3.5-0.20190321072447-42cf74fc2a92
+replace (
+	github.com/openzipkin-contrib/zipkin-go-opentracing v0.3.5 => github.com/go-chassis/zipkin-go-opentracing v0.3.5-0.20190321072447-42cf74fc2a92
+	github.com/tetratelabs/go2sky v0.1.1-0.20190703154722-1eaab8035277 => github.com/SkyAPM/go2sky v0.1.1-0.20190703154722-1eaab8035277
+)
diff --git a/proxy/config/struct.go b/proxy/config/struct.go
index 87b35f1..a4a4c51 100644
--- a/proxy/config/struct.go
+++ b/proxy/config/struct.go
@@ -25,6 +25,7 @@ type MesherConfig struct {
 	Admin       Admin          `yaml:"admin"`
 	HealthCheck []*HealthCheck `yaml:"localHealthCheck"`
 	ProxyedPro  string         `yaml:"proxyedProtocol"`
+	ServiceComb *ServiceComb   `yaml:"servicecomb"`
 }
 
 //HealthCheck define how to check local ports
@@ -66,3 +67,19 @@ type Admin struct {
 	Enable    bool   `yaml:"enable"`
 	ServerURI string `yaml:"serverUri"`
 }
+
+//Tracing has attributes for APM
+type Tracing struct {
+	Enable    bool   `yaml:"enable"`
+	ServerURI string `yaml:"serverUri"`
+}
+
+//APM is for Application Performance Management
+type APM struct {
+	Tracing Tracing `yaml:"tracing"`
+}
+
+//ServiceComb is for servicecomb config
+type ServiceComb struct {
+	APM APM `yaml:"apm"`
+}
diff --git a/proxy/handler/skywalking_handler.go b/proxy/handler/skywalking_handler.go
new file mode 100644
index 0000000..afaaec5
--- /dev/null
+++ b/proxy/handler/skywalking_handler.go
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+
+package handler
+
+import (
+	"github.com/apache/servicecomb-mesher/proxy/pkg/skywalking"
+	"github.com/go-chassis/go-chassis/core/handler"
+	"github.com/go-chassis/go-chassis/core/invocation"
+	"github.com/go-mesh/openlogging"
+	"github.com/tetratelabs/go2sky"
+	skycom "github.com/tetratelabs/go2sky/reporter/grpc/common"
+	"strconv"
+)
+
+const (
+	HTTPPrefix = "http://"
+)
+
+const (
+	HTTPClientComponentID  = 2
+	ServiceCombComponentID = 28
+	HTTPServerComponentID  = 49
+)
+
+//SkyWalkingProviderHandler struct
+type SkyWalkingProviderHandler struct {
+}
+
+//Handle is for provider
+func (sp *SkyWalkingProviderHandler) Handle(chain *handler.Chain, i *invocation.Invocation, cb invocation.ResponseCallBack) {
+	openlogging.GetLogger().Debugf("SkyWalkingProviderHandler begin. inv:%#v", *i)
+	span, _, err := skywalking.CreateEntrySpan(i)
+	if err != nil {
+		openlogging.GetLogger().Errorf("CreateEntrySpan error:%s", err.Error())
+	}
+	chain.Next(i, func(r *invocation.Response) (err error) {
+		err = cb(r)
+		span.Tag(go2sky.TagHTTPMethod, i.Protocol)
+		span.Tag(go2sky.TagURL, HTTPPrefix+i.MicroServiceName+i.URLPathFormat)
+		span.Tag(go2sky.TagStatusCode, strconv.Itoa(r.Status))
+		span.SetSpanLayer(skycom.SpanLayer_Http)
+		span.SetComponent(HTTPServerComponentID)
+		span.End()
+		return
+	})
+}
+
+//Name return provider name
+func (sp *SkyWalkingProviderHandler) Name() string {
+	return skywalking.SkyWalkingProvider
+}
+
+//NewSkyWalkingProvier return provider handler for SkyWalking
+func NewSkyWalkingProvier() handler.Handler {
+	return &SkyWalkingProviderHandler{}
+}
+
+//SkyWalkingConsumerHandler struct
+type SkyWalkingConsumerHandler struct {
+}
+
+//Handle is for consumer
+func (sc *SkyWalkingConsumerHandler) Handle(chain *handler.Chain, i *invocation.Invocation, cb invocation.ResponseCallBack) {
+	openlogging.GetLogger().Debugf("SkyWalkingConsumerHandler begin:%#v", *i)
+	span, ctx, err := skywalking.CreateEntrySpan(i)
+	if err != nil {
+		openlogging.GetLogger().Errorf("CreateEntrySpan error:%s", err.Error())
+	}
+	spanExit, err := skywalking.CreateExitSpan(ctx, i)
+	if err != nil {
+		openlogging.GetLogger().Errorf("CreateExitSpan error:%s", err.Error())
+	}
+	chain.Next(i, func(r *invocation.Response) (err error) {
+		err = cb(r)
+		span.Tag(go2sky.TagHTTPMethod, i.Protocol)
+		span.Tag(go2sky.TagURL, HTTPPrefix+i.MicroServiceName+i.URLPathFormat)
+		span.Tag(go2sky.TagStatusCode, strconv.Itoa(r.Status))
+		span.SetSpanLayer(skycom.SpanLayer_Http)
+		span.SetComponent(HTTPServerComponentID)
+
+		spanExit.Tag(go2sky.TagHTTPMethod, i.Protocol)
+		spanExit.Tag(go2sky.TagURL, HTTPPrefix+i.MicroServiceName+i.URLPathFormat)
+		spanExit.Tag(go2sky.TagStatusCode, strconv.Itoa(r.Status))
+		spanExit.SetSpanLayer(skycom.SpanLayer_Http)
+		spanExit.SetComponent(HTTPClientComponentID)
+
+		spanExit.End()
+		span.End()
+		openlogging.GetLogger().Debugf("SkyWalkingConsumerHandler end.")
+		return
+	})
+}
+
+//Name return consumer name
+func (sc *SkyWalkingConsumerHandler) Name() string {
+	return skywalking.SkyWalkingConsumer
+}
+
+//NewSkyWalkingConsumer return consumer handler for SkyWalking
+func NewSkyWalkingConsumer() handler.Handler {
+	return &SkyWalkingConsumerHandler{}
+}
+
+func init() {
+	handler.RegisterHandler(skywalking.SkyWalkingProvider, NewSkyWalkingProvier)
+	handler.RegisterHandler(skywalking.SkyWalkingConsumer, NewSkyWalkingConsumer)
+}
diff --git a/proxy/handler/skywalking_handler_test.go b/proxy/handler/skywalking_handler_test.go
new file mode 100644
index 0000000..3e7a1bf
--- /dev/null
+++ b/proxy/handler/skywalking_handler_test.go
@@ -0,0 +1,120 @@
+/*
+ * 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.
+ */
+
+package handler_test
+
+import (
+	"context"
+	"github.com/apache/servicecomb-mesher/proxy/config"
+	mhandler "github.com/apache/servicecomb-mesher/proxy/handler"
+	"github.com/apache/servicecomb-mesher/proxy/pkg/skywalking"
+	gcconfig "github.com/go-chassis/go-chassis/core/config"
+	"github.com/go-chassis/go-chassis/core/config/model"
+	"github.com/go-chassis/go-chassis/core/handler"
+	"github.com/go-chassis/go-chassis/core/invocation"
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+const (
+	Port      = ":49800"
+	ServerUrl = "127.0.0.1:49800"
+)
+
+//initGcConfig
+func initGcConfig() {
+	var micCfg model.MicroserviceCfg
+	micCfg.ServiceDescription.Name = "TEST"
+	gcconfig.MicroserviceDefinition = &micCfg
+}
+
+//initMesherConfig
+func initMesherConfig() {
+	config.SetConfig(&config.MesherConfig{ServiceComb: &config.ServiceComb{config.APM{config.Tracing{Enable: true, ServerURI: "192.168.0.1:17289"}}}})
+}
+
+//initInv
+func initInv() *invocation.Invocation {
+	var i invocation.Invocation
+	i.MicroServiceName = "test"
+	i.Ctx = context.Background()
+	i.Endpoint = "calculator"
+	i.URLPathFormat = "/bmi"
+	return &i
+}
+
+//TestProviderHandlerName
+func TestProviderHandlerName(t *testing.T) {
+	h := mhandler.SkyWalkingProviderHandler{}
+	assert.Equal(t, h.Name(), skywalking.SkyWalkingProvider)
+}
+
+//TestNewProvier
+func TestNewProvier(t *testing.T) {
+	h := mhandler.NewSkyWalkingProvier()
+	assert.NotEqual(t, h, nil)
+	assert.Equal(t, h.Name(), skywalking.SkyWalkingProvider)
+}
+
+//TestProvierHandle
+func TestProvierHandle(t *testing.T) {
+	initGcConfig()
+	initMesherConfig()
+	skywalking.Init()
+	c := handler.Chain{}
+	c.AddHandler(mhandler.NewSkyWalkingProvier())
+
+	gcconfig.GlobalDefinition = &model.GlobalCfg{}
+	gcconfig.GlobalDefinition.Cse.Handler.Chain.Consumer = make(map[string]string)
+	gcconfig.GlobalDefinition.Cse.Handler.Chain.Consumer["skywalking-provider"] = "skywalking-provider"
+
+	c.Next(initInv(), func(r *invocation.Response) error {
+		assert.Equal(t, r.Err, nil)
+		return r.Err
+	})
+}
+
+//TestConsumerHandlerName
+func TestConsumerHandlerName(t *testing.T) {
+	c := mhandler.SkyWalkingConsumerHandler{}
+	assert.Equal(t, c.Name(), skywalking.SkyWalkingConsumer)
+}
+
+//TestNewConsumer
+func TestNewConsumer(t *testing.T) {
+	h := mhandler.NewSkyWalkingConsumer()
+	assert.NotEqual(t, h, nil)
+	assert.Equal(t, h.Name(), skywalking.SkyWalkingConsumer)
+}
+
+//TestConsumerHandle
+func TestConsumerHandle(t *testing.T) {
+	initGcConfig()
+	initMesherConfig()
+	skywalking.Init()
+	c := handler.Chain{}
+	c.AddHandler(mhandler.NewSkyWalkingConsumer())
+
+	gcconfig.GlobalDefinition = &model.GlobalCfg{}
+	gcconfig.GlobalDefinition.Cse.Handler.Chain.Consumer = make(map[string]string)
+	gcconfig.GlobalDefinition.Cse.Handler.Chain.Consumer["skywalking-consumer"] = "skywalking-consumer"
+
+	c.Next(initInv(), func(r *invocation.Response) error {
+		assert.Equal(t, r.Err, nil)
+		return r.Err
+	})
+}
diff --git a/proxy/pkg/skywalking/skywalking_manager.go b/proxy/pkg/skywalking/skywalking_manager.go
new file mode 100644
index 0000000..27bdf71
--- /dev/null
+++ b/proxy/pkg/skywalking/skywalking_manager.go
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+package skywalking
+
+import (
+	"context"
+	"github.com/apache/servicecomb-mesher/proxy/config"
+	gcconfig "github.com/go-chassis/go-chassis/core/config"
+	"github.com/go-chassis/go-chassis/core/invocation"
+	"github.com/go-mesh/openlogging"
+	"github.com/tetratelabs/go2sky"
+	"github.com/tetratelabs/go2sky/reporter"
+)
+
+const (
+	CrossProcessProtocolV2 = "Sw6"
+	SkyWalkingConsumer     = "skywalking-consumer"
+	SkyWalkingProvider     = "skywalking-provider"
+	SkyWalkingName         = "skywalking"
+	DeafaultSWServerURI    = "127.0.0.1:11800"
+)
+
+var r go2sky.Reporter
+var tracer *go2sky.Tracer
+
+//CreateEntrySpan use tracer to create and start an entry span for incoming request
+func CreateEntrySpan(i *invocation.Invocation) (go2sky.Span, context.Context, error) {
+	return tracer.CreateEntrySpan(i.Ctx, i.MicroServiceName+i.URLPathFormat, func() (string, error) {
+		return i.Headers()[CrossProcessProtocolV2], nil
+	})
+}
+
+//CreateExitSpan use tracer to create and start an exit span for client
+func CreateExitSpan(ctx context.Context, i *invocation.Invocation) (go2sky.Span, error) {
+	return tracer.CreateExitSpan(ctx, i.MicroServiceName+i.URLPathFormat, i.Endpoint+i.URLPathFormat, func(header string) error {
+		i.SetHeader(CrossProcessProtocolV2, header)
+		return nil
+	})
+}
+
+//CreateLocalSpan use tracer to create and start a span for local usage
+func CreateLocalSpan(ctx context.Context, opts ...go2sky.SpanOption) (go2sky.Span, context.Context, error) {
+	return tracer.CreateLocalSpan(ctx, opts...)
+}
+
+//Init skywalking manager
+func Init() {
+	openlogging.GetLogger().Debugf("SkyWalking manager Init begin config:%#v", config.GetConfig().ServiceComb.APM)
+	var err error
+	serverURI := DeafaultSWServerURI
+	if config.GetConfig().ServiceComb.APM.Tracing.ServerURI != "" && config.GetConfig().ServiceComb.APM.Tracing.Enable {
+		serverURI = config.GetConfig().ServiceComb.APM.Tracing.ServerURI
+	}
+	r, err = reporter.NewGRPCReporter(serverURI)
+	if err != nil {
+		openlogging.GetLogger().Errorf("NewGRPCReporter error:%s ", err.Error())
+	}
+	tracer, err = go2sky.NewTracer(gcconfig.MicroserviceDefinition.ServiceDescription.Name, go2sky.WithReporter(r))
+	if err != nil {
+		openlogging.GetLogger().Errorf("NewTracer error " + err.Error())
+	}
+	//tracer.WaitUntilRegister()
+	openlogging.GetLogger().Debugf("SkyWalking manager Init end")
+}
diff --git a/proxy/pkg/skywalking/skywalking_manager_test.go b/proxy/pkg/skywalking/skywalking_manager_test.go
new file mode 100644
index 0000000..e722c44
--- /dev/null
+++ b/proxy/pkg/skywalking/skywalking_manager_test.go
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+
+package skywalking_test
+
+import (
+	"context"
+	"github.com/apache/servicecomb-mesher/proxy/config"
+	"github.com/apache/servicecomb-mesher/proxy/pkg/skywalking"
+	gcconfig "github.com/go-chassis/go-chassis/core/config"
+	"github.com/go-chassis/go-chassis/core/config/model"
+	"github.com/go-chassis/go-chassis/core/invocation"
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+const (
+	Port      = ":49800"
+	ServerUrl = "127.0.0.1:49800"
+)
+
+//initConfig
+func initConfig() {
+	var micCfg model.MicroserviceCfg
+	micCfg.ServiceDescription.Name = "TEST"
+	gcconfig.MicroserviceDefinition = &micCfg
+}
+
+//initMesherConfig
+func initMesherConfig() {
+	config.SetConfig(&config.MesherConfig{ServiceComb: &config.ServiceComb{config.APM{config.Tracing{Enable: true, ServerURI: "192.168.0.1:17289"}}}})
+}
+
+//initInv
+func initInv() *invocation.Invocation {
+	var i invocation.Invocation
+	i.MicroServiceName = "test"
+	i.Ctx = context.Background()
+	i.Endpoint = "calculator"
+	i.URLPathFormat = "/bmi"
+	return &i
+}
+
+//TestInit init skywalking manager
+func TestInit(t *testing.T) {
+	initConfig()
+	initMesherConfig()
+	skywalking.Init()
+	assert.NotEqual(t, gcconfig.MicroserviceDefinition, nil)
+}
+
+//TestCreateEntrySpan test skywalking manager creating entryspan
+func TestCreateEntrySpan(t *testing.T) {
+	initConfig()
+	initMesherConfig()
+	skywalking.Init()
+	span, _, err := skywalking.CreateEntrySpan(initInv())
+	assert.Equal(t, err, nil)
+	assert.NotEqual(t, span, nil)
+	span.End()
+}
+
+//TestCreateExitSpan test skywalking manager creating endspan
+func TestCreateExitSpan(t *testing.T) {
+	initConfig()
+	initMesherConfig()
+	skywalking.Init()
+	inv := initInv()
+	span, ctx, err := skywalking.CreateEntrySpan(inv)
+	assert.Equal(t, err, nil)
+	assert.NotEqual(t, span, nil)
+	spanExit, err := skywalking.CreateExitSpan(ctx, inv)
+	assert.Equal(t, err, nil)
+	assert.NotEqual(t, spanExit, nil)
+	spanExit.End()
+	span.End()
+}
+
+//TestCreateLocalSpan test skywalking manager creating localspan
+func TestCreateLocalSpan(t *testing.T) {
+	initConfig()
+	initMesherConfig()
+	skywalking.Init()
+	span, _, err := skywalking.CreateLocalSpan(context.Background())
+	assert.Equal(t, err, nil)
+	assert.NotEqual(t, span, nil)
+}