diff --git a/cmd/layotto/main.go b/cmd/layotto/main.go index 5add5a8de4..b71606be4c 100644 --- a/cmd/layotto/main.go +++ b/cmd/layotto/main.go @@ -22,6 +22,10 @@ import ( "strconv" "time" + mosn_zipkin "mosn.io/mosn/pkg/trace/zipkin" + + "mosn.io/layotto/diagnostics/zipkin" + mosn_jaeger "mosn.io/mosn/pkg/trace/jaeger" "github.com/dapr/components-contrib/secretstores" @@ -519,6 +523,7 @@ func ExtensionsRegister(_ *cli.Context) { trace.RegisterTracerBuilder("SOFATracer", lprotocol.Layotto, diagnostics.NewTracer) trace.RegisterTracerBuilder(skywalking.SkyDriverName, lprotocol.Layotto, lsky.NewGrpcSkyTracer) trace.RegisterTracerBuilder(mosn_jaeger.DriverName, lprotocol.Layotto, jaeger.NewGrpcJaegerTracer) + trace.RegisterTracerBuilder(mosn_zipkin.DriverName, lprotocol.Layotto, zipkin.NewGrpcZipTracer) } func main() { diff --git a/cmd/layotto_multiple_api/main.go b/cmd/layotto_multiple_api/main.go index 696d73a9a3..123142cdbd 100644 --- a/cmd/layotto_multiple_api/main.go +++ b/cmd/layotto_multiple_api/main.go @@ -32,6 +32,7 @@ import ( secretstore_env "github.com/dapr/components-contrib/secretstores/local/env" secretstore_file "github.com/dapr/components-contrib/secretstores/local/file" mosn_jaeger "mosn.io/mosn/pkg/trace/jaeger" + mosn_zipkin "mosn.io/mosn/pkg/trace/zipkin" secretstores_loader "mosn.io/layotto/pkg/runtime/secretstores" @@ -179,6 +180,7 @@ import ( "mosn.io/layotto/diagnostics/jaeger" lprotocol "mosn.io/layotto/diagnostics/protocol" lsky "mosn.io/layotto/diagnostics/skywalking" + "mosn.io/layotto/diagnostics/zipkin" ) // loggerForDaprComp is constructed for reusing dapr's components. @@ -531,6 +533,7 @@ func ExtensionsRegister(_ *cli.Context) { trace.RegisterTracerBuilder("SOFATracer", "layotto", diagnostics.NewTracer) trace.RegisterTracerBuilder(skywalking.SkyDriverName, lprotocol.Layotto, lsky.NewGrpcSkyTracer) trace.RegisterTracerBuilder(mosn_jaeger.DriverName, lprotocol.Layotto, jaeger.NewGrpcJaegerTracer) + trace.RegisterTracerBuilder(mosn_zipkin.DriverName, lprotocol.Layotto, zipkin.NewGrpcZipTracer) } func main() { diff --git a/configs/config_trace_zipkin.json b/configs/config_trace_zipkin.json new file mode 100644 index 0000000000..46362df280 --- /dev/null +++ b/configs/config_trace_zipkin.json @@ -0,0 +1,83 @@ +{ + "servers": [ + { + "default_log_path": "stdout", + "default_log_level": "INFO", + "listeners": [ + { + "name": "grpc", + "address": "0.0.0.0:34904", + "bind_port": true, + "filter_chains": [ + { + "filters": [ + { + "type": "grpc", + "config": { + "server_name": "runtime", + "grpc_config": { + "hellos": { + "quick_start_demo": { + "type": "helloworld", + "hello": "greeting" + } + }, + "config_store": { + "config_demo": { + "type": "etcd", + "address": [ + "127.0.0.1:2379" + ], + "timeout": "10" + } + } + } + } + } + ] + } + ], + "stream_filters": [ + { + "type": "flowControlFilter", + "config": { + "global_switch": true, + "limit_key_type": "PATH", + "rules": [ + { + "resource": "/spec.proto.runtime.v1.Runtime/SayHello", + "grade": 1, + "threshold": 5 + } + ] + } + }, + { + "type": "grpc_metric" + } + ] + } + ] + } + ], + "tracing": { + "enable": true, + "driver": "Zipkin", + "config": { + "service_name": "layotto", + "reporter_endpoint": "http://127.0.0.1:9411/api/v2/spans", + "recorder_host_post": "127.0.0.1:34904" + } + }, + "metrics": { + "sinks": [ + { + "type": "prometheus", + "config": { + "port": 34903 + } + } + ] + } +} + diff --git a/diagnostics/zipkin/grpc_tracer.go b/diagnostics/zipkin/grpc_tracer.go new file mode 100644 index 0000000000..cc9bcabf53 --- /dev/null +++ b/diagnostics/zipkin/grpc_tracer.go @@ -0,0 +1,143 @@ +/* +* Copyright 2021 Layotto Authors +* +* Licensed 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 zipkin + +import ( + "context" + "fmt" + "time" + + "mosn.io/layotto/diagnostics/grpc" + + "github.com/openzipkin/zipkin-go" + reporterhttp "github.com/openzipkin/zipkin-go/reporter/http" + "mosn.io/api" + "mosn.io/mosn/pkg/types" + "mosn.io/pkg/log" + + ltrace "mosn.io/layotto/components/trace" +) + +const ( + service_name = "service_name" + reporter_endpoint = "reporter_endpoint" + recorder_host_post = "recorder_host_post" +) + +type grpcZipTracer struct { + *zipkin.Tracer +} + +type grpcZipSpan struct { + *ltrace.Span + tracer *grpcZipTracer + ctx context.Context + span zipkin.Span +} + +func NewGrpcZipTracer(traceCfg map[string]interface{}) (api.Tracer, error) { + point, err := getReporterEndpoint(traceCfg) + if err != nil { + return nil, err + } + + reporter := reporterhttp.NewReporter(point) + + name, err := getServerName(traceCfg) + if err != nil { + return nil, err + } + + host_post, err := getRecorderHostPort(traceCfg) + if err != nil { + return nil, err + } + + endpoint, err := zipkin.NewEndpoint(name, host_post) + if err != nil { + log.DefaultLogger.Errorf("[layotto] [zipkin] [tracer] unable to create zipkin reporter endpoint") + return nil, err + } + + tracer, err := zipkin.NewTracer(reporter, zipkin.WithLocalEndpoint(endpoint), zipkin.WithTraceID128Bit(true)) + if err != nil { + log.DefaultLogger.Errorf("[layotto] [zipkin] [tracer] cannot initialize zipkin Tracer") + return nil, err + } + + log.DefaultLogger.Infof("[layotto] [zipkin] [tracer] create success") + + return &grpcZipTracer{ + tracer, + }, nil +} + +func getRecorderHostPort(traceCfg map[string]interface{}) (string, error) { + if recorder, ok := traceCfg[recorder_host_post]; ok { + return recorder.(string), nil + } + + return "", fmt.Errorf("[layotto] [zipkin] [tracer] no config zipkin server host and port") +} + +func getReporterEndpoint(traceCfg map[string]interface{}) (string, error) { + if point, ok := traceCfg[reporter_endpoint]; ok { + return point.(string), nil + } + + return "", fmt.Errorf("[layotto] [zipkin] [tracer] no config zipkin reporter endpoint") +} + +func getServerName(traceCfg map[string]interface{}) (string, error) { + if name, ok := traceCfg[service_name]; ok { + return name.(string), nil + } + + return "", fmt.Errorf("[layotto] [zipkin] [tracer] no config zipkin server name") +} + +func (t *grpcZipTracer) Start(ctx context.Context, request interface{}, _ time.Time) api.Span { + info, ok := request.(*grpc.RequestInfo) + if !ok { + log.DefaultLogger.Debugf("[layotto] [zipkin] [tracer] unable to get request header, downstream trace ignored") + return nil + } + + // start span + span := t.StartSpan(info.FullMethod) + + return &grpcZipSpan{ + tracer: t, + ctx: ctx, + Span: <race.Span{}, + span: span, + } +} + +func (s *grpcZipSpan) TraceId() string { + return s.span.Context().TraceID.String() +} + +func (s *grpcZipSpan) InjectContext(requestHeaders types.HeaderMap, requestInfo api.RequestInfo) { +} + +func (s *grpcZipSpan) SetRequestInfo(requestInfo api.RequestInfo) { +} + +func (s *grpcZipSpan) FinishSpan() { + s.span.Finish() +} diff --git a/diagnostics/zipkin/zipkin-docker-compose.yaml b/diagnostics/zipkin/zipkin-docker-compose.yaml new file mode 100644 index 0000000000..128ccda352 --- /dev/null +++ b/diagnostics/zipkin/zipkin-docker-compose.yaml @@ -0,0 +1,23 @@ +#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. + +version: '3.3' +services: + zipkin: + image: openzipkin/zipkin:latest + container_name: zipkin + restart: always + ports: + - "9411:9411" diff --git a/docs/zh/_sidebar.md b/docs/zh/_sidebar.md index 2032eebbf2..95cd8cad52 100644 --- a/docs/zh/_sidebar.md +++ b/docs/zh/_sidebar.md @@ -24,6 +24,7 @@ - 可观测性 - [Trace, Metrics](zh/start/trace/trace.md) - [Trace 接入 Skywalking](zh/start/trace/skywalking.md) + - [Trace 接入 Zipkin](zh/start/trace/zipkin.md) - [Trace 接入 Jaeger](zh/start/trace/jaeger.md) - [Metrics 接入 Prometheus](zh/start/trace/prometheus.md) - [将业务逻辑通过 WASM 下沉进sidecar](zh/start/wasm/start.md) diff --git a/docs/zh/start/trace/zipkin.md b/docs/zh/start/trace/zipkin.md new file mode 100644 index 0000000000..d071d3eefc --- /dev/null +++ b/docs/zh/start/trace/zipkin.md @@ -0,0 +1,101 @@ +# ZipKin trace 接入 + +## 配置 + +示例:configs/config_trace_zipkin.json + +```json +{ + "tracing": { + "enable": true, + "driver": "Zipkin", + "config": { + "config": { + "service_name": "layotto", + "reporter_endpoint": "http://127.0.0.1:9411/api/v2/spans", + "recorder_host_post": "127.0.0.1:34904" + } + } + } +} + +``` +| 字段 | 必填 | 说明 | +|------|-----|--------------------------| +| service_name | Y | 当前服务名称,例如layotto | +| reporter_endpoint | Y | 链路日志上报url | +| recorder_host_post | Y | 当前服务端口信息,例如layotto服务的端口为127.0.0.1:34904 | + +注意:目前只支持Http方式的Reporter。 + +## 运行ZipKin + +```shell +docker-compose -f diagnostics/zipkin/zipkin-docker-compose.yaml up -d +``` + +## 运行layotto + + + +#### **使用 Docker** + +您可以用 docker 启动 Layotto + +```bash +docker run -d \ + -v "$(pwd)/configs/config_trace_zipkin.json:/runtime/configs/config.json" \ + -p 34904:34904 --network=zipkin_default --name layotto \ + layotto/layotto start +``` + +#### **本地编译(不适合 Windows)** +您可以本地编译、运行 Layotto。 + +> [!TIP|label: 不适合 Windows 用户] +> Layotto 在 Windows 下会编译失败。建议 Windows 用户使用 docker 部署 + + +构建: + +```shell +cd ${project_path}/cmd/layotto_multiple_api/ +``` + +```shell @if.not.exist layotto +go build -o layotto +``` + +运行: + +```shell @background +./layotto start -c ../../configs/config_trace_zipkin.json +``` + + +## 运行 Demo + +```shell + cd ${project_path}/demo/flowcontrol/ + go run client.go +``` + +访问:http://localhost:9411/zipkin/?serviceName=layotto&lookback=15m&endTs=1655559536414&limit=10 + +![](https://gw.alipayobjects.com/mdn/rms_5891a1/afts/img/A*WodlQKsN5UcAAAAAAAAAAAAAARQnAQ) + +## 清理资源 + +如果您使用 Docker 启动 Layotto,记得删除容器: + +```bash +docker rm -f layotto +``` + +记得关闭 zipkin: + +```shell +cd ${project_path}/diagnostics/zipkin + +docker-compose -f zipkin-docker-compose.yaml down +``` \ No newline at end of file diff --git a/etc/script/test-quickstart.sh b/etc/script/test-quickstart.sh index 63d54142c3..813045a275 100755 --- a/etc/script/test-quickstart.sh +++ b/etc/script/test-quickstart.sh @@ -33,6 +33,7 @@ quickstarts_in_default="docs/en/start/configuration/start.md docs/zh/start/trace/skywalking.md docs/zh/start/trace/prometheus.md docs/en/start/trace/prometheus.md + docs/zh/start/trace/zipkin.md docs/zh/start/trace/jaeger.md docs/en/start/wasm/start.md docs/zh/start/wasm/start.md diff --git a/go.mod b/go.mod index 449892055c..8cb9ce3635 100644 --- a/go.mod +++ b/go.mod @@ -22,6 +22,7 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/json-iterator/go v1.1.12 github.com/opentracing/opentracing-go v1.2.0 + github.com/openzipkin/zipkin-go v0.2.2 github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 github.com/pkg/errors v0.9.1 github.com/shirou/gopsutil v3.21.3+incompatible @@ -37,7 +38,7 @@ require ( mosn.io/api v1.0.0 mosn.io/layotto/components v0.0.0-20220413092851-55c58dbb1a23 mosn.io/layotto/spec v0.0.0-20220413092851-55c58dbb1a23 - mosn.io/mosn v1.0.1 + mosn.io/mosn v1.0.2-0.20220607053200-448da0ebe355 mosn.io/pkg v1.0.0 mosn.io/proxy-wasm-go-host v0.1.1-0.20210524020952-3fb13ba763a6 nhooyr.io/websocket v1.8.7 // indirect diff --git a/go.sum b/go.sum index 00572e74a2..bf68dacc81 100644 --- a/go.sum +++ b/go.sum @@ -683,6 +683,7 @@ github.com/gorilla/mux v0.0.0-20181024020800-521ea7b17d02/go.mod h1:1lud6UwP+6or github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= @@ -1140,6 +1141,7 @@ github.com/openzipkin-contrib/zipkin-go-opentracing v0.3.5/go.mod h1:uVHyebswE1c github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2 h1:nY8Hti+WKaP0cRsSeQ026wU03QsM762XBeCXBb9NAWI= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= @@ -2129,8 +2131,8 @@ mosn.io/api v1.0.0 h1:EK5jHRaqeszV3tKzgNKX1NZf1JdPU9QTF6E276xQHPk= mosn.io/api v1.0.0/go.mod h1:TBv4bz2f2RbpgdohbVAFRFVOoN8YyEUiLH3jAh752Qc= mosn.io/holmes v1.0.1/go.mod h1:pZjPamcZk4Z16xlZySG1rU9psLUCOx6MVNuj/3bfkEk= mosn.io/mosn v0.25.1-0.20211217125944-69b50c40af81/go.mod h1:JwLkls6oMaap0+P1uZ1d1ccdLPigdK8xH8gDSm3SEq4= -mosn.io/mosn v1.0.1 h1:3X2Sh7B6K2PD/4cKZ72GtXohG+jeubojJBbArXQ/ZqI= -mosn.io/mosn v1.0.1/go.mod h1:NtUWYhOSHgC+yRlLLFGSD1zUbEXKm4XhvLwAbCh1F8U= +mosn.io/mosn v1.0.2-0.20220607053200-448da0ebe355 h1:Vl509sjily+XBKsodd4Ha36TIwFgv0olOa+3jYkRAns= +mosn.io/mosn v1.0.2-0.20220607053200-448da0ebe355/go.mod h1:vPhLsrbmbRfucz9znc08PiYxi0b+890NrAqe1JB7f3E= mosn.io/pkg v0.0.0-20211217101631-d914102d1baf/go.mod h1:tK3Vbw6CcVeJ9H/BGjJ1wn6hRXt4Oxjfq1+gkOM0zG8= mosn.io/pkg v1.0.0 h1:zmvPVfk5zZ5il7lEwa9hdtt77vWVtpioKD1DHTQ/PcI= mosn.io/pkg v1.0.0/go.mod h1:tK3Vbw6CcVeJ9H/BGjJ1wn6hRXt4Oxjfq1+gkOM0zG8=