0%

git

git webhook

git add 参数不同区别

  • git add -A 提交所有变化

  • git add -u 提交被修改(modified)和被删除(deleted)文件,不包括新文件(new)

  • git add . 提交新文件(new)和被修改(modified)文件,不包括被删除(deleted)文件

git core.autocrlf

core.autocrlf
假如你正在 Windows 上写程序,而你的同伴用的是其他系统(或相反),你可能会遇到 CRLF 问题。 这是因为 Windows 使用回车(CR)和换行(LF)两个字符来结束一行,而 macOS 和 Linux 只使用换行(LF)一个字符。 虽然这是小问题,但它会极大地扰乱跨平台协作。许多 Windows 上的编辑器会悄悄把行尾的换行字符转换成回车和换行, 或在用户按下 Enter 键时,插入回车和换行两个字符。

Git 可以在你提交时自动地把回车和换行转换成换行,而在检出代码时把换行转换成回车和换行。 你可以用 core.autocrlf 来打开此项功能。 如果是在 Windows 系统上,把它设置成 true,这样在检出代码时,换行会被转换成回车和换行:

$ git config –global core.autocrlf true

如果使用以换行作为行结束符的 Linux 或 macOS,你不需要 Git 在检出文件时进行自动的转换; 然而当一个以回车加换行作为行结束符的文件不小心被引入时,你肯定想让 Git 修正。 你可以把 core.autocrlf 设置成 input 来告诉 Git 在提交时把回车和换行转换成换行,检出时不转换:

$ git config –global core.autocrlf input

这样在 Windows 上的检出文件中会保留回车和换行,而在 macOS 和 Linux 上,以及版本库中会保留换行。

如果你是 Windows 程序员,且正在开发仅运行在 Windows 上的项目,可以设置 false 取消此功能,把回车保留在版本库中:

$ git config –global core.autocrlf false

logrus 特性

  • 完全兼容golang标准库日志模块:logrus拥有六种日志级别:debug、info、warn、error、fatal和panic,这是golang标准库日志模块的API的超集.如果您的项目使用标准库日志模块,完全可以以最低的代价迁移到logrus上.
    • logrus.Debug(“Useful debugging information.”)
    • logrus.Info(“Something noteworthy happened!”)
    • logrus.Warn(“You should probably take a look at this.”)
    • logrus.Error(“Something failed but I’m not quitting.”)
    • logrus.Fatal(“Bye.”) //log之后会调用os.Exit(1)
    • logrus.Panic(“I’m bailing.”) //log之后会panic()
  • 可扩展的Hook机制:允许使用者通过hook的方式将日志分发到任意地方,如本地文件系统、标准输出、logstash、elasticsearch或者mq等,或者通过hook定义日志内容和格式等.
  • 可选的日志输出格式:logrus内置了两种日志格式,JSONFormatter和TextFormatter,如果这两个格式不满足需求,可以自己动手实现接口Formatter,来定义自己的日志格式.
  • Field机制:logrus鼓励通过Field机制进行精细化的、结构化的日志记录,而不是通过冗长的消息来记录日志.
  • logrus是一个可插拔的、结构化的日志框架.
  • Entry: logrus.WithFields会自动返回一个 *Entry,Entry里面的有些变量会被自动加上
    • time:entry被创建时的时间戳
    • msg:在调用.Info()等方法时被添加
    • level

gin logrus middleware

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package middleware

import (
"fmt"
"os"
"path"
"time"

"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
)

