user new prometheus.

pull/223/head
shunza 5 years ago
parent c39d76128f
commit 6b5f06c584
  1. 39
      go.mod
  2. 91
      go.sum
  3. 5
      pkg/cache/memcache/errors.go
  4. 51
      pkg/cache/memcache/metrics.go
  5. 33
      pkg/cache/memcache/pool_conn.go
  6. 32
      pkg/cache/redis/conn.go
  7. 5
      pkg/cache/redis/errors.go
  8. 51
      pkg/cache/redis/metrics.go
  9. 26
      pkg/cache/redis/pool.go
  10. 2
      pkg/database/hbase/hbase.go
  11. 33
      pkg/database/hbase/metrics.go
  12. 37
      pkg/database/sql/metrics.go
  13. 3
      pkg/database/sql/mysql.go
  14. 38
      pkg/database/sql/sql.go
  15. 37
      pkg/database/tidb/metrics.go
  16. 38
      pkg/database/tidb/sql.go
  17. 3
      pkg/database/tidb/tidb.go
  18. 10
      pkg/log/log.go
  19. 8
      pkg/net/http/blademaster/client.go
  20. 4
      pkg/net/http/blademaster/logger.go
  21. 48
      pkg/net/http/blademaster/metrics.go
  22. 11
      pkg/net/http/blademaster/ratelimit.go
  23. 6
      pkg/net/http/blademaster/server.go
  24. 2
      pkg/net/rpc/warden/client.go
  25. 14
      pkg/net/rpc/warden/logging.go
  26. 41
      pkg/net/rpc/warden/metrics.go
  27. 17
      pkg/net/rpc/warden/ratelimiter/ratelimiter.go
  28. 48
      pkg/stat/metric/counter.go
  29. 29
      pkg/stat/metric/counter_test.go
  30. 59
      pkg/stat/metric/gauge.go
  31. 29
      pkg/stat/metric/gauge_test.go
  32. 50
      pkg/stat/metric/histogram.go
  33. 39
      pkg/stat/metric/histogram_test.go
  34. 68
      pkg/stat/metric/metric.go
  35. 5
      pkg/stat/prom/README.md
  36. 163
      pkg/stat/prom/prometheus.go
  37. 25
      pkg/stat/stat.go
  38. 6
      pkg/sync/pipeline/fanout/fanout.go
  39. 15
      pkg/sync/pipeline/fanout/metrics.go
  40. 8
      tool/kratos-gen-bts/header_template.go
  41. 8
      tool/kratos-gen-bts/multi_template.go
  42. 6
      tool/kratos-gen-bts/none_template.go
  43. 24
      tool/kratos-gen-bts/testdata/dao.bts.go
  44. 7
      tool/kratos-gen-mc/header_template.go
  45. 16
      tool/kratos-gen-mc/multi_template.go
  46. 8
      tool/kratos-gen-mc/none_template.go
  47. 8
      tool/kratos-gen-mc/single_template.go
  48. 39
      tool/kratos-gen-mc/testdata/mc.cache.go
  49. 4
      tool/kratos/tool_index.go

