Compare commits
8 Commits
Author | Date | ||
---|---|---|---|
![]() |
98eac47127 | ||
![]() |
69b0fb05aa | ||
![]() |
ba9357e166 | ||
![]() |
9df516247c | ||
![]() |
93bdc425e5 | ||
![]() |
426a77f4cf | ||
![]() |
a098d141c2 | ||
![]() |
1d8453af9d |
38
api.go
38
api.go
@ -1,6 +1,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@ -12,7 +13,7 @@ import (
|
||||
var (
|
||||
validate = validator.New()
|
||||
requestLogidGetter = defaultLogidGetter
|
||||
requestHandlerMapper = map[string]Handler{}
|
||||
requestHandlerMapper = map[string]gin.HandlerFunc{}
|
||||
errCodeUnknownError = -10000
|
||||
errCodeParameterError = -20000
|
||||
errCodeUnimplementApi = -20401
|
||||
@ -37,9 +38,12 @@ type BaseWithErrCodeOutput struct {
|
||||
ErrMsg string `json:"errMsg"`
|
||||
}
|
||||
|
||||
func NewEngine() *Engine {
|
||||
func NewEngine(pre ...gin.HandlerFunc) *Engine {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
e := gin.New()
|
||||
for _, m := range pre {
|
||||
e.Use(m)
|
||||
}
|
||||
e.Use(middlewareMyApiEngine())
|
||||
return &Engine{e}
|
||||
}
|
||||
@ -50,10 +54,16 @@ func (e *Engine) POST(uri string, handler Handler) {
|
||||
e.Engine.POST(uri, h)
|
||||
}
|
||||
|
||||
func (e *Engine) GET(uri string, handler Handler) {
|
||||
h := handlerWrapper(handler)
|
||||
log.Infof("api handler [%v] registor success", handler)
|
||||
e.Engine.GET(uri, h)
|
||||
}
|
||||
|
||||
// handlerWrapper
|
||||
func handlerWrapper(handler Handler) gin.HandlerFunc {
|
||||
handlerFunc := handler.HandlerFunc()
|
||||
return func(c *gin.Context) {
|
||||
wrappedHandlerFunc := func(c *gin.Context) {
|
||||
// Case 1. get request handler
|
||||
if c.Request == nil && c.Keys != nil {
|
||||
c.Keys["handler"] = handler
|
||||
@ -75,6 +85,9 @@ func handlerWrapper(handler Handler) gin.HandlerFunc {
|
||||
return
|
||||
}
|
||||
}
|
||||
hkey := fmt.Sprintf("%v", wrappedHandlerFunc)
|
||||
requestHandlerMapper[hkey] = wrappedHandlerFunc
|
||||
return wrappedHandlerFunc
|
||||
}
|
||||
|
||||
// handlerWrapper
|
||||
@ -112,8 +125,8 @@ func middlewareMyApiEngine() gin.HandlerFunc {
|
||||
// Step 3. do request
|
||||
c.Next()
|
||||
|
||||
// Step 4. metrics record
|
||||
cc.recordMetric()
|
||||
// Step 4. recorde metrics
|
||||
cc.recordMetrics()
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,8 +154,17 @@ func CC(c *gin.Context) *Context {
|
||||
}
|
||||
|
||||
func ApiHandler(c *gin.Context) Handler {
|
||||
newc := &gin.Context{Request: nil, Keys: map[string]any{}}
|
||||
c.Handler()(newc)
|
||||
h := c.Handler()
|
||||
hkey := fmt.Sprintf("%v", h)
|
||||
if _, ok := requestHandlerMapper[hkey]; !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
newc := &gin.Context{
|
||||
Request: nil,
|
||||
Keys: map[string]any{},
|
||||
}
|
||||
h(newc)
|
||||
return newc.Keys["handler"].(Handler)
|
||||
}
|
||||
|
||||
@ -157,7 +179,7 @@ func RecordMetrics(api, errcode, appid string, costms float64) {
|
||||
summary.Observe(costms)
|
||||
}
|
||||
|
||||
func DumpHandler(c *Context) error {
|
||||
func DumpHandlerFunc(c *Context) error {
|
||||
errmsg := "api not implemented"
|
||||
errcode := errCodeUnimplementApi
|
||||
return c.RESULT_ERROR(errcode, errmsg)
|
||||
|
14
context.go
14
context.go
@ -120,7 +120,14 @@ func (c *Context) SetCookie(cookie *http.Cookie) {
|
||||
http.SetCookie(c.Writer, cookie)
|
||||
}
|
||||
|
||||
func (c *Context) AlreadyHaveResult() (done bool, entry string) {
|
||||
return c.resultentry != "", c.resultentry
|
||||
}
|
||||
|
||||
func (c *Context) RESULT(output interface{}) error {
|
||||
if c.resultentry == "" {
|
||||
c.resultentry = "RESULT"
|
||||
}
|
||||
var t = reflect.TypeOf(output)
|
||||
defer func(o *interface{}) {
|
||||
b, err := json.Marshal(o)
|
||||
@ -212,13 +219,16 @@ func (c *Context) shapeOutput(o interface{}) {
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Context) recordMetric() {
|
||||
func (c *Context) recordMetrics() {
|
||||
if metricApiCounter == nil ||
|
||||
metricApiSummary == nil {
|
||||
return
|
||||
}
|
||||
var h = c.ApiHandler()
|
||||
if h == nil {
|
||||
h = unimplementHandler{c.Context}
|
||||
}
|
||||
var (
|
||||
h = c.ApiHandler()
|
||||
api = h.ApiName()
|
||||
appid = c.AppId
|
||||
costus = time.Now().Sub(c.starttime).Microseconds()
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
@ -14,9 +15,10 @@ import (
|
||||
var (
|
||||
MetricExporterPusher = func() error { return nil }
|
||||
MetricExporterHandler Handler = nil
|
||||
metricRegistry *prometheus.Registry = nil
|
||||
MetricRegistry *prometheus.Registry = nil
|
||||
metricApiCounter *prometheus.CounterVec = nil
|
||||
metricApiSummary *prometheus.SummaryVec = nil
|
||||
instance string = "--unknown--"
|
||||
)
|
||||
|
||||
type metricExporterHandler struct {
|
||||
@ -39,14 +41,20 @@ func dumpMetricExporterPusher() error {
|
||||
return errors.New("not initilized, forgot call 'SetupMetricsExporterPusher'?")
|
||||
}
|
||||
|
||||
func InitMetrics() {
|
||||
instance := getInstanceIpAddress()
|
||||
log.Infof("self instance ip: [%s]", instance)
|
||||
func InitMetrics(instanceValue string) {
|
||||
if instanceValue == "" {
|
||||
instance = getInstanceIpAddress()
|
||||
} else if ap := strings.Split(instanceValue, ":"); len(ap) == 2 &&
|
||||
ap[0] == "0.0.0.0" || ap[0] == "" {
|
||||
instance = getInstanceIpAddress() + ":" + ap[1]
|
||||
}
|
||||
log.Infof("self instance: [%s]", instance)
|
||||
|
||||
metricApiCounter = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "api_requests_total",
|
||||
Help: "How many HTTP requests processed",
|
||||
ConstLabels: prometheus.Labels{"instance": instance},
|
||||
//ConstLabels: prometheus.Labels{"instance": instance},
|
||||
},
|
||||
[]string{"api", "errcode", "appid"},
|
||||
)
|
||||
@ -55,13 +63,14 @@ func InitMetrics() {
|
||||
Name: "api_requests_summary",
|
||||
Help: "The api request summary of cost.",
|
||||
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
|
||||
ConstLabels: prometheus.Labels{"instance": instance},
|
||||
//ConstLabels: prometheus.Labels{"instance": instance},
|
||||
},
|
||||
[]string{"api", "errcode", "appid"},
|
||||
)
|
||||
metricRegistry = prometheus.NewRegistry()
|
||||
metricRegistry.MustRegister(metricApiCounter)
|
||||
metricRegistry.MustRegister(metricApiSummary)
|
||||
|
||||
MetricRegistry = prometheus.NewRegistry()
|
||||
MetricRegistry.MustRegister(metricApiCounter)
|
||||
MetricRegistry.MustRegister(metricApiSummary)
|
||||
}
|
||||
|
||||
func SetupMetricsExporterHandler(apiname string) {
|
||||
@ -69,10 +78,10 @@ func SetupMetricsExporterHandler(apiname string) {
|
||||
apiname = "premetheus_metrics_exporter"
|
||||
}
|
||||
|
||||
opt := promhttp.HandlerOpts{Registry: metricRegistry}
|
||||
opt := promhttp.HandlerOpts{Registry: MetricRegistry}
|
||||
MetricExporterHandler = &metricExporterHandler{
|
||||
name: apiname,
|
||||
promhttpHandler: promhttp.HandlerFor(metricRegistry, opt),
|
||||
promhttpHandler: promhttp.HandlerFor(MetricRegistry, opt),
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,7 +90,11 @@ func SetupMetricsExporterPusher(pushgateway string, jobname string) {
|
||||
jobname = fmt.Sprintf("api-metrics-job-%s", getExeFilename())
|
||||
}
|
||||
|
||||
var pusher = push.New(pushgateway, jobname).Gatherer(metricRegistry)
|
||||
var pusher = push.
|
||||
New(pushgateway, jobname).
|
||||
Grouping("instance", instance).
|
||||
Gatherer(MetricRegistry)
|
||||
|
||||
MetricExporterPusher = func() error {
|
||||
RecordMetrics("push_metrics_to_prometheus", "0", "selfmonitoring", 1.0)
|
||||
return pusher.Push()
|
||||
|
21
routes.go
21
routes.go
@ -1,5 +1,12 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// ///////////////////////////////////////////////////////////////////
|
||||
// IRouter & IRoutes in gin, we redefine it simple
|
||||
// ///////////////////////////////////////////////////////////////////
|
||||
@ -40,5 +47,19 @@ type Handler interface {
|
||||
type HandlerFunc func(*Context) error
|
||||
|
||||
type IRoutes interface {
|
||||
GET(uri string, handler Handler)
|
||||
POST(uri string, handler Handler)
|
||||
}
|
||||
|
||||
type unimplementHandler struct {
|
||||
c *gin.Context
|
||||
}
|
||||
|
||||
func (u unimplementHandler) ApiName() string {
|
||||
req := u.c.Request
|
||||
return strings.ToLower(fmt.Sprintf("[%s]%s", req.Method, req.RequestURI))
|
||||
}
|
||||
|
||||
func (u unimplementHandler) HandlerFunc() HandlerFunc {
|
||||
return DumpHandlerFunc
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user