diff --git a/cmd/main.go b/cmd/main.go index 20788d10d0..8c57771e39 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -93,7 +93,7 @@ func main() { flag.Parse() - logger := utils.InitLogger("cluster-logging-operator") + logger := utils.InitStaticLogger("cluster-logging-operator") // LOG-5136 Fixes error caused by updates to controller-runtime ctrl.SetLogger(logger) diff --git a/go.mod b/go.mod index 8c651d164c..b04898ee0e 100644 --- a/go.mod +++ b/go.mod @@ -21,10 +21,12 @@ require ( github.com/prometheus/client_golang v1.20.5 github.com/spf13/pflag v1.0.6 github.com/stretchr/testify v1.10.0 + github.com/vspaz/wls-go v0.0.0-20230405190232-47d1e477c82c golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac golang.org/x/net v0.37.0 golang.org/x/sync v0.12.0 golang.org/x/sys v0.32.0 + gonum.org/v1/plot v0.16.0 k8s.io/api v0.32.2 k8s.io/apimachinery v0.32.2 k8s.io/apiserver v0.32.2 @@ -36,11 +38,17 @@ require ( require ( cel.dev/expr v0.18.0 // indirect + codeberg.org/go-fonts/liberation v0.5.0 // indirect + codeberg.org/go-latex/latex v0.1.0 // indirect + codeberg.org/go-pdf/fpdf v0.10.0 // indirect + git.sr.ht/~sbinet/gg v0.6.0 // indirect + github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b // indirect github.com/antlr4-go/antlr/v4 v4.13.0 // indirect github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect github.com/aws/smithy-go v1.8.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect + github.com/campoy/embedmd v1.0.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -56,6 +64,7 @@ require ( github.com/go-openapi/swag v0.23.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/cel-go v0.22.0 // indirect github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect @@ -93,6 +102,7 @@ require ( go.uber.org/automaxprocs v1.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect + golang.org/x/image v0.25.0 // indirect golang.org/x/oauth2 v0.27.0 // indirect golang.org/x/term v0.30.0 // indirect golang.org/x/text v0.23.0 // indirect diff --git a/go.sum b/go.sum index a04a77056b..ef2502acae 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,26 @@ cel.dev/expr v0.18.0 h1:CJ6drgk+Hf96lkLikr4rFf19WrU0BOWEihyZnI2TAzo= cel.dev/expr v0.18.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= +codeberg.org/go-fonts/dejavu v0.4.0 h1:2yn58Vkh4CFK3ipacWUAIE3XVBGNa0y1bc95Bmfx91I= +codeberg.org/go-fonts/dejavu v0.4.0/go.mod h1:abni088lmhQJvso2Lsb7azCKzwkfcnttl6tL1UTWKzg= +codeberg.org/go-fonts/latin-modern v0.4.0 h1:vkRCc1y3whKA7iL9Ep0fSGVuJfqjix0ica9UflHORO8= +codeberg.org/go-fonts/latin-modern v0.4.0/go.mod h1:BF68mZznJ9QHn+hic9ks2DaFl4sR5YhfM6xTYaP9vNw= +codeberg.org/go-fonts/liberation v0.5.0 h1:SsKoMO1v1OZmzkG2DY+7ZkCL9U+rrWI09niOLfQ5Bo0= +codeberg.org/go-fonts/liberation v0.5.0/go.mod h1:zS/2e1354/mJ4pGzIIaEtm/59VFCFnYC7YV6YdGl5GU= +codeberg.org/go-latex/latex v0.1.0 h1:hoGO86rIbWVyjtlDLzCqZPjNykpWQ9YuTZqAzPcfL3c= +codeberg.org/go-latex/latex v0.1.0/go.mod h1:LA0q/AyWIYrqVd+A9Upkgsb+IqPcmSTKc9Dny04MHMw= +codeberg.org/go-pdf/fpdf v0.10.0 h1:u+w669foDDx5Ds43mpiiayp40Ov6sZalgcPMDBcZRd4= +codeberg.org/go-pdf/fpdf v0.10.0/go.mod h1:Y0DGRAdZ0OmnZPvjbMp/1bYxmIPxm0ws4tfoPOc4LjU= +git.sr.ht/~sbinet/cmpimg v0.1.0 h1:E0zPRk2muWuCqSKSVZIWsgtU9pjsw3eKHi8VmQeScxo= +git.sr.ht/~sbinet/cmpimg v0.1.0/go.mod h1:FU12psLbF4TfNXkKH2ZZQ29crIqoiqTZmeQ7dkp/pxE= +git.sr.ht/~sbinet/gg v0.6.0 h1:RIzgkizAk+9r7uPzf/VfbJHBMKUr0F5hRFxTUGMnt38= +git.sr.ht/~sbinet/gg v0.6.0/go.mod h1:uucygbfC9wVPQIfrmwM2et0imr8L7KQWywX0xpFMm94= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/ViaQ/logerr/v2 v2.1.0 h1:8WwzuNa1x+a6tRUl+6sFel83A/QxlFBUaFW2FyG2zzY= github.com/ViaQ/logerr/v2 v2.1.0/go.mod h1:/qoWLm3YG40Sv5u75s4fvzjZ5p36xINzaxU2L+DJ9uw= +github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= +github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= +github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b h1:slYM766cy2nI3BwyRiyQj/Ud48djTMtMebDqepE95rw= +github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= @@ -18,6 +37,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/campoy/embedmd v1.0.0 h1:V4kI2qTJJLf4J29RzI/MAt2c3Bl4dQSYPuflzwFH2hY= +github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -58,6 +79,8 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 h1:zN2lZNZRflqFyxVaTIU61KNKQ9C0055u9CAfpmqUvo4= github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3/go.mod h1:nPpo7qLxd6XL3hWJG/O60sR8ZKfMCiIoNap5GvD12KU= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/cel-go v0.22.0 h1:b3FJZxpiv1vTMo2/5RDUqAHPxkT8mmMfJIrq1llbf7g= @@ -159,6 +182,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/vspaz/wls-go v0.0.0-20230405190232-47d1e477c82c h1:gc7YbOdV619w8KYK71jClfbq6m89wJkCVTAko8DNtfY= +github.com/vspaz/wls-go v0.0.0-20230405190232-47d1e477c82c/go.mod h1:sN2G8r+ME16x0qBg571lKYvJe9dLgY5Kil58P7dm1Vw= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -192,6 +217,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac h1:l5+whBCLH3iH2ZNHYLbAe58bo7yrN4mVcnkHDYz5vvs= golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac/go.mod h1:hH+7mtFmImwwcMvScyxUhjuVHR3HGaDPMn9rMSUUbxo= +golang.org/x/image v0.25.0 h1:Y6uW6rH1y5y/LK1J8BPWZtr6yZ7hrsy6hFrXjgsc2fQ= +golang.org/x/image v0.25.0/go.mod h1:tCAmOEGthTtkalusGp1g3xa2gke8J6c2N565dTyl9Rs= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -210,6 +237,7 @@ golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= 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-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= @@ -224,6 +252,7 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU= golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -232,6 +261,10 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +gonum.org/v1/plot v0.16.0 h1:dK28Qx/Ky4VmPUN/2zeW0ELyM6ucDnBAj5yun7M9n1g= +gonum.org/v1/plot v0.16.0/go.mod h1:Xz6U1yDMi6Ni6aaXILqmVIb6Vro8E+K7Q/GeeH+Pn0c= google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7 h1:YcyjlL1PRr2Q17/I0dPk2JmYS5CDXfcdb2Z3YRioEbw= google.golang.org/genproto/googleapis/api v0.0.0-20240826202546-f6391c0de4c7/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo= google.golang.org/genproto/googleapis/rpc v0.0.0-20240826202546-f6391c0de4c7 h1:2035KHhUv+EpyB+hWgJnaWKJOdX1E95w2S8Rr4uWKTs= @@ -251,6 +284,7 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= k8s.io/api v0.32.2 h1:bZrMLEkgizC24G9eViHGOPbW+aRo9duEISRIJKfdJuw= k8s.io/api v0.32.2/go.mod h1:hKlhk4x1sJyYnHENsrdCWw31FEmCijNGPJO5WzHiJ6Y= k8s.io/apiextensions-apiserver v0.32.2 h1:2YMk285jWMk2188V2AERy5yDwBYrjgWYggscghPCvV4= @@ -269,6 +303,8 @@ k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJ k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4= k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0= k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0 h1:CPT0ExVicCzcpeN4baWEV2ko2Z/AsiZgEdwgcfwLgMo= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= sigs.k8s.io/controller-runtime v0.19.6 h1:fuq53qTLQ7aJTA7aNsklNnu7eQtSFqJUomOyM+phPLk= diff --git a/internal/cmd/forwarder-generator/main.go b/internal/cmd/forwarder-generator/main.go index 33383e0a63..d1c06fb3ff 100644 --- a/internal/cmd/forwarder-generator/main.go +++ b/internal/cmd/forwarder-generator/main.go @@ -19,7 +19,7 @@ import ( // HACK - This command is for development use only func main() { - utils.InitLogger("forwarder-generator") + utils.InitStaticLogger("forwarder-generator") yamlFile := flag.String("file", "", "ClusterLogForwarder yaml file. - for stdin") debugOutput := flag.Bool("debug-output", false, "Generate config normally, but replace output plugins with @stdout plugin, so that records can be printed in collector logs.") diff --git a/internal/cmd/functional-benchmarker/config/options.go b/internal/cmd/functional-benchmarker/config/options.go index bc4fa512ca..95af38a62a 100644 --- a/internal/cmd/functional-benchmarker/config/options.go +++ b/internal/cmd/functional-benchmarker/config/options.go @@ -24,7 +24,6 @@ type Options struct { Image string TotalMessages int MsgSize int - Verbosity int BaseLine bool DoCleanup bool Sample bool @@ -53,7 +52,6 @@ func InitOptions() Options { //fs.IntVar(&options.TotalMessages, "tot-messages", 10000, "The number of messages to write per stressor") fs.IntVar(&options.MsgSize, "size", 1024, "The message size in bytes per stressor for 'synthetic' payload") fs.IntVar(&options.LinesPerSecond, "lines-per-sec", 1, "The log lines per second per stressor") - fs.IntVar(&options.Verbosity, "verbosity", 0, "The output log level") fs.BoolVar(&options.DoCleanup, "do-cleanup", true, "set to false to preserve the namespace") //fs.BoolVar(&options.BaseLine, "baseline", false, "run the test with a baseline config. This supercedes --collector-config") //fs.StringVar(&options.Platform, "platform", "cluster", "The runtime environment: cluster, local. local requires podman") diff --git a/internal/cmd/functional-benchmarker/main.go b/internal/cmd/functional-benchmarker/main.go index aafd7bd216..e8f8b3c80f 100644 --- a/internal/cmd/functional-benchmarker/main.go +++ b/internal/cmd/functional-benchmarker/main.go @@ -12,7 +12,6 @@ import ( "github.com/openshift/cluster-logging-operator/internal/constants" "github.com/openshift/cluster-logging-operator/test/helpers/oc" - log "github.com/ViaQ/logerr/v2/log/static" "github.com/openshift/cluster-logging-operator/internal/cmd/functional-benchmarker/config" "github.com/openshift/cluster-logging-operator/internal/cmd/functional-benchmarker/reports" "github.com/openshift/cluster-logging-operator/internal/cmd/functional-benchmarker/runners" @@ -20,10 +19,16 @@ import ( "github.com/openshift/cluster-logging-operator/internal/utils" ) +var ( + log = utils.InitLogger("functional-benchmarker") +) + // HACK - This command is for development use only func main() { utils.InitLogger("functional-benchmarker") - + defer func() { + log.Info("Test complete") + }() options := config.InitOptions() options.CollectorConfig = config.ReadConfig(options.CollectorConfigPath, options.BaseLine) @@ -42,6 +47,7 @@ func main() { options.CollectorConfig = config reporter := reports.NewReporter(options, artifactDir, metrics, statistics) + log.Info("Generating reports...") reporter.Generate() } @@ -49,6 +55,7 @@ func RunBenchmark(artifactDir string, options config.Options) (*stats.ResourceMe runDuration := config.MustParseDuration(options.RunDuration, "run-duration") sampleDuration := config.MustParseDuration(options.SampleDuration, "resource-sample-duration") runner := runners.NewRunner(options) + log.Info("Deploying collector, loaders, and receivers") runner.Deploy() if options.DoCleanup { log.V(2).Info("Deferring cleanup", "DoCleanup", options.DoCleanup) @@ -58,6 +65,7 @@ func RunBenchmark(artifactDir string, options config.Options) (*stats.ResourceMe startTime := time.Now() sampler := time.NewTicker(sampleDuration) metrics := stats.NewResourceMetrics() + log.V(0).Info("Starting to sample metrics for the collector...") go func() { for { select { @@ -76,6 +84,8 @@ func RunBenchmark(artifactDir string, options config.Options) (*stats.ResourceMe endTime := time.Now() done <- true sampler.Stop() + log.Info("Stopped sampling metrics") + log.Info("Fetching log data from receiver...") if err := runner.FetchApplicationLogs(); err != nil { return nil, nil, "", err } @@ -105,6 +115,7 @@ func fetchContainerLogs(runner runners.Runner, artifactDir string) { } func gatherStatistics(runner runners.Runner, sample bool, msgSize int, startTime, endTime time.Time) *stats.Statistics { + log.Info("Evaluating log data to calculate statistics") logs, err := runner.ReadApplicationLogs() if err != nil { log.Error(err, "Error reading logs") diff --git a/internal/cmd/functional-benchmarker/reports/gnuplot/plot_scripts.go b/internal/cmd/functional-benchmarker/reports/format_templates.go similarity index 61% rename from internal/cmd/functional-benchmarker/reports/gnuplot/plot_scripts.go rename to internal/cmd/functional-benchmarker/reports/format_templates.go index 4ec4cb5565..c896f77ea0 100644 --- a/internal/cmd/functional-benchmarker/reports/gnuplot/plot_scripts.go +++ b/internal/cmd/functional-benchmarker/reports/format_templates.go @@ -1,58 +1,6 @@ -package gnuplot +package reports const ( - cpuPlotPNG = `set term png size 1024,768 -set output 'cpu.png' -set timefmt '%s' -set xdata time -set title 'CPU(Cores)' -set xlabel 'Time' -plot 'cpu.data' using 1:2 with lines` - - memPlotPNG = `set term png size 1024,768 -set output 'mem.png' -set timefmt '%s' -set xdata time -set title 'Mem(Mb)' -set xlabel 'Time' -plot 'mem.data' using 1:2 with lines` - - latencyPlotPNG = `set term png size 1024,768 -set output 'latency.png' -set title 'Latency(s)' -set xlabel 'Message' -f(x)=m*x+b -fit f(x) 'latency.data' using 1:2 via m,b -plot 'latency.data' using 1:2 with lines title 'Data', f(x) title 'Trend'` - - lossPlotPNG = `set term png size 1024,768 -set output 'loss.png'; -set xlabel 'SeqId'; -set ylabel 'Lost Count'` - - lossPlotDumb = `set term dumb -set xlabel 'SeqId'; -set ylabel 'Lost Count'` - - cpuPlotDumb = `set term dumb -set timefmt '%s' -set xdata time -set title 'CPU(Cores)' -set xlabel 'Time' -plot 'cpu.data' using 1:2 with lines` - - memPlotDumb = `set term dumb -set timefmt '%s' -set xdata time -set title 'Mem(Mb)' -set xlabel 'Time' -plot 'mem.data' using 1:2 with lines` - - latencyPlotDumb = `set term dumb -set title 'Latency(s)' -set xlabel 'Message' -plot 'latency.data' using 1:2 with lines` - html = `
@@ -98,15 +46,23 @@ plot 'latency.data' using 1:2 with lines`
+
+
+
+
+
+
+
+
diff --git a/internal/cmd/functional-benchmarker/reports/gnuplot/gnuplot.go b/internal/cmd/functional-benchmarker/reports/gnuplot/gnuplot.go deleted file mode 100644 index 25d7113ae2..0000000000 --- a/internal/cmd/functional-benchmarker/reports/gnuplot/gnuplot.go +++ /dev/null @@ -1,269 +0,0 @@ -package gnuplot - -import ( - "fmt" - htmllib "html" - "io" - "os" - "os/exec" - "path" - "strings" - "text/tabwriter" - "time" - - log "github.com/ViaQ/logerr/v2/log/static" - "github.com/openshift/cluster-logging-operator/internal/cmd/functional-benchmarker/config" - "github.com/openshift/cluster-logging-operator/internal/cmd/functional-benchmarker/stats" -) - -type GNUPlotReporter struct { - Options config.Options - Metrics stats.ResourceMetrics - Stats stats.Statistics - ArtifactDir string -} - -func exportResourceMetricTo(outDir string, rm stats.ResourceMetrics) { - exportCPU(outDir, rm.Samples) - exportMemory(outDir, rm.Samples) -} - -/* #nosec G306*/ -func exportLatency(outDir string, logs stats.PerfLogs) { - log.V(3).Info("Exporting latency") - buffer := []string{} - for i, log := range logs { - value := log.ElapsedEpoc() - buffer = append(buffer, fmt.Sprintf("%d %.3f", i, value)) - } - log.V(3).Info("Writing latency data", "outDir", outDir, "data", buffer) - err := os.WriteFile(path.Join(outDir, "latency.data"), []byte(strings.Join(buffer, "\n")), 0755) - if err != nil { - log.Error(err, "Error writing latency data") - } -} - -/* #nosec G306*/ -func exportMemory(outDir string, samples []stats.Sample) { - log.V(3).Info("Exporting memory", "samples", samples) - buffer := []string{} - for _, sample := range samples { - value := sample.MemoryBytesAsFloat() - buffer = append(buffer, fmt.Sprintf("%d %.3f", sample.Time, value/1024/1024)) - } - log.V(3).Info("Writing resource metric data", "outDir", outDir, "memoryInMb", buffer) - err := os.WriteFile(path.Join(outDir, "mem.data"), []byte(strings.Join(buffer, "\n")), 0755) - if err != nil { - log.Error(err, "Error writing resource Memory Metrics") - } -} - -/* #nosec G306*/ -func exportCPU(outDir string, samples []stats.Sample) { - log.V(3).Info("Exporting cpu", "samples", samples) - buffer := []string{} - for _, sample := range samples { - cpu := sample.CPUCoresAsFloat() - buffer = append(buffer, fmt.Sprintf("%d %.3f", sample.Time, cpu)) - } - log.V(3).Info("Writing resource metric data", "outDir", outDir, "cpu", buffer) - err := os.WriteFile(path.Join(outDir, "cpu.data"), []byte(strings.Join(buffer, "\n")), 0755) - if err != nil { - log.Error(err, "Error writing resource CPU Metrics") - } -} - -/* #nosec G306*/ -func exportLoss(outDir string, samples stats.LossStats) { - log.V(3).Info("Exporting message losses", "samples", samples) - buffer := []string{} - for _, stream := range samples.Streams() { - streamStats, err := samples.LossStatsFor(stream) - if err != nil { - log.Error(err, "Unable to generate stats", "stream", stream) - return - } - if len(streamStats.Entries) == 0 { - log.V(0).Info("No entries returned for stream", "stream", stream, "streamStats", streamStats) - continue - } - lostLogs := 0 - i := 0 - for expSeqId := streamStats.MinSeqId; expSeqId <= streamStats.MaxSeqId; expSeqId++ { - seqId := streamStats.Entries[i].SequenceId - if seqId != expSeqId { - lostLogs += 1 - } else { - i += 1 //found entry - } - buffer = append(buffer, fmt.Sprintf("%d %d", expSeqId, lostLogs)) - } - - log.V(3).Info("Writing message losses data", "outDir", outDir, "losses", buffer) - err = os.WriteFile(path.Join(outDir, fmt.Sprintf("%s-loss.data", stream)), []byte(strings.Join(buffer, "\n")), 0755) - if err != nil { - log.Error(err, "Error writing message loss metrics", "stream", stream) - } - - } -} - -func formatLossPlot(base string, samples stats.LossStats) string { - buffer := base - for i, stream := range samples.Streams() { - if i == 0 { - buffer = fmt.Sprintf("%s;plot '%s-loss.data' using 1:2 title '%s' with lines", buffer, stream, stream) - } else { - buffer = fmt.Sprintf("%s,'%s-loss.data' using 1:2 title '%s' with lines", buffer, stream, stream) - } - } - return buffer -} - -func (r *GNUPlotReporter) Generate() { - exportResourceMetricTo(r.ArtifactDir, r.Metrics) - exportLatency(r.ArtifactDir, r.Stats.Logs) - - for _, plot := range []string{memPlotPNG, cpuPlotPNG, latencyPlotPNG} { - plotData(plot, r.ArtifactDir, nil) - } - - for _, plot := range []string{memPlotDumb, cpuPlotDumb, latencyPlotDumb} { - plotData(plot, r.ArtifactDir, os.Stdout) - } - - exportLoss(r.ArtifactDir, r.Stats.Losses) - plotData(formatLossPlot(lossPlotPNG, r.Stats.Losses), r.ArtifactDir, nil) - plotData(formatLossPlot(lossPlotDumb, r.Stats.Losses), r.ArtifactDir, os.Stdout) - - r.generateStats() - -} - -func plotData(plot, dir string, writer io.Writer) { - plot = strings.Join(strings.Split(plot, "\n"), ";") - log.V(3).Info("running gnuplot", "cmd", plot) - cmd := exec.Command("gnuplot", "-e", plot) - cmd.Dir = dir - if writer != nil { - cmd.Stdout = writer - } - - err := cmd.Run() - if err != nil { - log.Error(err, "Error starting command", "dir", cmd.Dir, "cmd", cmd.String()) - } -} - -/* #nosec G306*/ -func (r *GNUPlotReporter) generateStats() { - reports := map[string]string{ - "results.html": html, - "readme.md": markdown, - } - s := r.Stats - o := r.Options - - var lossFmtFun func() string - var escapeFn func(content string) string - for file, template := range reports { - if template == html { - escapeFn = htmllib.EscapeString - lossFmtFun = func() string { - losses := "" - for _, name := range s.Losses.Streams() { - streamLoss, _ := s.Losses.LossStatsFor(name) - losses += fmt.Sprintf("", - name, - streamLoss.MinSeqId, - streamLoss.MaxSeqId, - streamLoss.Purged, - streamLoss.Collected, - streamLoss.PercentCollected()) - } - return losses - } - } - if template == markdown { - escapeFn = func(content string) string { - return "```\n" + content + "\n```" - } - lossFmtFun = func() string { - losses := "" - for _, name := range s.Losses.Streams() { - streamLoss, _ := s.Losses.LossStatsFor(name) - losses += fmt.Sprintf("| %s|%d|%d|%d|%d|%.1f%%\n", - name, - streamLoss.MinSeqId, - streamLoss.MaxSeqId, - streamLoss.Purged, - streamLoss.Collected, - streamLoss.PercentCollected()) - } - return losses - } - } - out := fmt.Sprintf(template, - o.Image, - o.TotalLogStressors, - o.LinesPerSecond, - o.RunDuration, - o.PayloadSource, - s.TotMessages(), - s.MsgSize, - s.Elapsed.Round(time.Second), - s.Mean(), - s.Min(), - s.Max(), - s.Median(), - lossFmtFun(), - escapeFn(o.CollectorConfig), - ) - err := os.WriteFile(path.Join(r.ArtifactDir, file), []byte(out), 0755) - if err != nil { - log.Error(err, "Error writing file") - } - } - writeStatsToConsole(s) -} -func writeStatsToConsole(s stats.Statistics) { - w := new(tabwriter.Writer) - // minwidth, tabwidth, padding, padchar, flags - w.Init(os.Stdout, 3, 2, 2, ' ', tabwriter.AlignRight) - - defer w.Flush() - div := "--------" - headerFmt := "\n %s\t%s\t%s\t%s\t%s\t%s\t%s\t" - - fmt.Fprintf(w, "Latency of logs collected based on the time the log was generated and ingested") - fmt.Fprintf(w, headerFmt, "Total", "Size", "Elapsed", "Mean", "Min", "Max", "Median") - fmt.Fprintf(w, headerFmt, "Msg", "(bytes)", "", "(s)", "(s)", "(s)", "(s)") - fmt.Fprintf(w, headerFmt, div, div, div, div, div, div, div) - - fmt.Fprintf(w, "\n %d\t%d\t%s\t%.3f\t%.3f\t%.3f\t%.3f\t", - s.TotMessages(), - s.MsgSize, - s.Elapsed.Round(time.Second), - s.Mean(), - s.Min(), - s.Max(), - s.Median()) - - fmt.Fprintf(w, "\n") - - headerFmt = "\n %s\t%s\t%s\t%s\t%s\t%s\t" - fmt.Fprintf(w, "\nPercent logs lost between first and last collected sequence ids") - fmt.Fprintf(w, headerFmt, "Stream", "Min", "Max", "Purged", "Collected", "Per. Coll.") - fmt.Fprintf(w, headerFmt, div, div, div, div, div, div) - for _, name := range s.Losses.Streams() { - streamLoss, _ := s.Losses.LossStatsFor(name) - fmt.Fprintf(w, "\n%s\t%d\t%d\t%d\t%d\t\t%.1f%%\n", - name, - streamLoss.MinSeqId, - streamLoss.MaxSeqId, - streamLoss.Purged, - streamLoss.Collected, - streamLoss.PercentCollected()) - } - fmt.Fprintf(w, "\n") -} diff --git a/internal/cmd/functional-benchmarker/reports/gonumplot/init.go b/internal/cmd/functional-benchmarker/reports/gonumplot/init.go new file mode 100644 index 0000000000..7de6bc1257 --- /dev/null +++ b/internal/cmd/functional-benchmarker/reports/gonumplot/init.go @@ -0,0 +1,9 @@ +package gonumplot + +import ( + "github.com/openshift/cluster-logging-operator/internal/utils" +) + +var ( + log = utils.InitLogger("gonumplut") +) diff --git a/internal/cmd/functional-benchmarker/reports/gonumplot/plotter.go b/internal/cmd/functional-benchmarker/reports/gonumplot/plotter.go new file mode 100644 index 0000000000..ec2bcbf6af --- /dev/null +++ b/internal/cmd/functional-benchmarker/reports/gonumplot/plotter.go @@ -0,0 +1,191 @@ +package gonumplot + +import ( + "fmt" + "github.com/openshift/cluster-logging-operator/internal/cmd/functional-benchmarker/stats" + "github.com/vspaz/wls-go/pkg/models" + "gonum.org/v1/plot" + "gonum.org/v1/plot/plotter" + "gonum.org/v1/plot/plotutil" + "gonum.org/v1/plot/vg" + "path" +) + +var ( + defaultWidth = vg.Points(768) + defaultHeight = vg.Points(576) + + megaBytesPerByte = 1.0 / float64(1024) / float64(1024) +) + +type GoNumPlot struct { + Metrics stats.ResourceMetrics + Stats stats.Statistics + ArtifactDir string +} + +func (p GoNumPlot) Plot() { + cpu, memory := extractPlotData(p.Metrics.Samples) + p.exportCpuPlot(cpu) + p.exportMemoryPlot(memory) + exportLatencyPlot(p.ArtifactDir, p.Stats.Losses) + exportLossStatsPlot(p.ArtifactDir, p.Stats.Losses) +} + +func exportLatencyPlot(outDir string, stats stats.LossStats) { + aPlot := plot.New() + + aPlot.Title.Text = "Latency" + aPlot.Legend.Top = true + aPlot.X.Label.Text = "Message" + aPlot.Y.Label.Text = "Seconds" + + var data []interface{} + for i, stream := range stats.Streams() { + if streamState, err := stats.LossStatsFor(stream); err == nil { + var xs []float64 + var ys []float64 + var xys plotter.XYs + for i, entry := range streamState.Entries { + xs = append(xs, float64(i)) + ys = append(ys, entry.ElapsedEpoc()) + xys = append(xys, plotter.XY{ + X: float64(i), + Y: entry.ElapsedEpoc(), + }) + } + data = append(data, xys) + + wls := models.NewWlsWithoutWeights(xs, ys) + point := wls.FitLinearRegression() + slope := point.GetSlope() + yIntercept := point.GetIntercept() + + fnLinear := plotter.NewFunction(func(x float64) float64 { + return slope*x + yIntercept + }) + fnLinear.Color = plotutil.Color(i) + + aPlot.Add(fnLinear) + aPlot.Legend.Add(fmt.Sprintf("%s trend", stream), fnLinear) + } else { + log.V(0).Error(err, "Unable to calculate latency", "stream", stream) + } + } + if err := plotutil.AddLinePoints(aPlot, data...); err != nil { + panic(err) + } + + if err := aPlot.Save(defaultWidth, defaultHeight, path.Join(outDir, "latency.png")); err != nil { + panic(err) + } +} + +func (p GoNumPlot) exportMemoryPlot(data plotter.XYs) { + log.V(3).Info("Generating Memory Plot", "data", data) + aPlot := plot.New() + + aPlot.Title.Text = "Mem" + aPlot.X.Label.Text = "Time(m)" + aPlot.Y.Label.Text = "Megabytes" + + if err := plotutil.AddLinePoints( + aPlot, + "Mem", + data, + ); err != nil { + panic(err) + } + + if err := aPlot.Save(defaultWidth, defaultHeight, path.Join(p.ArtifactDir, "mem.png")); err != nil { + panic(err) + } +} + +func (p GoNumPlot) exportCpuPlot(data plotter.XYs) { + log.V(3).Info("Generating CPU Plot", "data", data) + aPlot := plot.New() + + aPlot.Title.Text = "CPU" + aPlot.X.Label.Text = "Time(m)" + aPlot.Y.Label.Text = "Cores" + + if err := plotutil.AddLinePoints( + aPlot, + "CPU", + data, + ); err != nil { + panic(err) + } + + if err := aPlot.Save(defaultWidth, defaultHeight, path.Join(p.ArtifactDir, "cpu.png")); err != nil { + panic(err) + } +} + +func extractPlotData(samples []stats.Sample) (cpu, memory plotter.XYs) { + var first int64 + for i, sample := range samples { + if i == 0 { + first = sample.Time + } + timeSample := float64(sample.Time-first) / 60.0 + cpu = append(cpu, plotter.XY{ + X: timeSample, + Y: sample.CPUCoresAsFloat(), + }) + + memory = append(memory, plotter.XY{ + X: timeSample, + Y: sample.MemoryBytesAsFloat() * megaBytesPerByte, + }) + } + return cpu, memory +} + +func exportLossStatsPlot(outDir string, samples stats.LossStats) { + log.Info("Exporting message losses") + aPlot := plot.New() + aPlot.Title.Text = "Percent Collected Per Stream" + aPlot.Legend.Top = true + aPlot.X.Label.Text = "SeqId" + aPlot.Y.Label.Text = "Per. Collected" + aPlot.Y.Min = 0 + + var data []interface{} + for _, stream := range samples.Streams() { + streamStats, err := samples.LossStatsFor(stream) + if err != nil { + log.Error(err, "Unable to generate stats", "stream", stream) + return + } + if len(streamStats.Entries) == 0 { + log.V(0).Info("No entries returned for stream", "stream", stream, "streamStats", streamStats) + continue + } + lostLogs := 0 + i := 0 + var xys plotter.XYs + + minID := streamStats.MinSeqId + + for expSeqId := streamStats.MinSeqId; expSeqId <= streamStats.MaxSeqId; expSeqId++ { + seqId := streamStats.Entries[i].SequenceId + if seqId != expSeqId { + lostLogs += 1 + } else { + i += 1 //found entry + } + per := float64(i) / float64(expSeqId-minID+1) * 100.0 + xys = append(xys, plotter.XY{X: float64(expSeqId), Y: per}) + } + log.V(3).Info("Adding loss stats to plot", "xys", xys, "stream", "stream") + data = append(data, stream, xys) + } + if err := plotutil.AddLinePoints(aPlot, data...); err != nil { + panic(err) + } + if err := aPlot.Save(defaultWidth, defaultHeight, path.Join(outDir, "loss.png")); err != nil { + panic(err) + } +} diff --git a/internal/cmd/functional-benchmarker/reports/report.go b/internal/cmd/functional-benchmarker/reports/report.go index 45e943e87f..4ba6822568 100644 --- a/internal/cmd/functional-benchmarker/reports/report.go +++ b/internal/cmd/functional-benchmarker/reports/report.go @@ -1,20 +1,122 @@ package reports import ( + "fmt" + log "github.com/ViaQ/logerr/v2/log/static" "github.com/openshift/cluster-logging-operator/internal/cmd/functional-benchmarker/config" - "github.com/openshift/cluster-logging-operator/internal/cmd/functional-benchmarker/reports/gnuplot" + "github.com/openshift/cluster-logging-operator/internal/cmd/functional-benchmarker/reports/gonumplot" "github.com/openshift/cluster-logging-operator/internal/cmd/functional-benchmarker/stats" + htmllib "html" + "os" + "path" + "time" ) type Report interface { Generate() } +type Plotter interface { + Plot() +} + func NewReporter(options config.Options, artifactDir string, metrics *stats.ResourceMetrics, statistics *stats.Statistics) Report { - return &gnuplot.GNUPlotReporter{ + return &Reporter{ Options: options, + Stats: *statistics, + ArtifactDir: artifactDir, + Plotter: NewPlotter(artifactDir, metrics, statistics), + } +} + +func NewPlotter(artifactDir string, metrics *stats.ResourceMetrics, statistics *stats.Statistics) Plotter { + return &gonumplot.GoNumPlot{ Metrics: *metrics, Stats: *statistics, ArtifactDir: artifactDir, } } + +type Reporter struct { + Options config.Options + Stats stats.Statistics + Plotter Plotter + ArtifactDir string +} + +func (r *Reporter) Generate() { + r.Plotter.Plot() + r.generateReports() +} + +/* #nosec G306*/ +func (r *Reporter) generateReports() { + log.Info("Generating stats reports") + reports := map[string]string{ + "results.html": html, + "readme.md": markdown, + } + s := r.Stats + o := r.Options + + var lossFmtFun func() string + var escapeFn func(content string) string + for file, template := range reports { + if template == html { + escapeFn = htmllib.EscapeString + lossFmtFun = func() string { + losses := "" + for _, name := range s.Losses.Streams() { + streamLoss, _ := s.Losses.LossStatsFor(name) + losses += fmt.Sprintf("", + name, + streamLoss.MinSeqId, + streamLoss.MaxSeqId, + streamLoss.Purged, + streamLoss.Collected, + streamLoss.PercentCollected()) + } + return losses + } + } + if template == markdown { + escapeFn = func(content string) string { + return "```\n" + content + "\n```" + } + lossFmtFun = func() string { + losses := "" + for _, name := range s.Losses.Streams() { + streamLoss, _ := s.Losses.LossStatsFor(name) + losses += fmt.Sprintf("| %s|%d|%d|%d|%d|%.1f%%\n", + name, + streamLoss.MinSeqId, + streamLoss.MaxSeqId, + streamLoss.Purged, + streamLoss.Collected, + streamLoss.PercentCollected()) + } + return losses + } + } + out := fmt.Sprintf(template, + o.Image, + o.TotalLogStressors, + o.LinesPerSecond, + o.RunDuration, + o.PayloadSource, + s.TotMessages(), + s.MsgSize, + s.Elapsed.Round(time.Second), + s.Mean(), + s.Min(), + s.Max(), + s.Median(), + lossFmtFun(), + escapeFn(o.CollectorConfig), + ) + err := os.WriteFile(path.Join(r.ArtifactDir, file), []byte(out), 0755) + if err != nil { + log.Error(err, "Error writing file") + } + } +} diff --git a/internal/cmd/functional-benchmarker/runners/cluster/cluster_runner.go b/internal/cmd/functional-benchmarker/runners/cluster/cluster_runner.go index 4aa7ac219f..908888301b 100644 --- a/internal/cmd/functional-benchmarker/runners/cluster/cluster_runner.go +++ b/internal/cmd/functional-benchmarker/runners/cluster/cluster_runner.go @@ -14,7 +14,6 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" - log "github.com/ViaQ/logerr/v2/log/static" obs "github.com/openshift/cluster-logging-operator/api/observability/v1" "github.com/openshift/cluster-logging-operator/internal/cmd/functional-benchmarker/config" "github.com/openshift/cluster-logging-operator/internal/cmd/functional-benchmarker/stats" @@ -60,7 +59,7 @@ func (r *ClusterRunner) Deploy() { testClient.Close() } } - r.framework = functional.NewCollectorFunctionalFrameworkUsing(&testClient.Test, cleanup, r.Verbosity) + r.framework = functional.NewCollectorFunctionalFrameworkUsing(&testClient.Test, cleanup, 0) r.framework.Conf = r.CollectorConfig obsruntime.NewClusterLogForwarderBuilder(r.framework.Forwarder). @@ -68,7 +67,17 @@ func (r *ClusterRunner) Deploy() { spec.Type = obs.InputTypeApplication spec.Application = &obs.Application{ Includes: []obs.NamespaceContainerSpec{ - {Namespace: r.Namespace()}, + { + Namespace: r.Namespace(), + }, + }, + Excludes: []obs.NamespaceContainerSpec{ + { + Container: "collector", + }, + { + Container: "http", + }, }, } }). diff --git a/internal/cmd/functional-benchmarker/runners/cluster/init.go b/internal/cmd/functional-benchmarker/runners/cluster/init.go new file mode 100644 index 0000000000..192b4a970b --- /dev/null +++ b/internal/cmd/functional-benchmarker/runners/cluster/init.go @@ -0,0 +1,9 @@ +package cluster + +import ( + "github.com/openshift/cluster-logging-operator/internal/utils" +) + +var ( + log = utils.InitLogger("cluster") +) diff --git a/internal/cmd/functional-benchmarker/stats/init.go b/internal/cmd/functional-benchmarker/stats/init.go new file mode 100644 index 0000000000..65eee2b5f2 --- /dev/null +++ b/internal/cmd/functional-benchmarker/stats/init.go @@ -0,0 +1,9 @@ +package stats + +import ( + "github.com/openshift/cluster-logging-operator/internal/utils" +) + +var ( + log = utils.InitLogger("stats") +) diff --git a/internal/cmd/functional-benchmarker/stats/sample.go b/internal/cmd/functional-benchmarker/stats/sample.go index 79ba5b125c..bb5d5645a0 100644 --- a/internal/cmd/functional-benchmarker/stats/sample.go +++ b/internal/cmd/functional-benchmarker/stats/sample.go @@ -4,8 +4,6 @@ import ( "math" "regexp" "strconv" - - log "github.com/ViaQ/logerr/v2/log/static" ) var ( diff --git a/internal/cmd/functional-benchmarker/stats/types.go b/internal/cmd/functional-benchmarker/stats/types.go index 6410034902..df064b405c 100644 --- a/internal/cmd/functional-benchmarker/stats/types.go +++ b/internal/cmd/functional-benchmarker/stats/types.go @@ -1,30 +1,33 @@ package stats import ( - log "github.com/ViaQ/logerr/v2/log/static" + "github.com/openshift/cluster-logging-operator/test" "github.com/openshift/cluster-logging-operator/test/helpers/types" - "regexp" - "strconv" - "strings" -) - -var ( - perfLogPattern = regexp.MustCompile(`.*epoc_in\":(?P[0-9\.]*).*epoc_out\":(?P[0-9\.]*).*message\":\"(?P.*(?Pfunctional((\.0)?\.[0-9A-Z]*)?) - (?P\d{10}) -.*?\").*?`) ) type PerfLog struct { - Stream string types.Timing - SequenceId int - // Bloat is the ratio of overall size / Message size - bloat float64 + // ContainerName is the name of the container producing the logstream + ContainerName string `json:"container_name,omitempty"` + + // Message is the receiver processed messsage, not the original message + Message string `json:"message,omitempty"` + + // MessageSize is the original message size before it was processed by the receiver + MessageSize int `json:"message_size,omitempty"` + + // PayloadSize is the original payload size before it was processed by the receiver + PayloadSize int `json:"payload_size,omitempty"` + + Stream string + SequenceId int `json:"seqid,omitempty"` } type PerfLogs []PerfLog func (t *PerfLog) Bloat() float64 { - return t.bloat + return float64(t.PayloadSize) / float64(t.MessageSize) } func (t *PerfLog) ElapsedEpoc() float64 { return t.EpocOut - t.EpocIn @@ -32,41 +35,13 @@ func (t *PerfLog) ElapsedEpoc() float64 { // NewPerfLog creates a PerfLog from a line parsing it or returning nil if there is an error func NewPerfLog(line string) *PerfLog { - match := perfLogPattern.FindStringSubmatch(line) - if len(match) > 0 { - entry := PerfLog{} - for i, name := range perfLogPattern.SubexpNames() { - switch name { - case "message": - entry.bloat = float64(len(line)) / float64(len(match[i])) - case "stream": - entry.Stream = match[i] - case "seqid": - seqId, err := strconv.Atoi(strings.TrimSpace(match[i])) - if err != nil { - log.Error(err, "Skipping entry. Unable to parse sequence id", "match", match[i], "line", line) - return nil - } - entry.SequenceId = seqId - case "epoc_out": - epocOut, err := strconv.ParseFloat(strings.TrimSpace(match[i]), 64) - if err != nil { - log.Error(err, "Skipping entry. Unable to parse epic_out", "match", match[i], "line", line) - return nil - } - entry.EpocOut = epocOut - case "epoc_in": - epicIn, err := strconv.ParseFloat(strings.TrimSpace(match[i]), 64) - if err != nil { - log.Error(err, "Skipping entry. Unable to parse epic_in", "match", match[i], "line", line) - return nil - } - entry.EpocIn = epicIn - } - } - - return &entry + entry := &PerfLog{} + log.V(4).Info("Unmarshalling", "line", line) + if err := test.Unmarshal(line, entry); err != nil { + log.V(4).Info("Failed to unmarshall perflog", "line", line) + return nil } - log.V(4).Info("Failed to match perflog", "line", line) - return nil + entry.Stream = entry.ContainerName + log.V(4).Info("Returning", "perfLog", entry) + return entry } diff --git a/internal/cmd/functional-benchmarker/stats/types_test.go b/internal/cmd/functional-benchmarker/stats/types_test.go index 79a1e4d705..784ae3894d 100644 --- a/internal/cmd/functional-benchmarker/stats/types_test.go +++ b/internal/cmd/functional-benchmarker/stats/types_test.go @@ -7,14 +7,14 @@ import ( var _ = Describe("Evaluating log loss stats", func() { - var sample = `{"@timestamp":"2023-06-09T16:48:18.929938124+00:00","docker":{"container_id":"8d5fb743542b8c13afb0d5d3cf4cb52e724750d63de58006f16784c9c00da641"},"epoc_in":1682023305.6504774,"epoc_out":1686329299.934293,"hostname":"ip-10-0-173-26.us-east-2.compute.internal","kubernetes":{"container_image":"quay.io/openshift-logging/cluster-logging-load-client:latest","container_image_id":"quay.io/openshift-logging/cluster-logging-load-client@sha256:c8682432425be4b6f64821f0634fb1150b7cf805da0fa724b6047135b9d4d783","container_name":"loader-0","flat_labels":["test-client=true","testname=functional","testtype=functional"],"host":"ip-10-0-173-26.us-east-2.compute.internal","labels":{"test-client":"true","testname":"functional","testtype":"functional"},"master_url":"https://kubernetes.default.svc","namespace_id":"1dca9c0d-1365-4090-9bb3-80fda9b5fec6","namespace_labels":{"kubernetes_io_metadata_name":"testhack-imh2tzge","pod-security_kubernetes_io_enforce":"privileged","security_openshift_io_scc_podSecurityLabelSync":"false","test-client":"true"},"namespace_name":"testhack-imh2tzge","pod_id":"ca9b1dbf-84f3-4aa5-a876-46c0f4bba186","pod_ip":"10.131.0.21","pod_name":"functional"},"level":"unknown","log_type":"application","message":"goloader seq - functional.0.00000000000000002A536241AD427647 - 0000000123 - hvFtZpIOtnnhugEaqJqWWHqCmVCQXExRcOnXEaGpwWgIUlRjtCXLhmQUuqgnpStPjMudPrjUFRBBqolWCNCXdGrpvCqIclJzokNTrQgSUDKmrisDaohrCGDEHeihthYcAyUXmxlQHTkWEfViIVtQHoCQEBDFFWXJfKFqrgpIjgAdqBYeillNOikhURuwFZTEmwcWLElnrlBkZICapoGmFNeBxotMRQXGQLtntyCDiYjiihtvutkzbnHixjFuXKWkhWJbzHiVTuFJvYDlXBKfqGVQejokSwYueuDCdoAxyZCLglsVPijCEmjjGQaKLzlMYZApIOcZdeWVYIWZszhVDDfXArvuVxIdCtKSWMkQJXVuukvkSqKZbkQFcvaZdbDINbYgDAXOPMlYdGTULIwQdTSYyLIlSVyrxSZCnjZfAUhOTObIAXOZJhoJOaKmOpMqzLgYgSaZBaWiMcczEXVzVVXOsjdUKNJgjmdoyhvjcRbGQcLQNpRuTRsgaTbgnziKpEOVlngQEKDIkelRRhdErcIKisDQYNOxhIOysuJXDVYKILOLvritsLpqMJFGuBJjUHcJamedAMPGzkGidwrPWZeScywFftuevYThNNTzNqaQAAyYoSpHbmoZomqSYtDxAfnpCHAOBidVMwMXNLMHUuvrGVCdRwvEignmJOqaPCnYzFSbfZQFjFauIQfjCCnRvnQHPrCKPbnDWhuphjFIFJwjFKKqqmfDzaxizIoEjCHkBGWTEfEKfDYBKhwHfqLRBsGidLzdmAzUImEqWBUDFXWCHBhLIGlyQvGOLDSBymDfydqGoqxtlwVJNzjQdGTExPgBRxQZpVuqpOXGCHIGzjvBmggNSwWqHoxsxexAmjhtfIFrhHFkpkfYlcBTOyxetSvtVCmpAsAwGTRsFmkueLsgFeTqWYiLznDvYWtyXDRBLqwqepDsPPMRslWLYhIWuPRNTWXKsfNbWXpfigOtShXEIPCSEArirHpLLeamyQJOWkIsNWRdErHMpRpzHZXu","openshift":{"cluster_id":"functional","sequence":21526},"path":"/","pipeline_metadata":{"collector":{"inputname":"fluent-plugin-systemd","ipaddr4":"10.131.0.21","name":"fluentd","received_at":"2023-06-09T16:48:18.930687+00:00","version":"1.14.6 1.6.0"}},"source_type":"http_server","timestamp":"2023-06-09T16:48:19.933871646Z","viaq_msg_id":"NGFlNDVhNzItN2ZjZi00Nzc3LTliMzItOTlmZWEyODliYWJj"}` + var sample = `{"container_name":"loader-0","epoc_in":1742334136.8465972,"epoc_out":1742334154.0828154,"message":"goloader seq - functional.0000000000000000C08D75201BF50A40 - 0000000001","message_size":586,"payload_size":2616,"seqid":1}` It("NewPerfLog", func() { log := NewPerfLog(sample) - Expect(log.Bloat()).To(BeNumerically("~", 2.4, 0.1)) - Expect(log.SequenceId).To(Equal(123)) - Expect(log.EpocIn).To(Equal(1682023305.6504774)) - Expect(log.EpocOut).To(Equal(1686329299.934293)) - Expect(log.Stream).To(Equal("functional.0.00000000000000002A536241AD427647")) + Expect(log.Bloat()).To(BeNumerically("~", 4.4, 0.1)) + Expect(log.SequenceId).To(Equal(1)) + Expect(log.EpocIn).To(Equal(1742334136.8465972)) + Expect(log.EpocOut).To(Equal(1742334154.0828154)) + Expect(log.Stream).To(Equal("loader-0")) }) }) diff --git a/internal/utils/logger.go b/internal/utils/logger.go index 00a13f7e6b..d7d31e69e1 100644 --- a/internal/utils/logger.go +++ b/internal/utils/logger.go @@ -16,8 +16,6 @@ const ( ) // InitLogger creates a logger and optionally initializes the verbosity with the value in LOG_LEVEL. -// -// It also replaces the static logger with the newly-created logger. func InitLogger(component string) logr.Logger { verbosity := defaultLoggerVerbosity if rawVerbosity, ok := os.LookupEnv(envLogLevel); ok { @@ -28,8 +26,13 @@ func InitLogger(component string) logr.Logger { verbosity = envVerbosity } + return log.NewLogger(component, log.WithVerbosity(verbosity)) +} - logger := log.NewLogger(component, log.WithVerbosity(verbosity)) +// InitStaticLogger creates a logger and optionally initializes the verbosity with the value in LOG_LEVEL +// and replaces the static logger with the newly-created logger. +func InitStaticLogger(component string) logr.Logger { + logger := InitLogger(component) static.SetLogger(logger) return logger } diff --git a/test/framework/functional/output_http.go b/test/framework/functional/output_http.go index fc0445e1fc..277b69a464 100644 --- a/test/framework/functional/output_http.go +++ b/test/framework/functional/output_http.go @@ -21,8 +21,8 @@ import ( ) const ( - VectorHttpSourceBenchmarkConfTemplate = "" + - `[sources.my_source] + VectorHttpSourceBenchmarkConfTemplate = ` +[sources.my_source] type = "http_server" address = "127.0.0.1:8090" decoding.codec = "json" @@ -45,7 +45,7 @@ crt_file = "/tmp/secrets/http/tls.crt" type = "remap" inputs = ["my_source"] source = ''' - .epoc_out = to_float(now()) + epoc_out = to_float(now()) mytime, err = parse_timestamp(."@timestamp", format: "%Y-%m-%dT%H:%M:%S%.fZ") if err != null { mytime, err = parse_timestamp(."@timestamp", format: "%Y-%m-%dT%H:%M:%S%.f%z") @@ -53,8 +53,23 @@ source = ''' log("Unable to parse @timestamp: " + err, level: "error") } } - .epoc_in = to_float(mytime) - + epoc_in = to_float(mytime) + + content = parse_regex!(.message,r'(?goloader seq - functional\.[0-9A-Z]* - (?[0-9]{10}))') + message = to_string(content.sub) + container_name = .kubernetes.container_name + message_size = length!(.message) + payload_size = length(encode_json(.)) + + . = { + "epoc_in": epoc_in, + "epoc_out": epoc_out, + "message": to_string(message), + "container_name": container_name, + "message_size": message_size, + "payload_size": payload_size, + "seqid": to_int!(content.seqid) + } ''' [sinks.my_sink] @@ -227,7 +242,7 @@ func (f *CollectorFunctionalFramework) AddFluentdHttpOutput(b *runtime.PodBuilde } func (f *CollectorFunctionalFramework) AddBenchmarkForwardOutput(b *runtime.PodBuilder, output obs.OutputSpec, image string) error { - if err := f.AddVectorHttpOutputWithConfig(b, output, "", nil, Option{"path", "/tmp/{{kubernetes.container_name}}.log"}, Option{"template", VectorHttpSourceBenchmarkConfTemplate}); err != nil { + if err := f.AddVectorHttpOutputWithConfig(b, output, "", nil, Option{"path", "/tmp/{{.container_name}}.log"}, Option{"template", VectorHttpSourceBenchmarkConfTemplate}); err != nil { return err } b.GetContainer(string(obs.OutputTypeHTTP)).WithImage(image).Update()
%s%d%d%d%d%.1f%%
%s%d%d%d%d%.1f%%