@ -4,8 +4,8 @@ go 1.12
require (
github.com/BurntSushi/toml v0.3.1
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
github.com/aristanetworks/goarista v0.0.0-20190409234242-46f4bc7b73ef // indirect
github.com/StackExchange/wmi v0.0.0-20190523213609-cbe66965904d // indirect
github.com/aristanetworks/goarista v0.0.0-20190712234253-ed1100a1c015 // indirect
github.com/coreos/bbolt v1.3.3 // indirect
github.com/coreos/etcd v3.3.13+incompatible
github.com/coreos/go-semver v0.3.0 // indirect
@ -15,55 +15,58 @@ require (
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 // indirect
github.com/cznic/strutil v0.0.0-20181122101858-275e90344537 // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
github.com/dgryski/go-farm v0.0.0-20190323231341-8198c7b169ec
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2
github.com/fatih/color v1.7.0
github.com/fsnotify/fsnotify v1.4.7
github.com/go-ole/go-ole v1.2.4 // indirect
github.com/go-playground/locales v0.12.1 // indirect
github.com/go-playground/universal-translator v0.16.0 // indirect
github.com/go-sql-driver/mysql v1.4.1
github.com/gogo/protobuf v1.2.0
github.com/gogo/protobuf v1.2.1
github.com/golang/glog v0.0.0-20170312005925-543a34c32e4d // indirect
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 // indirect
github.com/golang/mock v1.3.1 // indirect
github.com/golang/protobuf v1.3.1
github.com/golang/protobuf v1.3.2
github.com/google/btree v1.0.0 // indirect
github.com/gorilla/websocket v1.4.0 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 // indirect
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
github.com/grpc-ecosystem/grpc-gateway v1.9.4 // indirect
github.com/jonboulle/clockwork v0.1.0 // indirect
github.com/json-iterator/go v1.1.6 // indirect
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
github.com/leodido/go-urn v1.1.0 // indirect
github.com/mattn/go-colorable v0.0.9 // indirect
github.com/mattn/go-isatty v0.0.4 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/mattn/go-colorable v0.1.2 // indirect
github.com/montanaflynn/stats v0.5.0
github.com/openzipkin/zipkin-go v0.2.0
github.com/pkg/errors v0.8.1
github.com/prometheus/client_golang v0.9.2
github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001 // indirect
github.com/prometheus/client_golang v1.0.0
github.com/prometheus/client_model v0.0.0-20190220174349-fd36f4220a90 // indirect
github.com/prometheus/common v0.6.0 // indirect
github.com/prometheus/procfs v0.0.3 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20190806203942-babf20351dd7e3ac320adedbbe5eb311aec8763c // indirect
github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec // indirect
github.com/shirou/gopsutil v2.18.12+incompatible
github.com/shirou/gopsutil v2.19.6+incompatible
github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726
github.com/sirupsen/logrus v1.4.1
github.com/sirupsen/logrus v1.4.2
github.com/soheilhy/cmux v0.1.4 // indirect
github.com/stretchr/testify v1.3.0
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect
github.com/tsuna/gohbase v0.0.0-20190201102810-d3184c1526df
github.com/tsuna/gohbase v0.0.0-20190502052937-24ffed0537aa
github.com/urfave/cli v1.20.0
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
go.etcd.io/bbolt v1.3.3 // indirect
go.uber.org/atomic v1.4.0 // indirect
go.uber.org/multierr v1.1.0 // indirect
go.uber.org/zap v1.10.0 // indirect
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 // indirect
golang.org/x/net v0.0.0-20190628185345-da137c7871d7
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect
golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7 // indirect
golang.org/x/time v0.0.0-20190513212739-9d24e82272b4 // indirect
google.golang.org/appengine v1.6.1 // indirect
google.golang.org/genproto v0.0.0-20190701230453-710ae3a149df
google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610
google.golang.org/grpc v1.22.0
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
gopkg.in/go-playground/validator.v9 v9.26.0
gopkg.in/go-playground/validator.v9 v9.29.1
gopkg.in/yaml.v2 v2.2.2
)

@ -2,12 +2,17 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d h1:G0m3OIz70MZUWq3EgK3CesDbo8upS2Vm9/P3FtgI+Jk=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/aristanetworks/goarista v0.0.0-20190409234242-46f4bc7b73ef h1:ajsnF5qTstiBlP+V/mgh91zZfoKP477KfSmRoCoyYGU=
github.com/aristanetworks/goarista v0.0.0-20190409234242-46f4bc7b73ef/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/StackExchange/wmi v0.0.0-20190523213609-cbe66965904d h1:VWP4o43LuzNbykZJzMUv5b9DWLgn0sn3GUj3RUyWMMQ=
github.com/StackExchange/wmi v0.0.0-20190523213609-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/aristanetworks/goarista v0.0.0-20190712234253-ed1100a1c015 h1:7ABPr1+uJdqESAdlVevnc/2FJGiC/K3uMg1JiELeF+0=
github.com/aristanetworks/goarista v0.0.0-20190712234253-ed1100a1c015/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/coreos/bbolt v1.3.3 h1:n6AiVyVRKQFNb6mJlwESEvvLoDyiTzXX7ORAUlkeBdY=
github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
@ -31,8 +36,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-farm v0.0.0-20190323231341-8198c7b169ec h1:sElGDs3V8VdCxH5tWi0ycWJzteOPLJ3HtItSSKI95PY=
github.com/dgryski/go-farm v0.0.0-20190323231341-8198c7b169ec/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
@ -42,6 +47,10 @@ github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
github.com/go-playground/locales v0.12.1 h1:2FITxuFt/xuCNP1Acdhv62OzaCiviiE4kotfhkmOqEc=
@ -50,14 +59,20 @@ github.com/go-playground/universal-translator v0.16.0 h1:X++omBR/4cE2MNg91AoC3rm
github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.0 h1:xU6/SpYbvkNYiptHJYEDRseDLvYE7wSqhYYNy0QSUzI=
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang/appengine v1.6.1 h1:j62c5sc2q/cKw4YtXXZOOJJEGNwUSIN/PHd/mH0/gxU=
github.com/golang/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
github.com/golang/crypto v0.0.0-20190605123033-f99c8df09eb5 h1:18ekSt7rlAyNXX6XVP6wJFxTItXuUfQlKMxzVay65p4=
github.com/golang/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/glog v0.0.0-20170312005925-543a34c32e4d h1:2j91wXsfKhjdY61S6AYScHlrpaHzjeUlCjBLVii2N1g=
github.com/golang/glog v0.0.0-20170312005925-543a34c32e4d/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1 h1:G5FRp8JnTd7RQH5kemVNlMeyXQAztQ3mOWV95KxsXH8=
@ -68,11 +83,14 @@ github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/sync v0.0.0-20190427212804-112230192c58 h1:CfvS2lsMxwV6vyyjjeXQ0dqkW/yQ0gyOHG6QNzjOUw0=
github.com/golang/sync v0.0.0-20190427212804-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
github.com/golang/sys v0.0.0-20190602015325-4c4f7f33c9ed h1:BIG54Uwbp5ZzFl3i2t+d+EGE8jq89zYK7iXM6tyv76E=
github.com/golang/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
github.com/golang/text v0.3.2 h1:vDAeTQXl8YUdGoj2vMsMnzHi1xMJJ9S7iwnTBFL/pkA=
github.com/golang/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
github.com/golang/time v0.0.0-20190308202827-9d24e82272b4 h1:F9e5QAps6/3zc8881JhdfJBCj+KjFaahs4YNEzAPc/Q=
github.com/golang/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -80,6 +98,7 @@ github.com/golang/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-genproto v0.0.0-20190701230453-710ae3a149df h1:eFJURqQs4vskSlhP3Y2PpC0vp8Zj4xS689gjPGrGksA=
github.com/google/go-genproto v0.0.0-20190701230453-710ae3a149df/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
github.com/googleapis/google-cloud-go v0.26.0/go.mod h1:yJoOdPPE9UpqbamBhJvp7Ur6OUPPV4rUY3RnssPGNBA=
@ -100,8 +119,14 @@ github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@ -109,47 +134,60 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/leodido/go-urn v1.1.0 h1:Sm1gr51B1kKyfD2BlRcLSiEkffoG96g6TPv6eRoEiB8=
github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/montanaflynn/stats v0.5.0 h1:2EkzeTSqBB4V4bJwWrt5gIIrZmpJBcoIRGS2kWLgzmk=
github.com/montanaflynn/stats v0.5.0/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/openzipkin/zipkin-go v0.2.0 h1:33/f6xXB6YlOQ9tgTsXVOkdLCJsHTcZJnMy4DnSd6FU=
github.com/openzipkin/zipkin-go v0.2.0/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.2 h1:awm861/B8OKDd2I/6o1dy3ra4BamzKhYOiGItCeZ740=
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0 h1:vrDKnkGzuGvhNAL56c7DBz29ZL+KxnoR0x7enabFceM=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275 h1:PnBWHBf+6L0jOqq0gIVUe6Yk0/QMZ640k6NvkxcBf+8=
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a h1:9a8MnZMP0X2nLJdBg+pBmGgkJlSaKC2KaQmTCk1XDtE=
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190220174349-fd36f4220a90 h1:Cov9QkEXNhh8QeXoICvORjJ4RrpyvXmSf7rHSpS+ZfI=
github.com/prometheus/client_model v0.0.0-20190220174349-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.6.0 h1:kRhiuYSXR3+uv2IbVbZhUxK5zVD/2pp3Gd2PpvPkpEo=
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.3 h1:CTwfnzjQ+8dS6MhHHu4YswVAD99sL2wjPqP+VkURmKE=
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001 h1:YDeskXpkNDhPdWN3REluVa46HQOVuVkjkd2sWnrABNQ=
github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/remyoudompheng/bigfft v0.0.0-20190806203942-babf20351dd7e3ac320adedbbe5eb311aec8763c h1:eED6LswgZ3TfAl9fb+L2TfdSlXpYdg21iWZMdHuoSks=
github.com/remyoudompheng/bigfft v0.0.0-20190806203942-babf20351dd7e3ac320adedbbe5eb311aec8763c/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec h1:6ncX5ko6B9LntYM0YBRXkiSaZMmLYeZ/NWcmeB43mMY=
github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
github.com/shirou/gopsutil v2.18.12+incompatible h1:1eaJvGomDnH74/5cF4CTmTbLHAriGFsTZppLXDX93OM=
github.com/shirou/gopsutil v2.18.12+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil v2.19.6+incompatible h1:49/Gru26Lne9Cl3IoAVDZVM09hvkSrUodgIIsCVRwbs=
github.com/shirou/gopsutil v2.19.6+incompatible/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc=
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726 h1:xT+JlYxNGqyT+XcU8iUrN18JYed2TvG9yN5ULG2jATM=
github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
@ -160,8 +198,8 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tsuna/gohbase v0.0.0-20190201102810-d3184c1526df h1:jYiwqXfoRWU6pJMzClEpLn9Jofi3U/8qS+w3iRNJ/hw=
github.com/tsuna/gohbase v0.0.0-20190201102810-d3184c1526df/go.mod h1:3HfLQly3YNLGxNv/2YOfmz30vcjG9hbuME1GpxoLlGs=
github.com/tsuna/gohbase v0.0.0-20190502052937-24ffed0537aa h1:V/ABqiqsgqmpoIcLDSpJ1KqPfbxRmkcfET5+BRy9ctM=
github.com/tsuna/gohbase v0.0.0-20190502052937-24ffed0537aa/go.mod h1:3HfLQly3YNLGxNv/2YOfmz30vcjG9hbuME1GpxoLlGs=
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
@ -179,6 +217,7 @@ golang.org/x/lint v0.0.0-20190511005446-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHl
golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8j4DQRpdYMnGn/bJUEU=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20190614102709-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
@ -186,8 +225,8 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
gopkg.in/go-playground/validator.v9 v9.26.0 h1:2NPPsBpD0ZoxshmLWewQru8rWmbT5JqSzz9D1ZrAjYQ=
gopkg.in/go-playground/validator.v9 v9.26.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
gopkg.in/go-playground/validator.v9 v9.29.1 h1:SvGtYmN60a5CVKTOzMSyfzWDeZRxRuGvRQyEAKbw1xc=
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=

@ -49,10 +49,13 @@ func (pe protocolError) Error() string {
return fmt.Sprintf("memcache: %s (possible server error or unsupported concurrent read by application)", string(pe))
}
func formatErr(err error) string {
func (pc *poolConn) formatErr(err error) string {
e := pkgerr.Cause(err)
switch e {
case ErrNotFound, ErrExists, ErrNotStored, nil:
if e == ErrNotFound {
_metricMisses.Inc(pc.p.c.Name, pc.p.c.Addr)
}
return ""
default:
es := e.Error()

@ -0,0 +1,51 @@
package memcache
import "github.com/bilibili/kratos/pkg/stat/metric"
const namespace = "memcache_client"
var (
_metricReqDur = metric.NewHistogramVec(&metric.HistogramVecOpts{
Namespace: namespace,
Subsystem: "requests",
Name: "duration_ms",
Help: "memcache client requests duration(ms).",
Labels: []string{"name", "addr", "command"},
Buckets: []float64{5, 10, 25, 50, 100, 250, 500, 1000, 2500},
})
_metricReqErr = metric.NewCounterVec(&metric.CounterVecOpts{
Namespace: namespace,
Subsystem: "requests",
Name: "error_total",
Help: "memcache client requests error count.",
Labels: []string{"name", "addr", "command", "error"},
})
_metricConnTotal = metric.NewCounterVec(&metric.CounterVecOpts{
Namespace: namespace,
Subsystem: "connections",
Name: "total",
Help: "memcache client connections total count.",
Labels: []string{"name", "addr", "state"},
})
_metricConnCurrent = metric.NewGaugeVec(&metric.GaugeVecOpts{
Namespace: namespace,
Subsystem: "connections",
Name: "current",
Help: "memcache client connections current.",
Labels: []string{"name", "addr", "state"},
})
_metricHits = metric.NewCounterVec(&metric.CounterVecOpts{
Namespace: namespace,
Subsystem: "",
Name: "hits_total",
Help: "memcache client hits total.",
Labels: []string{"name", "addr"},
})
_metricMisses = metric.NewCounterVec(&metric.CounterVecOpts{
Namespace: namespace,
Subsystem: "",
Name: "misses_total",
Help: "memcache client misses total.",
Labels: []string{"name", "addr"},
})
)

@ -7,11 +7,8 @@ import (
"time"
"github.com/bilibili/kratos/pkg/container/pool"
"github.com/bilibili/kratos/pkg/stat"
)
var stats = stat.Cache
// Pool memcache connection pool struct.
// Deprecated: Use Memcache instead
type Pool struct {
@ -62,13 +59,15 @@ type poolConn struct {
ctx context.Context
}
func pstat(key string, t time.Time, err error) {
stats.Timing(key, int64(time.Since(t)/time.Millisecond))
func (pc *poolConn) pstat(key string, t time.Time, err error) {
_metricReqDur.Observe(int64(time.Since(t)/time.Millisecond), pc.p.c.Name, pc.p.c.Addr, key)
if err != nil {
if msg := formatErr(err); msg != "" {
stats.Incr("memcache", msg)
if msg := pc.formatErr(err); msg != "" {
_metricReqErr.Inc(pc.p.c.Name, pc.p.c.Addr, key, msg)
}
return
}
_metricHits.Inc(pc.p.c.Name, pc.p.c.Addr)
}
func (pc *poolConn) Close() error {
@ -132,28 +131,28 @@ func (pc *poolConn) Decrement(key string, delta uint64) (newValue uint64, err er
func (pc *poolConn) AddContext(ctx context.Context, item *Item) error {
now := time.Now()
err := pc.c.AddContext(ctx, item)
pstat("memcache:add", now, err)
pc.pstat("add", now, err)
return err
}
func (pc *poolConn) SetContext(ctx context.Context, item *Item) error {
now := time.Now()
err := pc.c.SetContext(ctx, item)
pstat("memcache:set", now, err)
pc.pstat("set", now, err)
return err
}
func (pc *poolConn) ReplaceContext(ctx context.Context, item *Item) error {
now := time.Now()
err := pc.c.ReplaceContext(ctx, item)
pstat("memcache:replace", now, err)
pc.pstat("replace", now, err)
return err
}
func (pc *poolConn) GetContext(ctx context.Context, key string) (*Item, error) {
now := time.Now()
item, err := pc.c.Get(key)
pstat("memcache:get", now, err)
pc.pstat("get", now, err)
return item, err
}
@ -164,41 +163,41 @@ func (pc *poolConn) GetMultiContext(ctx context.Context, keys []string) (map[str
}
now := time.Now()
items, err := pc.c.GetMulti(keys)
pstat("memcache:gets", now, err)
pc.pstat("gets", now, err)
return items, err
}
func (pc *poolConn) DeleteContext(ctx context.Context, key string) error {
now := time.Now()
err := pc.c.Delete(key)
pstat("memcache:delete", now, err)
pc.pstat("delete", now, err)
return err
}
func (pc *poolConn) IncrementContext(ctx context.Context, key string, delta uint64) (uint64, error) {
now := time.Now()
newValue, err := pc.c.IncrementContext(ctx, key, delta)
pstat("memcache:increment", now, err)
pc.pstat("increment", now, err)
return newValue, err
}
func (pc *poolConn) DecrementContext(ctx context.Context, key string, delta uint64) (uint64, error) {
now := time.Now()
newValue, err := pc.c.DecrementContext(ctx, key, delta)
pstat("memcache:decrement", now, err)
pc.pstat("decrement", now, err)
return newValue, err
}
func (pc *poolConn) CompareAndSwapContext(ctx context.Context, item *Item) error {
now := time.Now()
err := pc.c.CompareAndSwap(item)
pstat("memcache:cas", now, err)
pc.pstat("cas", now, err)
return err
}
func (pc *poolConn) TouchContext(ctx context.Context, key string, seconds int32) error {
now := time.Now()
err := pc.c.Touch(key, seconds)
pstat("memcache:touch", now, err)
pc.pstat("touch", now, err)
return err
}

@ -27,16 +27,11 @@ import (
"sync"
"time"
"github.com/bilibili/kratos/pkg/stat"
"github.com/pkg/errors"
)
var stats = stat.Cache
// conn is the low-level implementation of Conn
type conn struct {
// Shared
mu sync.Mutex
pending int
@ -57,20 +52,6 @@ type conn struct {
// Scratch space for formatting integers and floats.
numScratch [40]byte
// stat func,default prom
stat func(string, *error) func()
}
func statfunc(cmd string, err *error) func() {
now := time.Now()
return func() {
stats.Timing(fmt.Sprintf("redis:%s", cmd), int64(time.Since(now)/time.Millisecond))
if err != nil {
if msg := formatErr(*err); msg != "" {
stats.Incr("redis", msg)
}
}
}
}
// DialTimeout acts like Dial but takes timeouts for establishing the
@ -95,14 +76,6 @@ type dialOptions struct {
dial func(network, addr string) (net.Conn, error)
db int
password string
stat func(string, *error) func()
}
// DialStats specifies stat func for stats.default statfunc.
func DialStats(fn func(string, *error) func()) DialOption {
return DialOption{func(do *dialOptions) {
do.stat = fn
}}
}
// DialReadTimeout specifies the timeout for reading a single command reply.
@ -171,7 +144,6 @@ func Dial(network, address string, options ...DialOption) (Conn, error) {
br: bufio.NewReader(netConn),
readTimeout: do.readTimeout,
writeTimeout: do.writeTimeout,
stat: statfunc,
}
if do.password != "" {
@ -187,9 +159,6 @@ func Dial(network, address string, options ...DialOption) (Conn, error) {
return nil, errors.WithStack(err)
}
}
if do.stat != nil {
c.stat = do.stat
}
return c, nil
}
@ -551,7 +520,6 @@ func (c *conn) Do(cmd string, args ...interface{}) (interface{}, error) {
return nil, nil
}
var err error
defer c.stat(cmd, &err)()
if cmd != "" {
err = c.writeCommand(cmd, args)
}

@ -6,10 +6,13 @@ import (
pkgerr "github.com/pkg/errors"
)
func formatErr(err error) string {
func formatErr(err error, name, addr string) string {
e := pkgerr.Cause(err)
switch e {
case ErrNil, nil:
if e == ErrNil {
_metricMisses.Inc(name, addr)
}
return ""
default:
es := e.Error()

@ -0,0 +1,51 @@
package redis
import "github.com/bilibili/kratos/pkg/stat/metric"
const namespace = "redis_client"
var (
_metricReqDur = metric.NewHistogramVec(&metric.HistogramVecOpts{
Namespace: namespace,
Subsystem: "requests",
Name: "duration_ms",
Help: "redis client requests duration(ms).",
Labels: []string{"name", "addr", "command"},
Buckets: []float64{5, 10, 25, 50, 100, 250, 500, 1000, 2500},
})
_metricReqErr = metric.NewCounterVec(&metric.CounterVecOpts{
Namespace: namespace,
Subsystem: "requests",
Name: "error_total",
Help: "redis client requests error count.",
Labels: []string{"name", "addr", "command", "error"},
})
_metricConnTotal = metric.NewCounterVec(&metric.CounterVecOpts{
Namespace: namespace,
Subsystem: "connections",
Name: "total",
Help: "redis client connections total count.",
Labels: []string{"name", "addr", "state"},
})
_metricConnCurrent = metric.NewGaugeVec(&metric.GaugeVecOpts{
Namespace: namespace,
Subsystem: "connections",
Name: "current",
Help: "redis client connections current.",
Labels: []string{"name", "addr", "state"},
})
_metricHits = metric.NewCounterVec(&metric.CounterVecOpts{
Namespace: namespace,
Subsystem: "",
Name: "hits_total",
Help: "redis client hits total.",
Labels: []string{"name", "addr"},
})
_metricMisses = metric.NewCounterVec(&metric.CounterVecOpts{
Namespace: namespace,
Subsystem: "",
Name: "misses_total",
Help: "redis client misses total.",
Labels: []string{"name", "addr"},
})
)

@ -41,6 +41,8 @@ type Pool struct {
*pool.Slice
// config
c *Config
// statfunc
statfunc func(name, addr, cmd string, t time.Time, err error) func()
}
// Config client settings.
@ -76,7 +78,7 @@ func NewPool(c *Config, options ...DialOption) (p *Pool) {
}
return &traceConn{Conn: conn, connTags: []trace.Tag{trace.TagString(trace.TagPeerAddress, c.Addr)}}, nil
}
p = &Pool{Slice: p1, c: c}
p = &Pool{Slice: p1, c: c, statfunc: pstat}
return
}
@ -126,6 +128,24 @@ func initSentinel() {
}
}
// SetStatFunc set stat func.
func (p *Pool) SetStatFunc(fn func(name, addr, cmd string, t time.Time, err error) func()) {
p.statfunc = fn
}
func pstat(name, addr, cmd string, t time.Time, err error) func() {
return func() {
_metricReqDur.Observe(int64(time.Since(t)/time.Millisecond), name, addr, cmd)
if err != nil {
if msg := formatErr(err, name, addr); msg != "" {
_metricReqErr.Inc(name, addr, cmd, msg)
}
return
}
_metricHits.Inc(name, addr)
}
}
func (pc *pooledConnection) Close() error {
c := pc.c
if _, ok := c.(errorConnection); ok {
@ -169,9 +189,11 @@ func (pc *pooledConnection) Err() error {
}
func (pc *pooledConnection) Do(commandName string, args ...interface{}) (reply interface{}, err error) {
now := time.Now()
ci := LookupCommandInfo(commandName)
pc.state = (pc.state | ci.Set) &^ ci.Clear
reply, err = pc.c.Do(commandName, args...)
pc.p.statfunc(pc.p.c.Name, pc.p.c.Addr, commandName, now, err)()
return
}
@ -193,7 +215,9 @@ func (pc *pooledConnection) Flush() error {
func (pc *pooledConnection) Receive() (reply interface{}, err error) {
reply, err = pc.c.Receive()
if len(pc.cmds) > 0 {
cmd := pc.cmds[0]
pc.cmds = pc.cmds[1:]
pc.p.statfunc(pc.p.c.Name, pc.p.c.Addr, cmd, pc.now, err)()
}
return
}

@ -44,7 +44,7 @@ func (c *Client) invokeHook(ctx context.Context, call hrpc.Call, customName stri
func NewClient(config *Config, options ...gohbase.Option) *Client {
rawcli := NewRawClient(config, options...)
rawcli.AddHook(NewSlowLogHook(250 * time.Millisecond))
rawcli.AddHook(MetricsHook(nil))
rawcli.AddHook(MetricsHook(config))
rawcli.AddHook(TraceHook("database/hbase", strings.Join(config.Zookeeper.Addrs, ",")))
return rawcli
}

@ -3,12 +3,33 @@ package hbase
import (
"context"
"io"
"strings"
"time"
"github.com/tsuna/gohbase"
"github.com/tsuna/gohbase/hrpc"
"github.com/bilibili/kratos/pkg/stat"
"github.com/bilibili/kratos/pkg/stat/metric"
)
const namespace = "hbase_client"
var (
_metricReqDur = metric.NewHistogramVec(&metric.HistogramVecOpts{
Namespace: namespace,
Subsystem: "requests",
Name: "duration_ms",
Help: "hbase client requests duration(ms).",
Labels: []string{"name", "addr", "command"},
Buckets: []float64{5, 10, 25, 50, 100, 250, 500, 1000, 2500},
})
_metricReqErr = metric.NewCounterVec(&metric.CounterVecOpts{
Namespace: namespace,
Subsystem: "requests",
Name: "error_total",
Help: "mysql client requests error count.",
Labels: []string{"name", "addr", "command", "error"},
})
)
func codeFromErr(err error) string {
@ -27,21 +48,17 @@ func codeFromErr(err error) string {
}
// MetricsHook if stats is nil use stat.DB as default.
func MetricsHook(stats stat.Stat) HookFunc {
if stats == nil {
stats = stat.DB
}
func MetricsHook(config *Config) HookFunc {
return func(ctx context.Context, call hrpc.Call, customName string) func(err error) {
now := time.Now()
if customName == "" {
customName = call.Name()
}
method := "hbase:" + customName
return func(err error) {
durationMs := int64(time.Since(now) / time.Millisecond)
stats.Timing(method, durationMs)
_metricReqDur.Observe(durationMs, strings.Join(config.Zookeeper.Addrs, ","), "", customName)
if err != nil && err != io.EOF {
stats.Incr(method, codeFromErr(err))
_metricReqErr.Inc(strings.Join(config.Zookeeper.Addrs, ","), "", customName, codeFromErr(err))
}
}
}

@ -0,0 +1,37 @@
package sql
import "github.com/bilibili/kratos/pkg/stat/metric"
const namespace = "mysql_client"
var (
_metricReqDur = metric.NewHistogramVec(&metric.HistogramVecOpts{
Namespace: namespace,
Subsystem: "requests",
Name: "duration_ms",
Help: "mysql client requests duration(ms).",
Labels: []string{"name", "addr", "command"},
Buckets: []float64{5, 10, 25, 50, 100, 250, 500, 1000, 2500},
})
_metricReqErr = metric.NewCounterVec(&metric.CounterVecOpts{
Namespace: namespace,
Subsystem: "requests",
Name: "error_total",
Help: "mysql client requests error count.",
Labels: []string{"name", "addr", "command", "error"},
})
_metricConnTotal = metric.NewCounterVec(&metric.CounterVecOpts{
Namespace: namespace,
Subsystem: "connections",
Name: "total",
Help: "mysql client connections total count.",
Labels: []string{"name", "addr", "state"},
})
_metricConnCurrent = metric.NewGaugeVec(&metric.GaugeVecOpts{
Namespace: namespace,
Subsystem: "connections",
Name: "current",
Help: "mysql client connections current.",
Labels: []string{"name", "addr", "state"},
})
)

@ -3,15 +3,12 @@ package sql
import (
"github.com/bilibili/kratos/pkg/log"
"github.com/bilibili/kratos/pkg/net/netutil/breaker"
"github.com/bilibili/kratos/pkg/stat"
"github.com/bilibili/kratos/pkg/time"
// database driver
_ "github.com/go-sql-driver/mysql"
)
var stats = stat.DB
// Config mysql config.
type Config struct {
Addr string // for trace

@ -279,12 +279,12 @@ func (db *conn) begin(c context.Context) (tx *Tx, err error) {
}()
}
if err = db.breaker.Allow(); err != nil {
stats.Incr("mysql:begin", "breaker")
_metricReqErr.Inc(db.conf.Addr, db.conf.Addr, "begin", "breaker")
return
}
_, c, cancel := db.conf.TranTimeout.Shrink(c)
rtx, err := db.BeginTx(c, nil)
stats.Timing("mysql:begin", int64(time.Since(now)/time.Millisecond))
_metricReqDur.Observe(int64(time.Since(now)/time.Millisecond), db.conf.Addr, db.conf.Addr, "begin")
if err != nil {
err = errors.WithStack(err)
cancel()
@ -303,14 +303,14 @@ func (db *conn) exec(c context.Context, query string, args ...interface{}) (res
defer t.Finish(&err)
}
if err = db.breaker.Allow(); err != nil {
stats.Incr("mysql:exec", "breaker")
_metricReqErr.Inc(db.conf.Addr, db.conf.Addr, "exec", "breaker")
return
}
_, c, cancel := db.conf.ExecTimeout.Shrink(c)
res, err = db.ExecContext(c, query, args...)
cancel()
db.onBreaker(&err)
stats.Timing("mysql:exec", int64(time.Since(now)/time.Millisecond))
_metricReqDur.Observe(int64(time.Since(now)/time.Millisecond), db.conf.Addr, db.conf.Addr, "exec")
if err != nil {
err = errors.Wrapf(err, "exec:%s, args:%+v", query, args)
}
@ -326,14 +326,14 @@ func (db *conn) ping(c context.Context) (err error) {
defer t.Finish(&err)
}
if err = db.breaker.Allow(); err != nil {
stats.Incr("mysql:ping", "breaker")
_metricReqErr.Inc(db.conf.Addr, db.conf.Addr, "ping", "breaker")
return
}
_, c, cancel := db.conf.ExecTimeout.Shrink(c)
err = db.PingContext(c)
cancel()
db.onBreaker(&err)
stats.Timing("mysql:ping", int64(time.Since(now)/time.Millisecond))
_metricReqDur.Observe(int64(time.Since(now)/time.Millisecond), db.conf.Addr, db.conf.Addr, "ping")
if err != nil {
err = errors.WithStack(err)
}
@ -383,13 +383,13 @@ func (db *conn) query(c context.Context, query string, args ...interface{}) (row
defer t.Finish(&err)
}
if err = db.breaker.Allow(); err != nil {
stats.Incr("mysql:query", "breaker")
_metricReqErr.Inc(db.conf.Addr, db.conf.Addr, "query", "breaker")
return
}
_, c, cancel := db.conf.QueryTimeout.Shrink(c)
rs, err := db.DB.QueryContext(c, query, args...)
db.onBreaker(&err)
stats.Timing("mysql:query", int64(time.Since(now)/time.Millisecond))
_metricReqDur.Observe(int64(time.Since(now)/time.Millisecond), db.conf.Addr, db.conf.Addr, "query")
if err != nil {
err = errors.Wrapf(err, "query:%s, args:%+v", query, args)
cancel()
@ -408,12 +408,12 @@ func (db *conn) queryRow(c context.Context, query string, args ...interface{}) *
t.SetTag(trace.String(trace.TagAddress, db.conf.Addr), trace.String(trace.TagComment, query))
}
if err := db.breaker.Allow(); err != nil {
stats.Incr("mysql:queryrow", "breaker")
_metricReqErr.Inc(db.conf.Addr, db.conf.Addr, "queryRow", "breaker")
return &Row{db: db, t: t, err: err}
}
_, c, cancel := db.conf.QueryTimeout.Shrink(c)
r := db.DB.QueryRowContext(c, query, args...)
stats.Timing("mysql:queryrow", int64(time.Since(now)/time.Millisecond))
_metricReqDur.Observe(int64(time.Since(now)/time.Millisecond), db.conf.Addr, db.conf.Addr, "queryrow")
return &Row{db: db, Row: r, query: query, args: args, t: t, cancel: cancel}
}
@ -449,7 +449,7 @@ func (s *Stmt) Exec(c context.Context, args ...interface{}) (res sql.Result, err
defer t.Finish(&err)
}
if err = s.db.breaker.Allow(); err != nil {
stats.Incr("mysql:stmt:exec", "breaker")
_metricReqErr.Inc(s.db.conf.Addr, s.db.conf.Addr, "stmt:exec", "breaker")
return
}
stmt, ok := s.stmt.Load().(*sql.Stmt)
@ -461,7 +461,7 @@ func (s *Stmt) Exec(c context.Context, args ...interface{}) (res sql.Result, err
res, err = stmt.ExecContext(c, args...)
cancel()
s.db.onBreaker(&err)
stats.Timing("mysql:stmt:exec", int64(time.Since(now)/time.Millisecond))
_metricReqDur.Observe(int64(time.Since(now)/time.Millisecond), s.db.conf.Addr, s.db.conf.Addr, "stmt:exec")
if err != nil {
err = errors.Wrapf(err, "exec:%s, args:%+v", s.query, args)
}
@ -487,7 +487,7 @@ func (s *Stmt) Query(c context.Context, args ...interface{}) (rows *Rows, err er
defer t.Finish(&err)
}
if err = s.db.breaker.Allow(); err != nil {
stats.Incr("mysql:stmt:query", "breaker")
_metricReqErr.Inc(s.db.conf.Addr, s.db.conf.Addr, "stmt:query", "breaker")
return
}
stmt, ok := s.stmt.Load().(*sql.Stmt)
@ -498,7 +498,7 @@ func (s *Stmt) Query(c context.Context, args ...interface{}) (rows *Rows, err er
_, c, cancel := s.db.conf.QueryTimeout.Shrink(c)
rs, err := stmt.QueryContext(c, args...)
s.db.onBreaker(&err)
stats.Timing("mysql:stmt:query", int64(time.Since(now)/time.Millisecond))
_metricReqDur.Observe(int64(time.Since(now)/time.Millisecond), s.db.conf.Addr, s.db.conf.Addr, "stmt:query")
if err != nil {
err = errors.Wrapf(err, "query:%s, args:%+v", s.query, args)
cancel()
@ -531,7 +531,7 @@ func (s *Stmt) QueryRow(c context.Context, args ...interface{}) (row *Row) {
row.t = t
}
if row.err = s.db.breaker.Allow(); row.err != nil {
stats.Incr("mysql:stmt:queryrow", "breaker")
_metricReqErr.Inc(s.db.conf.Addr, s.db.conf.Addr, "stmt:queryrow", "breaker")
return
}
stmt, ok := s.stmt.Load().(*sql.Stmt)
@ -541,7 +541,7 @@ func (s *Stmt) QueryRow(c context.Context, args ...interface{}) (row *Row) {
_, c, cancel := s.db.conf.QueryTimeout.Shrink(c)
row.Row = stmt.QueryRowContext(c, args...)
row.cancel = cancel
stats.Timing("mysql:stmt:queryrow", int64(time.Since(now)/time.Millisecond))
_metricReqDur.Observe(int64(time.Since(now)/time.Millisecond), s.db.conf.Addr, s.db.conf.Addr, "stmt:queryrow")
return
}
@ -582,7 +582,7 @@ func (tx *Tx) Exec(query string, args ...interface{}) (res sql.Result, err error
tx.t.SetTag(trace.String(trace.TagAnnotation, fmt.Sprintf("exec %s", query)))
}
res, err = tx.tx.ExecContext(tx.c, query, args...)
stats.Timing("mysql:tx:exec", int64(time.Since(now)/time.Millisecond))
_metricReqDur.Observe(int64(time.Since(now)/time.Millisecond), tx.db.conf.Addr, tx.db.conf.Addr, "tx:exec")
if err != nil {
err = errors.Wrapf(err, "exec:%s, args:%+v", query, args)
}
@ -597,7 +597,7 @@ func (tx *Tx) Query(query string, args ...interface{}) (rows *Rows, err error) {
now := time.Now()
defer slowLog(fmt.Sprintf("Query query(%s) args(%+v)", query, args), now)
defer func() {
stats.Timing("mysql:tx:query", int64(time.Since(now)/time.Millisecond))
_metricReqDur.Observe(int64(time.Since(now)/time.Millisecond), tx.db.conf.Addr, tx.db.conf.Addr, "tx:query")
}()
rs, err := tx.tx.QueryContext(tx.c, query, args...)
if err == nil {
@ -618,7 +618,7 @@ func (tx *Tx) QueryRow(query string, args ...interface{}) *Row {
now := time.Now()
defer slowLog(fmt.Sprintf("QueryRow query(%s) args(%+v)", query, args), now)
defer func() {
stats.Timing("mysql:tx:queryrow", int64(time.Since(now)/time.Millisecond))
_metricReqDur.Observe(int64(time.Since(now)/time.Millisecond), tx.db.conf.Addr, tx.db.conf.Addr, "tx:queryrow")
}()
r := tx.tx.QueryRowContext(tx.c, query, args...)
return &Row{Row: r, db: tx.db, query: query, args: args}

@ -0,0 +1,37 @@
package tidb
import "github.com/bilibili/kratos/pkg/stat/metric"
const namespace = "tidb_client"
var (
_metricReqDur = metric.NewHistogramVec(&metric.HistogramVecOpts{
Namespace: namespace,
Subsystem: "requests",
Name: "duration_ms",
Help: "tidb client requests duration(ms).",
Labels: []string{"name", "addr", "command"},
Buckets: []float64{5, 10, 25, 50, 100, 250, 500, 1000, 2500},
})
_metricReqErr = metric.NewCounterVec(&metric.CounterVecOpts{
Namespace: namespace,
Subsystem: "requests",
Name: "error_total",
Help: "tidb client requests error count.",
Labels: []string{"name", "addr", "command", "error"},
})
_metricConnTotal = metric.NewCounterVec(&metric.CounterVecOpts{
Namespace: namespace,
Subsystem: "connections",
Name: "total",
Help: "tidb client connections total count.",
Labels: []string{"name", "addr", "state"},
})
_metricConnCurrent = metric.NewGaugeVec(&metric.GaugeVecOpts{
Namespace: namespace,
Subsystem: "connections",
Name: "current",
Help: "tidb client connections current.",
Labels: []string{"name", "addr", "state"},
})
)

@ -291,12 +291,12 @@ func (db *conn) begin(c context.Context) (tx *Tx, err error) {
}()
}
if err = db.breaker.Allow(); err != nil {
stats.Incr("tidb:begin", "breaker")
_metricReqErr.Inc(db.addr, db.addr, "begin", "breaker")
return
}
_, c, cancel := db.conf.TranTimeout.Shrink(c)
rtx, err := db.BeginTx(c, nil)
stats.Timing("tidb:begin", int64(time.Since(now)/time.Millisecond))
_metricReqDur.Observe(int64(time.Since(now)/time.Millisecond), db.addr, db.addr, "begin")
if err != nil {
err = errors.WithStack(err)
cancel()
@ -315,14 +315,14 @@ func (db *conn) exec(c context.Context, query string, args ...interface{}) (res
defer t.Finish(&err)
}
if err = db.breaker.Allow(); err != nil {
stats.Incr("tidb:exec", "breaker")
_metricReqErr.Inc(db.addr, db.addr, "exec", "breaker")
return
}
_, c, cancel := db.conf.ExecTimeout.Shrink(c)
res, err = db.ExecContext(c, query, args...)
cancel()
db.onBreaker(&err)
stats.Timing("tidb:exec", int64(time.Since(now)/time.Millisecond))
_metricReqDur.Observe(int64(time.Since(now)/time.Millisecond), db.addr, db.addr, "exec")
if err != nil {
err = errors.Wrapf(err, "addr: %s exec:%s, args:%+v", db.addr, query, args)
}
@ -338,14 +338,14 @@ func (db *conn) ping(c context.Context) (err error) {
defer t.Finish(&err)
}
if err = db.breaker.Allow(); err != nil {
stats.Incr("tidb:ping", "breaker")
_metricReqErr.Inc(db.addr, db.addr, "ping", "breaker")
return
}
_, c, cancel := db.conf.ExecTimeout.Shrink(c)
err = db.PingContext(c)
cancel()
db.onBreaker(&err)
stats.Timing("tidb:ping", int64(time.Since(now)/time.Millisecond))
_metricReqDur.Observe(int64(time.Since(now)/time.Millisecond), db.addr, db.addr, "ping")
if err != nil {
err = errors.WithStack(err)
}
@ -384,13 +384,13 @@ func (db *conn) query(c context.Context, query string, args ...interface{}) (row
defer t.Finish(&err)
}
if err = db.breaker.Allow(); err != nil {
stats.Incr("tidb:query", "breaker")
_metricReqErr.Inc(db.addr, db.addr, "query", "breaker")
return
}
_, c, cancel := db.conf.QueryTimeout.Shrink(c)
rs, err := db.DB.QueryContext(c, query, args...)
db.onBreaker(&err)
stats.Timing("tidb:query", int64(time.Since(now)/time.Millisecond))
_metricReqDur.Observe(int64(time.Since(now)/time.Millisecond), db.addr, db.addr, "query")
if err != nil {
err = errors.Wrapf(err, "addr: %s, query:%s, args:%+v", db.addr, query, args)
cancel()
@ -409,12 +409,12 @@ func (db *conn) queryRow(c context.Context, query string, args ...interface{}) *
t.SetTag(trace.String(trace.TagAddress, db.addr), trace.String(trace.TagComment, query))
}
if err := db.breaker.Allow(); err != nil {
stats.Incr("tidb:queryrow", "breaker")
_metricReqErr.Inc(db.addr, db.addr, "queryrow", "breaker")
return &Row{db: db, t: t, err: err}
}
_, c, cancel := db.conf.QueryTimeout.Shrink(c)
r := db.DB.QueryRowContext(c, query, args...)
stats.Timing("tidb:queryrow", int64(time.Since(now)/time.Millisecond))
_metricReqDur.Observe(int64(time.Since(now)/time.Millisecond), db.addr, db.addr, "queryrow")
return &Row{db: db, Row: r, query: query, args: args, t: t, cancel: cancel}
}
@ -454,7 +454,7 @@ func (s *Stmt) Exec(c context.Context, args ...interface{}) (res sql.Result, err
defer t.Finish(&err)
}
if err = s.db.breaker.Allow(); err != nil {
stats.Incr("tidb:stmt:exec", "breaker")
_metricReqErr.Inc(s.db.addr, s.db.addr, "stmt:exec", "breaker")
return
}
stmt := s.prepare()
@ -466,7 +466,7 @@ func (s *Stmt) Exec(c context.Context, args ...interface{}) (res sql.Result, err
res, err = stmt.ExecContext(c, args...)
cancel()
s.db.onBreaker(&err)
stats.Timing("tidb:stmt:exec", int64(time.Since(now)/time.Millisecond))
_metricReqDur.Observe(int64(time.Since(now)/time.Millisecond), s.db.addr, s.db.addr, "stmt:exec")
if err != nil {
err = errors.Wrapf(err, "addr: %s exec:%s, args:%+v", s.db.addr, s.query, args)
}
@ -488,7 +488,7 @@ func (s *Stmt) Query(c context.Context, args ...interface{}) (rows *Rows, err er
defer t.Finish(&err)
}
if err = s.db.breaker.Allow(); err != nil {
stats.Incr("tidb:stmt:query", "breaker")
_metricReqErr.Inc(s.db.addr, s.db.addr, "stmt:query", "breaker")
return
}
stmt := s.prepare()
@ -499,7 +499,7 @@ func (s *Stmt) Query(c context.Context, args ...interface{}) (rows *Rows, err er
_, c, cancel := s.db.conf.QueryTimeout.Shrink(c)
rs, err := stmt.QueryContext(c, args...)
s.db.onBreaker(&err)
stats.Timing("tidb:stmt:query", int64(time.Since(now)/time.Millisecond))
_metricReqDur.Observe(int64(time.Since(now)/time.Millisecond), s.db.addr, s.db.addr, "stmt:query")
if err != nil {
err = errors.Wrapf(err, "addr: %s, query:%s, args:%+v", s.db.addr, s.query, args)
cancel()
@ -528,7 +528,7 @@ func (s *Stmt) QueryRow(c context.Context, args ...interface{}) (row *Row) {
row.t = t
}
if row.err = s.db.breaker.Allow(); row.err != nil {
stats.Incr("tidb:stmt:queryrow", "breaker")
_metricReqErr.Inc(s.db.addr, s.db.addr, "stmt:queryrow", "breaker")
return
}
stmt := s.prepare()
@ -538,7 +538,7 @@ func (s *Stmt) QueryRow(c context.Context, args ...interface{}) (row *Row) {
_, c, cancel := s.db.conf.QueryTimeout.Shrink(c)
row.Row = stmt.QueryRowContext(c, args...)
row.cancel = cancel
stats.Timing("tidb:stmt:queryrow", int64(time.Since(now)/time.Millisecond))
_metricReqDur.Observe(int64(time.Since(now)/time.Millisecond), s.db.addr, s.db.addr, "stmt:queryrow")
return
}
@ -626,7 +626,7 @@ func (tx *Tx) Exec(query string, args ...interface{}) (res sql.Result, err error
tx.t.SetTag(trace.String(trace.TagAnnotation, fmt.Sprintf("exec %s", query)))
}
res, err = tx.tx.ExecContext(tx.c, query, args...)
stats.Timing("tidb:tx:exec", int64(time.Since(now)/time.Millisecond))
_metricReqDur.Observe(int64(time.Since(now)/time.Millisecond), tx.db.addr, tx.db.addr, "tx:exec")
if err != nil {
err = errors.Wrapf(err, "addr: %s exec:%s, args:%+v", tx.db.addr, query, args)
}
@ -641,7 +641,7 @@ func (tx *Tx) Query(query string, args ...interface{}) (rows *Rows, err error) {
now := time.Now()
defer slowLog(fmt.Sprintf("Query addr: %s query(%s) args(%+v)", tx.db.addr, query, args), now)
defer func() {
stats.Timing("tidb:tx:query", int64(time.Since(now)/time.Millisecond))
_metricReqDur.Observe(int64(time.Since(now)/time.Millisecond), tx.db.addr, tx.db.addr, "tx:query")
}()
rs, err := tx.tx.QueryContext(tx.c, query, args...)
if err == nil {
@ -662,7 +662,7 @@ func (tx *Tx) QueryRow(query string, args ...interface{}) *Row {
now := time.Now()
defer slowLog(fmt.Sprintf("QueryRow addr: %s query(%s) args(%+v)", tx.db.addr, query, args), now)
defer func() {
stats.Timing("tidb:tx:queryrow", int64(time.Since(now)/time.Millisecond))
_metricReqDur.Observe(int64(time.Since(now)/time.Millisecond), tx.db.addr, tx.db.addr, "tx:queryrow")
}()
r := tx.tx.QueryRowContext(tx.c, query, args...)
return &Row{Row: r, db: tx.db, query: query, args: args}

@ -3,15 +3,12 @@ package tidb
import (
"github.com/bilibili/kratos/pkg/log"
"github.com/bilibili/kratos/pkg/net/netutil/breaker"
"github.com/bilibili/kratos/pkg/stat"
"github.com/bilibili/kratos/pkg/time"
// database driver
_ "github.com/go-sql-driver/mysql"
)
var stats = stat.DB
// Config mysql config.
type Config struct {
DSN string // dsn

@ -9,7 +9,7 @@ import (
"strconv"
"github.com/bilibili/kratos/pkg/conf/env"
"github.com/bilibili/kratos/pkg/stat/prom"
"github.com/bilibili/kratos/pkg/stat/metric"
)
// Config log config.
@ -44,8 +44,10 @@ type Config struct {
Filter []string
}
// errProm prometheus error counter.
var errProm = prom.BusinessErrCount
// metricErrCount prometheus error counter.
var (
metricErrCount = metric.NewBusinessMetricCount("log_error_total", "source")
)
// Render render log output
type Render interface {
@ -238,6 +240,6 @@ func Close() (err error) {
func errIncr(lv Level, source string) {
if lv == _errorLevel {
errProm.Incr(source)
metricErrCount.Inc(source)
}
}

@ -20,7 +20,6 @@ import (
"github.com/bilibili/kratos/pkg/conf/env"
"github.com/bilibili/kratos/pkg/net/metadata"
"github.com/bilibili/kratos/pkg/net/netutil/breaker"
"github.com/bilibili/kratos/pkg/stat"
xtime "github.com/bilibili/kratos/pkg/time"
"github.com/gogo/protobuf/proto"
@ -33,7 +32,6 @@ const (
var (
_noKickUserAgent = "blademaster"
clientStats = stat.HTTPClient
)
func init() {
@ -215,16 +213,16 @@ func (client *Client) Raw(c context.Context, req *xhttp.Request, v ...string) (b
brk := client.breaker.Get(uri)
if err = brk.Allow(); err != nil {
code = "breaker"
clientStats.Incr(uri, code)
_metricClientReqCodeTotal.Inc(uri, code)
return
}
defer client.onBreaker(brk, &err)
// stat
now := time.Now()
defer func() {
clientStats.Timing(uri, int64(time.Since(now)/time.Millisecond))
_metricClientReqDur.Observe(int64(time.Since(now)/time.Millisecond), uri)
if code != "" {
clientStats.Incr(uri, code)
_metricClientReqCodeTotal.Inc(uri, code)
}
}()
// get config

@ -34,8 +34,8 @@ func Logger() HandlerFunc {
caller = noUser
}
stats.Incr(caller, path[1:], strconv.FormatInt(int64(cerr.Code()), 10))
stats.Timing(caller, int64(dt/time.Millisecond), path[1:])
_metricServerReqCodeTotal.Inc(c.RoutePath[1:], caller, strconv.FormatInt(int64(cerr.Code()), 10))
_metricServerReqDur.Observe(int64(dt/time.Millisecond), c.RoutePath[1:], caller)
lf := log.Infov
errmsg := ""

@ -0,0 +1,48 @@
package blademaster
import "github.com/bilibili/kratos/pkg/stat/metric"
const (
clientNamespace = "http_client"
serverNamespace = "http_server"
)
var (
_metricServerReqDur = metric.NewHistogramVec(&metric.HistogramVecOpts{
Namespace: serverNamespace,
Subsystem: "requests",
Name: "duration_ms",
Help: "http server requests duration(ms).",
Labels: []string{"path", "caller"},
Buckets: []float64{5, 10, 25, 50, 100, 250, 500, 1000},
})
_metricServerReqCodeTotal = metric.NewCounterVec(&metric.CounterVecOpts{
Namespace: serverNamespace,
Subsystem: "requests",
Name: "code_total",
Help: "http server requests error count.",
Labels: []string{"path", "caller", "code"},
})
_metricServerBBR = metric.NewCounterVec(&metric.CounterVecOpts{
Namespace: serverNamespace,
Subsystem: "",
Name: "bbr_total",
Help: "http server bbr total.",
Labels: []string{"url"},
})
_metricClientReqDur = metric.NewHistogramVec(&metric.HistogramVecOpts{
Namespace: clientNamespace,
Subsystem: "requests",
Name: "duration_ms",
Help: "http client requests duration(ms).",
Labels: []string{"path"},
Buckets: []float64{5, 10, 25, 50, 100, 250, 500, 1000},
})
_metricClientReqCodeTotal = metric.NewCounterVec(&metric.CounterVecOpts{
Namespace: clientNamespace,
Subsystem: "requests",
Name: "code_total",
Help: "http client requests code count.",
Labels: []string{"path", "code"},
})
)

@ -8,15 +8,6 @@ import (
"github.com/bilibili/kratos/pkg/log"
limit "github.com/bilibili/kratos/pkg/ratelimit"
"github.com/bilibili/kratos/pkg/ratelimit/bbr"
"github.com/bilibili/kratos/pkg/stat/prom"
)
const (
_statName = "go_http_bbr"
)
var (
bbrStats = prom.New().WithState("go_http_bbr", []string{"url"})
)
// RateLimiter bbr middleware.
@ -48,7 +39,7 @@ func (b *RateLimiter) Limit() HandlerFunc {
limiter := b.group.Get(uri)
done, err := limiter.Allow(c)
if err != nil {
bbrStats.Incr(_statName, uri)
_metricServerBBR.Inc(uri)
c.JSON(nil, err)
c.Abort()
return

@ -18,7 +18,6 @@ import (
"github.com/bilibili/kratos/pkg/net/criticality"
"github.com/bilibili/kratos/pkg/net/ip"
"github.com/bilibili/kratos/pkg/net/metadata"
"github.com/bilibili/kratos/pkg/stat"
xtime "github.com/bilibili/kratos/pkg/time"
"github.com/pkg/errors"
@ -29,13 +28,11 @@ const (
)
var (
_ IRouter = &Engine{}
stats = stat.HTTPServer
_ IRouter = &Engine{}
_httpDSN string
default405Body = []byte("405 method not allowed")
default404Body = []byte("404 page not found")
)
func init() {
@ -155,7 +152,6 @@ type Engine struct {
allNoMethod []HandlerFunc
noRoute []HandlerFunc
noMethod []HandlerFunc
}
type injection struct {

@ -116,7 +116,7 @@ func (c *Client) handle() grpc.UnaryClientInterceptor {
c.mutex.RUnlock()
brk := c.breaker.Get(method)
if err = brk.Allow(); err != nil {
statsClient.Incr(method, "breaker")
_metricClientReqCodeTotal.Inc(method, "breaker")
return
}
defer onBreaker(brk, &err)

@ -12,12 +12,6 @@ import (
"github.com/bilibili/kratos/pkg/ecode"
"github.com/bilibili/kratos/pkg/log"
"github.com/bilibili/kratos/pkg/net/metadata"
"github.com/bilibili/kratos/pkg/stat"
)
var (
statsClient = stat.RPCClient
statsServer = stat.RPCServer
)
// Warden Log Flag
@ -94,8 +88,8 @@ func clientLogging(dialOptions ...grpc.DialOption) grpc.UnaryClientInterceptor {
code := ecode.Cause(err).Code()
duration := time.Since(startTime)
// monitor
statsClient.Timing(method, int64(duration/time.Millisecond))
statsClient.Incr(method, strconv.Itoa(code))
_metricClientReqDur.Observe(int64(duration/time.Millisecond), method)
_metricClientReqCodeTotal.Inc(method, strconv.Itoa(code))
if logFlag&LogFlagDisable != 0 {
return err
@ -148,8 +142,8 @@ func serverLogging(logFlag int8) grpc.UnaryServerInterceptor {
code := ecode.Cause(err).Code()
duration := time.Since(startTime)
// monitor
statsServer.Timing(caller, int64(duration/time.Millisecond), info.FullMethod)
statsServer.Incr(caller, info.FullMethod, strconv.Itoa(code))
_metricServerReqDur.Observe(int64(duration/time.Millisecond), info.FullMethod, caller)
_metricServerReqCodeTotal.Inc(info.FullMethod, caller, strconv.Itoa(code))
if logFlag&LogFlagDisable != 0 {
return resp, err

@ -0,0 +1,41 @@
package warden
import "github.com/bilibili/kratos/pkg/stat/metric"
const (
clientNamespace = "grpc_client"
serverNamespace = "grpc_server"
)
var (
_metricServerReqDur = metric.NewHistogramVec(&metric.HistogramVecOpts{
Namespace: serverNamespace,
Subsystem: "requests",
Name: "duration_ms",
Help: "grpc server requests duration(ms).",
Labels: []string{"method", "caller"},
Buckets: []float64{5, 10, 25, 50, 100, 250, 500, 1000},
})
_metricServerReqCodeTotal = metric.NewCounterVec(&metric.CounterVecOpts{
Namespace: serverNamespace,
Subsystem: "requests",
Name: "code_total",
Help: "grpc server requests code count.",
Labels: []string{"method", "caller", "code"},
})
_metricClientReqDur = metric.NewHistogramVec(&metric.HistogramVecOpts{
Namespace: clientNamespace,
Subsystem: "requests",
Name: "duration_ms",
Help: "grpc client requests duration(ms).",
Labels: []string{"method"},
Buckets: []float64{5, 10, 25, 50, 100, 250, 500, 1000},
})
_metricClientReqCodeTotal = metric.NewCounterVec(&metric.CounterVecOpts{
Namespace: clientNamespace,
Subsystem: "requests",
Name: "code_total",
Help: "grpc client requests code count.",
Labels: []string{"method", "code"},
})
)

@ -8,17 +8,18 @@ import (
"github.com/bilibili/kratos/pkg/log"
limit "github.com/bilibili/kratos/pkg/ratelimit"
"github.com/bilibili/kratos/pkg/ratelimit/bbr"
"github.com/bilibili/kratos/pkg/stat/prom"
"github.com/bilibili/kratos/pkg/stat/metric"
"google.golang.org/grpc"
)
const (
_statName = "go_grpc_bbr"
)
var (
stats = prom.New().WithState("go_grpc_bbr", []string{"url"})
_metricServerBBR = metric.NewCounterVec(&metric.CounterVecOpts{
Namespace: "grpc_server",
Subsystem: "",
Name: "bbr_total",
Help: "grpc server bbr total.",
Labels: []string{"url"},
})
)
// RateLimiter bbr middleware.
@ -50,7 +51,7 @@ func (b *RateLimiter) Limit() grpc.UnaryServerInterceptor {
limiter := b.group.Get(uri)
done, err := limiter.Allow(ctx)
if err != nil {
stats.Incr(_statName, uri)
_metricServerBBR.Inc(uri)
return
}
defer func() {

@ -3,6 +3,8 @@ package metric
import (
"fmt"
"sync/atomic"
"github.com/prometheus/client_golang/prometheus"
)
var _ Metric = &counter{}
@ -34,3 +36,49 @@ func (c *counter) Add(val int64) {
func (c *counter) Value() int64 {
return atomic.LoadInt64(&c.val)
}
// CounterVecOpts is an alias of VectorOpts.
type CounterVecOpts VectorOpts
// CounterVec counter vec.
type CounterVec interface {
// Inc increments the counter by 1. Use Add to increment it by arbitrary
// non-negative values.
Inc(labels ...string)
// Add adds the given value to the counter. It panics if the value is <
// 0.
Add(v float64, labels ...string)
}
// counterVec counter vec.
type promCounterVec struct {
counter *prometheus.CounterVec
}
// NewCounterVec .
func NewCounterVec(cfg *CounterVecOpts) CounterVec {
if cfg == nil {
return nil
}
vec := prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: cfg.Namespace,
Subsystem: cfg.Subsystem,
Name: cfg.Name,
Help: cfg.Help,
}, cfg.Labels)
prometheus.MustRegister(vec)
return &promCounterVec{
counter: vec,
}
}
// Inc Inc increments the counter by 1. Use Add to increment it by arbitrary.
func (counter *promCounterVec) Inc(labels ...string) {
counter.counter.WithLabelValues(labels...).Inc()
}
// Add Inc increments the counter by 1. Use Add to increment it by arbitrary.
func (counter *promCounterVec) Add(v float64, labels ...string) {
counter.counter.WithLabelValues(labels...).Add(v)
}

@ -16,3 +16,32 @@ func TestCounter(t *testing.T) {
val := counter.Value()
assert.Equal(t, val, int64(count))
}
func TestCounterVec(t *testing.T) {
counterVec := NewCounterVec(&CounterVecOpts{
Namespace: "test",
Subsystem: "test",
Name: "test",
Help: "this is test metrics.",
Labels: []string{"name", "addr"},
})
counterVec.Inc("name1", "127.0.0.1")
assert.Panics(t, func() {
NewCounterVec(&CounterVecOpts{
Namespace: "test",
Subsystem: "test",
Name: "test",
Help: "this is test metrics.",
Labels: []string{"name", "addr"},
})
}, "Expected to panic.")
assert.NotPanics(t, func() {
NewCounterVec(&CounterVecOpts{
Namespace: "test",
Subsystem: "test",
Name: "test2",
Help: "this is test metrics.",
Labels: []string{"name", "addr"},
})
}, "Expected normal. no panic.")
}

@ -1,6 +1,10 @@
package metric
import "sync/atomic"
import (
"sync/atomic"
"github.com/prometheus/client_golang/prometheus"
)
var _ Metric = &gauge{}
@ -35,3 +39,56 @@ func (g *gauge) Set(val int64) {
func (g *gauge) Value() int64 {
return atomic.LoadInt64(&g.val)
}
// GaugeVecOpts is an alias of VectorOpts.
type GaugeVecOpts VectorOpts
// GaugeVec gauge vec.
type GaugeVec interface {
// Set sets the Gauge to an arbitrary value.
Set(v float64, labels ...string)
// Inc increments the Gauge by 1. Use Add to increment it by arbitrary
// values.
Inc(labels ...string)
// Add adds the given value to the Gauge. (The value can be negative,
// resulting in a decrease of the Gauge.)
Add(v float64, labels ...string)
}
// gaugeVec gauge vec.
type promGaugeVec struct {
gauge *prometheus.GaugeVec
}
// NewGaugeVec .
func NewGaugeVec(cfg *GaugeVecOpts) GaugeVec {
if cfg == nil {
return nil
}
vec := prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Namespace: cfg.Namespace,
Subsystem: cfg.Subsystem,
Name: cfg.Name,
Help: cfg.Help,
}, cfg.Labels)
prometheus.MustRegister(vec)
return &promGaugeVec{
gauge: vec,
}
}
// Inc Inc increments the counter by 1. Use Add to increment it by arbitrary.
func (gauge *promGaugeVec) Inc(labels ...string) {
gauge.gauge.WithLabelValues(labels...).Inc()
}
// Add Inc increments the counter by 1. Use Add to increment it by arbitrary.
func (gauge *promGaugeVec) Add(v float64, labels ...string) {
gauge.gauge.WithLabelValues(labels...).Add(v)
}
// Set set the given value to the collection.
func (gauge *promGaugeVec) Set(v float64, labels ...string) {
gauge.gauge.WithLabelValues(labels...).Set(v)
}

@ -21,3 +21,32 @@ func TestGaugeSet(t *testing.T) {
val := gauge.Value()
assert.Equal(t, val, int64(50))
}
func TestGaugeVec(t *testing.T) {
gaugeVec := NewGaugeVec(&GaugeVecOpts{
Namespace: "test",
Subsystem: "test",
Name: "test",
Help: "this is test metrics.",
Labels: []string{"name", "addr"},
})
gaugeVec.Set(float64(22.33), "name1", "127.0.0.1")
assert.Panics(t, func() {
NewGaugeVec(&GaugeVecOpts{
Namespace: "test",
Subsystem: "test",
Name: "test",
Help: "this is test metrics.",
Labels: []string{"name", "addr"},
})
}, "Expected to panic.")
assert.NotPanics(t, func() {
NewGaugeVec(&GaugeVecOpts{
Namespace: "test",
Subsystem: "test",
Name: "test2",
Help: "this is test metrics.",
Labels: []string{"name", "addr"},
})
}, "Expected normal. no panic.")
}

@ -0,0 +1,50 @@
package metric
import (
"github.com/prometheus/client_golang/prometheus"
)
// HistogramVecOpts is histogram vector opts.
type HistogramVecOpts struct {
Namespace string
Subsystem string
Name string
Help string
Labels []string
Buckets []float64
}
// HistogramVec gauge vec.
type HistogramVec interface {
// Observe adds a single observation to the histogram.
Observe(v int64, labels ...string)
}
// Histogram prom histogram collection.
type promHistogramVec struct {
histogram *prometheus.HistogramVec
}
// NewHistogramVec new a histogram vec.
func NewHistogramVec(cfg *HistogramVecOpts) HistogramVec {
if cfg == nil {
return nil
}
vec := prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Namespace: cfg.Namespace,
Subsystem: cfg.Subsystem,
Name: cfg.Name,
Help: cfg.Help,
Buckets: cfg.Buckets,
}, cfg.Labels)
prometheus.MustRegister(vec)
return &promHistogramVec{
histogram: vec,
}
}
// Timing adds a single observation to the histogram.
func (histogram *promHistogramVec) Observe(v int64, labels ...string) {
histogram.histogram.WithLabelValues(labels...).Observe(float64(v))
}

@ -0,0 +1,39 @@
package metric
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestHistogramVec(t *testing.T) {
histogramVec := NewHistogramVec(&HistogramVecOpts{
Namespace: "test",
Subsystem: "test",
Name: "test",
Help: "this is test metrics.",
Labels: []string{"name", "addr"},
Buckets: _defaultBuckets,
})
histogramVec.Observe(int64(1), "name1", "127.0.0.1")
assert.Panics(t, func() {
NewHistogramVec(&HistogramVecOpts{
Namespace: "test",
Subsystem: "test",
Name: "test",
Help: "this is test metrics.",
Labels: []string{"name", "addr"},
Buckets: _defaultBuckets,
})
}, "Expected to panic.")
assert.NotPanics(t, func() {
NewHistogramVec(&HistogramVecOpts{
Namespace: "test",
Subsystem: "test",
Name: "test2",
Help: "this is test metrics.",
Labels: []string{"name", "addr"},
Buckets: _defaultBuckets,
})
}, "Expected normal. no panic.")
}

@ -1,5 +1,7 @@
package metric
import "errors"
// Opts contains the common arguments for creating Metric.
type Opts struct {
}
@ -28,3 +30,69 @@ type Aggregation interface {
// Sum computes sum value within the window.
Sum() float64
}
// VectorOpts contains the common arguments for creating vec Metric..
type VectorOpts struct {
Namespace string
Subsystem string
Name string
Help string
Labels []string
}
const (
_businessNamespace = "business"
_businessSubsystemCount = "count"
_businessSubSystemGauge = "gauge"
_businessSubSystemHistogram = "histogram"
)
var (
_defaultBuckets = []float64{5, 10, 25, 50, 100, 250, 500},
)
// NewBusinessMetricCount business Metric count vec.
// name or labels should not be empty.
func NewBusinessMetricCount(name string, labels ...string) CounterVec {
if name == "" || len(labels) == 0 {
panic(errors.New("stat:metric business count metric name should not be empty or labels length should be greater than zero"))
}
return NewCounterVec(&CounterVecOpts{
Namespace: _businessNamespace,
Subsystem: _businessSubsystemCount,
Name: name,
Labels: labels,
})
}
// NewBusinessMetricGauge business Metric gauge vec.
// name or labels should not be empty.
func NewBusinessMetricGauge(name string, labels ...string) GaugeVec {
if name == "" || len(labels) == 0 {
panic(errors.New("stat:metric business gauge metric name should not be empty or labels length should be greater than zero"))
}
return NewGaugeVec(&GaugeVecOpts{
Namespace: _businessNamespace,
Subsystem: _businessSubSystemGauge,
Name: name,
Labels: labels,
})
}
// NewBusinessMetricHistogram business Metric histogram vec.
// name or labels should not be empty.
func NewBusinessMetricHistogram(name string, buckets []float64, labels ...string) HistogramVec {
if name == "" || len(labels) == 0 {
panic(errors.New("stat:metric business histogram metric name should not be empty or labels length should be greater than zero"))
}
if len(buckets) == 0 {
buckets = _defaultBuckets
}
return NewHistogramVec(&HistogramVecOpts{
Namespace: _businessNamespace,
Subsystem: _businessSubSystemHistogram,
Name: name,
Labels: labels,
Buckets: buckets,
})
}

@ -1,5 +0,0 @@
# prom
## 项目简介
封装prometheus类。TODO:补充grafana通用面板json文件!!!

@ -1,163 +0,0 @@
package prom
import (
"flag"
"os"
"sync"
"github.com/prometheus/client_golang/prometheus"
)
var (
// LibClient for mc redis and db client.
LibClient = New().WithTimer("go_lib_client", []string{"method"}).WithCounter("go_lib_client_code", []string{"method", "code"})
// RPCClient rpc client
RPCClient = New().WithTimer("go_rpc_client", []string{"method"}).WithCounter("go_rpc_client_code", []string{"method", "code"})
// HTTPClient http client
HTTPClient = New().WithTimer("go_http_client", []string{"method"}).WithCounter("go_http_client_code", []string{"method", "code"})
// HTTPServer for http server
HTTPServer = New().WithTimer("go_http_server", []string{"user", "method"}).WithCounter("go_http_server_code", []string{"user", "method", "code"})
// RPCServer for rpc server
RPCServer = New().WithTimer("go_rpc_server", []string{"user", "method"}).WithCounter("go_rpc_server_code", []string{"user", "method", "code"})
// BusinessErrCount for business err count
BusinessErrCount = New().WithCounter("go_business_err_count", []string{"name"}).WithState("go_business_err_state", []string{"name"})
// BusinessInfoCount for business info count
BusinessInfoCount = New().WithCounter("go_business_info_count", []string{"name"}).WithState("go_business_info_state", []string{"name"})
// CacheHit for cache hit
CacheHit = New().WithCounter("go_cache_hit", []string{"name"})
// CacheMiss for cache miss
CacheMiss = New().WithCounter("go_cache_miss", []string{"name"})
// UseSummary use summary for Objectives that defines the quantile rank estimates.
_useSummary bool
)
// Prom struct info
type Prom struct {
histogram *prometheus.HistogramVec
summary *prometheus.SummaryVec
counter *prometheus.GaugeVec
state *prometheus.GaugeVec
once sync.Once
}
// New creates a Prom instance.
func New() *Prom {
return &Prom{}
}
func init() {
addFlag(flag.CommandLine)
}
func addFlag(fs *flag.FlagSet) {
v := os.Getenv("PROM_SUMMARY")
if v == "true" {
_useSummary = true
}
fs.BoolVar(&_useSummary, "prom_summary", _useSummary, "use summary in prometheus")
}
// WithTimer with summary timer
func (p *Prom) WithTimer(name string, labels []string) *Prom {
if p == nil {
return p
}
if p.histogram == nil {
p.histogram = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: name,
Help: name,
}, labels)
}
if p.summary == nil {
p.summary = prometheus.NewSummaryVec(
prometheus.SummaryOpts{
Name: name,
Help: name,
Objectives: map[float64]float64{0.99: 0.001, 0.9: 0.01},
}, labels)
}
return p
}
// WithCounter sets counter.
func (p *Prom) WithCounter(name string, labels []string) *Prom {
if p == nil || p.counter != nil {
return p
}
p.counter = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: name,
Help: name,
}, labels)
prometheus.MustRegister(p.counter)
return p
}
// WithState sets state.
func (p *Prom) WithState(name string, labels []string) *Prom {
if p == nil || p.state != nil {
return p
}
p.state = prometheus.NewGaugeVec(
prometheus.GaugeOpts{
Name: name,
Help: name,
}, labels)
prometheus.MustRegister(p.state)
return p
}
// Timing log timing information (in milliseconds) without sampling
func (p *Prom) Timing(name string, time int64, extra ...string) {
p.once.Do(func() {
if _useSummary && p.summary != nil {
prometheus.MustRegister(p.summary)
return
}
if !_useSummary && p.histogram != nil {
prometheus.MustRegister(p.histogram)
}
})
label := append([]string{name}, extra...)
if _useSummary && p.summary != nil {
p.summary.WithLabelValues(label...).Observe(float64(time))
return
}
if !_useSummary && p.histogram != nil {
p.histogram.WithLabelValues(label...).Observe(float64(time))
}
}
// Incr increments one stat counter without sampling
func (p *Prom) Incr(name string, extra ...string) {
label := append([]string{name}, extra...)
if p.counter != nil {
p.counter.WithLabelValues(label...).Inc()
}
}
// Decr decrements one stat counter without sampling
func (p *Prom) Decr(name string, extra ...string) {
if p.counter != nil {
label := append([]string{name}, extra...)
p.counter.WithLabelValues(label...).Dec()
}
}
// State set state
func (p *Prom) State(name string, v int64, extra ...string) {
if p.state != nil {
label := append([]string{name}, extra...)
p.state.WithLabelValues(label...).Set(float64(v))
}
}
// Add add count v must > 0
func (p *Prom) Add(name string, v int64, extra ...string) {
label := append([]string{name}, extra...)
if p.counter != nil {
p.counter.WithLabelValues(label...).Add(float64(v))
}
}

@ -1,25 +0,0 @@
package stat
import (
"github.com/bilibili/kratos/pkg/stat/prom"
)
// Stat interface.
type Stat interface {
Timing(name string, time int64, extra ...string)
Incr(name string, extra ...string) // name,ext...,code
State(name string, val int64, extra ...string)
}
// default stat struct.
var (
// http
HTTPClient Stat = prom.HTTPClient
HTTPServer Stat = prom.HTTPServer
// storage
Cache Stat = prom.LibClient
DB Stat = prom.LibClient
// rpc
RPCClient Stat = prom.RPCClient
RPCServer Stat = prom.RPCServer
)

@ -9,13 +9,11 @@ import (
"github.com/bilibili/kratos/pkg/log"
"github.com/bilibili/kratos/pkg/net/metadata"
"github.com/bilibili/kratos/pkg/net/trace"
"github.com/bilibili/kratos/pkg/stat/prom"
)
var (
// ErrFull chan full.
ErrFull = errors.New("fanout: chan full")
stats = prom.BusinessInfoCount
traceTags = []trace.Tag{
trace.Tag{Key: trace.TagSpanKind, Value: "background"},
trace.Tag{Key: trace.TagComponent, Value: "sync/pipeline/fanout"},
@ -97,7 +95,7 @@ func (c *Fanout) proc() {
select {
case t := <-c.ch:
wrapFunc(t.f)(t.ctx)
stats.State(c.name+"_channel", int64(len(c.ch)))
_metricChanSize.Set(float64(len(c.ch)), c.name)
case <-c.ctx.Done():
return
}
@ -136,7 +134,7 @@ func (c *Fanout) Do(ctx context.Context, f func(ctx context.Context)) (err error
default:
err = ErrFull
}
stats.State(c.name+"_channel", int64(len(c.ch)))
_metricChanSize.Set(float64(len(c.ch)), c.name)
return
}

@ -0,0 +1,15 @@
package fanout
import "github.com/bilibili/kratos/pkg/stat/metric"
const namespace = "sync"
var (
_metricChanSize = metric.NewGaugeVec(&metric.GaugeVecOpts{
Namespace: namespace,
Subsystem: "pipeline_fanout",
Name: "current",
Help: "sync pipeline fanout current channel size.",
Labels: []string{"name"},
})
)

@ -17,14 +17,18 @@ import (
"context"
{{if .EnableBatch }}"sync"{{end}}
NEWLINE
"github.com/bilibili/kratos/pkg/stat/prom"
"github.com/bilibili/kratos/pkg/stat/metric"
{{if .EnableBatch }}"github.com/bilibili/kratos/pkg/sync/errgroup"{{end}}
{{.ImportPackage}}
NEWLINE
{{if .EnableSingleFlight}} "golang.org/x/sync/singleflight" {{end}}
)
var _ _bts
var (
_ _bts
_metricHits = metric.NewBusinessMetricCount("hits_total", "name")
_metricMisses = metric.NewBusinessMetricCount("misses_total", "name")
)
{{if .EnableSingleFlight}}
var cacheSingleFlights = [SFCOUNT]*singleflight.Group{SFINIT}
{{end }}

@ -26,7 +26,7 @@ func (d *Dao) NAME(c context.Context, {{.IDName}} []KEY{{.ExtraArgsType}}) (res
miss = append(miss, key)
}
}
prom.CacheHit.Add("NAME", int64(len({{.IDName}}) - len(miss)))
_metricHits.Add(float64(len({{.IDName}}) - len(miss)), "NAME")
{{if .EnableNullCache}}
for k, v := range res {
{{if .SimpleValue}} if v == {{.NullCache}} { {{else}} if {{.CheckNullCode}} { {{end}}
@ -47,14 +47,14 @@ func (d *Dao) NAME(c context.Context, {{.IDName}} []KEY{{.ExtraArgsType}}) (res
var rr interface{}
sf := d.cacheSFNAME({{.IDName}} {{.ExtraArgs}})
rr, err, _ = cacheSingleFlights[SFNUM].Do(sf, func() (r interface{}, e error) {
prom.CacheMiss.Add("NAME", int64(len(miss)))
_metricMisses.Add(float64(len(miss)), "NAME")
r, e = RAWFUNC(c, miss {{.ExtraRawArgs}})
return
})
missData = rr.(map[KEY]VALUE)
{{else}}
{{if .EnableBatch}}
prom.CacheMiss.Add("NAME", int64(missLen))
_metricMisses.Add(int64(missLen), "NAME")
var mutex sync.Mutex
{{if .BatchErrBreak}}
group := errgroup.WithCancel(c)
@ -87,7 +87,7 @@ func (d *Dao) NAME(c context.Context, {{.IDName}} []KEY{{.ExtraArgsType}}) (res
}
err = group.Wait()
{{else}}
prom.CacheMiss.Add("NAME", int64(len(miss)))
_metricMisses.Add(int64(len(miss)), "NAME")
missData, err = RAWFUNC(c, miss {{.ExtraRawArgs}})
{{end}}
{{end}}

@ -21,20 +21,20 @@ func (d *Dao) NAME(c context.Context) (res VALUE, err error) {
{{else}}
if res != {{.ZeroValue}} {
{{end}}
prom.CacheHit.Incr("NAME")
_metricHits.Incr("NAME")
return
}
{{if .EnableSingleFlight}}
var rr interface{}
sf := d.cacheSFNAME()
rr, err, _ = cacheSingleFlights[SFNUM].Do(sf, func() (r interface{}, e error) {
prom.CacheMiss.Incr("NAME")
_metricMisses.Incr("NAME")
r, e = RAWFUNC(c)
return
})
res = rr.(VALUE)
{{else}}
prom.CacheMiss.Incr("NAME")
_metricMisses.Incr("NAME")
res, err = RAWFUNC(c)
{{end}}
if err != nil {

@ -6,8 +6,8 @@
type _bts interface {
// bts: -batch=2 -max_group=20 -batch_err=break -nullcache=&Demo{ID:-1} -check_null_code=$.ID==-1
Demos(c context.Context, keys []int64) (map[int64]*Demo, error)
// bts: -batch=2 -max_group=20 -batch_err=continue -nullcache=&Demo{ID:-1} -check_null_code=$.ID==-1
Demos1(c context.Context, keys []int64) (map[int64]*Demo, error)
// bts: -batch=2 -max_group=20 -batch_err=continue -nullcache=&Demo{ID:-1} -check_null_code=$.ID==-1
Demos1(c context.Context, keys []int64) (map[int64]*Demo, error)
// bts: -sync=true -nullcache=&Demo{ID:-1} -check_null_code=$.ID==-1
Demo(c context.Context, key int64) (*Demo, error)
// bts: -paging=true
@ -23,11 +23,15 @@ import (
"context"
"sync"
"github.com/bilibili/kratos/pkg/stat/prom"
"github.com/bilibili/kratos/pkg/stat/metric"
"github.com/bilibili/kratos/pkg/sync/errgroup"
)
var _ _bts
var (
_ _bts
_metricHits = metric.NewBusinessMetricCount("hits_total", "NAME")
_metricMisses = metric.NewBusinessMetricCount("misses_total", "NAME")
)
// Demos get data from cache if miss will call source method, then add to cache.
func (d *Dao) Demos(c context.Context, keys []int64) (res map[int64]*Demo, err error) {
@ -46,7 +50,7 @@ func (d *Dao) Demos(c context.Context, keys []int64) (res map[int64]*Demo, err e
miss = append(miss, key)
}
}
prom.CacheHit.Add("Demos", int64(len(keys)-len(miss)))
_metricHits.Add(float64(len(keys)-len(miss)), "Demos")
for k, v := range res {
if v.ID == -1 {
delete(res, k)
@ -57,7 +61,7 @@ func (d *Dao) Demos(c context.Context, keys []int64) (res map[int64]*Demo, err e
return
}
missData := make(map[int64]*Demo, missLen)
prom.CacheMiss.Add("Demos", int64(missLen))
_metricMisses.Add(int64(missLen), "Demos")
var mutex sync.Mutex
group := errgroup.WithCancel(c)
if missLen > 20 {
@ -125,7 +129,7 @@ func (d *Dao) Demos1(c context.Context, keys []int64) (res map[int64]*Demo, err
miss = append(miss, key)
}
}
prom.CacheHit.Add("Demos1", int64(len(keys)-len(miss)))
_metricHits.Add(float64(len(keys)-len(miss)), "Demos1")
for k, v := range res {
if v.ID == -1 {
delete(res, k)
@ -136,7 +140,7 @@ func (d *Dao) Demos1(c context.Context, keys []int64) (res map[int64]*Demo, err
return
}
missData := make(map[int64]*Demo, missLen)
prom.CacheMiss.Add("Demos1", int64(missLen))
_metricMisses.Add(int64(missLen), "Demos1")
var mutex sync.Mutex
group := errgroup.WithContext(c)
if missLen > 20 {
@ -261,10 +265,10 @@ func (d *Dao) None(c context.Context) (res *Demo, err error) {
}
}()
if res != nil {
prom.CacheHit.Incr("None")
_metricHits.Incr("None")
return
}
prom.CacheMiss.Incr("None")
_metricMisses.Incr("None")
res, err = d.RawNone(c)
if err != nil {
return

@ -19,12 +19,15 @@ import (
{{if .UseStrConv}}"strconv"{{end}}
{{if .EnableBatch }}"sync"{{end}}
NEWLINE
"github.com/bilibili/kratos/pkg/stat/prom"
"github.com/bilibili/kratos/pkg/stat/metric"
{{if .UseMemcached }}"github.com/bilibili/kratos/pkg/cache/memcache"{{end}}
{{if .EnableBatch }}"github.com/bilibili/kratos/pkg/sync/errgroup"{{end}}
"github.com/bilibili/kratos/pkg/log"
{{.ImportPackage}}
)
var _ _mc
var (
_ _mc
_metricErrCount = metric.NewBusinessMetricCount("mc_error_total", "NAME")
)
`

@ -44,7 +44,7 @@ func (d *{{.StructName}}) NAME(c context.Context, ids []KEY {{.ExtraArgsType}})
}
replies, err := d.mc.GetMulti(c, keys)
if err != nil {
prom.BusinessErrCount.Incr("mc:NAME")
_metricErrCount.Inc("NAME")
log.Errorv(ctx, log.KV("NAME", fmt.Sprintf("%+v", err)), log.KV("keys", keys))
return
}
@ -67,14 +67,14 @@ func (d *{{.StructName}}) NAME(c context.Context, ids []KEY {{.ExtraArgsType}})
{{end}}
{{end}}
if err != nil {
prom.BusinessErrCount.Incr("mc:NAME")
_metricErrCount.Inc("NAME")
log.Errorv(ctx, log.KV("NAME", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
{{if .GetSimpleValue}}
r, err := {{.ConvertBytes2Value}}
if err != nil {
prom.BusinessErrCount.Incr("mc:NAME")
_metricErrCount.Inc("NAME")
log.Errorv(ctx, log.KV("NAME", fmt.Sprintf("%+v", err)), log.KV("key", key))
return res, err
}
@ -114,7 +114,7 @@ func (d *{{.StructName}}) NAME(c context.Context, ids []KEY {{.ExtraArgsType}})
}
replies, err := d.mc.GetMulti(c, keys)
if err != nil {
prom.BusinessErrCount.Incr("mc:NAME")
_metricErrCount.Inc("NAME")
log.Errorv(c, log.KV("NAME", fmt.Sprintf("%+v", err)), log.KV("keys", keys))
return
}
@ -132,14 +132,14 @@ func (d *{{.StructName}}) NAME(c context.Context, ids []KEY {{.ExtraArgsType}})
{{end}}
{{end}}
if err != nil {
prom.BusinessErrCount.Incr("mc:NAME")
_metricErrCount.Inc("NAME")
log.Errorv(c, log.KV("NAME", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
{{if .GetSimpleValue}}
r, err := {{.ConvertBytes2Value}}
if err != nil {
prom.BusinessErrCount.Incr("mc:NAME")
_metricErrCount.Inc("NAME")
log.Errorv(c, log.KV("NAME", fmt.Sprintf("%+v", err)), log.KV("key", key))
return res, err
}
@ -174,7 +174,7 @@ func (d *{{.StructName}}) NAME(c context.Context, values map[KEY]VALUE {{.ExtraA
item := &memcache.Item{Key: key, Object: val, Expiration: {{.ExpireCode}}, Flags: {{.Encode}}}
{{end}}
if err = d.mc.Set(c, item); err != nil {
prom.BusinessErrCount.Incr("mc:NAME")
_metricErrCount.Inc("NAME")
log.Errorv(c, log.KV("NAME", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
@ -198,7 +198,7 @@ func (d *{{.StructName}}) NAME(c context.Context, ids []KEY {{.ExtraArgsType}})
err = nil
continue
}
prom.BusinessErrCount.Incr("mc:NAME")
_metricErrCount.Inc("NAME")
log.Errorv(c, log.KV("NAME", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}

@ -37,14 +37,14 @@ func (d *{{.StructName}}) NAME(c context.Context) (res VALUE, err error) {
return
}
{{end}}
prom.BusinessErrCount.Incr("mc:NAME")
_metricErrCount.Inc("NAME")
log.Errorv(c, log.KV("NAME", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
{{if .GetSimpleValue}}
r, err := {{.ConvertBytes2Value}}
if err != nil {
prom.BusinessErrCount.Incr("mc:NAME")
_metricErrCount.Inc("NAME")
log.Errorv(c, log.KV("NAME", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
@ -75,7 +75,7 @@ func (d *{{.StructName}}) NAME(c context.Context, val VALUE) (err error) {
item := &memcache.Item{Key: key, Object: val, Expiration: {{.ExpireCode}}, Flags: {{.Encode}}}
{{end}}
if err = d.mc.Set(c, item); err != nil {
prom.BusinessErrCount.Incr("mc:NAME")
_metricErrCount.Inc("NAME")
log.Errorv(c, log.KV("NAME", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
@ -94,7 +94,7 @@ func (d *{{.StructName}}) NAME(c context.Context) (err error) {
err = nil
return
}
prom.BusinessErrCount.Incr("mc:NAME")
_metricErrCount.Inc("NAME")
log.Errorv(c, log.KV("NAME", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}

@ -36,14 +36,14 @@ func (d *{{.StructName}}) NAME(c context.Context, id KEY {{.ExtraArgsType}}) (re
return
}
{{end}}
prom.BusinessErrCount.Incr("mc:NAME")
_metricErrCount.Inc("NAME")
log.Errorv(c, log.KV("NAME", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
{{if .GetSimpleValue}}
r, err := {{.ConvertBytes2Value}}
if err != nil {
prom.BusinessErrCount.Incr("mc:NAME")
_metricErrCount.Incr("NAME")
log.Errorv(c, log.KV("NAME", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
@ -74,7 +74,7 @@ func (d *{{.StructName}}) NAME(c context.Context, id KEY, val VALUE {{.ExtraArgs
item := &memcache.Item{Key: key, Object: val, Expiration: {{.ExpireCode}}, Flags: {{.Encode}}}
{{end}}
if err = d.mc.Set(c, item); err != nil {
prom.BusinessErrCount.Incr("mc:NAME")
_metricErrCount.Incr("NAME")
log.Errorv(c, log.KV("NAME", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
@ -93,7 +93,7 @@ func (d *{{.StructName}}) NAME(c context.Context, id KEY {{.ExtraArgsType}}) (er
err = nil
return
}
prom.BusinessErrCount.Incr("mc:NAME")
_metricErrCount.Incr("NAME")
log.Errorv(c, log.KV("NAME", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}

@ -48,10 +48,13 @@ import (
"github.com/bilibili/kratos/pkg/cache/memcache"
"github.com/bilibili/kratos/pkg/log"
"github.com/bilibili/kratos/pkg/stat/prom"
"github.com/bilibili/kratos/pkg/stat/metric"
)
var _ _mc
var (
_ _mc
_metricErrCount = metric.NewBusinessMetricCount("mc_error_total", "NAME")
)
// CacheDemos get data from mc
func (d *Dao) CacheDemos(c context.Context, ids []int64) (res map[int64]*Demo, err error) {
@ -68,7 +71,7 @@ func (d *Dao) CacheDemos(c context.Context, ids []int64) (res map[int64]*Demo, e
}
replies, err := d.mc.GetMulti(c, keys)
if err != nil {
prom.BusinessErrCount.Incr("mc:CacheDemos")
_metricErrCount.Inc("CacheDemos")
log.Errorv(c, log.KV("CacheDemos", fmt.Sprintf("%+v", err)), log.KV("keys", keys))
return
}
@ -76,7 +79,7 @@ func (d *Dao) CacheDemos(c context.Context, ids []int64) (res map[int64]*Demo, e
v := &Demo{}
err = replies.Scan(key, v)
if err != nil {
prom.BusinessErrCount.Incr("mc:CacheDemos")
_metricErrCount.Inc("CacheDemos")
log.Errorv(c, log.KV("CacheDemos", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
@ -99,7 +102,7 @@ func (d *Dao) CacheDemo(c context.Context, id int64) (res *Demo, err error) {
}
}
if err != nil {
prom.BusinessErrCount.Incr("mc:CacheDemo")
_metricErrCount.Inc("CacheDemo")
log.Errorv(c, log.KV("CacheDemo", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
@ -117,7 +120,7 @@ func (d *Dao) CacheDemo1(c context.Context, id int64, mid int64) (res *Demo, err
}
}
if err != nil {
prom.BusinessErrCount.Incr("mc:CacheDemo1")
_metricErrCount.Inc("CacheDemo1")
log.Errorv(c, log.KV("CacheDemo1", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
@ -136,7 +139,7 @@ func (d *Dao) CacheNone(c context.Context) (res *Demo, err error) {
}
}
if err != nil {
prom.BusinessErrCount.Incr("mc:CacheNone")
_metricErrCount.Inc("CacheNone")
log.Errorv(c, log.KV("CacheNone", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
@ -152,7 +155,7 @@ func (d *Dao) CacheString(c context.Context, id int64) (res string, err error) {
err = nil
return
}
prom.BusinessErrCount.Incr("mc:CacheString")
_metricErrCount.Inc("CacheString")
log.Errorv(c, log.KV("CacheString", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
@ -168,7 +171,7 @@ func (d *Dao) AddCacheDemos(c context.Context, values map[int64]*Demo) (err erro
key := demoKey(id)
item := &memcache.Item{Key: key, Object: val, Expiration: d.demoExpire, Flags: memcache.FlagJSON}
if err = d.mc.Set(c, item); err != nil {
prom.BusinessErrCount.Incr("mc:AddCacheDemos")
_metricErrCount.Inc("AddCacheDemos")
log.Errorv(c, log.KV("AddCacheDemos", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
@ -185,7 +188,7 @@ func (d *Dao) AddCacheDemos2(c context.Context, values map[int64]*Demo, tp int64
key := demo2Key(id, tp)
item := &memcache.Item{Key: key, Object: val, Expiration: d.demoExpire, Flags: memcache.FlagJSON}
if err = d.mc.Set(c, item); err != nil {
prom.BusinessErrCount.Incr("mc:AddCacheDemos2")
_metricErrCount.Inc("AddCacheDemos2")
log.Errorv(c, log.KV("AddCacheDemos2", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
@ -201,7 +204,7 @@ func (d *Dao) AddCacheDemo(c context.Context, id int64, val *Demo) (err error) {
key := demoKey(id)
item := &memcache.Item{Key: key, Object: val, Expiration: d.demoExpire, Flags: memcache.FlagJSON | memcache.FlagGzip}
if err = d.mc.Set(c, item); err != nil {
prom.BusinessErrCount.Incr("mc:AddCacheDemo")
_metricErrCount.Incr("AddCacheDemo")
log.Errorv(c, log.KV("AddCacheDemo", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
@ -216,7 +219,7 @@ func (d *Dao) AddCacheDemo1(c context.Context, id int64, val *Demo, mid int64) (
key := keyMid(id, mid)
item := &memcache.Item{Key: key, Object: val, Expiration: d.demoExpire, Flags: memcache.FlagGOB}
if err = d.mc.Set(c, item); err != nil {
prom.BusinessErrCount.Incr("mc:AddCacheDemo1")
_metricErrCount.Incr("AddCacheDemo1")
log.Errorv(c, log.KV("AddCacheDemo1", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
@ -231,7 +234,7 @@ func (d *Dao) AddCacheNone(c context.Context, val *Demo) (err error) {
key := noneKey()
item := &memcache.Item{Key: key, Object: val, Expiration: d.demoExpire, Flags: memcache.FlagJSON}
if err = d.mc.Set(c, item); err != nil {
prom.BusinessErrCount.Incr("mc:AddCacheNone")
_metricErrCount.Inc("AddCacheNone")
log.Errorv(c, log.KV("AddCacheNone", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
@ -247,7 +250,7 @@ func (d *Dao) AddCacheString(c context.Context, id int64, val string) (err error
bs := []byte(val)
item := &memcache.Item{Key: key, Value: bs, Expiration: d.demoExpire, Flags: memcache.FlagRAW}
if err = d.mc.Set(c, item); err != nil {
prom.BusinessErrCount.Incr("mc:AddCacheString")
_metricErrCount.Incr("AddCacheString")
log.Errorv(c, log.KV("AddCacheString", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
@ -266,7 +269,7 @@ func (d *Dao) DelCacheDemos(c context.Context, ids []int64) (err error) {
err = nil
continue
}
prom.BusinessErrCount.Incr("mc:DelCacheDemos")
_metricErrCount.Inc("DelCacheDemos")
log.Errorv(c, log.KV("DelCacheDemos", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
@ -282,7 +285,7 @@ func (d *Dao) DelCacheDemo(c context.Context, id int64) (err error) {
err = nil
return
}
prom.BusinessErrCount.Incr("mc:DelCacheDemo")
_metricErrCount.Incr("DelCacheDemo")
log.Errorv(c, log.KV("DelCacheDemo", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
@ -297,7 +300,7 @@ func (d *Dao) DelCacheDemo1(c context.Context, id int64, mid int64) (err error)
err = nil
return
}
prom.BusinessErrCount.Incr("mc:DelCacheDemo1")
_metricErrCount.Incr("DelCacheDemo1")
log.Errorv(c, log.KV("DelCacheDemo1", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}
@ -312,7 +315,7 @@ func (d *Dao) DelCacheNone(c context.Context) (err error) {
err = nil
return
}
prom.BusinessErrCount.Incr("mc:DelCacheNone")
_metricErrCount.Inc("DelCacheNone")
log.Errorv(c, log.KV("DelCacheNone", fmt.Sprintf("%+v", err)), log.KV("key", key))
return
}

@ -33,7 +33,7 @@ var toolIndexs = []*Tool{
&Tool{
Name: "genbts",
Alias: "kratos-gen-bts",
BuildTime: time.Date(2019, 5, 5, 0, 0, 0, 0, time.Local),
BuildTime: time.Date(2019, 7, 20, 0, 0, 0, 0, time.Local),
Install: "go get -u github.com/bilibili/kratos/tool/kratos-gen-bts",
Summary: "缓存回源逻辑代码生成器",
Platform: []string{"darwin", "linux", "windows"},
@ -42,7 +42,7 @@ var toolIndexs = []*Tool{
&Tool{
Name: "genmc",
Alias: "kratos-gen-mc",
BuildTime: time.Date(2019, 5, 5, 0, 0, 0, 0, time.Local),
BuildTime: time.Date(2019, 7, 20, 0, 0, 0, 0, time.Local),
Install: "go get -u github.com/bilibili/kratos/tool/kratos-gen-mc",
Summary: "mc缓存代码生成",
Platform: []string{"darwin", "linux", "windows"},

Loading…
Cancel
Save