Commit 3fa092d8 by 孙龙

init

parents
package boot
import (
"github.com/ichunt2019/cfg/lib"
xlog "github.com/ichunt2019/lxLog/log"
)
func Init(configPath string,logPath string)(err error){
err = lib.Init(configPath)
if err != nil{
panic(err)
}
xlog.Init(logPath,"sku","spu","request")
return
}
package main
import (
"flag"
"ichunt_golang/boot"
"os"
"os/signal"
"syscall"
"ichunt_golang/router"
)
var (
configPath string
logPath string
)
func main(){
flag.StringVar(&configPath, "config", "./config/dev/", "配置文件")
flag.StringVar(&logPath, "logdir", "./logs/", "日志文件存储目录")
flag.Parse()
boot.Init(configPath,logPath)
go func() {
router.HttpServerRun()
}()
quit := make(chan os.Signal)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
router.HttpServerStop()
}
title = "TOML 例子"
viewpath = "/home/www/templates/"
[owner]
name = "Tom Preston-Werner"
organization = "GitHub"
bio = "GitHub Cofounder & CEO\nLikes tater tots and beer."
dob = 1979-05-27T07:32:00Z # 日期时间是一等公民。为什么不呢?
[servers]
# 你可以依照你的意愿缩进。使用空格或Tab。TOML不会在意。
[servers.alpha]
ip = "10.0.0.1"
dc = "eqdc10"
[servers.beta]
ip = "10.0.0.2"
dc = "eqdc10"
[clients]
data = [["gamma", "delta"],[1, 2]]
[database]
[database.default]
host = "192.168.2.246"
[supplier_no_brand]
3 = [615,757,46596,43172,52,46481,47811,48817]
7 = [47778]
9 = [47778,4589,12369]
# This is base config
[base]
debug_mode="debug"
time_location="Asia/Chongqing"
[http]
addr ="192.168.2.246:8700" # 监听地址, default ":8700"
read_timeout = 10 # 读取超时时长
write_timeout = 10 # 写入超时时长
max_header_bytes = 20 # 最大的header大小,二进制位长度
module ichunt_golang
go 1.14
require (
github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff // indirect
github.com/gin-gonic/contrib v0.0.0-20201101042839-6a891bf89f19
github.com/gin-gonic/gin v1.6.3
github.com/gorilla/sessions v1.2.1 // indirect
github.com/ichunt2019/cfg v0.0.0-20210225081543-828ee9831d70
github.com/ichunt2019/lxLog v0.0.0-20210226024426-781becb3c042
github.com/spf13/viper v1.7.1
github.com/tidwall/gjson v1.6.8 // indirect
)
This diff is collapsed. Click to expand it.
[INFO][2021/03/01 14:32:04][log.go:58] _com_request_in||method=GET||args=map[]||cspanid=||spanid=1f3c8a6578629a0f||uri=/hbsdata||body=||from=192.168.2.246||traceid=7f000001603c8a64780c87f0658221b0
[INFO][2021/03/01 14:32:04][log.go:58] _com_request_out||uri=/hbsdata||from=192.168.2.246||proc_time=0.0289498||cspanid=||spanid=1f3c8a6578629a0f||method=GET||args=map[]||response=<nil>||traceid=7f000001603c8a64780c87f0658221b0
[INFO][2021/03/01 14:35:42][log.go:58] _com_request_in||args=map[]||body=||traceid=7f000001603c8b3e9a74af70658221b0||cspanid=||uri=/hbsdata||method=GET||spanid=1f3c8b3f78629a0f||from=192.168.2.246
[INFO][2021/03/01 14:35:42][log.go:58] _com_request_out||traceid=7f000001603c8b3e9a74af70658221b0||uri=/hbsdata||args=map[]||from=192.168.2.246||cspanid=||spanid=1f3c8b3f78629a0f||method=GET||response=<nil>||proc_time=0.0269554
[INFO][2021/03/01 14:35:44][log.go:58] _com_request_in||uri=/hbsdata||body=||traceid=7f000001603c8b40ce30af70104dc7b0||cspanid=||spanid=1f3c8b41380704bb||method=GET||args=map[]||from=192.168.2.246
[INFO][2021/03/01 14:35:44][log.go:58] _com_request_out||method=GET||cspanid=||proc_time=0||traceid=7f000001603c8b40ce30af70104dc7b0||spanid=1f3c8b41380704bb||uri=/hbsdata||args=map[]||from=192.168.2.246||response=<nil>
[INFO][2021/03/01 14:36:06][log.go:58] _com_request_in||body=||traceid=7f000001603c8b56767c8314658221b0||cspanid=||spanid=1f3c8b5778629a0f||method=GET||args=map[]||uri=/hbsdata||from=192.168.2.246
[INFO][2021/03/01 14:36:06][log.go:58] _com_request_out||proc_time=0.0299192||traceid=7f000001603c8b56767c8314658221b0||spanid=1f3c8b5778629a0f||uri=/hbsdata||from=192.168.2.246||response=<nil>||cspanid=||method=GET||args=map[]
[INFO][2021/03/01 14:36:08][log.go:58] _com_request_in||from=192.168.2.246||cspanid=||uri=/hbsdata||method=GET||body=||args=map[]||traceid=7f000001603c8b5860fc8314104dc7b0||spanid=1f3c8b59380704bb
[INFO][2021/03/01 14:36:08][log.go:58] _com_request_out||args=map[]||from=192.168.2.246||response=<nil>||proc_time=0||uri=/hbsdata||method=GET||cspanid=||spanid=1f3c8b59380704bb||traceid=7f000001603c8b5860fc8314104dc7b0
[INFO][2021/03/01 14:36:50][log.go:58] _com_request_in||body=||from=192.168.2.246||traceid=7f000001603c8b82d63058f8658221b0||spanid=1f3c8b8378629a0f||uri=/hbsdata||method=GET||args=map[]||cspanid=
[INFO][2021/03/01 14:36:50][log.go:58] _com_request_out||spanid=1f3c8b8378629a0f||uri=/hbsdata||proc_time=0.0279402||response=<nil>||traceid=7f000001603c8b82d63058f8658221b0||cspanid=||method=GET||args=map[]||from=192.168.2.246
[INFO][2021/03/01 14:36:50][log.go:58] _com_request_in||method=GET||args=map[]||cspanid=||spanid=1f3c8b83380704bb||uri=/hbsdata||body=||from=192.168.2.246||traceid=7f000001603c8b8259b458f8104dc7b0
[INFO][2021/03/01 14:36:50][log.go:58] _com_request_out||cspanid=||spanid=1f3c8b83380704bb||method=GET||args=map[]||response=<nil>||proc_time=0||uri=/hbsdata||from=192.168.2.246||traceid=7f000001603c8b8259b458f8104dc7b0
File mode changed
File mode changed
File mode changed
File mode changed
package middleware
import (
"errors"
"fmt"
"github.com/gin-gonic/gin"
"ichunt_golang/util"
"github.com/ichunt2019/cfg/lib"
"runtime/debug"
)
// RecoveryMiddleware捕获所有panic,并且返回错误信息
func RecoveryMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
fmt.Println(lib.Instance("proxy").GetString("base.debug_mode"))
defer func() {
if err := recover(); err != nil {
//先做一下日志记录
fmt.Println(string(debug.Stack()))
util.ComLogNotice(c, "_com_panic", map[string]interface{}{
"error": fmt.Sprint(err),
"stack": string(debug.Stack()),
})
if lib.Instance("proxy").GetString("base.debug_mode") != "debug" {
ResponseError(c, 500, errors.New("内部错误"))
return
} else {
ResponseError(c, 500, errors.New(fmt.Sprint(err)))
return
}
}
}()
c.Next()
}
}
\ No newline at end of file
package middleware
import (
"bytes"
"github.com/gin-gonic/gin"
"ichunt_golang/util"
"ichunt_golang/util/lib"
"io/ioutil"
"time"
)
// 请求进入日志
func RequestInLog(c *gin.Context) {
traceContext := lib.NewTrace()
if traceId := c.Request.Header.Get("com-header-rid"); traceId != "" {
traceContext.TraceId = traceId
}
if spanId := c.Request.Header.Get("com-header-spanid"); spanId != "" {
traceContext.SpanId = spanId
}
c.Set("startExecTime", time.Now())
c.Set("trace", traceContext)
bodyBytes, _ := ioutil.ReadAll(c.Request.Body)
c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes)) // Write body back
lib.Log.TagInfo(traceContext, "_com_request_in", map[string]interface{}{
"uri": c.Request.RequestURI,
"method": c.Request.Method,
"args": c.Request.PostForm,
"body": string(bodyBytes),
"from": c.ClientIP(),
})
}
// 请求输出日志
func RequestOutLog(c *gin.Context) {
// after request
endExecTime := time.Now()
response, _ := c.Get("response")
st, _ := c.Get("startExecTime")
startExecTime, _ := st.(time.Time)
util.ComLogNotice(c, "_com_request_out", map[string]interface{}{
"uri": c.Request.RequestURI,
"method": c.Request.Method,
"args": c.Request.PostForm,
"from": c.ClientIP(),
"response": response,
"proc_time": endExecTime.Sub(startExecTime).Seconds(),
})
}
func RequestLog() gin.HandlerFunc {
return func(c *gin.Context) {
RequestInLog(c)
defer RequestOutLog(c)
c.Next()
}
}
package middleware
import (
"encoding/json"
"fmt"
"ichunt_golang/util/lib"
"github.com/gin-gonic/gin"
"strings"
)
type ResponseCode int
//1000以下为通用码,1000以上为用户自定义码
const (
SuccessCode ResponseCode = iota
UndefErrorCode
ValidErrorCode
InternalErrorCode
InvalidRequestErrorCode ResponseCode = 401
CustomizeCode ResponseCode = 1000
GROUPALL_SAVE_FLOWERROR ResponseCode = 2001
)
type Response struct {
ErrorCode ResponseCode `json:"err_code"`
ErrorMsg string `json:"err_msg"`
Data interface{} `json:"data"`
TraceId interface{} `json:"trace_id"`
Stack interface{} `json:"stack"`
}
func ResponseError(c *gin.Context, code ResponseCode, err error) {
trace, _ := c.Get("trace")
traceContext, _ := trace.(*lib.TraceContext)
traceId := ""
if traceContext != nil {
traceId = traceContext.TraceId
}
stack := ""
if c.Query("is_debug") == "1" || lib.GetConfEnv() == "dev" {
stack = strings.Replace(fmt.Sprintf("%+v", err), err.Error()+"\n", "", -1)
}
traceId=traceId
stack=stack
//resp := &Response{ErrorCode: code, ErrorMsg: err.Error(), Data: "", TraceId: traceId, Stack: stack}
resp := &Response{ErrorCode: code, ErrorMsg: err.Error(), Data: ""}
c.JSON(200, resp)
response, _ := json.Marshal(resp)
c.Set("response", string(response))
c.AbortWithError(200, err)
}
func ResponseSuccess(c *gin.Context, data interface{}) {
trace, _ := c.Get("trace")
traceContext, _ := trace.(*lib.TraceContext)
traceId := ""
if traceContext != nil {
traceId = traceContext.TraceId
}
resp := &Response{ErrorCode: SuccessCode, ErrorMsg: "", Data: data, TraceId: traceId}
c.JSON(200, resp)
response, _ := json.Marshal(resp)
c.Set("response", string(response))
}
package router
import (
"context"
"fmt"
"github.com/gin-gonic/gin"
cfg "github.com/ichunt2019/cfg/lib"
"ichunt_golang/middleware"
"log"
"net/http"
"time"
)
var (
HttpSrvHandler *http.Server
HttpsSrvHandler *http.Server
)
func HttpServerRun() {
//debug release test 开发使用debug模式
fmt.Println(cfg.Instance("proxy").GetString("base.debug_mode"))
gin.SetMode(cfg.Instance("proxy").GetString("base.debug_mode"))
r := InitRouter(middleware.RequestLog(),middleware.RecoveryMiddleware())
HttpSrvHandler = &http.Server{
Addr: cfg.Instance("proxy").GetString("http.addr"),
//Addr: "192.168.1.234:2002",
Handler: r,
ReadTimeout: time.Duration(cfg.Instance("proxy").GetInt("http.read_timeout")) * time.Second,
WriteTimeout: time.Duration(cfg.Instance("proxy").GetInt("http.write_timeout")) * time.Second,
MaxHeaderBytes: 1 << uint(cfg.Instance("proxy").GetInt("http.max_header_bytes")),
}
if err := HttpSrvHandler.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf(" [ERROR] http_proxy_run %s err:%v\n", cfg.Instance("proxy").GetString("http.addr"), err)
}
}
/*
异常退出告警提醒
*/
func HttpServerStop() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := HttpSrvHandler.Shutdown(ctx); err != nil {
log.Printf(" [ERROR] http_proxy_stop err:%v\n", err)
}
log.Printf(" [INFO] http_proxy_stop %v stopped\n", cfg.Instance("proxy").GetString("http.addr"))
}
package router
import (
"github.com/gin-gonic/gin"
)
func InitRouter(middlewares ...gin.HandlerFunc) *gin.Engine {
//todo 优化点1
//router := gin.Default()
router := gin.New()
router.Use(middlewares...)
router.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
router.GET("/hbsdata", func(c *gin.Context) {
c.Writer.Write([]byte("ok"))
})
router.Use(
gin.Logger(),
)
return router
}
package lib
import (
"bytes"
"fmt"
"github.com/spf13/viper"
"io/ioutil"
"os"
"strings"
)
var ConfEnvPath string //配置文件夹
var ConfEnv string //配置环境名 比如:dev prod test
// 解析配置文件目录
//
// 配置文件必须放到一个文件夹中
// 如:config=conf/dev/base.json ConfEnvPath=conf/dev ConfEnv=dev
// 如:config=conf/base.json ConfEnvPath=conf ConfEnv=conf
func ParseConfPath(config string) error {
path := strings.Split(config, "/")
prefix := strings.Join(path[:len(path)-1], "/")
ConfEnvPath = prefix
ConfEnv = path[len(path)-2]
return nil
}
//获取配置环境名
func GetConfEnv() string{
return ConfEnv
}
func GetConfPath(fileName string) string {
return ConfEnvPath + "/" + fileName + ".toml"
}
func GetConfFilePath(fileName string) string {
return ConfEnvPath + "/" + fileName
}
//本地解析文件
func ParseLocalConfig(fileName string, st interface{}) error {
path := GetConfFilePath(fileName)
err := ParseConfig(path, st)
if err != nil {
return err
}
return nil
}
func ParseConfig(path string, conf interface{}) error {
file, err := os.Open(path)
if err != nil {
return fmt.Errorf("Open config %v fail, %v", path, err)
}
data, err := ioutil.ReadAll(file)
if err != nil {
return fmt.Errorf("Read config fail, %v", err)
}
v:=viper.New()
v.SetConfigType("toml")
v.ReadConfig(bytes.NewBuffer(data))
if err:=v.Unmarshal(conf);err!=nil{
return fmt.Errorf("Parse config fail, config:%v, err:%v", string(data), err)
}
return nil
}
package lib
import (
"bytes"
"crypto/md5"
"encoding/binary"
"encoding/hex"
"fmt"
"io/ioutil"
"math/rand"
"net"
"net/http"
"net/url"
"os"
"regexp"
"strings"
"time"
)
var TimeLocation *time.Location
var TimeFormat = "2006-01-02 15:04:05"
var DateFormat = "2006-01-02"
var LocalIP = net.ParseIP("127.0.0.1")
func HttpGET(trace *TraceContext, urlString string, urlParams url.Values, msTimeout int, header http.Header) (*http.Response, []byte, error) {
startTime := time.Now().UnixNano()
client := http.Client{
Timeout: time.Duration(msTimeout) * time.Millisecond,
}
urlString = AddGetDataToUrl(urlString, urlParams)
req, err := http.NewRequest("GET", urlString, nil)
if err != nil {
Log.TagWarn(trace, DLTagHTTPFailed, map[string]interface{}{
"url": urlString,
"proc_time": float32(time.Now().UnixNano()-startTime) / 1.0e9,
"method": "GET",
"args": urlParams,
"err": err.Error(),
})
return nil, nil, err
}
if len(header) > 0 {
req.Header = header
}
req = addTrace2Header(req, trace)
resp, err := client.Do(req)
if err != nil {
Log.TagWarn(trace, DLTagHTTPFailed, map[string]interface{}{
"url": urlString,
"proc_time": float32(time.Now().UnixNano()-startTime) / 1.0e9,
"method": "GET",
"args": urlParams,
"err": err.Error(),
})
return nil, nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
Log.TagWarn(trace, DLTagHTTPFailed, map[string]interface{}{
"url": urlString,
"proc_time": float32(time.Now().UnixNano()-startTime) / 1.0e9,
"method": "GET",
"args": urlParams,
"result": Substr(string(body), 0, 1024),
"err": err.Error(),
})
return nil, nil, err
}
Log.TagInfo(trace, DLTagHTTPSuccess, map[string]interface{}{
"url": urlString,
"proc_time": float32(time.Now().UnixNano()-startTime) / 1.0e9,
"method": "GET",
"args": urlParams,
"result": Substr(string(body), 0, 1024),
})
return resp, body, nil
}
func HttpPOST(trace *TraceContext, urlString string, urlParams url.Values, msTimeout int, header http.Header, contextType string) (*http.Response, []byte, error) {
startTime := time.Now().UnixNano()
client := http.Client{
Timeout: time.Duration(msTimeout) * time.Millisecond,
}
if contextType == "" {
contextType = "application/x-www-form-urlencoded"
}
urlParamEncode := urlParams.Encode()
req, err := http.NewRequest("POST", urlString, strings.NewReader(urlParamEncode))
if len(header) > 0 {
req.Header = header
}
req = addTrace2Header(req, trace)
req.Header.Set("Content-Type", contextType)
resp, err := client.Do(req)
if err != nil {
Log.TagWarn(trace, DLTagHTTPFailed, map[string]interface{}{
"url": urlString,
"proc_time": float32(time.Now().UnixNano()-startTime) / 1.0e9,
"method": "POST",
"args": Substr(urlParamEncode, 0, 1024),
"err": err.Error(),
})
return nil, nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
Log.TagWarn(trace, DLTagHTTPFailed, map[string]interface{}{
"url": urlString,
"proc_time": float32(time.Now().UnixNano()-startTime) / 1.0e9,
"method": "POST",
"args": Substr(urlParamEncode, 0, 1024),
"result": Substr(string(body), 0, 1024),
"err": err.Error(),
})
return nil, nil, err
}
Log.TagInfo(trace, DLTagHTTPSuccess, map[string]interface{}{
"url": urlString,
"proc_time": float32(time.Now().UnixNano()-startTime) / 1.0e9,
"method": "POST",
"args": Substr(urlParamEncode, 0, 1024),
"result": Substr(string(body), 0, 1024),
})
return resp, body, nil
}
func HttpJSON(trace *TraceContext, urlString string, jsonContent string, msTimeout int, header http.Header) (*http.Response, []byte, error) {
startTime := time.Now().UnixNano()
client := http.Client{
Timeout: time.Duration(msTimeout) * time.Millisecond,
}
req, err := http.NewRequest("POST", urlString, strings.NewReader(jsonContent))
if len(header) > 0 {
req.Header = header
}
req = addTrace2Header(req, trace)
req.Header.Set("Content-Type", "application/json")
resp, err := client.Do(req)
if err != nil {
Log.TagWarn(trace, DLTagHTTPFailed, map[string]interface{}{
"url": urlString,
"proc_time": float32(time.Now().UnixNano()-startTime) / 1.0e9,
"method": "POST",
"args": Substr(jsonContent, 0, 1024),
"err": err.Error(),
})
return nil, nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
Log.TagWarn(trace, DLTagHTTPFailed, map[string]interface{}{
"url": urlString,
"proc_time": float32(time.Now().UnixNano()-startTime) / 1.0e9,
"method": "POST",
"args": Substr(jsonContent, 0, 1024),
"result": Substr(string(body), 0, 1024),
"err": err.Error(),
})
return nil, nil, err
}
Log.TagInfo(trace, DLTagHTTPSuccess, map[string]interface{}{
"url": urlString,
"proc_time": float32(time.Now().UnixNano()-startTime) / 1.0e9,
"method": "POST",
"args": Substr(jsonContent, 0, 1024),
"result": Substr(string(body), 0, 1024),
})
return resp, body, nil
}
func AddGetDataToUrl(urlString string, data url.Values) string {
if strings.Contains(urlString, "?") {
urlString = urlString + "&"
} else {
urlString = urlString + "?"
}
return fmt.Sprintf("%s%s", urlString, data.Encode())
}
func addTrace2Header(request *http.Request, trace *TraceContext) *http.Request {
traceId := trace.TraceId
cSpanId := NewSpanId()
if traceId != "" {
request.Header.Set("didi-header-rid", traceId)
}
if cSpanId != "" {
request.Header.Set("didi-header-spanid", cSpanId)
}
trace.CSpanId = cSpanId
return request
}
func GetMd5Hash(text string) string {
hasher := md5.New()
hasher.Write([]byte(text))
return hex.EncodeToString(hasher.Sum(nil))
}
func Encode(data string) (string, error) {
h := md5.New()
_, err := h.Write([]byte(data))
if err != nil {
return "", err
}
return hex.EncodeToString(h.Sum(nil)), nil
}
func ParseServerAddr(serverAddr string) (host, port string) {
serverInfo := strings.Split(serverAddr, ":")
if len(serverInfo) == 2 {
host = serverInfo[0]
port = serverInfo[1]
} else {
host = serverAddr
port = ""
}
return host, port
}
func NewTrace() *TraceContext {
trace := &TraceContext{}
trace.TraceId = GetTraceId()
trace.SpanId = NewSpanId()
return trace
}
func NewSpanId() string {
timestamp := uint32(time.Now().Unix())
ipToLong := binary.BigEndian.Uint32(LocalIP.To4())
b := bytes.Buffer{}
b.WriteString(fmt.Sprintf("%08x", ipToLong^timestamp))
b.WriteString(fmt.Sprintf("%08x", rand.Int31()))
return b.String()
}
func GetTraceId() (traceId string) {
return calcTraceId(LocalIP.String())
}
func calcTraceId(ip string) (traceId string) {
now := time.Now()
timestamp := uint32(now.Unix())
timeNano := now.UnixNano()
pid := os.Getpid()
b := bytes.Buffer{}
netIP := net.ParseIP(ip)
if netIP == nil {
b.WriteString("00000000")
} else {
b.WriteString(hex.EncodeToString(netIP.To4()))
}
b.WriteString(fmt.Sprintf("%08x", timestamp&0xffffffff))
b.WriteString(fmt.Sprintf("%04x", timeNano&0xffff))
b.WriteString(fmt.Sprintf("%04x", pid&0xffff))
b.WriteString(fmt.Sprintf("%06x", rand.Int31n(1<<24)))
b.WriteString("b0") // 末两位标记来源,b0为go
return b.String()
}
func GetLocalIPs() (ips []net.IP) {
interfaceAddr, err := net.InterfaceAddrs()
if err != nil {
return nil
}
for _, address := range interfaceAddr {
ipNet, isValidIpNet := address.(*net.IPNet)
if isValidIpNet && !ipNet.IP.IsLoopback() {
if ipNet.IP.To4() != nil {
ips = append(ips, ipNet.IP)
}
}
}
return ips
}
func InArrayString(s string, arr []string) bool {
for _, i := range arr {
if i == s {
return true
}
}
return false
}
//Substr 字符串的截取
func Substr(str string, start int64, end int64) string {
length := int64(len(str))
if start < 0 || start > length {
return ""
}
if end < 0 {
return ""
}
if end > length {
end = length
}
return string(str[start:end])
}
//利用正则表达式压缩字符串,去除空格或制表符
func CompressStr(str string) string {
if str == "" {
return ""
}
//匹配一个或多个空白符的正则表达式
reg := regexp.MustCompile("\\s+")
return reg.ReplaceAllString(str, "")
}
func ClientIP(r *http.Request) string {
xForwardedFor := r.Header.Get("X-Forwarded-For")
ip := strings.TrimSpace(strings.Split(xForwardedFor, ",")[0])
if ip != "" {
return ip
}
ip = strings.TrimSpace(r.Header.Get("X-Real-Ip"))
if ip != "" {
return ip
}
if ip, _, err := net.SplitHostPort(strings.TrimSpace(r.RemoteAddr)); err == nil {
return ip
}
return ""
}
\ No newline at end of file
package lib
import (
"fmt"
dlog "github.com/ichunt2019/lxLog/log"
"strings"
)
// 通用DLTag常量定义
const (
DLTagUndefind = "_undef"
DLTagMySqlFailed = "_com_mysql_failure"
DLTagRedisFailed = "_com_redis_failure"
DLTagMySqlSuccess = "_com_mysql_success"
DLTagRedisSuccess = "_com_redis_success"
DLTagThriftFailed = "_com_thrift_failure"
DLTagThriftSuccess = "_com_thrift_success"
DLTagHTTPSuccess = "_com_http_success"
DLTagHTTPFailed = "_com_http_failure"
DLTagTCPFailed = "_com_tcp_failure"
DLTagRequestIn = "_com_request_in"
DLTagRequestOut = "_com_request_out"
)
const (
_dlTag = "dltag"
_traceId = "traceid"
_spanId = "spanid"
_childSpanId = "cspanid"
_dlTagBizPrefix = "_com_"
_dlTagBizUndef = "_com_undef"
)
var Log *Logger
type Trace struct {
TraceId string
SpanId string
Caller string
SrcMethod string
HintCode int64
HintContent string
}
type TraceContext struct {
Trace
CSpanId string
}
type Logger struct {
}
func (l *Logger) TagInfo(trace *TraceContext, dltag string, m map[string]interface{}) {
m[_dlTag] = checkDLTag(dltag)
m[_traceId] = trace.TraceId
m[_childSpanId] = trace.CSpanId
m[_spanId] = trace.SpanId
dlog.Instance("request").Info(parseParams(m))
}
func (l *Logger) TagWarn(trace *TraceContext, dltag string, m map[string]interface{}) {
m[_dlTag] = checkDLTag(dltag)
m[_traceId] = trace.TraceId
m[_childSpanId] = trace.CSpanId
m[_spanId] = trace.SpanId
dlog.Instance("request").Warn(parseParams(m))
}
func (l *Logger) TagError(trace *TraceContext, dltag string, m map[string]interface{}) {
m[_dlTag] = checkDLTag(dltag)
m[_traceId] = trace.TraceId
m[_childSpanId] = trace.CSpanId
m[_spanId] = trace.SpanId
dlog.Instance("request").Error(parseParams(m))
}
func (l *Logger) TagTrace(trace *TraceContext, dltag string, m map[string]interface{}) {
m[_dlTag] = checkDLTag(dltag)
m[_traceId] = trace.TraceId
m[_childSpanId] = trace.CSpanId
m[_spanId] = trace.SpanId
dlog.Instance("request").Trace(parseParams(m))
}
func (l *Logger) TagDebug(trace *TraceContext, dltag string, m map[string]interface{}) {
m[_dlTag] = checkDLTag(dltag)
m[_traceId] = trace.TraceId
m[_childSpanId] = trace.CSpanId
m[_spanId] = trace.SpanId
dlog.Instance("request").Debug(parseParams(m))
}
func (l *Logger) Close() {
dlog.Instance("request").Close()
}
// 生成业务dltag
func CreateBizDLTag(tagName string) string {
if tagName == "" {
return _dlTagBizUndef
}
return _dlTagBizPrefix + tagName
}
// 校验dltag合法性
func checkDLTag(dltag string) string {
if strings.HasPrefix(dltag, _dlTagBizPrefix) {
return dltag
}
if strings.HasPrefix(dltag, "_com_") {
return dltag
}
if dltag == DLTagUndefind {
return dltag
}
return dltag
}
//map格式化为string
func parseParams(m map[string]interface{}) string {
var dltag string = "_undef"
if _dltag, _have := m["dltag"]; _have {
if __val, __ok := _dltag.(string); __ok {
dltag = __val
}
}
for _key, _val := range m {
if _key == "dltag" {
continue
}
dltag = dltag + "||" + fmt.Sprintf("%v=%+v", _key, _val)
}
dltag = strings.Trim(fmt.Sprintf("%q", dltag), "\"")
return dltag
}
package util
import (
"context"
"ichunt_golang/util/lib"
"github.com/gin-gonic/gin"
)
//错误日志
func ContextWarning(c context.Context, dltag string, m map[string]interface{}) {
v:=c.Value("trace")
traceContext,ok := v.(*lib.TraceContext)
if !ok{
traceContext = lib.NewTrace()
}
lib.Log.TagWarn(traceContext, dltag, m)
}
//错误日志
func ContextError(c context.Context, dltag string, m map[string]interface{}) {
v:=c.Value("trace")
traceContext,ok := v.(*lib.TraceContext)
if !ok{
traceContext = lib.NewTrace()
}
lib.Log.TagError(traceContext, dltag, m)
}
//普通日志
func ContextNotice(c context.Context, dltag string, m map[string]interface{}) {
v:=c.Value("trace")
traceContext,ok := v.(*lib.TraceContext)
if !ok{
traceContext = lib.NewTrace()
}
lib.Log.TagInfo(traceContext, dltag, m)
}
//错误日志
func ComLogWarning(c *gin.Context, dltag string, m map[string]interface{}) {
traceContext := GetGinTraceContext(c)
lib.Log.TagError(traceContext, dltag, m)
}
//普通日志
func ComLogNotice(c *gin.Context, dltag string, m map[string]interface{}) {
traceContext := GetGinTraceContext(c)
lib.Log.TagInfo(traceContext, dltag, m)
}
// 从gin的Context中获取数据
func GetGinTraceContext(c *gin.Context) *lib.TraceContext {
// 防御
if c == nil {
return lib.NewTrace()
}
traceContext, exists := c.Get("trace")
if exists {
if tc, ok := traceContext.(*lib.TraceContext); ok {
return tc
}
}
return lib.NewTrace()
}
// 从Context中获取数据
func GetTraceContext(c context.Context) *lib.TraceContext {
if c == nil {
return lib.NewTrace()
}
traceContext:=c.Value("trace")
if tc, ok := traceContext.(*lib.TraceContext); ok {
return tc
}
return lib.NewTrace()
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment