mirror of
https://github.com/zhufuyi/sponge.git
synced 2025-10-05 08:46:57 +08:00
code quality inspection for pkg direcory
This commit is contained in:
5
.github/RELEASE.md
vendored
5
.github/RELEASE.md
vendored
@@ -1,4 +1,5 @@
|
|||||||
## New
|
## New
|
||||||
|
|
||||||
- Add automatic code merge function to solve the problem that you need to copy code manually after executing the command `make proto`.
|
- Add automated code merge functionality in the command `make proto`, no more copying code manually.
|
||||||
- Improve documentation
|
- Add code quality inspection.
|
||||||
|
- Improve documentation.
|
||||||
|
@@ -12,10 +12,8 @@ run:
|
|||||||
# default value is empty list, but default dirs are skipped independently
|
# default value is empty list, but default dirs are skipped independently
|
||||||
# from this option's value (see skip-dirs-use-default).
|
# from this option's value (see skip-dirs-use-default).
|
||||||
skip-dirs:
|
skip-dirs:
|
||||||
- pkg
|
|
||||||
- docs
|
- docs
|
||||||
- api
|
- api
|
||||||
- configs
|
|
||||||
# which files to skip: they will be analyzed, but issues from them
|
# which files to skip: they will be analyzed, but issues from them
|
||||||
# won't be reported. Default value is empty list, but there is
|
# won't be reported. Default value is empty list, but there is
|
||||||
# no need to include all autogenerated files, we confidently recognize
|
# no need to include all autogenerated files, we confidently recognize
|
||||||
|
@@ -97,6 +97,8 @@ Visit `http://localhost:24631` in your browser, generate code by manipulating it
|
|||||||
|
|
||||||
### Examples of use
|
### Examples of use
|
||||||
|
|
||||||
|
The following sample code , in addition to the core business logic code , the other code is generated by the tool sponge .
|
||||||
|
|
||||||
#### Basic Services examples
|
#### Basic Services examples
|
||||||
|
|
||||||
- [1_web-gin-CRUD](https://github.com/zhufuyi/sponge_examples/tree/main/1_web-gin-CRUD)
|
- [1_web-gin-CRUD](https://github.com/zhufuyi/sponge_examples/tree/main/1_web-gin-CRUD)
|
||||||
|
@@ -138,6 +138,8 @@ sponge run
|
|||||||
|
|
||||||
### 使用示例
|
### 使用示例
|
||||||
|
|
||||||
|
下面的示例代码,除了核心业务逻辑代码,其他代码都是由工具sponge生成。
|
||||||
|
|
||||||
#### 基础服务示例
|
#### 基础服务示例
|
||||||
|
|
||||||
- [1_web-gin-CRUD](https://github.com/zhufuyi/sponge_examples/tree/main/1_web-gin-CRUD)
|
- [1_web-gin-CRUD](https://github.com/zhufuyi/sponge_examples/tree/main/1_web-gin-CRUD)
|
||||||
|
@@ -101,7 +101,9 @@ func buildHTTPRule(m *protogen.Method, rule *annotations.HttpRule) *RPCMethod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func buildMethodDesc(m *protogen.Method, httpMethod, path string) *RPCMethod {
|
func buildMethodDesc(m *protogen.Method, httpMethod, path string) *RPCMethod {
|
||||||
defer func() { methodSets[m.GoName]++ }()
|
defer func() {
|
||||||
|
methodSets[m.GoName]++
|
||||||
|
}()
|
||||||
md := &RPCMethod{
|
md := &RPCMethod{
|
||||||
Name: m.GoName,
|
Name: m.GoName,
|
||||||
Num: methodSets[m.GoName],
|
Num: methodSets[m.GoName],
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package configs used to locate config file.
|
||||||
package configs
|
package configs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -5,12 +6,10 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
// used to locate a directory
|
|
||||||
|
|
||||||
var basePath string
|
var basePath string
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
_, currentFile, _, _ := runtime.Caller(0)
|
_, currentFile, _, _ := runtime.Caller(0) //nolint
|
||||||
basePath = filepath.Dir(currentFile)
|
basePath = filepath.Dir(currentFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -51,7 +51,7 @@ grpcClient:
|
|||||||
host: "127.0.0.1" # rpc service address, used for direct connection
|
host: "127.0.0.1" # rpc service address, used for direct connection
|
||||||
port: 8282 # rpc service port
|
port: 8282 # rpc service port
|
||||||
registryDiscoveryType: "" # registration and discovery types: consul, etcd, nacos, if empty, connecting to server using host and port
|
registryDiscoveryType: "" # registration and discovery types: consul, etcd, nacos, if empty, connecting to server using host and port
|
||||||
enableLoadBalance: false # whether to turn on the load balancer
|
enableLoadBalance: true # whether to turn on the load balancer
|
||||||
# clientSecure parameter setting
|
# clientSecure parameter setting
|
||||||
# if type="", it means no secure connection, no need to fill in any parameters
|
# if type="", it means no secure connection, no need to fill in any parameters
|
||||||
# if type="one-way", it means server-side certification, only the fields 'serverName' and 'certFile' should be filled in
|
# if type="one-way", it means server-side certification, only the fields 'serverName' and 'certFile' should be filled in
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package app is starting and stopping services gracefully, using golang.org/x/sync/errgroup to ensure that multiple services are started properly at the same time.
|
||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -46,10 +47,7 @@ func (a *App) Run() {
|
|||||||
s := server
|
s := server
|
||||||
eg.Go(func() error {
|
eg.Go(func() error {
|
||||||
fmt.Println(s.String())
|
fmt.Println(s.String())
|
||||||
if err := s.Start(); err != nil {
|
return s.Start()
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
pkg/cache/cache.go
vendored
1
pkg/cache/cache.go
vendored
@@ -1,3 +1,4 @@
|
|||||||
|
// Package cache is memory and redis cache libraries.
|
||||||
package cache
|
package cache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
12
pkg/cache/memory.go
vendored
12
pkg/cache/memory.go
vendored
@@ -21,7 +21,7 @@ type memoryCache struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewMemoryCache create a memory cache
|
// NewMemoryCache create a memory cache
|
||||||
func NewMemoryCache(keyPrefix string, encoding encoding.Encoding, newObject func() interface{}) Cache {
|
func NewMemoryCache(keyPrefix string, encode encoding.Encoding, newObject func() interface{}) Cache {
|
||||||
// see: https://dgraph.io/blog/post/introducing-ristretto-high-perf-go-cache/
|
// see: https://dgraph.io/blog/post/introducing-ristretto-high-perf-go-cache/
|
||||||
// https://www.start.io/blog/we-chose-ristretto-cache-for-go-heres-why/
|
// https://www.start.io/blog/we-chose-ristretto-cache-for-go-heres-why/
|
||||||
config := &ristretto.Config{
|
config := &ristretto.Config{
|
||||||
@@ -33,13 +33,13 @@ func NewMemoryCache(keyPrefix string, encoding encoding.Encoding, newObject func
|
|||||||
return &memoryCache{
|
return &memoryCache{
|
||||||
client: store,
|
client: store,
|
||||||
KeyPrefix: keyPrefix,
|
KeyPrefix: keyPrefix,
|
||||||
encoding: encoding,
|
encoding: encode,
|
||||||
newObject: newObject,
|
newObject: newObject,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set data
|
// Set data
|
||||||
func (m *memoryCache) Set(ctx context.Context, key string, val interface{}, expiration time.Duration) error {
|
func (m *memoryCache) Set(_ context.Context, key string, val interface{}, expiration time.Duration) error {
|
||||||
buf, err := encoding.Marshal(m.encoding, val)
|
buf, err := encoding.Marshal(m.encoding, val)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("encoding.Marshal error: %v, key=%s, val=%+v ", err, key, val)
|
return fmt.Errorf("encoding.Marshal error: %v, key=%s, val=%+v ", err, key, val)
|
||||||
@@ -57,7 +57,7 @@ func (m *memoryCache) Set(ctx context.Context, key string, val interface{}, expi
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get data
|
// Get data
|
||||||
func (m *memoryCache) Get(ctx context.Context, key string, val interface{}) error {
|
func (m *memoryCache) Get(_ context.Context, key string, val interface{}) error {
|
||||||
cacheKey, err := BuildCacheKey(m.KeyPrefix, key)
|
cacheKey, err := BuildCacheKey(m.KeyPrefix, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("BuildCacheKey error: %v, key=%s", err, key)
|
return fmt.Errorf("BuildCacheKey error: %v, key=%s", err, key)
|
||||||
@@ -81,7 +81,7 @@ func (m *memoryCache) Get(ctx context.Context, key string, val interface{}) erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Del delete data
|
// Del delete data
|
||||||
func (m *memoryCache) Del(ctx context.Context, keys ...string) error {
|
func (m *memoryCache) Del(_ context.Context, keys ...string) error {
|
||||||
if len(keys) == 0 {
|
if len(keys) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -124,7 +124,7 @@ func (m *memoryCache) MultiGet(ctx context.Context, keys []string, value interfa
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetCacheWithNotFound set not found
|
// SetCacheWithNotFound set not found
|
||||||
func (m *memoryCache) SetCacheWithNotFound(ctx context.Context, key string) error {
|
func (m *memoryCache) SetCacheWithNotFound(_ context.Context, key string) error {
|
||||||
cacheKey, err := BuildCacheKey(m.KeyPrefix, key)
|
cacheKey, err := BuildCacheKey(m.KeyPrefix, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("BuildCacheKey error: %v, key=%s", err, key)
|
return fmt.Errorf("BuildCacheKey error: %v, key=%s", err, key)
|
||||||
|
4
pkg/cache/redis.go
vendored
4
pkg/cache/redis.go
vendored
@@ -26,11 +26,11 @@ type redisCache struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewRedisCache new a cache, client parameter can be passed in for unit testing
|
// NewRedisCache new a cache, client parameter can be passed in for unit testing
|
||||||
func NewRedisCache(client *redis.Client, keyPrefix string, encoding encoding.Encoding, newObject func() interface{}) Cache {
|
func NewRedisCache(client *redis.Client, keyPrefix string, encode encoding.Encoding, newObject func() interface{}) Cache {
|
||||||
return &redisCache{
|
return &redisCache{
|
||||||
client: client,
|
client: client,
|
||||||
KeyPrefix: keyPrefix,
|
KeyPrefix: keyPrefix,
|
||||||
encoding: encoding,
|
encoding: encode,
|
||||||
newObject: newObject,
|
newObject: newObject,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package conf is parsing yaml, json, toml configuration files to go struct.
|
||||||
package conf
|
package conf
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package consulcli is connecting to the consul service client.
|
||||||
package consulcli
|
package consulcli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package encoding Provides encoding and decoding of json, protobuf and gob.
|
||||||
package encoding
|
package encoding
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -74,19 +75,18 @@ func Marshal(e Encoding, v interface{}) (data []byte, err error) {
|
|||||||
}
|
}
|
||||||
bm, ok := v.(encoding.BinaryMarshaler)
|
bm, ok := v.(encoding.BinaryMarshaler)
|
||||||
if ok && e == nil {
|
if ok && e == nil {
|
||||||
data, err = bm.MarshalBinary()
|
return bm.MarshalBinary()
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err = e.Marshal(v)
|
data, err = e.Marshal(v)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return
|
return data, err
|
||||||
}
|
}
|
||||||
if ok {
|
if ok {
|
||||||
data, err = bm.MarshalBinary()
|
data, err = bm.MarshalBinary()
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return data, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unmarshal decode data
|
// Unmarshal decode data
|
||||||
@@ -101,12 +101,12 @@ func Unmarshal(e Encoding, data []byte, v interface{}) (err error) {
|
|||||||
}
|
}
|
||||||
err = e.Unmarshal(data, v)
|
err = e.Unmarshal(data, v)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
if ok {
|
if ok {
|
||||||
return bm.UnmarshalBinary(data)
|
return bm.UnmarshalBinary(data)
|
||||||
}
|
}
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func isPointer(data interface{}) bool {
|
func isPointer(data interface{}) bool {
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package json is a JSON encoding and decoding.
|
||||||
package json
|
package json
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -106,7 +106,7 @@ func GzipDecode(in []byte) ([]byte, error) {
|
|||||||
// JSONSnappyEncoding json format and snappy compression
|
// JSONSnappyEncoding json format and snappy compression
|
||||||
type JSONSnappyEncoding struct{}
|
type JSONSnappyEncoding struct{}
|
||||||
|
|
||||||
// Marshal serialisation
|
// Marshal serialization
|
||||||
func (s JSONSnappyEncoding) Marshal(v interface{}) (data []byte, err error) {
|
func (s JSONSnappyEncoding) Marshal(v interface{}) (data []byte, err error) {
|
||||||
b, err := json.Marshal(v)
|
b, err := json.Marshal(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package proto is a protobuf encoding and decoding.
|
||||||
package proto
|
package proto
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package errcode is used for http and grpc error codes, include system-level error codes and service-level error codes
|
||||||
package errcode
|
package errcode
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -10,9 +10,9 @@ package errcode
|
|||||||
// ErrUserUpdate = NewError(HCode(1)+3, "failed to update user") // 200103
|
// ErrUserUpdate = NewError(HCode(1)+3, "failed to update user") // 200103
|
||||||
// ErrUserGet = NewError(HCode(1)+4, "failed to get user details") // 200104
|
// ErrUserGet = NewError(HCode(1)+4, "failed to get user details") // 200104
|
||||||
// )
|
// )
|
||||||
func HCode(NO int) int {
|
func HCode(num int) int {
|
||||||
if NO > 99 || NO < 1 {
|
if num > 99 || num < 1 {
|
||||||
panic("NO range must be between 0 to 100")
|
panic("num range must be between 0 to 100")
|
||||||
}
|
}
|
||||||
return 200000 + NO*100
|
return 200000 + num*100
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
package errcode
|
package errcode
|
||||||
|
|
||||||
// nolint
|
|
||||||
// http system level error code, error code range 10000~20000
|
// http system level error code, error code range 10000~20000
|
||||||
var (
|
var (
|
||||||
Success = NewError(0, "ok")
|
Success = NewError(0, "ok")
|
||||||
|
@@ -54,8 +54,8 @@ type defaultResponse struct {
|
|||||||
rpcStatus map[int]*RPCStatus
|
rpcStatus map[int]*RPCStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
func (resp *defaultResponse) response(c *gin.Context, status, code int, msg string, data interface{}) {
|
func (resp *defaultResponse) response(c *gin.Context, respStatus, code int, msg string, data interface{}) {
|
||||||
c.JSON(status, map[string]interface{}{
|
c.JSON(respStatus, map[string]interface{}{
|
||||||
"code": code,
|
"code": code,
|
||||||
"msg": msg,
|
"msg": msg,
|
||||||
"data": data,
|
"data": data,
|
||||||
@@ -67,8 +67,8 @@ func (resp *defaultResponse) Success(c *gin.Context, data interface{}) {
|
|||||||
resp.response(c, http.StatusOK, 0, "ok", data)
|
resp.response(c, http.StatusOK, 0, "ok", data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParamError response parameter error information
|
// ParamError response parameter error information, does not return an error message
|
||||||
func (resp *defaultResponse) ParamError(c *gin.Context, err error) {
|
func (resp *defaultResponse) ParamError(c *gin.Context, _ error) {
|
||||||
resp.response(c, http.StatusOK, InvalidParams.Code(), InvalidParams.Msg(), struct{}{})
|
resp.response(c, http.StatusOK, InvalidParams.Code(), InvalidParams.Msg(), struct{}{})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,24 +173,37 @@ func (resp *defaultResponse) isUserDefinedHTTPErrorCode(c *gin.Context, errCode
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ToHTTPErr converted to http error
|
// ToHTTPErr converted to http error
|
||||||
func ToHTTPErr(st *status.Status) *Error {
|
func ToHTTPErr(st *status.Status) *Error { //nolint
|
||||||
switch st.Code() {
|
switch st.Code() {
|
||||||
case StatusSuccess.status.Code(), codes.OK:
|
case StatusSuccess.status.Code(), codes.OK:
|
||||||
return Success
|
return Success
|
||||||
|
case StatusInvalidParams.status.Code(), codes.InvalidArgument:
|
||||||
|
return InvalidParams
|
||||||
|
case StatusInternalServerError.status.Code(), codes.Internal:
|
||||||
|
return InternalServerError
|
||||||
|
case StatusUnimplemented.status.Code(), codes.Unimplemented:
|
||||||
|
return Unimplemented
|
||||||
|
case StatusPermissionDenied.status.Code(), codes.PermissionDenied:
|
||||||
|
return PermissionDenied
|
||||||
|
}
|
||||||
|
|
||||||
|
switch st.Code() {
|
||||||
|
//case StatusSuccess.status.Code(), codes.OK:
|
||||||
|
// return Success
|
||||||
case StatusCanceled.status.Code(), codes.Canceled:
|
case StatusCanceled.status.Code(), codes.Canceled:
|
||||||
return Canceled
|
return Canceled
|
||||||
case StatusUnknown.status.Code(), codes.Unknown:
|
case StatusUnknown.status.Code(), codes.Unknown:
|
||||||
return Unknown
|
return Unknown
|
||||||
case StatusInvalidParams.status.Code(), codes.InvalidArgument:
|
//case StatusInvalidParams.status.Code(), codes.InvalidArgument:
|
||||||
return InvalidParams
|
// return InvalidParams
|
||||||
case StatusDeadlineExceeded.status.Code(), codes.DeadlineExceeded:
|
case StatusDeadlineExceeded.status.Code(), codes.DeadlineExceeded:
|
||||||
return DeadlineExceeded
|
return DeadlineExceeded
|
||||||
case StatusNotFound.status.Code(), codes.NotFound:
|
case StatusNotFound.status.Code(), codes.NotFound:
|
||||||
return NotFound
|
return NotFound
|
||||||
case StatusAlreadyExists.status.Code(), codes.AlreadyExists:
|
case StatusAlreadyExists.status.Code(), codes.AlreadyExists:
|
||||||
return AlreadyExists
|
return AlreadyExists
|
||||||
case StatusPermissionDenied.status.Code(), codes.PermissionDenied:
|
//case StatusPermissionDenied.status.Code(), codes.PermissionDenied:
|
||||||
return PermissionDenied
|
// return PermissionDenied
|
||||||
case StatusResourceExhausted.status.Code(), codes.ResourceExhausted:
|
case StatusResourceExhausted.status.Code(), codes.ResourceExhausted:
|
||||||
return ResourceExhausted
|
return ResourceExhausted
|
||||||
case StatusFailedPrecondition.status.Code(), codes.FailedPrecondition:
|
case StatusFailedPrecondition.status.Code(), codes.FailedPrecondition:
|
||||||
@@ -199,10 +212,10 @@ func ToHTTPErr(st *status.Status) *Error {
|
|||||||
return Aborted
|
return Aborted
|
||||||
case StatusOutOfRange.status.Code(), codes.OutOfRange:
|
case StatusOutOfRange.status.Code(), codes.OutOfRange:
|
||||||
return OutOfRange
|
return OutOfRange
|
||||||
case StatusUnimplemented.status.Code(), codes.Unimplemented:
|
//case StatusUnimplemented.status.Code(), codes.Unimplemented:
|
||||||
return Unimplemented
|
// return Unimplemented
|
||||||
case StatusInternalServerError.status.Code(), codes.Internal:
|
//case StatusInternalServerError.status.Code(), codes.Internal:
|
||||||
return InternalServerError
|
// return InternalServerError
|
||||||
case StatusServiceUnavailable.status.Code(), codes.Unavailable:
|
case StatusServiceUnavailable.status.Code(), codes.Unavailable:
|
||||||
return ServiceUnavailable
|
return ServiceUnavailable
|
||||||
case StatusDataLoss.status.Code(), codes.DataLoss:
|
case StatusDataLoss.status.Code(), codes.DataLoss:
|
||||||
|
@@ -128,21 +128,32 @@ func toRPCErr(code codes.Code, descs ...string) error {
|
|||||||
|
|
||||||
// ToRPCCode converted to standard RPC error code
|
// ToRPCCode converted to standard RPC error code
|
||||||
func (g *RPCStatus) ToRPCCode() codes.Code {
|
func (g *RPCStatus) ToRPCCode() codes.Code {
|
||||||
|
switch g.status.Code() {
|
||||||
|
case StatusInvalidParams.status.Code():
|
||||||
|
return codes.InvalidArgument
|
||||||
|
case StatusInternalServerError.status.Code():
|
||||||
|
return codes.Internal
|
||||||
|
case StatusUnimplemented.status.Code():
|
||||||
|
return codes.Unimplemented
|
||||||
|
case StatusPermissionDenied.status.Code():
|
||||||
|
return codes.PermissionDenied
|
||||||
|
}
|
||||||
|
|
||||||
switch g.status.Code() {
|
switch g.status.Code() {
|
||||||
case StatusCanceled.status.Code():
|
case StatusCanceled.status.Code():
|
||||||
return codes.Canceled
|
return codes.Canceled
|
||||||
case StatusUnknown.status.Code():
|
case StatusUnknown.status.Code():
|
||||||
return codes.Unknown
|
return codes.Unknown
|
||||||
case StatusInvalidParams.status.Code():
|
//case StatusInvalidParams.status.Code():
|
||||||
return codes.InvalidArgument
|
// return codes.InvalidArgument
|
||||||
case StatusDeadlineExceeded.status.Code():
|
case StatusDeadlineExceeded.status.Code():
|
||||||
return codes.DeadlineExceeded
|
return codes.DeadlineExceeded
|
||||||
case StatusNotFound.status.Code():
|
case StatusNotFound.status.Code():
|
||||||
return codes.NotFound
|
return codes.NotFound
|
||||||
case StatusAlreadyExists.status.Code():
|
case StatusAlreadyExists.status.Code():
|
||||||
return codes.AlreadyExists
|
return codes.AlreadyExists
|
||||||
case StatusPermissionDenied.status.Code():
|
//case StatusPermissionDenied.status.Code():
|
||||||
return codes.PermissionDenied
|
// return codes.PermissionDenied
|
||||||
case StatusResourceExhausted.status.Code():
|
case StatusResourceExhausted.status.Code():
|
||||||
return codes.ResourceExhausted
|
return codes.ResourceExhausted
|
||||||
case StatusFailedPrecondition.status.Code():
|
case StatusFailedPrecondition.status.Code():
|
||||||
@@ -151,10 +162,10 @@ func (g *RPCStatus) ToRPCCode() codes.Code {
|
|||||||
return codes.Aborted
|
return codes.Aborted
|
||||||
case StatusOutOfRange.status.Code():
|
case StatusOutOfRange.status.Code():
|
||||||
return codes.OutOfRange
|
return codes.OutOfRange
|
||||||
case StatusUnimplemented.status.Code():
|
//case StatusUnimplemented.status.Code():
|
||||||
return codes.Unimplemented
|
// return codes.Unimplemented
|
||||||
case StatusInternalServerError.status.Code():
|
//case StatusInternalServerError.status.Code():
|
||||||
return codes.Internal
|
// return codes.Internal
|
||||||
case StatusServiceUnavailable.status.Code():
|
case StatusServiceUnavailable.status.Code():
|
||||||
return codes.Unavailable
|
return codes.Unavailable
|
||||||
case StatusDataLoss.status.Code():
|
case StatusDataLoss.status.Code():
|
||||||
|
@@ -12,9 +12,9 @@ import "google.golang.org/grpc/codes"
|
|||||||
// StatusUserUpdate = NewRPCStatus(RCode(1)+3, "failed to update user") // 40103
|
// StatusUserUpdate = NewRPCStatus(RCode(1)+3, "failed to update user") // 40103
|
||||||
// StatusUserGet = NewRPCStatus(RCode(1)+4, "failed to get user details") // 40104
|
// StatusUserGet = NewRPCStatus(RCode(1)+4, "failed to get user details") // 40104
|
||||||
// )
|
// )
|
||||||
func RCode(NO int) codes.Code {
|
func RCode(num int) codes.Code {
|
||||||
if NO > 99 || NO < 1 {
|
if num > 99 || num < 1 {
|
||||||
panic("NO range must be between 0 to 100")
|
panic("NO range must be between 0 to 100")
|
||||||
}
|
}
|
||||||
return codes.Code(40000 + NO*100)
|
return codes.Code(40000 + num*100)
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
package errcode
|
package errcode
|
||||||
|
|
||||||
// nolint
|
|
||||||
// rpc system level error code with status prefix, error code range 30000~40000
|
// rpc system level error code with status prefix, error code range 30000~40000
|
||||||
var (
|
var (
|
||||||
StatusSuccess = NewRPCStatus(0, "ok")
|
StatusSuccess = NewRPCStatus(0, "ok")
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package etcdcli is use for connecting to the etcd service
|
||||||
package etcdcli
|
package etcdcli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -19,7 +19,7 @@ type options struct {
|
|||||||
serverNameOverride string // etcd domain
|
serverNameOverride string // etcd domain
|
||||||
certFile string // path to certificate file
|
certFile string // path to certificate file
|
||||||
|
|
||||||
autoSyncInterval time.Duration // automatic synchronisation of member list intervals
|
autoSyncInterval time.Duration // automatic synchronization of member list intervals
|
||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package handlerfunc is used for public http request handler.
|
||||||
package handlerfunc
|
package handlerfunc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package middleware is gin middleware plugin.
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -67,8 +67,7 @@ func CircuitBreaker(opts ...CircuitBreakerOption) gin.HandlerFunc {
|
|||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
breaker := o.group.Get(c.FullPath()).(circuitbreaker.CircuitBreaker)
|
breaker := o.group.Get(c.FullPath()).(circuitbreaker.CircuitBreaker)
|
||||||
if err := breaker.Allow(); err != nil {
|
if err := breaker.Allow(); err != nil {
|
||||||
// NOTE: when client reject request locally,
|
// NOTE: when client reject request locally, keep adding counter let the drop ratio higher.
|
||||||
// continue to add counter let the drop ratio higher.
|
|
||||||
breaker.MarkFailed()
|
breaker.MarkFailed()
|
||||||
response.Output(c, http.StatusServiceUnavailable, err.Error())
|
response.Output(c, http.StatusServiceUnavailable, err.Error())
|
||||||
c.Abort()
|
c.Abort()
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
// Package metrics is gin metrics library, collect five metrics, "uptime", "http_request_count_total",
|
||||||
|
// "http_request_duration_seconds", "http_request_size_bytes", "http_response_size_bytes".
|
||||||
package metrics
|
package metrics
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -4,9 +4,10 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/zhufuyi/sponge/pkg/gin/response"
|
"github.com/zhufuyi/sponge/pkg/gin/response"
|
||||||
rl "github.com/zhufuyi/sponge/pkg/shield/ratelimit"
|
rl "github.com/zhufuyi/sponge/pkg/shield/ratelimit"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrLimitExceed is returned when the rate limiter is
|
// ErrLimitExceed is returned when the rate limiter is
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package prof is used for gin profiling.
|
||||||
package prof
|
package prof
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package response provides wrapper gin returns json data in the same format.
|
||||||
package response
|
package response
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -52,11 +53,11 @@ func writeJSON(c *gin.Context, code int, res interface{}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func respJSONWithStatusCode(c *gin.Context, code int, msg string, data ...interface{}) {
|
func respJSONWithStatusCode(c *gin.Context, code int, msg string, data ...interface{}) {
|
||||||
var FirstData interface{}
|
var firstData interface{}
|
||||||
if len(data) > 0 {
|
if len(data) > 0 {
|
||||||
FirstData = data[0]
|
firstData = data[0]
|
||||||
}
|
}
|
||||||
resp := newResp(code, msg, FirstData)
|
resp := newResp(code, msg, firstData)
|
||||||
|
|
||||||
writeJSON(c, code, resp)
|
writeJSON(c, code, resp)
|
||||||
}
|
}
|
||||||
@@ -122,11 +123,11 @@ func Out(c *gin.Context, err *errcode.Error, data ...interface{}) {
|
|||||||
|
|
||||||
// status code flat 200, custom error codes in data.code
|
// status code flat 200, custom error codes in data.code
|
||||||
func respJSONWith200(c *gin.Context, code int, msg string, data ...interface{}) {
|
func respJSONWith200(c *gin.Context, code int, msg string, data ...interface{}) {
|
||||||
var FirstData interface{}
|
var firstData interface{}
|
||||||
if len(data) > 0 {
|
if len(data) > 0 {
|
||||||
FirstData = data[0]
|
firstData = data[0]
|
||||||
}
|
}
|
||||||
resp := newResp(code, msg, FirstData)
|
resp := newResp(code, msg, firstData)
|
||||||
|
|
||||||
writeJSON(c, http.StatusOK, resp)
|
writeJSON(c, http.StatusOK, resp)
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package swagger is gin swagger library.
|
||||||
package swagger
|
package swagger
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package validator is gin request parameter check library.
|
||||||
package validator
|
package validator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -9,9 +10,9 @@ import (
|
|||||||
|
|
||||||
// Init request body file valid
|
// Init request body file valid
|
||||||
func Init() *CustomValidator {
|
func Init() *CustomValidator {
|
||||||
valid := NewCustomValidator()
|
validator := NewCustomValidator()
|
||||||
valid.Engine()
|
validator.Engine()
|
||||||
return valid
|
return validator
|
||||||
}
|
}
|
||||||
|
|
||||||
// CustomValidator Custom valid objects
|
// CustomValidator Custom valid objects
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package gobash provides the ability to execute commands, scripts, executables in the go environment with live log output.
|
||||||
package gobash
|
package gobash
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
## gofile
|
## gofile
|
||||||
|
|
||||||
For file and directory management libraries.
|
File and directory management libraries.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package gofile is file and directory management libraries.
|
||||||
package gofile
|
package gofile
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -9,8 +9,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// IsExists determine if a file or folder exists
|
// IsExists determine if a file or folder exists
|
||||||
func IsExists(path string) bool {
|
func IsExists(f string) bool {
|
||||||
_, err := os.Stat(path)
|
_, err := os.Stat(f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return !os.IsNotExist(err)
|
return !os.IsNotExist(err)
|
||||||
}
|
}
|
||||||
@@ -56,13 +56,13 @@ func GetFilenameWithoutSuffix(filePath string) string {
|
|||||||
|
|
||||||
// Join joins any number of path elements into a single path
|
// Join joins any number of path elements into a single path
|
||||||
func Join(elem ...string) string {
|
func Join(elem ...string) string {
|
||||||
path := strings.Join(elem, "/")
|
dir := strings.Join(elem, "/")
|
||||||
|
|
||||||
if IsWindows() {
|
if IsWindows() {
|
||||||
return strings.ReplaceAll(path, "/", "\\")
|
return strings.ReplaceAll(dir, "/", "\\")
|
||||||
}
|
}
|
||||||
|
|
||||||
return path
|
return dir
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsWindows determining whether a window environment
|
// IsWindows determining whether a window environment
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package gohttp is http request client, which only supports returning json format.
|
||||||
package gohttp
|
package gohttp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -166,7 +167,7 @@ func (req *Request) Do(method string, data interface{}) (*Response, error) {
|
|||||||
switch method {
|
switch method {
|
||||||
case http.MethodGet, http.MethodDelete:
|
case http.MethodGet, http.MethodDelete:
|
||||||
if data != nil {
|
if data != nil {
|
||||||
if params, ok := data.(map[string]interface{}); ok {
|
if params, ok := data.(map[string]interface{}); ok { //nolint
|
||||||
req.SetParams(params)
|
req.SetParams(params)
|
||||||
} else {
|
} else {
|
||||||
req.err = errors.New("params is not a map[string]interface{}")
|
req.err = errors.New("params is not a map[string]interface{}")
|
||||||
@@ -321,36 +322,36 @@ func (resp *Response) BindJSON(v interface{}) error {
|
|||||||
// Simple crud function, no support for setting header, timeout, etc.
|
// Simple crud function, no support for setting header, timeout, etc.
|
||||||
|
|
||||||
// Get request, return custom json format
|
// Get request, return custom json format
|
||||||
func Get(result interface{}, url string, params ...KV) error {
|
func Get(result interface{}, urlStr string, params ...KV) error {
|
||||||
var pms KV
|
var pms KV
|
||||||
if len(params) > 0 {
|
if len(params) > 0 {
|
||||||
pms = params[0]
|
pms = params[0]
|
||||||
}
|
}
|
||||||
return gDo("GET", result, url, pms)
|
return gDo("GET", result, urlStr, pms)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete request, return custom json format
|
// Delete request, return custom json format
|
||||||
func Delete(result interface{}, url string, params ...KV) error {
|
func Delete(result interface{}, urlStr string, params ...KV) error {
|
||||||
var pms KV
|
var pms KV
|
||||||
if len(params) > 0 {
|
if len(params) > 0 {
|
||||||
pms = params[0]
|
pms = params[0]
|
||||||
}
|
}
|
||||||
return gDo("DELETE", result, url, pms)
|
return gDo("DELETE", result, urlStr, pms)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Post request, return custom json format
|
// Post request, return custom json format
|
||||||
func Post(result interface{}, url string, body interface{}) error {
|
func Post(result interface{}, urlStr string, body interface{}) error {
|
||||||
return do("POST", result, url, body)
|
return do("POST", result, urlStr, body)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put request, return custom json format
|
// Put request, return custom json format
|
||||||
func Put(result interface{}, url string, body interface{}) error {
|
func Put(result interface{}, urlStr string, body interface{}) error {
|
||||||
return do("PUT", result, url, body)
|
return do("PUT", result, urlStr, body)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Patch request, return custom json format
|
// Patch request, return custom json format
|
||||||
func Patch(result interface{}, url string, body interface{}) error {
|
func Patch(result interface{}, urlStr string, body interface{}) error {
|
||||||
return do("PATCH", result, url, body)
|
return do("PATCH", result, urlStr, body)
|
||||||
}
|
}
|
||||||
|
|
||||||
var requestErr = func(err error) error { return fmt.Errorf("request error, err=%v", err) }
|
var requestErr = func(err error) error { return fmt.Errorf("request error, err=%v", err) }
|
||||||
@@ -366,13 +367,13 @@ var notOKErr = func(resp *Response) error {
|
|||||||
return fmt.Errorf("statusCode=%d, body=%s", resp.StatusCode, body)
|
return fmt.Errorf("statusCode=%d, body=%s", resp.StatusCode, body)
|
||||||
}
|
}
|
||||||
|
|
||||||
func do(method string, result interface{}, url string, body interface{}, params ...KV) error {
|
func do(method string, result interface{}, urlStr string, body interface{}, params ...KV) error {
|
||||||
if result == nil {
|
if result == nil {
|
||||||
return fmt.Errorf("params 'result' is nil")
|
return fmt.Errorf("params 'result' is nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
req := &Request{}
|
req := &Request{}
|
||||||
req.SetURL(url)
|
req.SetURL(urlStr)
|
||||||
req.SetContentType("application/json")
|
req.SetContentType("application/json")
|
||||||
if len(params) > 0 {
|
if len(params) > 0 {
|
||||||
req.SetParams(params[0])
|
req.SetParams(params[0])
|
||||||
@@ -406,9 +407,9 @@ func do(method string, result interface{}, url string, body interface{}, params
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func gDo(method string, result interface{}, url string, params KV) error {
|
func gDo(method string, result interface{}, urlStr string, params KV) error {
|
||||||
req := &Request{}
|
req := &Request{}
|
||||||
req.SetURL(url)
|
req.SetURL(urlStr)
|
||||||
req.SetParams(params)
|
req.SetParams(params)
|
||||||
|
|
||||||
var resp *Response
|
var resp *Response
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package goredis is a library wrapped on top of github.com/go-redis/redis.
|
||||||
package goredis
|
package goredis
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package gotest is a library that simulates the testing of cache, dao and handler.
|
||||||
package gotest
|
package gotest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package benchmark is compression testing of rpc methods and generation of reported results.
|
||||||
package benchmark
|
package benchmark
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package grpccli is grpc client with support for service discovery, logging, load balancing, trace, metrics, retries, circuit breaker.
|
||||||
package grpccli
|
package grpccli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
## gtls
|
## gtls
|
||||||
|
|
||||||
|
gtls provides grpc secure connectivity, supporting both server-only authentication and client-server authentication.
|
||||||
|
|
||||||
#### Example of use
|
#### Example of use
|
||||||
|
|
||||||
#### grpc server
|
#### grpc server
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package certfile is used to locate the certificate file.
|
||||||
package certfile
|
package certfile
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package gtls provides grpc secure connectivity, supporting both server-only authentication and client-server authentication.
|
||||||
package gtls
|
package gtls
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
## interceptor
|
## interceptor
|
||||||
|
|
||||||
Commonly used grpc client and server-side interceptors.
|
Commonly used grpc client-side and server-side interceptors.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
@@ -60,10 +60,9 @@ var logger *zap.Logger
|
|||||||
|
|
||||||
func getServerOptions() []grpc.ServerOption {
|
func getServerOptions() []grpc.ServerOption {
|
||||||
var options []grpc.ServerOption
|
var options []grpc.ServerOption
|
||||||
|
|
||||||
// log setting, which prints client disconnection information by default, example https://pkg.go.dev/github.com/grpc-ecosystem/go-grpc-middleware/logging/zap
|
|
||||||
options = append(options, grpc_middleware.WithUnaryServerChain(
|
options = append(options, grpc_middleware.WithUnaryServerChain(
|
||||||
interceptor.UnaryServerZapLogging(
|
interceptor.UnaryClientLog(
|
||||||
logger.Get(), // zap
|
logger.Get(), // zap
|
||||||
// middleware.WithLogFields(map[string]interface{}{"serverName": "userExample"}), // additional print fields
|
// middleware.WithLogFields(map[string]interface{}{"serverName": "userExample"}), // additional print fields
|
||||||
middleware.WithLogIgnoreMethods("/proto.userExampleService/GetByID"), // ignore the specified method print, you can specify more than one
|
middleware.WithLogIgnoreMethods("/proto.userExampleService/GetByID"), // ignore the specified method print, you can specify more than one
|
||||||
|
@@ -1,7 +1,9 @@
|
|||||||
|
// Package interceptor provides commonly used grpc client-side and server-side interceptors.
|
||||||
package interceptor
|
package interceptor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/zhufuyi/sponge/pkg/container/group"
|
"github.com/zhufuyi/sponge/pkg/container/group"
|
||||||
"github.com/zhufuyi/sponge/pkg/errcode"
|
"github.com/zhufuyi/sponge/pkg/errcode"
|
||||||
"github.com/zhufuyi/sponge/pkg/shield/circuitbreaker"
|
"github.com/zhufuyi/sponge/pkg/shield/circuitbreaker"
|
||||||
@@ -68,8 +70,7 @@ func UnaryClientCircuitBreaker(opts ...CircuitBreakerOption) grpc.UnaryClientInt
|
|||||||
return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
|
return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
|
||||||
breaker := o.group.Get(method).(circuitbreaker.CircuitBreaker)
|
breaker := o.group.Get(method).(circuitbreaker.CircuitBreaker)
|
||||||
if err := breaker.Allow(); err != nil {
|
if err := breaker.Allow(); err != nil {
|
||||||
// NOTE: when client reject request locally,
|
// NOTE: when client reject request locally, keep adding counter let the drop ratio higher.
|
||||||
// continue to add counter let the drop ratio higher.
|
|
||||||
breaker.MarkFailed()
|
breaker.MarkFailed()
|
||||||
return errcode.StatusServiceUnavailable.ToRPCErr(err.Error())
|
return errcode.StatusServiceUnavailable.ToRPCErr(err.Error())
|
||||||
}
|
}
|
||||||
@@ -98,8 +99,7 @@ func StreamClientCircuitBreaker(opts ...CircuitBreakerOption) grpc.StreamClientI
|
|||||||
return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
|
return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
|
||||||
breaker := o.group.Get(method).(circuitbreaker.CircuitBreaker)
|
breaker := o.group.Get(method).(circuitbreaker.CircuitBreaker)
|
||||||
if err := breaker.Allow(); err != nil {
|
if err := breaker.Allow(); err != nil {
|
||||||
// NOTE: when client reject request locally,
|
// NOTE: when client reject request locally, keep adding counter let the drop ratio higher.
|
||||||
// continue to add counter let the drop ratio higher.
|
|
||||||
breaker.MarkFailed()
|
breaker.MarkFailed()
|
||||||
return nil, errcode.StatusServiceUnavailable.ToRPCErr(err.Error())
|
return nil, errcode.StatusServiceUnavailable.ToRPCErr(err.Error())
|
||||||
}
|
}
|
||||||
@@ -128,8 +128,7 @@ func UnaryServerCircuitBreaker(opts ...CircuitBreakerOption) grpc.UnaryServerInt
|
|||||||
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||||
breaker := o.group.Get(info.FullMethod).(circuitbreaker.CircuitBreaker)
|
breaker := o.group.Get(info.FullMethod).(circuitbreaker.CircuitBreaker)
|
||||||
if err := breaker.Allow(); err != nil {
|
if err := breaker.Allow(); err != nil {
|
||||||
// NOTE: when client reject request locally,
|
// NOTE: when client reject request locally, keep adding let the drop ratio higher.
|
||||||
// continue to add counter let the drop ratio higher.
|
|
||||||
breaker.MarkFailed()
|
breaker.MarkFailed()
|
||||||
return nil, errcode.StatusServiceUnavailable.ToRPCErr(err.Error())
|
return nil, errcode.StatusServiceUnavailable.ToRPCErr(err.Error())
|
||||||
}
|
}
|
||||||
@@ -158,8 +157,7 @@ func StreamServerCircuitBreaker(opts ...CircuitBreakerOption) grpc.StreamServerI
|
|||||||
return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
|
return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
|
||||||
breaker := o.group.Get(info.FullMethod).(circuitbreaker.CircuitBreaker)
|
breaker := o.group.Get(info.FullMethod).(circuitbreaker.CircuitBreaker)
|
||||||
if err := breaker.Allow(); err != nil {
|
if err := breaker.Allow(); err != nil {
|
||||||
// NOTE: when client reject request locally,
|
// NOTE: when client reject request locally, keep adding counter let the drop ratio higher.
|
||||||
// continue to add counter let the drop ratio higher.
|
|
||||||
breaker.MarkFailed()
|
breaker.MarkFailed()
|
||||||
return errcode.StatusServiceUnavailable.ToRPCErr(err.Error())
|
return errcode.StatusServiceUnavailable.ToRPCErr(err.Error())
|
||||||
}
|
}
|
||||||
|
@@ -116,7 +116,8 @@ func JwtVerify(ctx context.Context) (context.Context, error) {
|
|||||||
return nil, status.Errorf(codes.Unauthenticated, "%v", err)
|
return nil, status.Errorf(codes.Unauthenticated, "%v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
newCtx := context.WithValue(ctx, authCtxClaimsName, cc) // get value by ctx.Value(interceptor.GetAuthCtxKey()).(*jwt.CustomClaims)
|
newCtx := context.WithValue(ctx, authCtxClaimsName, cc) //nolint
|
||||||
|
// get value by ctx.Value(interceptor.GetAuthCtxKey()).(*jwt.CustomClaims)
|
||||||
|
|
||||||
return newCtx, nil
|
return newCtx, nil
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@ package interceptor
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
grpc_recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery"
|
grpc_recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
|
@@ -81,14 +81,14 @@ func UnaryServerRequestID() grpc.UnaryServerInterceptor {
|
|||||||
|
|
||||||
// StreamServerRequestID server-side request id stream interceptor
|
// StreamServerRequestID server-side request id stream interceptor
|
||||||
func StreamServerRequestID() grpc.StreamServerInterceptor {
|
func StreamServerRequestID() grpc.StreamServerInterceptor {
|
||||||
|
// todo
|
||||||
return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
|
return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
|
||||||
ctx := stream.Context()
|
//ctx := stream.Context()
|
||||||
requestID := ServerCtxRequestID(ctx)
|
//requestID := ServerCtxRequestID(ctx)
|
||||||
if requestID == "" {
|
//if requestID == "" {
|
||||||
requestID = krand.String(krand.R_All, 10)
|
// requestID = krand.String(krand.R_All, 10)
|
||||||
ctx = metautils.ExtractIncoming(ctx).Add(ContextRequestIDKey, requestID).ToIncoming(ctx)
|
// ctx = metautils.ExtractIncoming(ctx).Add(ContextRequestIDKey, requestID).ToIncoming(ctx)
|
||||||
}
|
//}
|
||||||
|
|
||||||
return handler(srv, stream)
|
return handler(srv, stream)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@ package interceptor
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/grpc-ecosystem/go-grpc-middleware/util/metautils"
|
"github.com/grpc-ecosystem/go-grpc-middleware/util/metautils"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
@@ -15,7 +16,7 @@ type authToken struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetRequestMetadata get metadata
|
// GetRequestMetadata get metadata
|
||||||
func (t *authToken) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
|
func (t *authToken) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) { //nolint
|
||||||
return map[string]string{
|
return map[string]string{
|
||||||
"app_id": t.AppID,
|
"app_id": t.AppID,
|
||||||
"app_key": t.AppKey,
|
"app_key": t.AppKey,
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package keepalive is setting grpc keepalive parameters.
|
||||||
package keepalive
|
package keepalive
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
## metrics
|
## metrics
|
||||||
|
|
||||||
The grpc's server and client-side metrics can continue to be captured using prometheus.
|
The grpc's server-side and client-side metrics can continue to be captured using prometheus.
|
||||||
|
|
||||||
### Example of use
|
### Example of use
|
||||||
|
|
||||||
|
@@ -19,7 +19,7 @@ var (
|
|||||||
// create a Registry
|
// create a Registry
|
||||||
cliReg = prometheus.NewRegistry()
|
cliReg = prometheus.NewRegistry()
|
||||||
|
|
||||||
// initialise the client's default metrics
|
// initialize the client's default metrics
|
||||||
grpcClientMetrics = grpc_prometheus.NewClientMetrics()
|
grpcClientMetrics = grpc_prometheus.NewClientMetrics()
|
||||||
|
|
||||||
cliOnce sync.Once
|
cliOnce sync.Once
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package metrics is grpc's server-side and client-side metrics can continue to be captured using prometheus.
|
||||||
package metrics
|
package metrics
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -135,7 +136,7 @@ func ServerHTTPService(addr string, grpcServer *grpc.Server) *http.Server {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// initialising gRPC methods Metrics
|
// initialize gRPC methods Metrics
|
||||||
grpcServerMetrics.InitializeMetrics(grpcServer)
|
grpcServerMetrics.InitializeMetrics(grpcServer)
|
||||||
|
|
||||||
return httpServer
|
return httpServer
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package resolve is setting grpc client-side load balancing policy.
|
||||||
package resolve
|
package resolve
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -37,7 +38,7 @@ type ResolverBuilder struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build resolver
|
// Build resolver
|
||||||
func (r *ResolverBuilder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) {
|
func (r *ResolverBuilder) Build(target resolver.Target, cc resolver.ClientConn, _ resolver.BuildOptions) (resolver.Resolver, error) {
|
||||||
blr := &blResolver{
|
blr := &blResolver{
|
||||||
target: target,
|
target: target,
|
||||||
cc: cc,
|
cc: cc,
|
||||||
@@ -70,7 +71,7 @@ func (b *blResolver) start() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ResolveNow Resolve now
|
// ResolveNow Resolve now
|
||||||
func (*blResolver) ResolveNow(o resolver.ResolveNowOptions) {}
|
func (*blResolver) ResolveNow(_ resolver.ResolveNowOptions) {}
|
||||||
|
|
||||||
// Close resolver
|
// Close resolver
|
||||||
func (*blResolver) Close() {}
|
func (*blResolver) Close() {}
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package jwt is token generation and validation.
|
||||||
package jwt
|
package jwt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package jy2struct is a library for generating go struct code, supporting json and yaml.
|
||||||
package jy2struct
|
package jy2struct
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -16,7 +17,7 @@ type Args struct {
|
|||||||
SubStruct bool // are sub-structures separated
|
SubStruct bool // are sub-structures separated
|
||||||
Tags string // add additional tags, multiple tags separated by commas
|
Tags string // add additional tags, multiple tags separated by commas
|
||||||
|
|
||||||
tags []string
|
tags []string //nolint
|
||||||
convertFloats bool
|
convertFloats bool
|
||||||
parser Parser
|
parser Parser
|
||||||
}
|
}
|
||||||
|
@@ -107,7 +107,8 @@ func readFile(input io.Reader) ([]byte, error) {
|
|||||||
|
|
||||||
// json or yaml parse
|
// json or yaml parse
|
||||||
func jyParse(input io.Reader, parser Parser, structName, pkgName string, tags []string, subStruct bool, convertFloats bool) ([]byte, error) {
|
func jyParse(input io.Reader, parser Parser, structName, pkgName string, tags []string, subStruct bool, convertFloats bool) ([]byte, error) {
|
||||||
var subStructMap map[string]string = nil
|
_ = pkgName
|
||||||
|
var subStructMap map[string]string
|
||||||
if subStruct {
|
if subStruct {
|
||||||
subStructMap = make(map[string]string)
|
subStructMap = make(map[string]string)
|
||||||
}
|
}
|
||||||
@@ -125,7 +126,6 @@ func jyParse(input io.Reader, parser Parser, structName, pkgName string, tags []
|
|||||||
case map[string]interface{}:
|
case map[string]interface{}:
|
||||||
result = iresult
|
result = iresult
|
||||||
case []interface{}:
|
case []interface{}:
|
||||||
//src := fmt.Sprintf("package %s\n\ntype %s %s\n", pkgName, structName, typeForValue(iresult, structName, tags, subStructMap, convertFloats))
|
|
||||||
src := fmt.Sprintf("\ntype %s %s\n", structName, typeForValue(iresult, structName, tags, subStructMap, convertFloats))
|
src := fmt.Sprintf("\ntype %s %s\n", structName, typeForValue(iresult, structName, tags, subStructMap, convertFloats))
|
||||||
// supplementary sub-structures
|
// supplementary sub-structures
|
||||||
for k, v := range subStructMap {
|
for k, v := range subStructMap {
|
||||||
@@ -141,7 +141,6 @@ func jyParse(input io.Reader, parser Parser, structName, pkgName string, tags []
|
|||||||
return nil, fmt.Errorf("unexpected type: %T", iresult)
|
return nil, fmt.Errorf("unexpected type: %T", iresult)
|
||||||
}
|
}
|
||||||
|
|
||||||
//src := fmt.Sprintf("package %s\ntype %s %s}", pkgName, structName, generateTypes(result, structName, tags, 0, subStructMap, convertFloats))
|
|
||||||
src := fmt.Sprintf("\ntype %s %s}", structName, generateTypes(result, structName, tags, 0, subStructMap, convertFloats))
|
src := fmt.Sprintf("\ntype %s %s}", structName, generateTypes(result, structName, tags, 0, subStructMap, convertFloats))
|
||||||
|
|
||||||
keys := make([]string, 0, len(subStructMap))
|
keys := make([]string, 0, len(subStructMap))
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package krand is a library for generating random strings, integers, floating point numbers.
|
||||||
package krand
|
package krand
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -21,8 +21,8 @@ func Create(ctx context.Context, db *gorm.DB, table interface{}) error {
|
|||||||
|
|
||||||
// Delete record
|
// Delete record
|
||||||
// the param of 'table' must be pointer, eg: &StructName
|
// the param of 'table' must be pointer, eg: &StructName
|
||||||
func Delete(ctx context.Context, db *gorm.DB, table interface{}, query interface{}, args ...interface{}) error {
|
func Delete(ctx context.Context, db *gorm.DB, table interface{}, queryCondition interface{}, args ...interface{}) error {
|
||||||
return db.WithContext(ctx).Where(query, args...).Delete(table).Error
|
return db.WithContext(ctx).Where(queryCondition, args...).Delete(table).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteByID delete record by id
|
// DeleteByID delete record by id
|
||||||
@@ -33,20 +33,20 @@ func DeleteByID(ctx context.Context, db *gorm.DB, table interface{}, id interfac
|
|||||||
|
|
||||||
// Update record
|
// Update record
|
||||||
// the param of 'table' must be pointer, eg: &StructName
|
// the param of 'table' must be pointer, eg: &StructName
|
||||||
func Update(ctx context.Context, db *gorm.DB, table interface{}, column string, value interface{}, query interface{}, args ...interface{}) error {
|
func Update(ctx context.Context, db *gorm.DB, table interface{}, column string, value interface{}, queryCondition interface{}, args ...interface{}) error {
|
||||||
return db.WithContext(ctx).Model(table).Where(query, args...).Update(column, value).Error
|
return db.WithContext(ctx).Model(table).Where(queryCondition, args...).Update(column, value).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updates record
|
// Updates record
|
||||||
// the param of 'table' must be pointer, eg: &StructName
|
// the param of 'table' must be pointer, eg: &StructName
|
||||||
func Updates(ctx context.Context, db *gorm.DB, table interface{}, update KV, query interface{}, args ...interface{}) error {
|
func Updates(ctx context.Context, db *gorm.DB, table interface{}, update KV, queryCondition interface{}, args ...interface{}) error {
|
||||||
return db.WithContext(ctx).Model(table).Where(query, args...).Updates(update).Error
|
return db.WithContext(ctx).Model(table).Where(queryCondition, args...).Updates(update).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get one record
|
// Get one record
|
||||||
// the param of 'table' must be pointer, eg: &StructName
|
// the param of 'table' must be pointer, eg: &StructName
|
||||||
func Get(ctx context.Context, db *gorm.DB, table interface{}, query interface{}, args ...interface{}) error {
|
func Get(ctx context.Context, db *gorm.DB, table interface{}, queryCondition interface{}, args ...interface{}) error {
|
||||||
return db.WithContext(ctx).Where(query, args...).First(table).Error
|
return db.WithContext(ctx).Where(queryCondition, args...).First(table).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetByID get record by id
|
// GetByID get record by id
|
||||||
@@ -55,15 +55,15 @@ func GetByID(ctx context.Context, db *gorm.DB, table interface{}, id interface{}
|
|||||||
}
|
}
|
||||||
|
|
||||||
// List multiple records, starting from page 0
|
// List multiple records, starting from page 0
|
||||||
// the param of 'tables' must be slice, eg: []StructName
|
// the param of 'tables' must be a slice, eg: []StructName
|
||||||
func List(ctx context.Context, db *gorm.DB, tables interface{}, page *query.Page, query interface{}, args ...interface{}) error {
|
func List(ctx context.Context, db *gorm.DB, tables interface{}, page *query.Page, queryCondition interface{}, args ...interface{}) error {
|
||||||
return db.WithContext(ctx).Order(page.Sort()).Limit(page.Size()).Offset(page.Offset()).Where(query, args...).Find(tables).Error
|
return db.WithContext(ctx).Order(page.Sort()).Limit(page.Size()).Offset(page.Offset()).Where(queryCondition, args...).Find(tables).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count number of records
|
// Count number of records
|
||||||
// the param of 'table' must be pointer, eg: &StructName
|
// the param of 'table' must be pointer, eg: &StructName
|
||||||
func Count(ctx context.Context, db *gorm.DB, table interface{}, query interface{}, args ...interface{}) (int64, error) {
|
func Count(ctx context.Context, db *gorm.DB, table interface{}, queryCondition interface{}, args ...interface{}) (int64, error) {
|
||||||
var count int64
|
var count int64
|
||||||
err := db.WithContext(ctx).Model(table).Where(query, args...).Count(&count).Error
|
err := db.WithContext(ctx).Model(table).Where(queryCondition, args...).Count(&count).Error
|
||||||
return count, err
|
return count, err
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package mysql is a library wrapped on top of gorm.io/gorm, with added features such as link tracing, paging queries, etc.
|
||||||
package mysql
|
package mysql
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package query is a library for mysql query, support for complex conditional paging queries.
|
||||||
package query
|
package query
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -18,7 +19,7 @@ const (
|
|||||||
Lt = "lt"
|
Lt = "lt"
|
||||||
// Lte less than or equal
|
// Lte less than or equal
|
||||||
Lte = "lte"
|
Lte = "lte"
|
||||||
// Like like
|
// Like fuzzy lookup
|
||||||
Like = "like"
|
Like = "like"
|
||||||
|
|
||||||
// AND logic and
|
// AND logic and
|
||||||
@@ -86,7 +87,7 @@ func (c *Column) convert() error {
|
|||||||
if c.Exp == "" {
|
if c.Exp == "" {
|
||||||
c.Exp = Eq
|
c.Exp = Eq
|
||||||
}
|
}
|
||||||
if v, ok := expMap[strings.ToLower(c.Exp)]; ok {
|
if v, ok := expMap[strings.ToLower(c.Exp)]; ok { //nolint
|
||||||
c.Exp = v
|
c.Exp = v
|
||||||
if c.Exp == " LIKE " {
|
if c.Exp == " LIKE " {
|
||||||
c.Value = fmt.Sprintf("%%%v%%", c.Value)
|
c.Value = fmt.Sprintf("%%%v%%", c.Value)
|
||||||
@@ -98,7 +99,7 @@ func (c *Column) convert() error {
|
|||||||
if c.Logic == "" {
|
if c.Logic == "" {
|
||||||
c.Logic = AND
|
c.Logic = AND
|
||||||
}
|
}
|
||||||
if v, ok := logicMap[strings.ToLower(c.Logic)]; ok {
|
if v, ok := logicMap[strings.ToLower(c.Logic)]; ok { //nolint
|
||||||
c.Logic = v
|
c.Logic = v
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("unknown logic type '%s'", c.Logic)
|
return fmt.Errorf("unknown logic type '%s'", c.Logic)
|
||||||
@@ -108,12 +109,12 @@ func (c *Column) convert() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ConvertToPage converted to conform to gorm rules based on the page size sort parameter
|
// ConvertToPage converted to conform to gorm rules based on the page size sort parameter
|
||||||
func (p *Params) ConvertToPage() (order string, limit int, offset int) {
|
func (p *Params) ConvertToPage() (order string, limit int, offset int) { //nolint
|
||||||
page := NewPage(p.Page, p.Size, p.Sort)
|
page := NewPage(p.Page, p.Size, p.Sort)
|
||||||
order = page.sort
|
order = page.sort
|
||||||
limit = page.size
|
limit = page.size
|
||||||
offset = page.page * page.size
|
offset = page.page * page.size
|
||||||
return
|
return //nolint
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConvertToGormConditions conversion to gorm-compliant parameters based on the Columns parameter
|
// ConvertToGormConditions conversion to gorm-compliant parameters based on the Columns parameter
|
||||||
@@ -205,9 +206,8 @@ func getExpsAndLogics(keyLen int, paramSrc string) ([]string, []string) { //noli
|
|||||||
|
|
||||||
group = map[string]string{}
|
group = map[string]string{}
|
||||||
continue
|
continue
|
||||||
} else {
|
|
||||||
group[split[0]] = split[1]
|
|
||||||
}
|
}
|
||||||
|
group[split[0]] = split[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
// handling the last group
|
// handling the last group
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package nacoscli provides for getting the configuration from the nacos configuration center and parse it into a structure.
|
||||||
package nacoscli
|
package nacoscli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package prof is wrap the official `net/http/pprof` route and add the profile io wait time route.
|
||||||
package prof
|
package prof
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -24,8 +25,8 @@ var (
|
|||||||
timeFormat = "20060102T150405"
|
timeFormat = "20060102T150405"
|
||||||
|
|
||||||
status uint32
|
status uint32
|
||||||
statusStart uint32 = 1
|
statusStart uint32 = 1 // status=1
|
||||||
statusStop uint32 = 0
|
statusStop uint32 // status=0
|
||||||
)
|
)
|
||||||
|
|
||||||
// WaitSign wait system notification signals
|
// WaitSign wait system notification signals
|
||||||
@@ -52,7 +53,7 @@ type profile struct {
|
|||||||
files []string
|
files []string
|
||||||
closeFns []func()
|
closeFns []func()
|
||||||
|
|
||||||
ctx context.Context
|
//ctx context.Context
|
||||||
stopCh chan struct{}
|
stopCh chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +114,7 @@ func (p *profile) startProfile() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if isSamplingTrace {
|
if isSamplingTrace {
|
||||||
err = p.trace()
|
err = p.tracing()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
}
|
}
|
||||||
@@ -144,7 +145,8 @@ func (p *profile) stopProfile() {
|
|||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
p = NewProfile() // reset profile
|
// reset profile
|
||||||
|
p = NewProfile() //nolint
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *profile) checkTimeout() {
|
func (p *profile) checkTimeout() {
|
||||||
@@ -283,7 +285,7 @@ func (p *profile) threadCreate() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *profile) trace() error {
|
func (p *profile) tracing() error {
|
||||||
profileName := "trace"
|
profileName := "trace"
|
||||||
file := getFilePath(profileName)
|
file := getFilePath(profileName)
|
||||||
f, err := os.Create(file)
|
f, err := os.Create(file)
|
||||||
@@ -338,9 +340,9 @@ func getServerName() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func joinPath(elem ...string) string {
|
func joinPath(elem ...string) string {
|
||||||
path := strings.Join(elem, "/")
|
dir := strings.Join(elem, "/")
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
return strings.ReplaceAll(path, "/", "\\")
|
return strings.ReplaceAll(dir, "/", "\\")
|
||||||
}
|
}
|
||||||
return path
|
return dir
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
// Package replacer is a library of replacement file content, supports replacement of
|
||||||
|
// files in local directories and embedded directory files via embed.
|
||||||
package replacer
|
package replacer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -117,9 +119,8 @@ func (r *replacerInfo) SetSubDirsAndFiles(subDirs []string, subFiles ...string)
|
|||||||
if isSubPath(file, dir) {
|
if isSubPath(file, dir) {
|
||||||
if _, ok := isExistFile[file]; ok {
|
if _, ok := isExistFile[file]; ok {
|
||||||
continue
|
continue
|
||||||
} else {
|
|
||||||
isExistFile[file] = struct{}{}
|
|
||||||
}
|
}
|
||||||
|
isExistFile[file] = struct{}{}
|
||||||
files = append(files, file)
|
files = append(files, file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -127,9 +128,8 @@ func (r *replacerInfo) SetSubDirsAndFiles(subDirs []string, subFiles ...string)
|
|||||||
if isMatchFile(file, sf) {
|
if isMatchFile(file, sf) {
|
||||||
if _, ok := isExistFile[file]; ok {
|
if _, ok := isExistFile[file]; ok {
|
||||||
continue
|
continue
|
||||||
} else {
|
|
||||||
isExistFile[file] = struct{}{}
|
|
||||||
}
|
}
|
||||||
|
isExistFile[file] = struct{}{}
|
||||||
files = append(files, file)
|
files = append(files, file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -314,12 +314,13 @@ func isForbiddenFile(file string, path string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *replacerInfo) getNewFilePath(file string) string {
|
func (r *replacerInfo) getNewFilePath(file string) string {
|
||||||
var newFilePath string
|
//var newFilePath string
|
||||||
if r.isActual {
|
//if r.isActual {
|
||||||
newFilePath = r.outPath + strings.Replace(file, r.path, "", 1)
|
// newFilePath = r.outPath + strings.Replace(file, r.path, "", 1)
|
||||||
} else {
|
//} else {
|
||||||
newFilePath = r.outPath + strings.Replace(file, r.path, "", 1)
|
// newFilePath = r.outPath + strings.Replace(file, r.path, "", 1)
|
||||||
}
|
//}
|
||||||
|
newFilePath := r.outPath + strings.Replace(file, r.path, "", 1)
|
||||||
|
|
||||||
if gofile.IsWindows() {
|
if gofile.IsWindows() {
|
||||||
newFilePath = strings.ReplaceAll(newFilePath, "/", "\\")
|
newFilePath = strings.ReplaceAll(newFilePath, "/", "\\")
|
||||||
@@ -372,7 +373,7 @@ func listFiles(path string, fs embed.FS) ([]string, error) {
|
|||||||
return files, err
|
return files, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// iterating through the embedded catalogue
|
// iterating through the embedded catalog
|
||||||
func walkDir(dirPath string, allFiles *[]string, fs embed.FS) error {
|
func walkDir(dirPath string, allFiles *[]string, fs embed.FS) error {
|
||||||
files, err := fs.ReadDir(dirPath)
|
files, err := fs.ReadDir(dirPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -58,7 +58,7 @@ func NewBuilder(d registry.Discovery, opts ...Option) resolver.Builder {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *builder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) {
|
func (b *builder) Build(target resolver.Target, cc resolver.ClientConn, _ resolver.BuildOptions) (resolver.Resolver, error) {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
w registry.Watcher
|
w registry.Watcher
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package discovery is service discovery library, supports etcd, consul and nacos.
|
||||||
package discovery
|
package discovery
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -94,7 +95,7 @@ func (r *discoveryResolver) Close() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *discoveryResolver) ResolveNow(options resolver.ResolveNowOptions) {}
|
func (r *discoveryResolver) ResolveNow(_ resolver.ResolveNowOptions) {}
|
||||||
|
|
||||||
func parseAttributes(md map[string]string) *attributes.Attributes {
|
func parseAttributes(md map[string]string) *attributes.Attributes {
|
||||||
var a *attributes.Attributes
|
var a *attributes.Attributes
|
||||||
|
@@ -6,47 +6,64 @@ Service registry, corresponding to service [discovery](../discovery) corresponds
|
|||||||
|
|
||||||
```go
|
```go
|
||||||
func registryService(scheme string, host string, port int) (registry.Registry, *registry.ServiceInstance) {
|
func registryService(scheme string, host string, port int) (registry.Registry, *registry.ServiceInstance) {
|
||||||
instanceEndpoint := fmt.Sprintf("%s://%s:%d", scheme, host, port)
|
var (
|
||||||
cfg := config.Get()
|
instanceEndpoint = fmt.Sprintf("%s://%s:%d", scheme, host, port)
|
||||||
|
cfg = config.Get()
|
||||||
|
|
||||||
|
iRegistry registry.Registry
|
||||||
|
instance *registry.ServiceInstance
|
||||||
|
err error
|
||||||
|
|
||||||
|
id = cfg.App.Name + "_" + scheme + "_" + host
|
||||||
|
logField logger.Field
|
||||||
|
)
|
||||||
|
|
||||||
switch cfg.App.RegistryDiscoveryType {
|
switch cfg.App.RegistryDiscoveryType {
|
||||||
// registering service with consul
|
// registering service with consul
|
||||||
case "consul":
|
case "consul":
|
||||||
iRegistry, instance, err := consul.NewRegistry(
|
iRegistry, instance, err = consul.NewRegistry(
|
||||||
cfg.Consul.Addr,
|
cfg.Consul.Addr,
|
||||||
cfg.App.Name+"_"+scheme+"_"+host,
|
id,
|
||||||
cfg.App.Name,
|
cfg.App.Name,
|
||||||
[]string{instanceEndpoint},
|
[]string{instanceEndpoint},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
return iRegistry, instance
|
logField = logger.Any("consulAddress", cfg.Consul.Addr)
|
||||||
|
|
||||||
// registering service with etcd
|
// registering service with etcd
|
||||||
case "etcd":
|
case "etcd":
|
||||||
iRegistry, instance, err := etcd.NewRegistry(
|
iRegistry, instance, err = etcd.NewRegistry(
|
||||||
cfg.Etcd.Addrs,
|
cfg.Etcd.Addrs,
|
||||||
cfg.App.Name+"_"+scheme+"_"+host,
|
id,
|
||||||
cfg.App.Name,
|
cfg.App.Name,
|
||||||
[]string{instanceEndpoint},
|
[]string{instanceEndpoint},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
return iRegistry, instance
|
logField = logger.Any("etcdAddress", cfg.Etcd.Addrs)
|
||||||
|
|
||||||
// registering service with nacos
|
// registering service with nacos
|
||||||
case "nacos":
|
case "nacos":
|
||||||
iRegistry, instance, err := nacos.NewRegistry(
|
iRegistry, instance, err = nacos.NewRegistry(
|
||||||
cfg.NacosRd.IPAddr,
|
cfg.NacosRd.IPAddr,
|
||||||
cfg.NacosRd.Port,
|
cfg.NacosRd.Port,
|
||||||
cfg.NacosRd.NamespaceID,
|
cfg.NacosRd.NamespaceID,
|
||||||
cfg.App.Name+"_"+scheme+"_"+host,
|
id,
|
||||||
cfg.App.Name,
|
cfg.App.Name,
|
||||||
[]string{instanceEndpoint},
|
[]string{instanceEndpoint},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
logField = logger.String("nacosAddress", fmt.Sprintf("%v:%d", cfg.NacosRd.IPAddr, cfg.NacosRd.Port))
|
||||||
|
}
|
||||||
|
|
||||||
|
if instance != nil {
|
||||||
|
msg := fmt.Sprintf("register service address to %s", cfg.App.RegistryDiscoveryType)
|
||||||
|
logger.Info(msg, logField, logger.String("id", id), logger.String("name", cfg.App.Name), logger.String("endpoint", instanceEndpoint))
|
||||||
return iRegistry, instance
|
return iRegistry, instance
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -68,7 +68,7 @@ func (d *Client) Service(ctx context.Context, service string, index uint64, pass
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Register register service instance to consul
|
// Register register service instance to consul
|
||||||
func (d *Client) Register(ctx context.Context, svc *registry.ServiceInstance, enableHealthCheck bool) error {
|
func (d *Client) Register(_ context.Context, svc *registry.ServiceInstance, enableHealthCheck bool) error {
|
||||||
addresses := make(map[string]api.ServiceAddress)
|
addresses := make(map[string]api.ServiceAddress)
|
||||||
var addr string
|
var addr string
|
||||||
var port uint64
|
var port uint64
|
||||||
@@ -120,7 +120,7 @@ func (d *Client) Register(ctx context.Context, svc *registry.ServiceInstance, en
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Deregister deregister service by service ID
|
// Deregister deregister service by service ID
|
||||||
func (d *Client) Deregister(ctx context.Context, serviceID string) error {
|
func (d *Client) Deregister(_ context.Context, serviceID string) error {
|
||||||
d.cancel()
|
d.cancel()
|
||||||
return d.client.Agent().ServiceDeregister(serviceID)
|
return d.client.Agent().ServiceDeregister(serviceID)
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package consul is registered as a service using consul.
|
||||||
package consul
|
package consul
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -78,7 +79,7 @@ func (r *Registry) Deregister(ctx context.Context, svc *registry.ServiceInstance
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetService return service by name
|
// GetService return service by name
|
||||||
func (r *Registry) GetService(ctx context.Context, name string) (services []*registry.ServiceInstance, err error) {
|
func (r *Registry) GetService(_ context.Context, name string) (services []*registry.ServiceInstance, err error) {
|
||||||
r.lock.RLock()
|
r.lock.RLock()
|
||||||
defer r.lock.RUnlock()
|
defer r.lock.RUnlock()
|
||||||
set := r.registry[name]
|
set := r.registry[name]
|
||||||
@@ -90,7 +91,7 @@ func (r *Registry) GetService(ctx context.Context, name string) (services []*reg
|
|||||||
return nil, fmt.Errorf("service %s not found in registry", name)
|
return nil, fmt.Errorf("service %s not found in registry", name)
|
||||||
}
|
}
|
||||||
services = append(services, ss...)
|
services = append(services, ss...)
|
||||||
return
|
return //nolint
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListServices return service list.
|
// ListServices return service list.
|
||||||
@@ -107,11 +108,11 @@ func (r *Registry) ListServices() (allServices map[string][]*registry.ServiceIns
|
|||||||
services = append(services, ss...)
|
services = append(services, ss...)
|
||||||
allServices[name] = services
|
allServices[name] = services
|
||||||
}
|
}
|
||||||
return
|
return //nolint
|
||||||
}
|
}
|
||||||
|
|
||||||
// Watch resolve service by name
|
// Watch resolve service by name
|
||||||
func (r *Registry) Watch(ctx context.Context, name string) (registry.Watcher, error) {
|
func (r *Registry) Watch(_ context.Context, name string) (registry.Watcher, error) {
|
||||||
r.lock.Lock()
|
r.lock.Lock()
|
||||||
defer r.lock.Unlock()
|
defer r.lock.Unlock()
|
||||||
set, ok := r.registry[name]
|
set, ok := r.registry[name]
|
||||||
|
@@ -27,7 +27,7 @@ func (w *watcher) Next() (services []*registry.ServiceInstance, err error) {
|
|||||||
if ok {
|
if ok {
|
||||||
services = append(services, ss...)
|
services = append(services, ss...)
|
||||||
}
|
}
|
||||||
return
|
return //nolint
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *watcher) Stop() error {
|
func (w *watcher) Stop() error {
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package etcd is registered as a service using etcd.
|
||||||
package etcd
|
package etcd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -14,6 +15,7 @@ func marshal(si *registry.ServiceInstance) (string, error) {
|
|||||||
return string(data), nil
|
return string(data), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nolint
|
||||||
func unmarshal(data []byte) (si *registry.ServiceInstance, err error) {
|
func unmarshal(data []byte) (si *registry.ServiceInstance, err error) {
|
||||||
err = json.Unmarshal(data, &si)
|
err = json.Unmarshal(data, &si)
|
||||||
return
|
return
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package nacos is registered as a service using nacos.
|
||||||
package nacos
|
package nacos
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package registry is service registry library, supports etcd, consul and nacos.
|
||||||
package registry
|
package registry
|
||||||
|
|
||||||
import "context"
|
import "context"
|
||||||
|
@@ -9,6 +9,7 @@ Circuit Breaker for web middleware and rpc interceptor.
|
|||||||
**gin circuit breaker middleware**
|
**gin circuit breaker middleware**
|
||||||
|
|
||||||
```go
|
```go
|
||||||
|
// CircuitBreaker a circuit breaker middleware
|
||||||
func CircuitBreaker(opts ...CircuitBreakerOption) gin.HandlerFunc {
|
func CircuitBreaker(opts ...CircuitBreakerOption) gin.HandlerFunc {
|
||||||
o := defaultCircuitBreakerOptions()
|
o := defaultCircuitBreakerOptions()
|
||||||
o.apply(opts...)
|
o.apply(opts...)
|
||||||
@@ -16,8 +17,7 @@ func CircuitBreaker(opts ...CircuitBreakerOption) gin.HandlerFunc {
|
|||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
breaker := o.group.Get(c.FullPath()).(circuitbreaker.CircuitBreaker)
|
breaker := o.group.Get(c.FullPath()).(circuitbreaker.CircuitBreaker)
|
||||||
if err := breaker.Allow(); err != nil {
|
if err := breaker.Allow(); err != nil {
|
||||||
// NOTE: when client reject request locally,
|
// NOTE: when client reject request locally, keep adding counter let the drop ratio higher.
|
||||||
// continue to add counter let the drop ratio higher.
|
|
||||||
breaker.MarkFailed()
|
breaker.MarkFailed()
|
||||||
response.Output(c, http.StatusServiceUnavailable, err.Error())
|
response.Output(c, http.StatusServiceUnavailable, err.Error())
|
||||||
c.Abort()
|
c.Abort()
|
||||||
@@ -27,8 +27,9 @@ func CircuitBreaker(opts ...CircuitBreakerOption) gin.HandlerFunc {
|
|||||||
c.Next()
|
c.Next()
|
||||||
|
|
||||||
code := c.Writer.Status()
|
code := c.Writer.Status()
|
||||||
// NOTE: need to check internal and service unavailable error
|
// NOTE: need to check internal and service unavailable error, e.g. http.StatusInternalServerError
|
||||||
if code == http.StatusInternalServerError || code == http.StatusServiceUnavailable || code == http.StatusGatewayTimeout {
|
_, isHit := o.validCodes[code]
|
||||||
|
if isHit {
|
||||||
breaker.MarkFailed()
|
breaker.MarkFailed()
|
||||||
} else {
|
} else {
|
||||||
breaker.MarkSuccess()
|
breaker.MarkSuccess()
|
||||||
@@ -37,9 +38,12 @@ func CircuitBreaker(opts ...CircuitBreakerOption) gin.HandlerFunc {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
**rpc server circuit breaker interceptor**
|
**rpc server circuit breaker interceptor**
|
||||||
|
|
||||||
```go
|
```go
|
||||||
|
// UnaryServerCircuitBreaker server-side unary circuit breaker interceptor
|
||||||
func UnaryServerCircuitBreaker(opts ...CircuitBreakerOption) grpc.UnaryServerInterceptor {
|
func UnaryServerCircuitBreaker(opts ...CircuitBreakerOption) grpc.UnaryServerInterceptor {
|
||||||
o := defaultCircuitBreakerOptions()
|
o := defaultCircuitBreakerOptions()
|
||||||
o.apply(opts...)
|
o.apply(opts...)
|
||||||
@@ -47,8 +51,7 @@ func UnaryServerCircuitBreaker(opts ...CircuitBreakerOption) grpc.UnaryServerInt
|
|||||||
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||||
breaker := o.group.Get(info.FullMethod).(circuitbreaker.CircuitBreaker)
|
breaker := o.group.Get(info.FullMethod).(circuitbreaker.CircuitBreaker)
|
||||||
if err := breaker.Allow(); err != nil {
|
if err := breaker.Allow(); err != nil {
|
||||||
// NOTE: when client reject request locally,
|
// NOTE: when client reject request locally, keep adding let the drop ratio higher.
|
||||||
// continue to add counter let the drop ratio higher.
|
|
||||||
breaker.MarkFailed()
|
breaker.MarkFailed()
|
||||||
return nil, errcode.StatusServiceUnavailable.ToRPCErr(err.Error())
|
return nil, errcode.StatusServiceUnavailable.ToRPCErr(err.Error())
|
||||||
}
|
}
|
||||||
@@ -57,7 +60,8 @@ func UnaryServerCircuitBreaker(opts ...CircuitBreakerOption) grpc.UnaryServerInt
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
// NOTE: need to check internal and service unavailable error
|
// NOTE: need to check internal and service unavailable error
|
||||||
s, ok := status.FromError(err)
|
s, ok := status.FromError(err)
|
||||||
if ok && (s.Code() == codes.Internal || s.Code() == codes.Unavailable) {
|
_, isHit := o.validCodes[s.Code()]
|
||||||
|
if ok && isHit {
|
||||||
breaker.MarkFailed()
|
breaker.MarkFailed()
|
||||||
} else {
|
} else {
|
||||||
breaker.MarkSuccess()
|
breaker.MarkSuccess()
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package circuitbreaker is an adaptive circuit breaker library, support for use in gin middleware and grpc interceptors.
|
||||||
package circuitbreaker
|
package circuitbreaker
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -117,7 +117,7 @@ func (b *Breaker) summary() (success int64, total int64) {
|
|||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
})
|
})
|
||||||
return
|
return //nolint
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow request if error returns nil.
|
// Allow request if error returns nil.
|
||||||
@@ -147,8 +147,7 @@ func (b *Breaker) MarkSuccess() {
|
|||||||
|
|
||||||
// MarkFailed mark request is failed.
|
// MarkFailed mark request is failed.
|
||||||
func (b *Breaker) MarkFailed() {
|
func (b *Breaker) MarkFailed() {
|
||||||
// NOTE: when client reject requets locally, continue add counter let the
|
// NOTE: when client reject request locally, keep adding counter let the drop ratio higher.
|
||||||
// drop ratio higher.
|
|
||||||
b.stat.Add(0)
|
b.stat.Add(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,5 +155,5 @@ func (b *Breaker) trueOnProba(proba float64) (truth bool) {
|
|||||||
b.randLock.Lock()
|
b.randLock.Lock()
|
||||||
truth = b.r.Float64() < proba
|
truth = b.r.Float64() < proba
|
||||||
b.randLock.Unlock()
|
b.randLock.Unlock()
|
||||||
return
|
return truth
|
||||||
}
|
}
|
||||||
|
@@ -51,7 +51,7 @@ func (c *cgroup) CPUAcctUsagePerCPU() ([]uint64, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var usage []uint64
|
var usage []uint64
|
||||||
for _, v := range strings.Fields(string(data)) {
|
for _, v := range strings.Fields(data) {
|
||||||
var u uint64
|
var u uint64
|
||||||
if u, err = parseUint(v); err != nil {
|
if u, err = parseUint(v); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -90,7 +90,7 @@ func currentcGroup() (*cgroup, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer fp.Close()
|
defer fp.Close() //nolint
|
||||||
buf := bufio.NewReader(fp)
|
buf := bufio.NewReader(fp)
|
||||||
for {
|
for {
|
||||||
line, err := buf.ReadString('\n')
|
line, err := buf.ReadString('\n')
|
||||||
|
@@ -32,14 +32,14 @@ func newCgroupCPU() (cpu *cgroupCPU, err error) {
|
|||||||
|
|
||||||
sets, err := cpuSets()
|
sets, err := cpuSets()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
quota := float64(len(sets))
|
quota := float64(len(sets))
|
||||||
cq, err := cpuQuota()
|
cq, err := cpuQuota()
|
||||||
if err == nil && cq != -1 {
|
if err == nil && cq != -1 {
|
||||||
var period uint64
|
var period uint64
|
||||||
if period, err = cpuPeriod(); err != nil {
|
if period, err = cpuPeriod(); err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
limit := float64(cq) / float64(period)
|
limit := float64(cq) / float64(period)
|
||||||
if limit < quota {
|
if limit < quota {
|
||||||
@@ -50,11 +50,11 @@ func newCgroupCPU() (cpu *cgroupCPU, err error) {
|
|||||||
|
|
||||||
preSystem, err := systemCPUUsage()
|
preSystem, err := systemCPUUsage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
preTotal, err := totalCPUUsage()
|
preTotal, err := totalCPUUsage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
cpu = &cgroupCPU{
|
cpu = &cgroupCPU{
|
||||||
frequency: maxFreq,
|
frequency: maxFreq,
|
||||||
@@ -63,7 +63,7 @@ func newCgroupCPU() (cpu *cgroupCPU, err error) {
|
|||||||
preSystem: preSystem,
|
preSystem: preSystem,
|
||||||
preTotal: preTotal,
|
preTotal: preTotal,
|
||||||
}
|
}
|
||||||
return
|
return cpu, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cpu *cgroupCPU) Usage() (u uint64, err error) {
|
func (cpu *cgroupCPU) Usage() (u uint64, err error) {
|
||||||
@@ -73,18 +73,18 @@ func (cpu *cgroupCPU) Usage() (u uint64, err error) {
|
|||||||
)
|
)
|
||||||
total, err = totalCPUUsage()
|
total, err = totalCPUUsage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
system, err = systemCPUUsage()
|
system, err = systemCPUUsage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
if system != cpu.preSystem {
|
if system != cpu.preSystem {
|
||||||
u = uint64(float64((total-cpu.preTotal)*cpu.cores*1e3) / (float64(system-cpu.preSystem) * cpu.quota))
|
u = uint64(float64((total-cpu.preTotal)*cpu.cores*1e3) / (float64(system-cpu.preSystem) * cpu.quota))
|
||||||
}
|
}
|
||||||
cpu.preSystem = system
|
cpu.preSystem = system
|
||||||
cpu.preTotal = total
|
cpu.preTotal = total
|
||||||
return
|
return u, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cpu *cgroupCPU) Info() Info {
|
func (cpu *cgroupCPU) Info() Info {
|
||||||
@@ -115,45 +115,44 @@ func systemCPUUsage() (usage uint64, err error) {
|
|||||||
f *os.File
|
f *os.File
|
||||||
)
|
)
|
||||||
if f, err = os.Open("/proc/stat"); err != nil {
|
if f, err = os.Open("/proc/stat"); err != nil {
|
||||||
return
|
return usage, err
|
||||||
}
|
}
|
||||||
bufReader := bufio.NewReaderSize(nil, 128)
|
bufReader := bufio.NewReaderSize(nil, 128)
|
||||||
defer func() {
|
defer func() {
|
||||||
bufReader.Reset(nil)
|
bufReader.Reset(nil)
|
||||||
f.Close()
|
_ = f.Close()
|
||||||
}()
|
}()
|
||||||
bufReader.Reset(f)
|
bufReader.Reset(f)
|
||||||
for err == nil {
|
for err == nil {
|
||||||
if line, err = bufReader.ReadString('\n'); err != nil {
|
if line, err = bufReader.ReadString('\n'); err != nil {
|
||||||
return
|
return usage, err
|
||||||
}
|
}
|
||||||
parts := strings.Fields(line)
|
parts := strings.Fields(line)
|
||||||
switch parts[0] {
|
if parts[0] == "cpu" {
|
||||||
case "cpu":
|
|
||||||
if len(parts) < 8 {
|
if len(parts) < 8 {
|
||||||
err = errors.New("bad format of cpu stats")
|
err = errors.New("bad format of cpu stats")
|
||||||
return
|
return usage, err
|
||||||
}
|
}
|
||||||
var totalClockTicks uint64
|
var totalClockTicks uint64
|
||||||
for _, i := range parts[1:8] {
|
for _, i := range parts[1:8] {
|
||||||
var v uint64
|
var v uint64
|
||||||
if v, err = strconv.ParseUint(i, 10, 64); err != nil {
|
if v, err = strconv.ParseUint(i, 10, 64); err != nil {
|
||||||
return
|
return usage, err
|
||||||
}
|
}
|
||||||
totalClockTicks += v
|
totalClockTicks += v
|
||||||
}
|
}
|
||||||
usage = (totalClockTicks * nanoSecondsPerSecond) / clockTicksPerSecond
|
usage = (totalClockTicks * nanoSecondsPerSecond) / clockTicksPerSecond
|
||||||
return
|
return usage, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = errors.New("bad stats format")
|
err = errors.New("bad stats format")
|
||||||
return
|
return usage, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func totalCPUUsage() (usage uint64, err error) {
|
func totalCPUUsage() (usage uint64, err error) {
|
||||||
var cg *cgroup
|
var cg *cgroup
|
||||||
if cg, err = currentcGroup(); err != nil {
|
if cg, err = currentcGroup(); err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
return cg.CPUAcctUsage()
|
return cg.CPUAcctUsage()
|
||||||
}
|
}
|
||||||
@@ -161,7 +160,7 @@ func totalCPUUsage() (usage uint64, err error) {
|
|||||||
func perCPUUsage() (usage []uint64, err error) {
|
func perCPUUsage() (usage []uint64, err error) {
|
||||||
var cg *cgroup
|
var cg *cgroup
|
||||||
if cg, err = currentcGroup(); err != nil {
|
if cg, err = currentcGroup(); err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
return cg.CPUAcctUsagePerCPU()
|
return cg.CPUAcctUsagePerCPU()
|
||||||
}
|
}
|
||||||
@@ -169,7 +168,7 @@ func perCPUUsage() (usage []uint64, err error) {
|
|||||||
func cpuSets() (sets []uint64, err error) {
|
func cpuSets() (sets []uint64, err error) {
|
||||||
var cg *cgroup
|
var cg *cgroup
|
||||||
if cg, err = currentcGroup(); err != nil {
|
if cg, err = currentcGroup(); err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
return cg.CPUSetCPUs()
|
return cg.CPUSetCPUs()
|
||||||
}
|
}
|
||||||
@@ -177,7 +176,7 @@ func cpuSets() (sets []uint64, err error) {
|
|||||||
func cpuQuota() (quota int64, err error) {
|
func cpuQuota() (quota int64, err error) {
|
||||||
var cg *cgroup
|
var cg *cgroup
|
||||||
if cg, err = currentcGroup(); err != nil {
|
if cg, err = currentcGroup(); err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
return cg.CPUCFSQuotaUs()
|
return cg.CPUCFSQuotaUs()
|
||||||
}
|
}
|
||||||
@@ -185,7 +184,7 @@ func cpuQuota() (quota int64, err error) {
|
|||||||
func cpuPeriod() (peroid uint64, err error) {
|
func cpuPeriod() (peroid uint64, err error) {
|
||||||
var cg *cgroup
|
var cg *cgroup
|
||||||
if cg, err = currentcGroup(); err != nil {
|
if cg, err = currentcGroup(); err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
return cg.CPUCFSPeriodUs()
|
return cg.CPUCFSPeriodUs()
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package cpu is a library that calculates cpu and memory usage.
|
||||||
package cpu
|
package cpu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -10,36 +11,36 @@ type psutilCPU struct {
|
|||||||
interval time.Duration
|
interval time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPsutilCPU(interval time.Duration) (cpu *psutilCPU, err error) {
|
func newPsutilCPU(interval time.Duration) (*psutilCPU, error) {
|
||||||
cpu = &psutilCPU{interval: interval}
|
psCPU := &psutilCPU{interval: interval}
|
||||||
_, err = cpu.Usage()
|
_, err := psCPU.Usage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return nil, err
|
||||||
}
|
}
|
||||||
return
|
return psCPU, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ps *psutilCPU) Usage() (u uint64, err error) {
|
func (ps *psutilCPU) Usage() (uint64, error) {
|
||||||
var percents []float64
|
var u uint64
|
||||||
percents, err = cpu.Percent(ps.interval, false)
|
percents, err := cpu.Percent(ps.interval, false)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
u = uint64(percents[0] * 10)
|
u = uint64(percents[0] * 10)
|
||||||
}
|
}
|
||||||
return
|
return u, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ps *psutilCPU) Info() (info Info) {
|
func (ps *psutilCPU) Info() Info {
|
||||||
stats, err := cpu.Info()
|
stats, err := cpu.Info()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return Info{}
|
||||||
}
|
}
|
||||||
cores, err := cpu.Counts(true)
|
cores, err := cpu.Counts(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return Info{}
|
||||||
}
|
}
|
||||||
info = Info{
|
|
||||||
|
return Info{
|
||||||
Frequency: uint64(stats[0].Mhz),
|
Frequency: uint64(stats[0].Mhz),
|
||||||
Quota: float64(cores),
|
Quota: float64(cores),
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
@@ -3,14 +3,13 @@ package cpu
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func readFile(path string) (string, error) {
|
func readFile(path string) (string, error) {
|
||||||
contents, err := ioutil.ReadFile(path)
|
contents, err := os.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -101,7 +100,7 @@ func readLinesOffsetN(filename string, offset uint, n int) ([]string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return []string{""}, err
|
return []string{""}, err
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close() //nolint
|
||||||
|
|
||||||
var ret []string
|
var ret []string
|
||||||
|
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package ratelimit is an adaptive rate limit library, support for use in gin middleware and grpc interceptors.
|
||||||
package ratelimit
|
package ratelimit
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -252,9 +253,8 @@ func (l *BBR) shouldDrop() bool {
|
|||||||
// accept current request
|
// accept current request
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if time.Duration(now-prevDropTime) <= time.Second {
|
if now-prevDropTime <= time.Second {
|
||||||
// just start drop one second ago,
|
// just start drop one second ago, check current inflight count
|
||||||
// check current inflight count
|
|
||||||
inFlight := atomic.LoadInt64(&l.inFlight)
|
inFlight := atomic.LoadInt64(&l.inFlight)
|
||||||
return inFlight > 1 && inFlight > l.maxInFlight()
|
return inFlight > 1 && inFlight > l.maxInFlight()
|
||||||
}
|
}
|
||||||
@@ -297,8 +297,7 @@ func (l *BBR) Allow() (DoneFunc, error) {
|
|||||||
start := time.Now().UnixNano()
|
start := time.Now().UnixNano()
|
||||||
ms := float64(time.Millisecond)
|
ms := float64(time.Millisecond)
|
||||||
return func(DoneInfo) {
|
return func(DoneInfo) {
|
||||||
//nolint
|
rt := int64(math.Ceil(float64(time.Now().UnixNano()-start)) / ms) //nolint
|
||||||
rt := int64(math.Ceil(float64(time.Now().UnixNano()-start)) / ms)
|
|
||||||
l.rtStat.Add(rt)
|
l.rtStat.Add(rt)
|
||||||
atomic.AddInt64(&l.inFlight, -1)
|
atomic.AddInt64(&l.inFlight, -1)
|
||||||
l.passStat.Add(1)
|
l.passStat.Add(1)
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package window is a library that calculates windows cpu and memory usage.
|
||||||
package window
|
package window
|
||||||
|
|
||||||
// Bucket contains multiple float64 points.
|
// Bucket contains multiple float64 points.
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
// Package parser is a library that parses to go structures based on sql
|
||||||
|
// and generates the code needed based on the template.
|
||||||
package parser
|
package parser
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -68,9 +70,9 @@ func ParseSQL(sql string, options ...Option) (map[string]string, error) {
|
|||||||
tableNames := make([]string, 0, len(stmts))
|
tableNames := make([]string, 0, len(stmts))
|
||||||
for _, stmt := range stmts {
|
for _, stmt := range stmts {
|
||||||
if ct, ok := stmt.(*ast.CreateTableStmt); ok {
|
if ct, ok := stmt.(*ast.CreateTableStmt); ok {
|
||||||
code, err := makeCode(ct, opt) //nolint
|
code, err2 := makeCode(ct, opt)
|
||||||
if err != nil {
|
if err2 != nil {
|
||||||
return nil, err
|
return nil, err2
|
||||||
}
|
}
|
||||||
modelStructCodes = append(modelStructCodes, code.modelStruct)
|
modelStructCodes = append(modelStructCodes, code.modelStruct)
|
||||||
updateFieldsCodes = append(updateFieldsCodes, code.updateFields)
|
updateFieldsCodes = append(updateFieldsCodes, code.updateFields)
|
||||||
@@ -150,12 +152,12 @@ func (t tmplField) ConditionZero() string {
|
|||||||
// GoZero type of 0
|
// GoZero type of 0
|
||||||
func (t tmplField) GoZero() string {
|
func (t tmplField) GoZero() string {
|
||||||
switch t.GoType {
|
switch t.GoType {
|
||||||
case "int8", "int16", "int32", "int64", "int", "uint8", "uint16", "uint32", "uint64", "uint", "float64", "float32", //nolint
|
case "int8", "int16", "int32", "int64", "int", "uint8", "uint16", "uint32", "uint64", "uint", "float64", "float32",
|
||||||
"sql.NullInt32", "sql.NullInt64", "sql.NullFloat64": //nolint
|
"sql.NullInt32", "sql.NullInt64", "sql.NullFloat64":
|
||||||
return `= 0`
|
return `= 0`
|
||||||
case "string", "sql.NullString": //nolint
|
case "string", "sql.NullString":
|
||||||
return `= "string"`
|
return `= "string"`
|
||||||
case "time.Time", "*time.Time", "sql.NullTime": //nolint
|
case "time.Time", "*time.Time", "sql.NullTime":
|
||||||
return `= "0000-01-00T00:00:00.000+08:00"`
|
return `= "0000-01-00T00:00:00.000+08:00"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,12 +167,12 @@ func (t tmplField) GoZero() string {
|
|||||||
// GoTypeZero type of 0
|
// GoTypeZero type of 0
|
||||||
func (t tmplField) GoTypeZero() string {
|
func (t tmplField) GoTypeZero() string {
|
||||||
switch t.GoType {
|
switch t.GoType {
|
||||||
case "int8", "int16", "int32", "int64", "int", "uint8", "uint16", "uint32", "uint64", "uint", "float64", "float32", //nolint
|
case "int8", "int16", "int32", "int64", "int", "uint8", "uint16", "uint32", "uint64", "uint", "float64", "float32",
|
||||||
"sql.NullInt32", "sql.NullInt64", "sql.NullFloat64": //nolint
|
"sql.NullInt32", "sql.NullInt64", "sql.NullFloat64":
|
||||||
return `0`
|
return `0`
|
||||||
case "string", "sql.NullString": //nolint
|
case "string", "sql.NullString":
|
||||||
return `""`
|
return `""`
|
||||||
case "time.Time", "*time.Time", "sql.NullTime": //nolint
|
case "time.Time", "*time.Time", "sql.NullTime":
|
||||||
return `0 /*time.Now().Second()*/`
|
return `0 /*time.Now().Second()*/`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,7 +211,6 @@ const (
|
|||||||
columnMysqlModel = __mysqlModel__
|
columnMysqlModel = __mysqlModel__
|
||||||
)
|
)
|
||||||
|
|
||||||
// nolint
|
|
||||||
var ignoreColumns = map[string]struct{}{
|
var ignoreColumns = map[string]struct{}{
|
||||||
columnID: {},
|
columnID: {},
|
||||||
columnCreatedAt: {},
|
columnCreatedAt: {},
|
||||||
@@ -481,6 +482,8 @@ func getModelCode(data modelCodes) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getUpdateFieldsCode(data tmplData, isEmbed bool) (string, error) {
|
func getUpdateFieldsCode(data tmplData, isEmbed bool) (string, error) {
|
||||||
|
_ = isEmbed
|
||||||
|
|
||||||
// filter fields
|
// filter fields
|
||||||
var newFields = []tmplField{}
|
var newFields = []tmplField{}
|
||||||
for _, field := range data.Fields {
|
for _, field := range data.Fields {
|
||||||
@@ -525,7 +528,7 @@ func getHandlerStructCodes(data tmplData) (string, error) {
|
|||||||
return postStructCode + putStructCode + getStructCode, nil
|
return postStructCode + putStructCode + getStructCode, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// customised filter fields
|
// customized filter fields
|
||||||
func tmplExecuteWithFilter(data tmplData, tmpl *template.Template, reservedColumns ...string) (string, error) {
|
func tmplExecuteWithFilter(data tmplData, tmpl *template.Template, reservedColumns ...string) (string, error) {
|
||||||
var newFields = []tmplField{}
|
var newFields = []tmplField{}
|
||||||
for _, field := range data.Fields {
|
for _, field := range data.Fields {
|
||||||
@@ -668,13 +671,13 @@ func mysqlToGoType(colTp *types.FieldType, style NullStyle) (name string, path s
|
|||||||
name = "sql.NullFloat64"
|
name = "sql.NullFloat64"
|
||||||
case mysql.TypeString, mysql.TypeVarchar, mysql.TypeVarString,
|
case mysql.TypeString, mysql.TypeVarchar, mysql.TypeVarString,
|
||||||
mysql.TypeBlob, mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob:
|
mysql.TypeBlob, mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob:
|
||||||
name = "sql.NullString" //nolint
|
name = "sql.NullString"
|
||||||
case mysql.TypeTimestamp, mysql.TypeDatetime, mysql.TypeDate:
|
case mysql.TypeTimestamp, mysql.TypeDatetime, mysql.TypeDate:
|
||||||
name = "sql.NullTime"
|
name = "sql.NullTime"
|
||||||
case mysql.TypeDecimal, mysql.TypeNewDecimal:
|
case mysql.TypeDecimal, mysql.TypeNewDecimal:
|
||||||
name = "sql.NullString" //nolint
|
name = "sql.NullString"
|
||||||
case mysql.TypeJSON:
|
case mysql.TypeJSON:
|
||||||
name = "sql.NullString" //nolint
|
name = "sql.NullString"
|
||||||
default:
|
default:
|
||||||
return "UnSupport", ""
|
return "UnSupport", ""
|
||||||
}
|
}
|
||||||
@@ -690,7 +693,7 @@ func mysqlToGoType(colTp *types.FieldType, style NullStyle) (name string, path s
|
|||||||
if mysql.HasUnsignedFlag(colTp.Flag) {
|
if mysql.HasUnsignedFlag(colTp.Flag) {
|
||||||
name = "uint64"
|
name = "uint64"
|
||||||
} else {
|
} else {
|
||||||
name = "int64" //nolint
|
name = "int64"
|
||||||
}
|
}
|
||||||
case mysql.TypeFloat, mysql.TypeDouble:
|
case mysql.TypeFloat, mysql.TypeDouble:
|
||||||
name = "float64"
|
name = "float64"
|
||||||
@@ -711,7 +714,7 @@ func mysqlToGoType(colTp *types.FieldType, style NullStyle) (name string, path s
|
|||||||
name = "*" + name
|
name = "*" + name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return name, path
|
||||||
}
|
}
|
||||||
|
|
||||||
func goTypeToProto(fields []tmplField) []tmplField {
|
func goTypeToProto(fields []tmplField) []tmplField {
|
||||||
@@ -758,7 +761,7 @@ func getDefaultValue(expr ast.ExprNode) (value string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
var acronym = map[string]struct{}{
|
var acronym = map[string]struct{}{
|
||||||
|
@@ -1,9 +1,10 @@
|
|||||||
package parser
|
package parser
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pkg/errors"
|
|
||||||
"sync"
|
"sync"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@@ -1,3 +1,6 @@
|
|||||||
|
// Package sql2code provides for generating code for different purposes according to sql,
|
||||||
|
// support generating json, gorm model, update parameter, request parameter code,
|
||||||
|
// sql can be obtained from parameter, file, db three ways, priority from high to low.
|
||||||
package sql2code
|
package sql2code
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package cpu is a library that counts system and process cpu usage.
|
||||||
package cpu
|
package cpu
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package mem is a library that counts system and process memory usage.
|
||||||
package mem
|
package mem
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -3,14 +3,21 @@
|
|||||||
|
|
||||||
package stat
|
package stat
|
||||||
|
|
||||||
import "syscall"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
// nolint
|
||||||
func init() {
|
func init() {
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-notifyCh:
|
case <-notifyCh:
|
||||||
syscall.Kill(syscall.Getpid(), syscall.SIGTRAP)
|
err := syscall.Kill(syscall.Getpid(), syscall.SIGTRAP)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package stat provides for counting system and process cpu and memory information, alarm notification support.
|
||||||
package stat
|
package stat
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -68,6 +69,7 @@ func Init(opts ...Option) {
|
|||||||
o := &options{}
|
o := &options{}
|
||||||
o.apply(opts...)
|
o.apply(opts...)
|
||||||
|
|
||||||
|
//nolint
|
||||||
go func() {
|
go func() {
|
||||||
printTick := time.NewTicker(printInfoInterval)
|
printTick := time.NewTicker(printInfoInterval)
|
||||||
defer printTick.Stop()
|
defer printTick.Stop()
|
||||||
@@ -87,16 +89,16 @@ func Init(opts ...Option) {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nolint
|
||||||
func sendSystemSignForLinux() {
|
func sendSystemSignForLinux() {
|
||||||
select {
|
select {
|
||||||
case notifyCh <- struct{}{}:
|
case notifyCh <- struct{}{}:
|
||||||
default:
|
default:
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func printUsageInfo() *statData {
|
func printUsageInfo() *statData {
|
||||||
defer func() { recover() }()
|
defer func() { _ = recover() }()
|
||||||
|
|
||||||
mSys := mem.GetSystemMemory()
|
mSys := mem.GetSystemMemory()
|
||||||
mProc := mem.GetProcessMemory()
|
mProc := mem.GetProcessMemory()
|
||||||
|
@@ -5,13 +5,12 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
|
"go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
|
||||||
stdout "go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
|
|
||||||
sdkTrace "go.opentelemetry.io/otel/sdk/trace"
|
sdkTrace "go.opentelemetry.io/otel/sdk/trace"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewConsoleExporter output to console
|
// NewConsoleExporter output to console
|
||||||
func NewConsoleExporter() (sdkTrace.SpanExporter, error) {
|
func NewConsoleExporter() (sdkTrace.SpanExporter, error) {
|
||||||
return stdout.New(stdout.WithPrettyPrint())
|
return stdouttrace.New(stdouttrace.WithPrettyPrint())
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFileExporter output to file, note: close the file before ending
|
// NewFileExporter output to file, note: close the file before ending
|
||||||
@@ -37,9 +36,9 @@ func NewFileExporter(filename string) (sdkTrace.SpanExporter, *os.File, error) {
|
|||||||
func newExporter(w io.Writer) (sdkTrace.SpanExporter, error) {
|
func newExporter(w io.Writer) (sdkTrace.SpanExporter, error) {
|
||||||
return stdouttrace.New(
|
return stdouttrace.New(
|
||||||
stdouttrace.WithWriter(w),
|
stdouttrace.WithWriter(w),
|
||||||
// Use human readable output.
|
// output to console.
|
||||||
stdouttrace.WithPrettyPrint(),
|
stdouttrace.WithPrettyPrint(),
|
||||||
// Do not print timestamps for the demo.
|
// do not print timestamps for the demo.
|
||||||
stdouttrace.WithoutTimestamps(),
|
stdouttrace.WithoutTimestamps(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@@ -22,6 +22,7 @@ func SetTraceName(name string) {
|
|||||||
func NewSpan(ctx context.Context, spanName string, tags map[string]interface{}) (context.Context, trace.Span) {
|
func NewSpan(ctx context.Context, spanName string, tags map[string]interface{}) (context.Context, trace.Span) {
|
||||||
var opts []trace.SpanStartOption
|
var opts []trace.SpanStartOption
|
||||||
|
|
||||||
|
//nolint
|
||||||
for k, v := range tags {
|
for k, v := range tags {
|
||||||
var tag attribute.KeyValue
|
var tag attribute.KeyValue
|
||||||
switch v.(type) {
|
switch v.(type) {
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package tracer is a library wrapped in go.opentelemetry.io/otel.
|
||||||
package tracer
|
package tracer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
// Package utils is a library of commonly used utility functions.
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -16,14 +17,14 @@ func GetHostname() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetLocalHTTPAddrPairs get available http server and request address
|
// GetLocalHTTPAddrPairs get available http server and request address
|
||||||
func GetLocalHTTPAddrPairs() (string, string) {
|
func GetLocalHTTPAddrPairs() (serverAddr string, requestAddr string) {
|
||||||
port, err := GetAvailablePort()
|
port, err := GetAvailablePort()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("GetAvailablePort error: %v\n", err)
|
fmt.Printf("GetAvailablePort error: %v\n", err)
|
||||||
return "", ""
|
return "", ""
|
||||||
}
|
}
|
||||||
serverAddr := fmt.Sprintf(":%d", port)
|
serverAddr = fmt.Sprintf(":%d", port)
|
||||||
requestAddr := fmt.Sprintf("http://127.0.0.1:%d", port)
|
requestAddr = fmt.Sprintf("http://127.0.0.1:%d", port)
|
||||||
return serverAddr, requestAddr
|
return serverAddr, requestAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user