github.com/isyscore/isc-gobase@v1.5.3-0.20231218061332-cbc7451899e9/server/rsp/responseHandler.go (about)

     1  package rsp
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"github.com/isyscore/isc-gobase/config"
     7  	"io"
     8  	"net/http"
     9  	"strings"
    10  	"time"
    11  	"unsafe"
    12  
    13  	"github.com/gin-gonic/gin"
    14  	"github.com/isyscore/isc-gobase/isc"
    15  	"github.com/isyscore/isc-gobase/logger"
    16  )
    17  
    18  type bodyLogWriter struct {
    19  	gin.ResponseWriter
    20  	body *bytes.Buffer
    21  }
    22  
    23  func (w bodyLogWriter) Write(b []byte) (int, error) {
    24  	w.body.Write(b)
    25  	return w.ResponseWriter.Write(b)
    26  }
    27  
    28  func ResponseHandler() gin.HandlerFunc {
    29  	return func(c *gin.Context) {
    30  		reqPrint := config.GetValueBoolDefault("base.server.request.print.enable", false)
    31  		rspPrint := config.GetValueBoolDefault("base.server.response.print.enable", false)
    32  		expPrint := config.GetValueBoolDefault("base.server.exception.print.enable", false)
    33  
    34  		if !reqPrint && !rspPrint && !expPrint {
    35  			return
    36  		}
    37  
    38  		// 开始时间
    39  		startTime := time.Now()
    40  
    41  		data, err := io.ReadAll(c.Request.Body)
    42  		if err != nil {
    43  			logger.Error("read request body failed,err = %s.", err)
    44  			return
    45  		}
    46  		c.Request.Body = io.NopCloser(bytes.NewBuffer(data))
    47  
    48  		blw := &bodyLogWriter{body: bytes.NewBufferString(""), ResponseWriter: c.Writer}
    49  		c.Writer = blw
    50  
    51  		// 处理请求
    52  		c.Next()
    53  
    54  		// 状态码
    55  		statusCode := c.Writer.Status()
    56  
    57  		var body any
    58  		bodyStr := string(data)
    59  		if "" != bodyStr && unsafe.Sizeof(bodyStr) < 10240 {
    60  			if strings.HasPrefix(bodyStr, "{") && strings.HasSuffix(bodyStr, "}") {
    61  				bodys := map[string]any{}
    62  				_ = isc.StrToObject(bodyStr, &bodys)
    63  				body = bodys
    64  			} else if strings.HasPrefix(bodyStr, "[") && strings.HasSuffix(bodyStr, "]") {
    65  				var bodys []any
    66  				_ = isc.StrToObject(bodyStr, &bodys)
    67  				body = bodys
    68  			}
    69  		}
    70  
    71  		request := Request{
    72  			Method:     c.Request.Method,
    73  			Uri:        c.Request.RequestURI,
    74  			Ip:         c.ClientIP(),
    75  			Parameters: c.Params,
    76  			Headers:    c.Request.Header,
    77  			Body:       body,
    78  		}
    79  
    80  		errMessage := ErrorMessage{
    81  			Request:    request,
    82  			StatusCode: statusCode,
    83  			Cost:       time.Now().Sub(startTime).String(),
    84  		}
    85  
    86  		responseMessage := Response{
    87  			Request:    request,
    88  			StatusCode: statusCode,
    89  			Cost:       time.Now().Sub(startTime).String(),
    90  		}
    91  
    92  		if reqPrint && !rspPrint {
    93  			printReq(request.Uri, request)
    94  		}
    95  
    96  		// 1xx和2xx都是成功
    97  		if (statusCode >= 300) && statusCode != 0 {
    98  			datas := config.BaseCfg.Server.Exception.Print.Exclude
    99  			for _, code := range datas {
   100  				if code == statusCode {
   101  					return
   102  				}
   103  			}
   104  			if expPrint {
   105  				logger.Error("返回异常, result:%v", isc.ObjectToJson(errMessage))
   106  			}
   107  		} else {
   108  			var response DataResponse[any]
   109  			if err := json.Unmarshal([]byte(blw.body.String()), &response); err != nil {
   110  				return
   111  			} else {
   112  				if response.Code != 0 && response.Code != 200 {
   113  					errMessage.Response = response
   114  					if expPrint {
   115  						logger.Error("返回异常, result:%v", isc.ObjectToJson(errMessage))
   116  					}
   117  				} else {
   118  					responseMessage.Response = response
   119  					if rspPrint {
   120  						printRsq(request.Uri, responseMessage)
   121  					}
   122  				}
   123  			}
   124  		}
   125  	}
   126  }
   127  
   128  func printReq(requestUri string, requestData Request) {
   129  	includeUri := config.GetValueArray("base.server.request.print.include-uri")
   130  	printFlag := false
   131  	if len(includeUri) != 0 {
   132  		for _, uri := range includeUri {
   133  			if strings.HasPrefix(requestUri, isc.ToString(uri)) {
   134  				printFlag = true
   135  				break
   136  			}
   137  		}
   138  	}
   139  
   140  	excludeUri := config.GetValueArray("base.server.request.print.exclude-uri")
   141  	if len(excludeUri) != 0 {
   142  		for _, uri := range excludeUri {
   143  			if strings.HasPrefix(requestUri, isc.ToString(uri)) {
   144  				printFlag = false
   145  				break
   146  			}
   147  		}
   148  	}
   149  
   150  	reqLogLevel := config.GetValueString("base.server.request.print.level")
   151  	if printFlag {
   152  		logger.Record(reqLogLevel, "请求:%v", isc.ToJsonString(requestData))
   153  	}
   154  	return
   155  }
   156  
   157  func printRsq(requestUri string, responseMessage Response) {
   158  	includeUri := config.GetValueArray("base.server.response.print.include-uri")
   159  	printFlag := false
   160  	if len(includeUri) != 0 {
   161  		for _, uri := range includeUri {
   162  			if strings.HasPrefix(requestUri, isc.ToString(uri)) {
   163  				printFlag = true
   164  				break
   165  			}
   166  		}
   167  	}
   168  
   169  	excludeUri := config.GetValueArray("base.server.response.print.exclude-uri")
   170  	if len(excludeUri) != 0 {
   171  		for _, uri := range excludeUri {
   172  			if strings.HasPrefix(requestUri, isc.ToString(uri)) {
   173  				printFlag = false
   174  				break
   175  			}
   176  		}
   177  	}
   178  
   179  	rspLogLevel := config.GetValueString("base.server.response.print.level")
   180  	if printFlag {
   181  		logger.Record(rspLogLevel, "响应:%v", isc.ToJsonString(responseMessage))
   182  	}
   183  }
   184  
   185  type Request struct {
   186  	Method     string
   187  	Uri        string
   188  	Ip         string
   189  	Headers    http.Header
   190  	Parameters gin.Params
   191  	Body       any
   192  }
   193  
   194  type ErrorMessage struct {
   195  	Request    Request
   196  	Response   DataResponse[any]
   197  	Cost       string
   198  	StatusCode int
   199  }
   200  
   201  type Response struct {
   202  	Request    Request
   203  	Response   DataResponse[any]
   204  	Cost       string
   205  	StatusCode int
   206  }