diff --git a/Dockerfile b/Dockerfile index 16f3dd8cd..50ad7e7c3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -68,6 +68,7 @@ COPY shared/go.mod shared/go.mod ../shared/ COPY logger/go.mod logger/go.mod ../logger/ COPY tap/go.mod tap/go.mod ../tap/ COPY tap/api/go.mod ../tap/api/ +COPY tap/dbgctl/go.mod ../tap/dbgctl/ COPY tap/extensions/amqp/go.mod ../tap/extensions/amqp/ COPY tap/extensions/http/go.mod ../tap/extensions/http/ COPY tap/extensions/kafka/go.mod ../tap/extensions/kafka/ diff --git a/Makefile b/Makefile index c2f471166..bed2f3318 100644 --- a/Makefile +++ b/Makefile @@ -83,6 +83,7 @@ test-lint: ## Run lint on all modules cd cli && golangci-lint run cd acceptanceTests && golangci-lint run cd tap/api && golangci-lint run + cd tap/dbgctl && golangci-lint run cd tap/extensions/ && for D in */; do cd $$D && golangci-lint run && cd ..; done test-cli: ## Run cli tests diff --git a/acceptanceTests/go.mod b/acceptanceTests/go.mod index a0ef26f8f..edc445e61 100644 --- a/acceptanceTests/go.mod +++ b/acceptanceTests/go.mod @@ -54,3 +54,5 @@ replace github.com/up9inc/mizu/logger v0.0.0 => ../logger replace github.com/up9inc/mizu/shared v0.0.0 => ../shared replace github.com/up9inc/mizu/tap/api v0.0.0 => ../tap/api + +replace github.com/up9inc/mizu/tap/dbgctl v0.0.0 => ../tap/dbgctl diff --git a/agent/go.mod b/agent/go.mod index cc0ae55f8..7074cf75a 100644 --- a/agent/go.mod +++ b/agent/go.mod @@ -7,6 +7,7 @@ require ( github.com/chanced/openapi v0.0.8 github.com/djherbis/atime v1.1.0 github.com/getkin/kin-openapi v0.89.0 + github.com/gin-contrib/pprof v1.3.0 github.com/gin-contrib/static v0.0.1 github.com/gin-gonic/gin v1.7.7 github.com/go-playground/locales v0.14.0 @@ -24,6 +25,7 @@ require ( github.com/up9inc/mizu/shared v0.0.0 github.com/up9inc/mizu/tap v0.0.0 github.com/up9inc/mizu/tap/api v0.0.0 + github.com/up9inc/mizu/tap/dbgctl v0.0.0 github.com/up9inc/mizu/tap/extensions/amqp v0.0.0 github.com/up9inc/mizu/tap/extensions/http v0.0.0 github.com/up9inc/mizu/tap/extensions/kafka v0.0.0 @@ -60,6 +62,7 @@ require ( github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-errors/errors v1.4.2 // indirect github.com/go-logr/logr v1.2.2 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect github.com/go-openapi/jsonreference v0.19.6 // indirect github.com/go-openapi/swag v0.21.1 // indirect @@ -101,15 +104,20 @@ require ( github.com/russross/blackfriday v1.6.0 // indirect github.com/santhosh-tekuri/jsonschema/v5 v5.0.0 // indirect github.com/segmentio/kafka-go v0.4.27 // indirect + github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/spf13/cobra v1.3.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/struCoder/pidusage v0.2.1 // indirect github.com/tidwall/gjson v1.14.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect github.com/tidwall/sjson v1.2.4 // indirect + github.com/tklauser/go-sysconf v0.3.10 // indirect + github.com/tklauser/numcpus v0.4.0 // indirect github.com/ugorji/go/codec v1.2.6 // indirect github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect github.com/xlab/treeprint v1.1.0 // indirect + github.com/yusufpapurcu/wmi v1.2.2 // indirect go.starlark.net v0.0.0-20220203230714-bb14e151c28f // indirect golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b // indirect golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect @@ -151,3 +159,5 @@ replace github.com/up9inc/mizu/tap/extensions/http v0.0.0 => ../tap/extensions/h replace github.com/up9inc/mizu/tap/extensions/kafka v0.0.0 => ../tap/extensions/kafka replace github.com/up9inc/mizu/tap/extensions/redis v0.0.0 => ../tap/extensions/redis + +replace github.com/up9inc/mizu/tap/dbgctl v0.0.0 => ../tap/dbgctl diff --git a/agent/go.sum b/agent/go.sum index 2b3f360b3..a080e07bf 100644 --- a/agent/go.sum +++ b/agent/go.sum @@ -213,10 +213,13 @@ github.com/getkin/kin-openapi v0.89.0 h1:p4nagHchUKGn85z/f+pse4aSh50nIBOYjOhMIku github.com/getkin/kin-openapi v0.89.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/pprof v1.3.0 h1:G9eK6HnbkSqDZBYbzG4wrjCsA4e+cvYAHUZw6W+W9K0= +github.com/gin-contrib/pprof v1.3.0/go.mod h1:waMjT1H9b179t3CxuG1cV3DHpga6ybizwfBaM5OXaB0= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-contrib/static v0.0.1 h1:JVxuvHPuUfkoul12N7dtQw7KRn/pSMq7Ue1Va9Swm1U= github.com/gin-contrib/static v0.0.1/go.mod h1:CSxeF+wep05e0kCOsqWdAWbSszmc31zTIbD8TvWl7Hs= +github.com/gin-gonic/gin v1.6.2/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs= github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= @@ -238,6 +241,8 @@ github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= @@ -618,6 +623,8 @@ github.com/segmentio/kafka-go v0.4.27 h1:sIhEozeL/TLN2mZ5dkG462vcGEWYKS+u31sXPjK github.com/segmentio/kafka-go v0.4.27/go.mod h1:XzMcoMjSzDGHcIwpWUI7GB43iKZ2fTVmryPSGLf/MPg= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= +github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -659,6 +666,8 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/struCoder/pidusage v0.2.1 h1:dFiEgUDkubeIj0XA1NpQ6+8LQmKrLi7NiIQl86E6BoY= +github.com/struCoder/pidusage v0.2.1/go.mod h1:bewtP2KUA1TBUyza5+/PCpSQ6sc/H6jJbIKAzqW86BA= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tidwall/gjson v1.10.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.12.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= @@ -672,6 +681,10 @@ github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhso github.com/tidwall/sjson v1.2.3/go.mod h1:5WdjKx3AQMvCJ4RG6/2UYT7dLrGvJUV1x4jdTAyGvZs= github.com/tidwall/sjson v1.2.4 h1:cuiLzLnaMeBhRmEv00Lpk3tkYrcxpmbU81tAY4Dw0tc= github.com/tidwall/sjson v1.2.4/go.mod h1:098SZ494YoMWPmMO6ct4dcFnqxwj9r/gF0Etp19pSNM= +github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw= +github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= +github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//o= +github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= @@ -702,6 +715,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= +github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= @@ -894,6 +909,7 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -962,6 +978,7 @@ golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220207234003-57398862261d h1:Bm7BNOQt2Qv7ZqysjeLjgCBanX+88Z/OtdvsrEv1Djc= golang.org/x/sys v0.0.0-20220207234003-57398862261d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= diff --git a/agent/main.go b/agent/main.go index f31706288..30d455b78 100644 --- a/agent/main.go +++ b/agent/main.go @@ -14,6 +14,7 @@ import ( "syscall" "time" + "github.com/gin-contrib/pprof" "github.com/gin-contrib/static" "github.com/gin-gonic/gin" "github.com/up9inc/mizu/agent/pkg/dependency" @@ -36,6 +37,7 @@ import ( "github.com/up9inc/mizu/shared" "github.com/up9inc/mizu/tap" tapApi "github.com/up9inc/mizu/tap/api" + "github.com/up9inc/mizu/tap/dbgctl" ) var tapperMode = flag.Bool("tap", false, "Run in tapper mode without API") @@ -45,6 +47,7 @@ var apiServerAddress = flag.String("api-server-address", "", "Address of mizu AP var namespace = flag.String("namespace", "", "Resolve IPs if they belong to resources in this namespace (default is all)") var harsReaderMode = flag.Bool("hars-read", false, "Run in hars-read mode") var harsDir = flag.String("hars-dir", "", "Directory to read hars from") +var profiler = flag.Bool("profiler", false, "Run pprof server") const ( socketConnectionRetries = 30 @@ -61,7 +64,7 @@ func main() { app.LoadExtensions() if !*tapperMode && !*apiServerMode && !*standaloneMode && !*harsReaderMode { - panic("One of the flags --tap, --api or --standalone or --hars-read must be provided") + panic("One of the flags --tap, --api-server, --standalone or --hars-read must be provided") } if *standaloneMode { @@ -69,7 +72,14 @@ func main() { } else if *tapperMode { runInTapperMode() } else if *apiServerMode { - utils.StartServer(runInApiServerMode(*namespace)) + app := runInApiServerMode(*namespace) + + if *profiler { + pprof.Register(app) + } + + utils.StartServer(app) + } else if *harsReaderMode { runInHarReaderMode() } @@ -283,6 +293,10 @@ func pipeTapChannelToSocket(connection *websocket.Conn, messageDataChannel <-cha continue } + if dbgctl.MizuTapperDisableSending { + continue + } + // NOTE: This is where the `*tapApi.OutputChannelItem` leaves the code // and goes into the intermediate WebSocket. err = connection.WriteMessage(websocket.TextMessage, marshaledData) diff --git a/agent/pkg/app/main.go b/agent/pkg/app/main.go index 65b7cb41d..eed1ae0b6 100644 --- a/agent/pkg/app/main.go +++ b/agent/pkg/app/main.go @@ -11,6 +11,7 @@ import ( "github.com/up9inc/mizu/agent/pkg/api" "github.com/up9inc/mizu/agent/pkg/utils" "github.com/up9inc/mizu/logger" + "github.com/up9inc/mizu/tap/dbgctl" tapApi "github.com/up9inc/mizu/tap/api" amqpExt "github.com/up9inc/mizu/tap/extensions/amqp" httpExt "github.com/up9inc/mizu/tap/extensions/http" @@ -24,36 +25,38 @@ var ( ) func LoadExtensions() { - Extensions = make([]*tapApi.Extension, 4) + Extensions = make([]*tapApi.Extension, 0) ExtensionsMap = make(map[string]*tapApi.Extension) - extensionAmqp := &tapApi.Extension{} - dissectorAmqp := amqpExt.NewDissector() - dissectorAmqp.Register(extensionAmqp) - extensionAmqp.Dissector = dissectorAmqp - Extensions[0] = extensionAmqp - ExtensionsMap[extensionAmqp.Protocol.Name] = extensionAmqp - extensionHttp := &tapApi.Extension{} dissectorHttp := httpExt.NewDissector() dissectorHttp.Register(extensionHttp) extensionHttp.Dissector = dissectorHttp - Extensions[1] = extensionHttp + Extensions = append(Extensions, extensionHttp) ExtensionsMap[extensionHttp.Protocol.Name] = extensionHttp - extensionKafka := &tapApi.Extension{} - dissectorKafka := kafkaExt.NewDissector() - dissectorKafka.Register(extensionKafka) - extensionKafka.Dissector = dissectorKafka - Extensions[2] = extensionKafka - ExtensionsMap[extensionKafka.Protocol.Name] = extensionKafka + if !dbgctl.MizuTapperDisableNonHttpExtensions { + extensionAmqp := &tapApi.Extension{} + dissectorAmqp := amqpExt.NewDissector() + dissectorAmqp.Register(extensionAmqp) + extensionAmqp.Dissector = dissectorAmqp + Extensions = append(Extensions, extensionAmqp) + ExtensionsMap[extensionAmqp.Protocol.Name] = extensionAmqp - extensionRedis := &tapApi.Extension{} - dissectorRedis := redisExt.NewDissector() - dissectorRedis.Register(extensionRedis) - extensionRedis.Dissector = dissectorRedis - Extensions[3] = extensionRedis - ExtensionsMap[extensionRedis.Protocol.Name] = extensionRedis + extensionKafka := &tapApi.Extension{} + dissectorKafka := kafkaExt.NewDissector() + dissectorKafka.Register(extensionKafka) + extensionKafka.Dissector = dissectorKafka + Extensions = append(Extensions, extensionKafka) + ExtensionsMap[extensionKafka.Protocol.Name] = extensionKafka + + extensionRedis := &tapApi.Extension{} + dissectorRedis := redisExt.NewDissector() + dissectorRedis.Register(extensionRedis) + extensionRedis.Dissector = dissectorRedis + Extensions = append(Extensions, extensionRedis) + ExtensionsMap[extensionRedis.Protocol.Name] = extensionRedis + } sort.Slice(Extensions, func(i, j int) bool { return Extensions[i].Protocol.Priority < Extensions[j].Protocol.Priority diff --git a/cli/cmd/tap.go b/cli/cmd/tap.go index 3399fc24a..6a590eeed 100644 --- a/cli/cmd/tap.go +++ b/cli/cmd/tap.go @@ -123,4 +123,5 @@ func init() { tapCmd.Flags().String(configStructs.ContractFile, defaultTapConfig.ContractFile, "OAS/Swagger file to validate to monitor the contracts") tapCmd.Flags().Bool(configStructs.ServiceMeshName, defaultTapConfig.ServiceMesh, "Record decrypted traffic if the cluster is configured with a service mesh and with mtls") tapCmd.Flags().Bool(configStructs.TlsName, defaultTapConfig.Tls, "Record tls traffic") + tapCmd.Flags().Bool(configStructs.ProfilerName, defaultTapConfig.Profiler, "Run pprof server") } diff --git a/cli/cmd/tapRunner.go b/cli/cmd/tapRunner.go index 9bf833ca6..20d911bb8 100644 --- a/cli/cmd/tapRunner.go +++ b/cli/cmd/tapRunner.go @@ -124,7 +124,7 @@ func RunMizuTap() { } logger.Log.Infof("Waiting for Mizu Agent to start...") - if state.mizuServiceAccountExists, err = resources.CreateTapMizuResources(ctx, kubernetesProvider, serializedValidationRules, serializedContract, serializedMizuConfig, config.Config.IsNsRestrictedMode(), config.Config.MizuResourcesNamespace, config.Config.AgentImage, getSyncEntriesConfig(), config.Config.Tap.MaxEntriesDBSizeBytes(), config.Config.Tap.ApiServerResources, config.Config.ImagePullPolicy(), config.Config.LogLevel()); err != nil { + if state.mizuServiceAccountExists, err = resources.CreateTapMizuResources(ctx, kubernetesProvider, serializedValidationRules, serializedContract, serializedMizuConfig, config.Config.IsNsRestrictedMode(), config.Config.MizuResourcesNamespace, config.Config.AgentImage, getSyncEntriesConfig(), config.Config.Tap.MaxEntriesDBSizeBytes(), config.Config.Tap.ApiServerResources, config.Config.ImagePullPolicy(), config.Config.LogLevel(), config.Config.Tap.Profiler); err != nil { var statusError *k8serrors.StatusError if errors.As(err, &statusError) && (statusError.ErrStatus.Reason == metav1.StatusReasonAlreadyExists) { logger.Log.Info("Mizu is already running in this namespace, change the `mizu-resources-namespace` configuration or run `mizu clean` to remove the currently running Mizu instance") diff --git a/cli/config/configStructs/tapConfig.go b/cli/config/configStructs/tapConfig.go index c3c4a8b35..4aba8ca7d 100644 --- a/cli/config/configStructs/tapConfig.go +++ b/cli/config/configStructs/tapConfig.go @@ -30,6 +30,7 @@ const ( ContractFile = "contract" ServiceMeshName = "service-mesh" TlsName = "tls" + ProfilerName = "profiler" ) type TapConfig struct { @@ -54,6 +55,7 @@ type TapConfig struct { TapperResources shared.Resources `yaml:"tapper-resources"` ServiceMesh bool `yaml:"service-mesh" default:"false"` Tls bool `yaml:"tls" default:"false"` + Profiler bool `yaml:"profiler" default:"false"` } func (config *TapConfig) PodRegex() *regexp.Regexp { diff --git a/cli/go.mod b/cli/go.mod index a703190c2..e3cac8b62 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -74,6 +74,7 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/russross/blackfriday v1.6.0 // indirect github.com/stretchr/testify v1.7.0 // indirect + github.com/up9inc/mizu/tap/dbgctl v0.0.0 // indirect github.com/xlab/treeprint v1.1.0 // indirect go.starlark.net v0.0.0-20220203230714-bb14e151c28f // indirect golang.org/x/crypto v0.0.0-20220208050332-20e1d8d225ab // indirect @@ -104,3 +105,5 @@ replace github.com/up9inc/mizu/logger v0.0.0 => ../logger replace github.com/up9inc/mizu/shared v0.0.0 => ../shared replace github.com/up9inc/mizu/tap/api v0.0.0 => ../tap/api + +replace github.com/up9inc/mizu/tap/dbgctl v0.0.0 => ../tap/dbgctl diff --git a/cli/resources/createResources.go b/cli/resources/createResources.go index ee2f2a46b..9d359cb7d 100644 --- a/cli/resources/createResources.go +++ b/cli/resources/createResources.go @@ -14,7 +14,7 @@ import ( core "k8s.io/api/core/v1" ) -func CreateTapMizuResources(ctx context.Context, kubernetesProvider *kubernetes.Provider, serializedValidationRules string, serializedContract string, serializedMizuConfig string, isNsRestrictedMode bool, mizuResourcesNamespace string, agentImage string, syncEntriesConfig *shared.SyncEntriesConfig, maxEntriesDBSizeBytes int64, apiServerResources shared.Resources, imagePullPolicy core.PullPolicy, logLevel logging.Level) (bool, error) { +func CreateTapMizuResources(ctx context.Context, kubernetesProvider *kubernetes.Provider, serializedValidationRules string, serializedContract string, serializedMizuConfig string, isNsRestrictedMode bool, mizuResourcesNamespace string, agentImage string, syncEntriesConfig *shared.SyncEntriesConfig, maxEntriesDBSizeBytes int64, apiServerResources shared.Resources, imagePullPolicy core.PullPolicy, logLevel logging.Level, profiler bool) (bool, error) { if !isNsRestrictedMode { if err := createMizuNamespace(ctx, kubernetesProvider, mizuResourcesNamespace); err != nil { return false, err @@ -50,6 +50,7 @@ func CreateTapMizuResources(ctx context.Context, kubernetesProvider *kubernetes. Resources: apiServerResources, ImagePullPolicy: imagePullPolicy, LogLevel: logLevel, + Profiler: profiler, } if err := createMizuApiServerPod(ctx, kubernetesProvider, opts); err != nil { diff --git a/performance_analysis/README.md b/performance_analysis/README.md new file mode 100644 index 000000000..cc3d677fc --- /dev/null +++ b/performance_analysis/README.md @@ -0,0 +1,107 @@ + +# Performance analysis + +This directory contains tools for analyzing tapper performance. + +# Periodic tapper logs + +In tapper logs there are some periodic lines that shows its internal state and consumed resources. + +Internal state example (formatted and commented): +``` +stats - { + "processedBytes":468940592, // how many bytes we read from pcap + "packetsCount":174883, // how many packets we read from pcap + "tcpPacketsCount":174883, // how many tcp packets we read from pcap + "reassembledTcpPayloadsCount":66893, // how many chunks sent to tcp stream + "matchedPairs":24821, // how many request response pairs found + "droppedTcpStreams":2 // how many tcp streams remained stale and dropped +} +``` + +Consumed resources example (formatted and commented): +``` +mem: 24441240, // golang heap size +goroutines: 29, // how many goroutines +cpu: 91.208791, // how much cpu the tapper process consume (in percentage per core) +cores: 16, // how many cores there are on the machine +rss: 87052288 // how many bytes held by the tapper process +``` + +# Plot tapper logs + +In order to plot a tapper log or many logs into a graph, use the `plot_from_tapper_logs.py` util. + +It gets a list of tapper logs as a parameter, and output an image with a nice graph. + +The log file names should be named in this format `XX_DESCRIPTION.log` when XX is the number between determining the color of the output graph and description is the name of the series. It allows for easy comparison between various modes. + +Example run: +``` +cd $MIZU_HOME/performance_analysis +virtualenv venv +source venv/bin/activate +pip install -r requirements.txt +python plot_from_tapper_logs.py 00_tapper.log +``` + +# Tapper Modes + +Every packet seen by the tapper is processed in a pipeline that contains various stages. +* Pcap - Read the packet from libpcap +* Assembler - Assemble the packet into a TcpStream +* TcpStream - Hold stream information and TcpReaders +* Dissectors - Read from TcpReader and recognize the packet content and protocol. +* Emit - Marshal the request response pair into a Json +* Send - Send the Json to Api Server + +Tapper can be run with various debug modes: +* No Pcap - Start the tapper process, but don't read from any packets from pcap +* No Assembler - Read packets from pcap, but don't assemble them +* No TcpStream - Assemble the packets, but don't create TcpStream for them +* No Dissectors - Create a TcpStream for the packets, but don't dissect their content +* No Emit - Dissect the TcpStream, but don't emit the matched request response pair +* No Send - Emit the request response pair, but don't send them to the Api Server. +* Regular mode + +![Tapper Modes](https://github.com/up9inc/mizu/blob/debug/profile-tapper-benchmark/performance_analysis/tapper-modes.png) + +# Run benchmark with various tapper modes + +## Prerequisite + +In order to run the benchmark you probably want: +1. An up and running Api Server +2. An up and running Basenine +3. An up and running UI (optional) +4. An up and running test server, like nginx, that can return a known payload at a known endpoint. +5. Set MIZU_HOME environment variable to points to mizu directory +6. Install the `hey` tool + +## Running the benchmark + +In order to run a benchmark use the `run_tapper_benchmark.sh` script. + +Example run: +``` +cd $MIZU_HOME/performance_analysis +source venv/bin/activate # Assuming you already run plot_from_tapper_logs.py +./run_tapper_benchmark.sh +``` + +Running it without params use the default values, use the following environment variables for customization: +``` +export=MIZU_BENCHMARK_OUTPUT_DIR=/path/to/dir # Set the output directory for tapper logs and graph +export=MIZU_BENCHMARK_CLIENT_PERIOD=1m # How long each test run +export=MIZU_BENCHMARK_URL=http://server:port/path # The URL to use for the benchmarking process (the test server endpoint) +export=MIZU_BENCHMARK_RUN_COUNT=3 # How many times each tapper mode should run +export=MIZU_BENCHMARK_QPS=250 # How many queries per second the each client should send to the test server +export=MIZU_BENCHMARK_CLIENTS_COUNT=5 # How many clients should run in parallel during the benchmark +``` + +# Example output graph + +An example output graph from a 15 min run with 15K payload and 1000 QPS looks like + +![Example Graph](https://github.com/up9inc/mizu/blob/debug/profile-tapper-benchmark/performance_analysis/example-graph.png) + diff --git a/performance_analysis/example-graph.png b/performance_analysis/example-graph.png new file mode 100644 index 000000000..e930b0f61 Binary files /dev/null and b/performance_analysis/example-graph.png differ diff --git a/performance_analysis/plot_from_tapper_logs.py b/performance_analysis/plot_from_tapper_logs.py new file mode 100644 index 000000000..a7364a22c --- /dev/null +++ b/performance_analysis/plot_from_tapper_logs.py @@ -0,0 +1,183 @@ +import matplotlib.pyplot as plt +import numpy as np +import pandas as pd +import pathlib +import re +import sys +import typing + +COLORMAP = plt.get_cmap('turbo') + +# Extract cpu and rss samples from log files and plot them +# Input: List of log files +# +# example: +# python plot_from_tapper_logs.py 01_no_pcap_01.log 99_normal_00.log +# +# The script assumes that the log file names start with a number (pattern '\d+') +# and groups based on this number. Files that start will the same number will be plotted with the same color. +# Change group_pattern to an empty string to disable this, or change to a regex of your liking. + + +def get_sample(name: str, line: str, default_value: float): + pattern = name + r': ?(\d+(\.\d+)?)' + maybe_sample = re.findall(pattern, line) + if len(maybe_sample) == 0: + return default_value + + sample = float(maybe_sample[0][0]) + return sample + + +def append_sample(name: str, line: str, samples: typing.List[float]): + sample = get_sample(name, line, -1) + + if sample == -1: + return + + samples.append(sample) + + +def extract_samples(f: typing.IO) -> typing.Tuple[pd.Series, pd.Series, pd.Series, pd.Series, pd.Series, pd.Series, pd.Series, pd.Series]: + cpu_samples = [] + rss_samples = [] + count_samples = [] + matched_samples = [] + live_samples = [] + processed_samples = [] + heap_samples = [] + goroutines_samples = [] + for line in f: + append_sample('cpu', line, cpu_samples) + append_sample('rss', line, rss_samples) + ignored_packets_count = get_sample('"ignoredPacketsCount"', line, -1) + packets_count = get_sample('"packetsCount"', line, -1) + if ignored_packets_count != -1 and packets_count != -1: + count_samples.append(packets_count - ignored_packets_count) + append_sample('"matchedPairs"', line, matched_samples) + append_sample('"liveTcpStreams"', line, live_samples) + append_sample('"processedBytes"', line, processed_samples) + append_sample('mem', line, heap_samples) + append_sample('goroutines', line, goroutines_samples) + + cpu_samples = pd.Series(cpu_samples) + rss_samples = pd.Series(rss_samples) + count_samples = pd.Series(count_samples) + matched_samples = pd.Series(matched_samples) + live_samples = pd.Series(live_samples) + processed_samples = pd.Series(processed_samples) + heap_samples = pd.Series(heap_samples) + goroutines_samples = pd.Series(goroutines_samples) + + return cpu_samples, rss_samples, count_samples, matched_samples, live_samples, processed_samples, heap_samples, goroutines_samples + + +def plot(ax, df: pd.DataFrame, title: str, xlabel: str, ylabel: str, group_pattern: typing.Optional[str]): + if group_pattern: + color = get_group_color(df.columns, group_pattern) + df.plot(color=color, ax=ax) + else: + df.plot(cmap=COLORMAP, ax=ax) + + ax.ticklabel_format(style='plain') + plt.title(title) + plt.legend() + plt.xlabel(xlabel) + plt.ylabel(ylabel) + + +def get_group_color(names, pattern): + props = [int(re.findall(pattern, pathlib.Path(name).name)[0]) for name in names] + key = dict(zip(sorted(list(set(props))), range(len(set(props))))) + n_colors = len(key) + color_options = plt.get_cmap('jet')(np.linspace(0, 1, n_colors)) + groups = [key[prop] for prop in props] + color = color_options[groups] # type: ignore + return color + + +if __name__ == '__main__': + filenames = sys.argv[1:] + + cpu_samples_all_files = [] + rss_samples_all_files = [] + count_samples_all_files = [] + matched_samples_all_files = [] + live_samples_all_files = [] + processed_samples_all_files = [] + heap_samples_all_files = [] + goroutines_samples_all_files = [] + + for ii, filename in enumerate(filenames): + print("Analyzing {}".format(filename)) + with open(filename, 'r') as f: + cpu_samples, rss_samples, count_samples, matched_samples, live_samples, processed_samples, heap_samples, goroutines_samples = extract_samples(f) + + cpu_samples.name = pathlib.Path(filename).name + rss_samples.name = pathlib.Path(filename).name + count_samples.name = pathlib.Path(filename).name + matched_samples.name = pathlib.Path(filename).name + live_samples.name = pathlib.Path(filename).name + processed_samples.name = pathlib.Path(filename).name + heap_samples.name = pathlib.Path(filename).name + goroutines_samples.name = pathlib.Path(filename).name + + cpu_samples_all_files.append(cpu_samples) + rss_samples_all_files.append(rss_samples) + count_samples_all_files.append(count_samples) + matched_samples_all_files.append(matched_samples) + live_samples_all_files.append(live_samples) + processed_samples_all_files.append(processed_samples) + heap_samples_all_files.append(processed_samples) + goroutines_samples_all_files.append(processed_samples) + + cpu_samples_df = pd.concat(cpu_samples_all_files, axis=1) + rss_samples_df = pd.concat(rss_samples_all_files, axis=1) + count_samples_df = pd.concat(count_samples_all_files, axis=1) + matched_samples_df = pd.concat(matched_samples_all_files, axis=1) + live_samples_df = pd.concat(live_samples_all_files, axis=1) + processed_samples_df = pd.concat(processed_samples_all_files, axis=1) + + heap_samples_df = pd.concat(heap_samples_all_files, axis=1) + goroutines_samples_df = pd.concat(goroutines_samples_all_files, axis=1) + + group_pattern = r'^\d+' + + cpu_plot = plt.subplot(8, 2, 1) + plot(cpu_plot, cpu_samples_df, 'cpu', '', 'cpu (%)', group_pattern) + cpu_plot.legend().remove() + + mem_plot = plt.subplot(8, 2, 2) + plot(mem_plot, (rss_samples_df / 1024 / 1024), 'rss', '', 'mem (mega)', group_pattern) + mem_plot.legend(loc='center left', bbox_to_anchor=(1, 0.5)) + + packets_plot = plt.subplot(8, 2, 3) + plot(packets_plot, count_samples_df, 'packetsCount', '', 'packetsCount', group_pattern) + packets_plot.legend().remove() + + matched_plot = plt.subplot(8, 2, 4) + plot(matched_plot, matched_samples_df, 'matchedCount', '', 'matchedCount', group_pattern) + matched_plot.legend().remove() + + live_plot = plt.subplot(8, 2, 5) + plot(live_plot, live_samples_df, 'liveStreamsCount', '', 'liveStreamsCount', group_pattern) + live_plot.legend().remove() + + processed_plot = plt.subplot(8, 2, 6) + plot(processed_plot, (processed_samples_df / 1024 / 1024), 'processedBytes', '', 'bytes (mega)', group_pattern) + processed_plot.legend().remove() + + heap_plot = plt.subplot(8, 2, 7) + plot(heap_plot, (heap_samples_df / 1024 / 1024), 'heap', '', 'heap (mega)', group_pattern) + heap_plot.legend().remove() + + goroutines_plot = plt.subplot(8, 2, 8) + plot(goroutines_plot, (goroutines_samples_df / 1024 / 1024), 'goroutines', '', 'goroutines', group_pattern) + goroutines_plot.legend().remove() + + fig = plt.gcf() + fig.set_size_inches(20, 18) + + print('Saving graph to graph.png') + plt.savefig('graph.png', bbox_inches='tight') + \ No newline at end of file diff --git a/performance_analysis/requirements.txt b/performance_analysis/requirements.txt new file mode 100644 index 000000000..babdd14a5 --- /dev/null +++ b/performance_analysis/requirements.txt @@ -0,0 +1,2 @@ +matplotlib +pandas diff --git a/performance_analysis/run_tapper_benchmark.sh b/performance_analysis/run_tapper_benchmark.sh new file mode 100755 index 000000000..055d2760a --- /dev/null +++ b/performance_analysis/run_tapper_benchmark.sh @@ -0,0 +1,92 @@ +#!/bin/bash + +[ -z "$MIZU_HOME" ] && { echo "MIZU_HOME is missing"; exit 1; } +[ -z "$MIZU_BENCHMARK_OUTPUT_DIR" ] && export MIZU_BENCHMARK_OUTPUT_DIR="/tmp/mizu-benchmark-results-$(date +%d-%m-%H-%M)" +[ -z "$MIZU_BENCHMARK_CLIENT_PERIOD" ] && export MIZU_BENCHMARK_CLIENT_PERIOD="1m" +[ -z "$MIZU_BENCHMARK_URL" ] && export MIZU_BENCHMARK_URL="http://localhost:8081/data/b.1000.json" +[ -z "$MIZU_BENCHMARK_RUN_COUNT" ] && export MIZU_BENCHMARK_RUN_COUNT="3" +[ -z "$MIZU_BENCHMARK_QPS" ] && export MIZU_BENCHMARK_QPS="500" +[ -z "$MIZU_BENCHMARK_CLIENTS_COUNT" ] && export MIZU_BENCHMARK_CLIENTS_COUNT="5" + +function log() { + local message=$@ + printf "[%s] %s\n" "$(date "+%d-%m %H:%M:%S")" "$message" +} + +function run_single_bench() { + local mode_num=$1 + local mode_str=$2 + + log "Starting ${mode_num}_${mode_str} (runs: $MIZU_BENCHMARK_RUN_COUNT) (period: $MIZU_BENCHMARK_CLIENT_PERIOD)" + + for ((i=0;i<"$MIZU_BENCHMARK_RUN_COUNT";i++)); do + log " $i: Running tapper" + rm -f tapper.log + nohup ./agent/build/mizuagent --tap --api-server-address ws://localhost:8899/wsTapper -i lo -stats 10 > tapper.log 2>&1 & + + log " $i: Running client (hey)" + hey -z $MIZU_BENCHMARK_CLIENT_PERIOD -c $MIZU_BENCHMARK_CLIENTS_COUNT -q $MIZU_BENCHMARK_QPS $MIZU_BENCHMARK_URL > /dev/null || return 1 + + log " $i: Killing tapper" + kill -9 $(ps -ef | grep agent/build/mizuagent | grep tap | grep -v grep | awk '{ print $2 }') > /dev/null 2>&1 + + local output_file=$MIZU_BENCHMARK_OUTPUT_DIR/${mode_num}_${mode_str}_${i}.log + log " $i: Moving output to $output_file" + mv tapper.log $output_file || return 1 + done +} + +function generate_bench_graph() { + cd performance_analysis/ || return 1 + source venv/bin/activate + python plot_from_tapper_logs.py $MIZU_BENCHMARK_OUTPUT_DIR/*.log || return 1 + mv graph.png $MIZU_BENCHMARK_OUTPUT_DIR || return 1 +} + +mkdir -p $MIZU_BENCHMARK_OUTPUT_DIR +rm -f $MIZU_BENCHMARK_OUTPUT_DIR/* +log "Writing output to $MIZU_BENCHMARK_OUTPUT_DIR" + +cd $MIZU_HOME || exit 1 + +export HOST_MODE=0 +export MIZU_DEBUG_DISABLE_PCAP=false +export MIZU_DEBUG_DISABLE_TCP_REASSEMBLY=false +export MIZU_DEBUG_DISABLE_TCP_STREAM=false +export MIZU_DEBUG_DISABLE_NON_HTTP_EXTENSSION=false +export MIZU_DEBUG_DISABLE_DISSECTORS=false +export MIZU_DEBUG_DISABLE_EMITTING=false +export MIZU_DEBUG_DISABLE_SENDING=false + +export MIZU_DEBUG_DISABLE_PCAP=true +run_single_bench "01" "no_pcap" || exit 1 +export MIZU_DEBUG_DISABLE_PCAP=false + +export MIZU_DEBUG_DISABLE_TCP_REASSEMBLY=true +run_single_bench "02" "no_assembler" || exit 1 +export MIZU_DEBUG_DISABLE_TCP_REASSEMBLY=false + +export MIZU_DEBUG_DISABLE_TCP_STREAM=true +run_single_bench "03" "no_tcp_stream" || exit 1 +export MIZU_DEBUG_DISABLE_TCP_STREAM=false + +export MIZU_DEBUG_DISABLE_NON_HTTP_EXTENSSION=true +run_single_bench "04" "only_http" || exit 1 +export MIZU_DEBUG_DISABLE_NON_HTTP_EXTENSSION=false + +export MIZU_DEBUG_DISABLE_DISSECTORS=true +run_single_bench "05" "no_dissectors" || exit 1 +export MIZU_DEBUG_DISABLE_DISSECTORS=false + +export MIZU_DEBUG_DISABLE_EMITTING=true +run_single_bench "06" "no_emit" || exit 1 +export MIZU_DEBUG_DISABLE_EMITTING=false + +export MIZU_DEBUG_DISABLE_SENDING=true +run_single_bench "07" "no_send" || exit 1 +export MIZU_DEBUG_DISABLE_SENDING=false + +run_single_bench "08" "normal" || exit 1 + +generate_bench_graph || exit 1 +log "Output written to to $MIZU_BENCHMARK_OUTPUT_DIR" diff --git a/performance_analysis/tapper-modes.png b/performance_analysis/tapper-modes.png new file mode 100644 index 000000000..e454c11a7 Binary files /dev/null and b/performance_analysis/tapper-modes.png differ diff --git a/shared/go.mod b/shared/go.mod index 142ecf7d0..b19620063 100644 --- a/shared/go.mod +++ b/shared/go.mod @@ -67,6 +67,7 @@ require ( github.com/spf13/cobra v1.3.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/testify v1.7.0 // indirect + github.com/up9inc/mizu/tap/dbgctl v0.0.0 // indirect github.com/xlab/treeprint v1.1.0 // indirect go.starlark.net v0.0.0-20220203230714-bb14e151c28f // indirect golang.org/x/crypto v0.0.0-20220208050332-20e1d8d225ab // indirect @@ -95,3 +96,5 @@ require ( replace github.com/up9inc/mizu/logger v0.0.0 => ../logger replace github.com/up9inc/mizu/tap/api v0.0.0 => ../tap/api + +replace github.com/up9inc/mizu/tap/dbgctl v0.0.0 => ../tap/dbgctl diff --git a/shared/kubernetes/provider.go b/shared/kubernetes/provider.go index 0994b34c7..610b3d5ab 100644 --- a/shared/kubernetes/provider.go +++ b/shared/kubernetes/provider.go @@ -181,6 +181,7 @@ type ApiServerOptions struct { Resources shared.Resources ImagePullPolicy core.PullPolicy LogLevel logging.Level + Profiler bool } func (provider *Provider) GetMizuApiServerPodObject(opts *ApiServerOptions, mountVolumeClaim bool, volumeClaimName string, createAuthContainer bool) (*core.Pod, error) { @@ -212,7 +213,15 @@ func (provider *Provider) GetMizuApiServerPodObject(opts *ApiServerOptions, moun return nil, fmt.Errorf("invalid memory request for %s container", opts.PodName) } - command := []string{"./mizuagent", "--api-server"} + command := []string{ + "./mizuagent", + "--api-server", + } + + if opts.Profiler { + command = append(command, "--profiler") + } + if opts.IsNamespaceRestricted { command = append(command, "--namespace", opts.Namespace) } diff --git a/tap/api/api.go b/tap/api/api.go index 586ff592b..8e6f07df9 100644 --- a/tap/api/api.go +++ b/tap/api/api.go @@ -15,6 +15,8 @@ import ( "time" "github.com/google/martian/har" + + "github.com/up9inc/mizu/tap/dbgctl" ) const mizuTestEnvVar = "MIZU_TEST" @@ -149,8 +151,13 @@ type Emitter interface { } func (e *Emitting) Emit(item *OutputChannelItem) { - e.OutputChannel <- item e.AppStats.IncMatchedPairs() + + if dbgctl.MizuTapperDisableEmitting { + return + } + + e.OutputChannel <- item } type Entry struct { diff --git a/tap/api/go.mod b/tap/api/go.mod index 1c43b3e5a..68bae1118 100644 --- a/tap/api/go.mod +++ b/tap/api/go.mod @@ -2,4 +2,9 @@ module github.com/up9inc/mizu/tap/api go 1.17 -require github.com/google/martian v2.1.0+incompatible +require ( + github.com/google/martian v2.1.0+incompatible + github.com/up9inc/mizu/tap/dbgctl v0.0.0 +) + +replace github.com/up9inc/mizu/tap/dbgctl v0.0.0 => ../dbgctl diff --git a/tap/api/stats_tracker.go b/tap/api/stats_tracker.go index d80f745f8..b5a26e934 100644 --- a/tap/api/stats_tracker.go +++ b/tap/api/stats_tracker.go @@ -15,6 +15,7 @@ type AppStats struct { TlsConnectionsCount uint64 `json:"tlsConnectionsCount"` MatchedPairs uint64 `json:"matchedPairs"` DroppedTcpStreams uint64 `json:"droppedTcpStreams"` + LiveTcpStreams uint64 `json:"liveTcpStreams"` } func (as *AppStats) IncMatchedPairs() { @@ -46,6 +47,14 @@ func (as *AppStats) IncTlsConnectionsCount() { atomic.AddUint64(&as.TlsConnectionsCount, 1) } +func (as *AppStats) IncLiveTcpStreams() { + atomic.AddUint64(&as.LiveTcpStreams, 1) +} + +func (as *AppStats) DecLiveTcpStreams() { + atomic.AddUint64(&as.LiveTcpStreams, ^uint64(0)) +} + func (as *AppStats) UpdateProcessedBytes(size uint64) { atomic.AddUint64(&as.ProcessedBytes, size) } @@ -65,6 +74,7 @@ func (as *AppStats) DumpStats() *AppStats { currentAppStats.TlsConnectionsCount = resetUint64(&as.TlsConnectionsCount) currentAppStats.MatchedPairs = resetUint64(&as.MatchedPairs) currentAppStats.DroppedTcpStreams = resetUint64(&as.DroppedTcpStreams) + currentAppStats.LiveTcpStreams = as.LiveTcpStreams return currentAppStats } diff --git a/tap/dbgctl/debug_control.go b/tap/dbgctl/debug_control.go new file mode 100644 index 000000000..0503a1469 --- /dev/null +++ b/tap/dbgctl/debug_control.go @@ -0,0 +1,15 @@ +package dbgctl + +import ( + "os" +) + +var ( + MizuTapperDisablePcap bool = os.Getenv("MIZU_DEBUG_DISABLE_PCAP") == "true" + MizuTapperDisableTcpReassembly bool = os.Getenv("MIZU_DEBUG_DISABLE_TCP_REASSEMBLY") == "true" + MizuTapperDisableTcpStream bool = os.Getenv("MIZU_DEBUG_DISABLE_TCP_STREAM") == "true" + MizuTapperDisableDissectors bool = os.Getenv("MIZU_DEBUG_DISABLE_DISSECTORS") == "true" + MizuTapperDisableEmitting bool = os.Getenv("MIZU_DEBUG_DISABLE_EMITTING") == "true" + MizuTapperDisableSending bool = os.Getenv("MIZU_DEBUG_DISABLE_SENDING") == "true" + MizuTapperDisableNonHttpExtensions bool = os.Getenv("MIZU_DEBUG_DISABLE_NON_HTTP_EXTENSSION") == "true" +) diff --git a/tap/dbgctl/go.mod b/tap/dbgctl/go.mod new file mode 100644 index 000000000..7cad5eba6 --- /dev/null +++ b/tap/dbgctl/go.mod @@ -0,0 +1,3 @@ +module github.com/up9inc/mizu/tap/dbgctl + +go 1.18 diff --git a/tap/extensions/amqp/go.mod b/tap/extensions/amqp/go.mod index 715f96321..d8d844441 100644 --- a/tap/extensions/amqp/go.mod +++ b/tap/extensions/amqp/go.mod @@ -11,7 +11,10 @@ require ( github.com/davecgh/go-spew v1.1.0 // indirect github.com/google/martian v2.1.0+incompatible // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/up9inc/mizu/tap/dbgctl v0.0.0 // indirect gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect ) replace github.com/up9inc/mizu/tap/api v0.0.0 => ../../api + +replace github.com/up9inc/mizu/tap/dbgctl v0.0.0 => ../../dbgctl diff --git a/tap/extensions/http/go.mod b/tap/extensions/http/go.mod index 1a8c8ee65..84254d222 100644 --- a/tap/extensions/http/go.mod +++ b/tap/extensions/http/go.mod @@ -14,8 +14,11 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/google/martian v2.1.0+incompatible // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/up9inc/mizu/tap/dbgctl v0.0.0 // indirect golang.org/x/text v0.3.7 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) replace github.com/up9inc/mizu/tap/api v0.0.0 => ../../api + +replace github.com/up9inc/mizu/tap/dbgctl v0.0.0 => ../../dbgctl diff --git a/tap/extensions/kafka/go.mod b/tap/extensions/kafka/go.mod index 34ef14433..d1963a473 100644 --- a/tap/extensions/kafka/go.mod +++ b/tap/extensions/kafka/go.mod @@ -18,7 +18,10 @@ require ( github.com/klauspost/compress v1.14.2 // indirect github.com/pierrec/lz4 v2.6.1+incompatible // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/up9inc/mizu/tap/dbgctl v0.0.0 // indirect gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect ) replace github.com/up9inc/mizu/tap/api v0.0.0 => ../../api + +replace github.com/up9inc/mizu/tap/dbgctl v0.0.0 => ../../dbgctl diff --git a/tap/extensions/redis/go.mod b/tap/extensions/redis/go.mod index 82bd16d51..8a64d5cdf 100644 --- a/tap/extensions/redis/go.mod +++ b/tap/extensions/redis/go.mod @@ -11,7 +11,10 @@ require ( github.com/davecgh/go-spew v1.1.0 // indirect github.com/google/martian v2.1.0+incompatible // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/up9inc/mizu/tap/dbgctl v0.0.0 // indirect gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect ) replace github.com/up9inc/mizu/tap/api v0.0.0 => ../../api + +replace github.com/up9inc/mizu/tap/dbgctl v0.0.0 => ../../dbgctl diff --git a/tap/go.mod b/tap/go.mod index cad3ace38..67b1c3174 100644 --- a/tap/go.mod +++ b/tap/go.mod @@ -7,14 +7,18 @@ require ( github.com/go-errors/errors v1.4.2 github.com/google/gopacket v1.1.19 github.com/hashicorp/golang-lru v0.5.4 + github.com/shirou/gopsutil v3.21.11+incompatible + github.com/struCoder/pidusage v0.2.1 github.com/up9inc/mizu/logger v0.0.0 github.com/up9inc/mizu/tap/api v0.0.0 + github.com/up9inc/mizu/tap/dbgctl v0.0.0 github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 k8s.io/api v0.23.3 ) require ( github.com/go-logr/logr v1.2.2 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/google/go-cmp v0.5.7 // indirect github.com/google/gofuzz v1.2.0 // indirect @@ -23,6 +27,9 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 // indirect + github.com/tklauser/go-sysconf v0.3.10 // indirect + github.com/tklauser/numcpus v0.4.0 // indirect + github.com/yusufpapurcu/wmi v1.2.2 // indirect golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect golang.org/x/sys v0.0.0-20220207234003-57398862261d // indirect golang.org/x/text v0.3.7 // indirect @@ -33,8 +40,11 @@ require ( k8s.io/utils v0.0.0-20220127004650-9b3446523e65 // indirect sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect ) replace github.com/up9inc/mizu/logger v0.0.0 => ../logger replace github.com/up9inc/mizu/tap/api v0.0.0 => ./api + +replace github.com/up9inc/mizu/tap/dbgctl v0.0.0 => ./dbgctl diff --git a/tap/go.sum b/tap/go.sum index 684d4f546..786480904 100644 --- a/tap/go.sum +++ b/tap/go.sum @@ -31,6 +31,8 @@ github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTg github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= @@ -117,6 +119,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= +github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -126,11 +130,19 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/struCoder/pidusage v0.2.1 h1:dFiEgUDkubeIj0XA1NpQ6+8LQmKrLi7NiIQl86E6BoY= +github.com/struCoder/pidusage v0.2.1/go.mod h1:bewtP2KUA1TBUyza5+/PCpSQ6sc/H6jJbIKAzqW86BA= +github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw= +github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= +github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//o= +github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg= github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= +github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= 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= @@ -170,6 +182,7 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h 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-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -184,6 +197,7 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220207234003-57398862261d h1:Bm7BNOQt2Qv7ZqysjeLjgCBanX+88Z/OtdvsrEv1Djc= golang.org/x/sys v0.0.0-20220207234003-57398862261d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= diff --git a/tap/passive_tapper.go b/tap/passive_tapper.go index d049622b0..20d15a8a8 100644 --- a/tap/passive_tapper.go +++ b/tap/passive_tapper.go @@ -18,6 +18,8 @@ import ( "time" "strconv" + "github.com/shirou/gopsutil/cpu" + "github.com/struCoder/pidusage" "github.com/up9inc/mizu/logger" "github.com/up9inc/mizu/tap/api" "github.com/up9inc/mizu/tap/diagnose" @@ -126,6 +128,16 @@ func printPeriodicStats(cleaner *Cleaner) { statsPeriod := time.Second * time.Duration(*statsevery) ticker := time.NewTicker(statsPeriod) + logicalCoreCount, err := cpu.Counts(true) + if err != nil { + logicalCoreCount = -1 + } + + physicalCoreCount, err := cpu.Counts(false) + if err != nil { + physicalCoreCount = -1 + } + for { <-ticker.C @@ -142,11 +154,21 @@ func printPeriodicStats(cleaner *Cleaner) { // At this moment memStats := runtime.MemStats{} runtime.ReadMemStats(&memStats) + sysInfo, err := pidusage.GetStat(os.Getpid()) + if err != nil { + sysInfo = &pidusage.SysInfo{ + CPU: -1, + Memory: -1, + } + } logger.Log.Infof( - "mem: %d, goroutines: %d", + "mem: %d, goroutines: %d, cpu: %f, cores: %d/%d, rss: %f", memStats.HeapAlloc, runtime.NumGoroutine(), - ) + sysInfo.CPU, + logicalCoreCount, + physicalCoreCount, + sysInfo.Memory) // Since the last print cleanStats := cleaner.dumpStats() diff --git a/tap/source/tcp_packet_source.go b/tap/source/tcp_packet_source.go index 315b69d54..9b174ed13 100644 --- a/tap/source/tcp_packet_source.go +++ b/tap/source/tcp_packet_source.go @@ -11,6 +11,7 @@ import ( "github.com/google/gopacket/pcap" "github.com/up9inc/mizu/logger" "github.com/up9inc/mizu/tap/api" + "github.com/up9inc/mizu/tap/dbgctl" "github.com/up9inc/mizu/tap/diagnose" ) @@ -116,6 +117,9 @@ func (source *tcpPacketSource) close() { } func (source *tcpPacketSource) readPackets(ipdefrag bool, packets chan<- TcpPacketInfo) { + if dbgctl.MizuTapperDisablePcap { + return + } logger.Log.Infof("Start reading packets from %v", source.name) for { diff --git a/tap/tcp_assembler.go b/tap/tcp_assembler.go index f8df01458..3d47d34a8 100644 --- a/tap/tcp_assembler.go +++ b/tap/tcp_assembler.go @@ -12,6 +12,7 @@ import ( "github.com/google/gopacket/reassembly" "github.com/up9inc/mizu/logger" "github.com/up9inc/mizu/tap/api" + "github.com/up9inc/mizu/tap/dbgctl" "github.com/up9inc/mizu/tap/diagnose" "github.com/up9inc/mizu/tap/source" ) @@ -93,9 +94,11 @@ func (a *tcpAssembler) processPackets(dumpPacket bool, packets <-chan source.Tcp Origin: packetInfo.Source.Origin, } diagnose.InternalStats.Totalsz += len(tcp.Payload) - a.assemblerMutex.Lock() - a.AssembleWithContext(packet.NetworkLayer().NetworkFlow(), tcp, &c) - a.assemblerMutex.Unlock() + if !dbgctl.MizuTapperDisableTcpReassembly { + a.assemblerMutex.Lock() + a.AssembleWithContext(packet.NetworkLayer().NetworkFlow(), tcp, &c) + a.assemblerMutex.Unlock() + } } } diff --git a/tap/tcp_reader.go b/tap/tcp_reader.go index 23528ff59..86d381bce 100644 --- a/tap/tcp_reader.go +++ b/tap/tcp_reader.go @@ -7,6 +7,7 @@ import ( "time" "github.com/up9inc/mizu/tap/api" + "github.com/up9inc/mizu/tap/dbgctl" ) /* TcpReader gets reads from a channel of bytes of tcp payload, and parses it into requests and responses. @@ -48,6 +49,13 @@ func NewTcpReader(ident string, tcpId *api.TcpID, parent *tcpStream, isClient bo func (reader *tcpReader) run(options *api.TrafficFilteringOptions, wg *sync.WaitGroup) { defer wg.Done() + + if dbgctl.MizuTapperDisableDissectors { + b := bufio.NewReader(reader) + _, _ = io.ReadAll(b) + return + } + for i, extension := range extensions { reader.reqResMatcher = reader.parent.reqResMatchers[i] reader.counterPair = reader.parent.counterPairs[i] diff --git a/tap/tcp_stream.go b/tap/tcp_stream.go index 31664ac3e..0d0532392 100644 --- a/tap/tcp_stream.go +++ b/tap/tcp_stream.go @@ -5,6 +5,7 @@ import ( "time" "github.com/up9inc/mizu/tap/api" + "github.com/up9inc/mizu/tap/dbgctl" ) /* It's a connection (bidirectional) @@ -91,6 +92,9 @@ func (t *tcpStream) GetReqResMatchers() []api.RequestResponseMatcher { } func (t *tcpStream) GetIsTapTarget() bool { + if dbgctl.MizuTapperDisableTcpStream { + return false + } return t.isTapTarget } diff --git a/tap/tcp_streams_map.go b/tap/tcp_streams_map.go index fc96aa5c7..a4285b402 100644 --- a/tap/tcp_streams_map.go +++ b/tap/tcp_streams_map.go @@ -28,10 +28,12 @@ func (streamMap *tcpStreamMap) Range(f func(key, value interface{}) bool) { func (streamMap *tcpStreamMap) Store(key, value interface{}) { streamMap.streams.Store(key, value) + diagnose.AppStats.IncLiveTcpStreams() } func (streamMap *tcpStreamMap) Delete(key interface{}) { streamMap.streams.Delete(key) + diagnose.AppStats.DecLiveTcpStreams() } func (streamMap *tcpStreamMap) NextId() int64 { diff --git a/ui-common/package.json b/ui-common/package.json index dc666a247..c4dae9b0f 100644 --- a/ui-common/package.json +++ b/ui-common/package.json @@ -91,4 +91,4 @@ "files": [ "dist" ] -} \ No newline at end of file +}