// LoggerToFile 日志记录到文件
func LoggerToFile() gin.HandlerFunc {

logFilePath := "log"
logFileName := "gin.log"

//日志文件
fileName := path.Join(logFilePath, logFileName)

if _, err := os.Stat(fileName); os.IsNotExist(err) {
// log path does not exist
os.Create(fileName)
}
//写入文件
src, err := os.OpenFile(fileName, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
if err != nil {
fmt.Println("err", err)
}

//实例化
logger := logrus.New()

//设置输出
logger.Out = src

//设置日志级别
logger.SetLevel(logrus.DebugLevel)

//设置日志格式
logger.SetFormatter(&logrus.TextFormatter{
// TimestampFormat: "2006/01/02 15:04:05",
})

return func(c *gin.Context) {
// 开始时间
startTime := time.Now()

// 处理请求
c.Next()

// 结束时间
endTime := time.Now()

// 执行时间
latencyTime := endTime.Sub(startTime)

// 请求方式
reqMethod := c.Request.Method

// 请求路由
reqURI := c.Request.RequestURI

// 状态码
statusCode := c.Writer.Status()

// 请求IP
clientIP := c.ClientIP()

// reference
referer := c.Request.Referer()

clientUserAgent := c.Request.UserAgent()

errors := c.Errors

entry := logger.WithFields(logrus.Fields{
"statusCode": statusCode,
"latency": latencyTime, // time to process
"clientIP": clientIP,
"method": reqMethod,
"path": reqURI,
"referer": referer,
"userAgent": clientUserAgent,
"errors": errors,
})

msg := fmt.Sprintf("| %3d | %13v | %15s | %s | %s | %s | %s |", statusCode, latencyTime, clientIP, reqMethod, reqURI, referer, clientUserAgent)
if statusCode > 499 {
entry.Error(msg)
} else if statusCode > 399 {
entry.Warn(msg)
} else {
entry.Info(msg)
}

// 日志格式
// logger.Infof("| %3d | %13v | %15s | %s | %s |",
// statusCode,
// latencyTime,
// clientIP,
// reqMethod,
// reqURI,
// )
}
}

// LoggerToMongo 日志记录到 MongoDB
func LoggerToMongo() gin.HandlerFunc {
return func(c *gin.Context) {

}
}

// LoggerToES 日志记录到 ES
func LoggerToES() gin.HandlerFunc {
return func(c *gin.Context) {

}
}

// LoggerToMQ 日志记录到 MQ
func LoggerToMQ() gin.HandlerFunc {
return func(c *gin.Context) {

}
}

react hooks

react 高阶组件

go build

By default, go build combines symbol and debug info with binary files. However, you can remove the symbol and debug info with go build -ldflags “-s -w”.

阅读全文 »

Cobra介绍

Cobra是一个库,其提供简单的接口来创建强大现代的CLI接口,类似于git或者go工具。同时,它也是一个应用,用来生成应用框架,从而开发以Cobra为基础的应用。Docker和Kubernetes源码中使用了Cobra。

概念
Cobra有三个基本概念commands,arguments和flags。其中commands代表行为,arguments代表数值,flags代表对行为的改变。

阅读全文 »

监控Nginx服务器

由于官方没有提供Nginx直接可用的exporter,Nginx的监控要相对复杂一些。这里使用的是三方提供nginx-vts-exporter。

安装Nginx

由于nginx-vts-exporter依赖于Nginx的nginx-module-vts模块,所以这里需要重新编译下Nginx。

阅读全文 »

jwt 生成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// GenerateJWT  jwt generate
func (service UserLoginService) GenerateJWT(user model.User) (string, error) {
expiresTime := time.Now().Unix() + int64(config.OneDayOfHours)
ID := fmt.Sprint(user.ID)
claims := CustomClaims{
user.Username,
jwt.StandardClaims{
Audience: "Audience", // 受众
ExpiresAt: expiresTime, // 失效时间
Id: ID, // 编号
IssuedAt: time.Now().Unix(), // 签发时间
Issuer: "gin project", // 签发人
NotBefore: time.Now().Unix(), // 生效时间
Subject: "login", // 主题
},
}

tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

// 通过密码和保留字段加密
var jwtSecret = []byte(config.Secret + user.PasswordDigest)
token, err := tokenClaims.SignedString(jwtSecret)

return token, err
}
阅读全文 »

golang gin框架 跨域访问配置代码

中间件代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package middleware

import (
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
)

// Cors 跨域配置
func Cors() gin.HandlerFunc {
config := cors.DefaultConfig()
config.AllowMethods = []string{"GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"}
config.AllowHeaders = []string{"Origin", "Content-Length", "Content-Type", "Cookie"}
if gin.Mode() == gin.ReleaseMode {
// 生产环境需要配置跨域域名,否则403
config.AllowOrigins = []string{"http://www.example.com"}
} else {
config.AllowOrigins = []string{"*"}
}
config.AllowCredentials = true
return cors.New(config)
}
阅读全文 »