Skip to content

Commit

Permalink
add Paymaster Mertics Log
Browse files Browse the repository at this point in the history
  • Loading branch information
cherry-yl-sh committed May 29, 2024
1 parent 7c79240 commit cdc3a21
Show file tree
Hide file tree
Showing 10 changed files with 166 additions and 29 deletions.
6 changes: 6 additions & 0 deletions common/network/ethereum_adaptable_executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/sirupsen/logrus"
"testing"
"time"
)

func TestEthereumAdaptableExecutor(t *testing.T) {
Expand Down Expand Up @@ -365,3 +366,8 @@ func testEthereumExecutorClientConnect(t *testing.T, chain global_const.Network)
}
t.Logf("network %s chainId: %s", chain, chainId.String())
}
func TestTime(t *testing.T) {
start := time.Now()
t.Logf("start time: %v", start.String())
t.Logf("start time: %v", start.Format("2006-01-02 15:04:05.MST"))
}
1 change: 1 addition & 0 deletions common/utils/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ func GenerateMockUservOperation() *map[string]any {

return &MockUserOpData
}

func ValidateHex(value string) bool {
if HexPattern.MatchString(value) {
return true
Expand Down
2 changes: 0 additions & 2 deletions rpc_server/api/health.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"AAStarCommunity/EthPaymaster_BackService/common/model"
"AAStarCommunity/EthPaymaster_BackService/envirment"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
"time"
)

Expand All @@ -17,7 +16,6 @@ import (
// @Success 200
func Healthz(c *gin.Context) {
response := model.GetResponse()
logrus.Debug("In the Healthz")
response.WithDataSuccess(c, gin.H{
"hello": "Eth Paymaster",
"environment": envirment.Environment.Name,
Expand Down
24 changes: 12 additions & 12 deletions rpc_server/api/v1/paymaster.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package v1
import (
"AAStarCommunity/EthPaymaster_BackService/common/global_const"
"AAStarCommunity/EthPaymaster_BackService/common/model"
"AAStarCommunity/EthPaymaster_BackService/common/utils"
"AAStarCommunity/EthPaymaster_BackService/config"
"AAStarCommunity/EthPaymaster_BackService/service/operator"
"fmt"
Expand Down Expand Up @@ -38,16 +37,17 @@ func Paymaster(ctx *gin.Context) {

jsonRpcRequest := model.JsonRpcRequest{}
response := model.GetResponse()

defer func() {
if r := recover(); r != nil {
errInfo := fmt.Sprintf("[panic]: err : [%v] , stack :[%v]", r, utils.GetCurrentGoroutineStack())
logrus.Error(errInfo)
response.SetHttpCode(http.StatusInternalServerError).FailCode(ctx, http.StatusInternalServerError, fmt.Sprintf("%v", r))
}

}()
//
//defer func() {
// if r := recover(); r != nil {
// errInfo := fmt.Sprintf("[panic]: err : [%v] , stack :[%v]", r, utils.GetCurrentGoroutineStack())
// logrus.Error(errInfo)
// response.SetHttpCode(http.StatusInternalServerError).FailCode(ctx, http.StatusInternalServerError, fmt.Sprintf("%v", r))
// }
//
//}()
network := ctx.Param("network")
logrus.Debugf("Paymaster network: %s", network)
if network == "" {
errStr := fmt.Sprintf("Request Error [network is empty]")
response.SetHttpCode(http.StatusBadRequest).FailCode(ctx, http.StatusBadRequest, errStr)
Expand All @@ -58,13 +58,13 @@ func Paymaster(ctx *gin.Context) {
response.SetHttpCode(http.StatusBadRequest).FailCode(ctx, http.StatusBadRequest, errStr)
return
}
jsonRpcRequest.Network = global_const.Network(network)

if err := ctx.ShouldBindJSON(&jsonRpcRequest); err != nil {
errStr := fmt.Sprintf("Request Error [%v]", err)
errStr := fmt.Sprintf("Parse Request Error [%v]", err)
response.SetHttpCode(http.StatusBadRequest).FailCode(ctx, http.StatusBadRequest, errStr)
return
}
jsonRpcRequest.Network = global_const.Network(network)
method := jsonRpcRequest.Method
if method == "" {
errStr := fmt.Sprintf("Request Error [method is empty]")
Expand Down
4 changes: 3 additions & 1 deletion rpc_server/middlewares/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@ import (

// LogHandler log handler
func LogHandler() gin.HandlerFunc {
return gin.Logger()
return gin.LoggerWithConfig(gin.LoggerConfig{
SkipPaths: []string{"/api/healthz"},
})
}
106 changes: 106 additions & 0 deletions rpc_server/middlewares/pv_mertics.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package middlewares

import (
"AAStarCommunity/EthPaymaster_BackService/common/global_const"
"AAStarCommunity/EthPaymaster_BackService/common/model"
"AAStarCommunity/EthPaymaster_BackService/service/dashboard_service"
"bytes"
"encoding/json"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
"io"
"net/http"
"strings"
"time"
)

type PayMasterParam struct {
ApiUserId int64
ApiKey string
Method string
SendTime string
Latency time.Duration
RequestBody string
ResponseBody string
NetWork string
Status int
}

func PvMetrics() gin.HandlerFunc {
return func(c *gin.Context) {
path := c.Request.URL.Path
if strings.HasPrefix(path, "/api/v1/paymaster/") {
responseWriter := &CustomResponseWriter{body: bytes.NewBufferString(""), ResponseWriter: c.Writer}
c.Writer = responseWriter
start := time.Now()
// get Request Body
requestBodyBytes, err := io.ReadAll(c.Request.Body)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Failed to read request body"})
c.Abort()
return
}
//Restore the request body to Request.Body for use by subsequent handlers.
c.Request.Body = io.NopCloser(bytes.NewBuffer(requestBodyBytes))

c.Next()

request := model.JsonRpcRequest{}
_ = json.Unmarshal(requestBodyBytes, &request)
requestJson, _ := json.Marshal(request)
requestBodyStr := string(requestJson)

responseWriter.body.Bytes()
responseBody := responseWriter.body.String()
endEnd := time.Now()
network := c.Param("network")
metricsParam := PayMasterParam{
NetWork: network,
Method: request.Method,
SendTime: start.Format("2006-01-02 15:04:05.MST"),
Latency: endEnd.Sub(start),
Status: c.Writer.Status(),
RequestBody: requestBodyStr,
ResponseBody: responseBody,
}
apiKeyContext, exist := c.Get(global_const.ContextKeyApiMoDel)
if exist {
apiKeyModel := apiKeyContext.(*model.ApiKeyModel)
metricsParam.ApiKey = apiKeyModel.ApiKey
metricsParam.ApiUserId = apiKeyModel.UserId
}
MetricsPaymaster(c, metricsParam)
} else {
return
}

}
}

type CustomResponseWriter struct {
gin.ResponseWriter
body *bytes.Buffer
}

func (w *CustomResponseWriter) Write(b []byte) (int, error) {
w.body.Write(b)
return w.ResponseWriter.Write(b)
}
func MetricsPaymaster(c *gin.Context, metricsParam PayMasterParam) {

recallModel := dashboard_service.PaymasterRecallLogDbModel{
ProjectApikey: metricsParam.ApiKey,
ProjectUserId: metricsParam.ApiUserId,
PaymasterMethod: metricsParam.Method,
SendTime: metricsParam.SendTime,
Latency: int64(metricsParam.Latency),
RequestBody: metricsParam.RequestBody,
ResponseBody: metricsParam.ResponseBody,
Status: metricsParam.Status,
NetWork: metricsParam.NetWork,
}
err := dashboard_service.CreatePaymasterCall(&recallModel)
if err != nil {
logrus.Error("CreatePaymasterCall error:", err)
}
}
13 changes: 7 additions & 6 deletions rpc_server/middlewares/recovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ package middlewares

import (
"AAStarCommunity/EthPaymaster_BackService/common/model"
"AAStarCommunity/EthPaymaster_BackService/envirment"
"AAStarCommunity/EthPaymaster_BackService/common/utils"
"errors"
"fmt"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
"net/http"
"strings"
)
Expand All @@ -14,11 +15,11 @@ import (
func GenericRecoveryHandler() gin.HandlerFunc {
DefaultErrorWriter := &PanicExceptionRecord{}
return gin.RecoveryWithWriter(DefaultErrorWriter, func(c *gin.Context, err interface{}) {
errStr := ""
if envirment.Environment.Debugger {
errStr = fmt.Sprintf("%v", err)
}
model.GetResponse().SetHttpCode(http.StatusInternalServerError).FailCode(c, http.StatusInternalServerError, errStr)
errInfo := fmt.Sprintf("[panic]: err : [%v] , stack :[%v]", err, utils.GetCurrentGoroutineStack())
logrus.Error(errInfo)
logrus.Errorf("%v", errInfo)
returnError := fmt.Sprintf("%v", err)
model.GetResponse().SetHttpCode(http.StatusInternalServerError).FailCode(c, http.StatusInternalServerError, returnError)
})
}

Expand Down
7 changes: 4 additions & 3 deletions rpc_server/routers/boot.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@ func SetRouters() (routers *gin.Engine) {
func buildRoute(routers *gin.Engine) {
// build http routers and middleware
routers.Use(middlewares.GenericRecoveryHandler())
if envirment.Environment.IsDevelopment() {
routers.Use(middlewares.LogHandler())
}

routers.Use(middlewares.LogHandler())

routers.Use(middlewares.PvMetrics())
routers.Use(middlewares.CorsHandler())
//build the routers not need api access like auth or Traffic limit
buildRouters(routers, PublicRouterMaps)
Expand Down
31 changes: 26 additions & 5 deletions service/dashboard_service/dashboard_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import (
)

var (
configDB *gorm.DB
onlyOnce = sync.Once{}
dashBoardDb *gorm.DB
onlyOnce = sync.Once{}
)

func Init() {
Expand All @@ -29,7 +29,7 @@ func Init() {
if err != nil {
panic(err)
}
configDB = configDBVar
dashBoardDb = configDBVar

})

Expand Down Expand Up @@ -58,7 +58,7 @@ func GetStrategyByCode(strategyCode string, entryPointVersion global_const.Entry
entryPointVersion = global_const.EntrypointV06
}
strategyDbModel := &StrategyDBModel{}
tx := configDB.Where("strategy_code = ?", strategyCode).First(&strategyDbModel)
tx := dashBoardDb.Where("strategy_code = ?", strategyCode).First(&strategyDbModel)
if tx.Error != nil {
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, xerrors.Errorf("strategy not found: %w", tx.Error)
Expand Down Expand Up @@ -242,7 +242,7 @@ func convertApiKeyDbModelToApiKeyModel(apiKeyDbModel *ApiKeyDbModel) *model.ApiK
}
func GetAPiInfoByApiKey(apiKey string) (*model.ApiKeyModel, error) {
apikeyModel := &ApiKeyDbModel{}
tx := configDB.Where("api_key = ?", apiKey).First(&apikeyModel)
tx := dashBoardDb.Where("api_key = ?", apiKey).First(&apikeyModel)
if tx.Error != nil {
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, tx.Error
Expand All @@ -252,3 +252,24 @@ func GetAPiInfoByApiKey(apiKey string) (*model.ApiKeyModel, error) {
apikeyRes := convertApiKeyDbModelToApiKeyModel(apikeyModel)
return apikeyRes, nil
}

type PaymasterRecallLogDbModel struct {
model.BaseData
ProjectUserId int64 `gorm:"column:project_user_id;type:integer" json:"project_user_id"`
ProjectApikey string `gorm:"column:project_apikey;type:varchar(255)" json:"project_apikey"`
PaymasterMethod string `gorm:"column:paymaster_method;type:varchar(25)" json:"paymaster_method"`
SendTime string `gorm:"column:send_time;type:varchar(50)" json:"send_time"`
Latency int64 `gorm:"column:latency;type:integer" json:"latency"`
RequestBody string `gorm:"column:request_body;type:varchar(500)" json:"request_body"`
ResponseBody string `gorm:"column:response_body;type:varchar(1000)" json:"response_body"`
NetWork string `gorm:"column:network;type:varchar(25)" json:"network"`
Status int `gorm:"column:status;type:integer" json:"status"`
Extra datatypes.JSON `gorm:"column:extra" json:"extra"`
}

func (*PaymasterRecallLogDbModel) TableName() string {
return "paymaster_recall_log"
}
func CreatePaymasterCall(recallModel *PaymasterRecallLogDbModel) error {
return dashBoardDb.Create(recallModel).Error
}
1 change: 1 addition & 0 deletions sponsor_manager/sponsor_balance_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ func CreateSponsorBalance(balanceModel *UserSponsorBalanceDBModel) error {
return relayDB.Create(balanceModel).Error
}
func FindUserSponsorBalance(userId string, isTestNet bool) (balanceModel *UserSponsorBalanceDBModel, err error) {

balanceModel = &UserSponsorBalanceDBModel{}
tx := relayDB.Where("pay_user_id = ?", userId).Where("is_test_net = ?", isTestNet).First(balanceModel)
if tx.Error != nil {
Expand Down

0 comments on commit cdc3a21

Please sign in to comment.