trpc.group/trpc-go/trpc-go@v1.0.3/admin/router.go (about) 1 // 2 // 3 // Tencent is pleased to support the open source community by making tRPC available. 4 // 5 // Copyright (C) 2023 THL A29 Limited, a Tencent company. 6 // All rights reserved. 7 // 8 // If you have downloaded a copy of the tRPC source code from Tencent, 9 // please note that tRPC source code is licensed under the Apache 2.0 License, 10 // A copy of the Apache 2.0 License is included in this file. 11 // 12 // 13 14 package admin 15 16 import ( 17 "encoding/json" 18 "fmt" 19 "net/http" 20 "runtime" 21 "sync" 22 23 "trpc.group/trpc-go/trpc-go/internal/report" 24 "trpc.group/trpc-go/trpc-go/log" 25 ) 26 27 // PanicBufLen is the length of the buffer used for stack trace logging 28 // when goroutine panics, default is 1024. 29 const panicBufLen = 1024 30 31 // newRouter creates a new Router. 32 func newRouter() *router { 33 return &router{ 34 ServeMux: http.NewServeMux(), 35 } 36 } 37 38 // newRouterHandler creates a new restful route info handler. 39 func newRouterHandler(pattern string, handler http.HandlerFunc) *routerHandler { 40 return &routerHandler{ 41 pattern: pattern, 42 handler: handler, 43 } 44 } 45 46 type router struct { 47 *http.ServeMux 48 49 sync.RWMutex 50 handlers map[string]*routerHandler 51 } 52 53 // add adds a routing pattern and handler function. 54 func (r *router) add(pattern string, handler http.HandlerFunc) *routerHandler { 55 r.Lock() 56 defer r.Unlock() 57 58 r.ServeMux.HandleFunc(pattern, handler) 59 if r.handlers == nil { 60 r.handlers = make(map[string]*routerHandler) 61 } 62 63 h := newRouterHandler(pattern, handler) 64 r.handlers[pattern] = h 65 return h 66 } 67 68 // ServeHTTP handles incoming HTTP requests. 69 func (r *router) ServeHTTP(w http.ResponseWriter, req *http.Request) { 70 defer func() { 71 if err := recover(); err != nil { 72 buf := make([]byte, panicBufLen) 73 buf = buf[:runtime.Stack(buf, false)] 74 log.Errorf("[PANIC]%v\n%s\n", err, buf) 75 report.AdminPanicNum.Incr() 76 ret := newDefaultRes() 77 ret[retErrCode] = http.StatusInternalServerError 78 ret[retMessage] = fmt.Sprintf("PANIC : %v", err) 79 _ = json.NewEncoder(w).Encode(ret) 80 } 81 }() 82 r.ServeMux.ServeHTTP(w, req) 83 } 84 85 // list returns a list of configured routes. 86 func (r *router) list() []*routerHandler { 87 l := make([]*routerHandler, 0, len(r.handlers)) 88 for _, handler := range r.handlers { 89 l = append(l, handler) 90 } 91 return l 92 } 93 94 // routerHandler routing information handler. 95 type routerHandler struct { 96 handler http.HandlerFunc 97 pattern string 98 }