1.resty
github链接:https://github.com/go-resty/resty/
使用:import “github.com/go-resty/resty/v2”
Resty包是一个很棒的http client库,封装了golang自带的http方法,
使用方法
//get方法
client := resty.New()
resp, err := client.R().//R()方法是创建一个Request实例
SetQueryParams(map[string]string{//必须是map[string]string
"page_no": "1",
"limit": "20",
"sort":"name",
"order": "asc",
"random":strconv.FormatInt(time.Now().Unix(), 10),
}).//也可以使用SetQueryString(),使用&拼接
SetHeader("Accept", "application/json").
SetContext(context.Background()).
SetResult(&result).//result实例,可以自动解析json
Get(url)
//post方法
client := resty.New()
// No need to set content type, if you have client level setting
resp, err := client.R().
EnableTrace().//配置trace
SetTimeout(24*60).//设置超时时间
SetHeader("Content-Type", "application/json").
SetBody(`{"username":"testuser", "password":"testpass"}`).
//一般使用map[string]interface{}的结构或者[]byte
SetResult(&AuthSuccess{}). // or SetResult(AuthSuccess{}).
SetContext(context.Background()).
Post("https://myapp.com/login")
返回内容解析
client := resty.New()
resp, err := client.R().
EnableTrace().
Get("https://httpbin.org/get")
// Explore response object
fmt.Println("Response Info:")
fmt.Println(" Error :", err)//nil
fmt.Println(" Status Code:", resp.StatusCode())
fmt.Println(" Status :", resp.Status())
fmt.Println(" Proto :", resp.Proto())
fmt.Println(" Time :", resp.Time())
fmt.Println(" Received At:", resp.ReceivedAt())
fmt.Println(" Body :\n", resp)
fmt.Println()
// Explore trace info
fmt.Println("Request Trace Info:")
ti := resp.Request.TraceInfo()
fmt.Println(" DNSLookup :", ti.DNSLookup)
fmt.Println(" ConnTime :", ti.ConnTime)
fmt.Println(" TCPConnTime :", ti.TCPConnTime)
fmt.Println(" TLSHandshake :", ti.TLSHandshake)
fmt.Println(" ServerTime :", ti.ServerTime)
fmt.Println(" ResponseTime :", ti.ResponseTime)
fmt.Println(" TotalTime :", ti.TotalTime)
fmt.Println(" IsConnReused :", ti.IsConnReused)
fmt.Println(" IsConnWasIdle :", ti.IsConnWasIdle)
fmt.Println(" ConnIdleTime :", ti.ConnIdleTime)
fmt.Println(" RequestAttempt:", ti.RequestAttempt)
fmt.Println(" RemoteAddr :", ti.RemoteAddr.String())
/*
Response Info:
Error : <nil>
Status Code: 200
Status : 200 OK
Proto : HTTP/2.0
Time : 457.034718ms
Received At: 2020-09-14 15:35:29.784681 -0700 PDT m=+0.458137045
Body :
{
"args": {},
"headers": {
"Accept-Encoding": "gzip",
"Host": "httpbin.org",
"User-Agent": "go-resty/2.4.0 (https://github.com/go-resty/resty)",
"X-Amzn-Trace-Id": "Root=1-5f5ff031-000ff6292204aa6898e4de49"
},
"origin": "0.0.0.0",
"url": "https://httpbin.org/get"
}
Request Trace Info:
DNSLookup : 4.074657ms
ConnTime : 381.709936ms
TCPConnTime : 77.428048ms
TLSHandshake : 299.623597ms
ServerTime : 75.414703ms
ResponseTime : 79.337µs
TotalTime : 457.034718ms
IsConnReused : false
IsConnWasIdle : false
ConnIdleTime : 0s
RequestAttempt: 1
RemoteAddr : 3.221.81.55:443
*/
2.logrus
logrus是golang常使用的log框架之一
https://github.com/sirupsen/logrus
https://blog.csdn.net/wslyk606/article/details/81670713
- 完全兼容golang标准库日志模块。logrus拥有六种日志级别:debug、info、warn、error、fatal和panic,这是golang标准库日志模块的API的超集。如果你的项目使用标准库日志模块,完全可以用最低的代价迁移到logrus上。
- 可扩展的Hook机制。允许使用者通过hook方式,将日志分发到任意地方,如本地文件系统、标准输出、logstash、elasticsearch或者mq等,或者通过hook定义日志内容和格式等。
- 可选的日志输出格式。logrus内置了两种日志格式,JSONFormatter和TextFormatter。如果这两个格式不满足需求,可以自己动手实现接口Formatter,来定义自己的日志格式。
- Field机制。logrus鼓励通过Field机制进行精细化、结构化的日志记录,而不是通过冗长的消息来记录日志。
- logrus是一个可插拔的、结构化的日志框架。
- 低层通过sync.Mutex加锁来实现线程安全 ```go import “github.com/sirupsen/logrus”
func main(){ logrus.SetLevel(logrus.TraceLevel)//设置日志级别 logrus.SetFormatter(&logrus.TextFormatter{})//设置输出格式 text or json logrus.AddHook(Hook())//添加hook,需要实现fire和Levels两个接口,可以使用第三方hook log.WithFields(logrus.Fields{ “errMsg”: “test err”, }).Info(“test error”) }
//type Hook interface { // Levels() []Level 记录Levels()返回的日志级别的消息时会触发HOOK, // Fire(*Entry) error 按照Fire方法定义的内容修改logrus.Entry。 //}
**行号和文件名的支持**<br />一就是自己实现一个hook;二就是通过装饰器包装logrus.Entry<br />**输出到本地文件系统时的日志分割功能**<br />通过file-rotatelogs进行日志本地文件分割
```go
func ConfigLocalFilesystemLogger(logPath string, logFileName string, maxAge time.Duration, rotationTime time.Duration) {
baseLogPaht := path.Join(logPath, logFileName)
writer, err := rotatelogs.New(
baseLogPaht+".%Y%m%d%H%M",
// 生成软链,指向最新日志文件
rotatelogs.WithLinkName(baseLogPaht),
// WithMaxAge和WithRotationCount只能设置一个
// WithMaxAge文件最大保存时间
// WithRotationCount最大保存数量
rotatelogs.WithMaxAge(maxAge),
// 日志切割时间间隔
rotatelogs.WithRotationTime(rotationTime),
)
if err != nil {
log.Errorf("config local file system logger error: %+v", err)
}
lfHook := lfshook.NewHook(lfshook.WriterMap{
log.DebugLevel: writer, // 为不同级别设置不同的输出目的
log.InfoLevel: writer,
log.WarnLevel: writer,
log.ErrorLevel: writer,
log.FatalLevel: writer,
log.PanicLevel: writer,
},&log.TextFormatter{})
log.AddHook(lfHook)
}
输出到ELK等日志处理中心的功能
import (
"github.com/olivere/elastic"
"gopkg.in/sohlich/elogrus"
)
func initLog() {
client, err := elastic.NewClient(elastic.SetURL("http://localhost:9200"))
if err != nil {
log.Panic(err)
}
hook, err := elogrus.NewElasticHook(client, "localhost", log.DebugLevel, "mylog")//elogrus第三方hook
if err != nil {
log.Panic(err)
}
log.AddHook(hook)
}
/**
https://github.com/vladoatanasov/logrus_amqp
Logrus hook for Activemq。
https://github.com/bshuster-repo/logrus-logstash-hookk
Logstash hook for logrus。
https://github.com/weekface/mgorus
Mongodb Hooks for Logrus。
https://github.com/abramovic/logrus_influxdb
InfluxDB Hook for Logrus。
https://github.com/rogierlommers/logrus-redis-hook
Hook for Logrus which enables logging to RELK stack (Redis, Elasticsearch, Logstash and Kibana)。
*/
3.excelize
excelize是golang处理excel的类库
import “github.com/xuri/excelize/v2”
文档:https://xuri.me/excelize/zh-hans/
f := excelize.NewFile()
sheetName := "testSheet"
f.NewSheet(sheetName)
//列表类型建议这么做
titles := []string{"name", "age", "phone"}
err = f.SetSheetRow(sheetName, "A1", &titles)
if err != nil{
fmt.Println(err)
return
}
for i, l := range list {
axis := i + 2
datas := []interface{}{
l.name,
l.age,
l.phone,
}
err = f.SetSheetRow(sheetName, fmt.Sprintf("A%d", axis), &datas)
if err != nil {
fmt.Println(err)
return
}
}
4.gjson
gjson是get json的缩写,它只能用用于解析json字符串,但不能用于序列号。官方的 JSON 解析库需要传两个参数,一个是需要被序列化的对象,另一个是表示这个对象的类型。
在真正执行 JSON 解析之前会调用 reflect.ValueOf来获取参数 v 的反射对象。然后会获取到传入的 data 对象的开头非空字符来界定该用哪种方式来进行解析,由于用到了反射,性能较低
func main(){
json := `{
"name":"rzy",
"age":25
}`
name := gjson.Get(json,"name")
if !gjson.Valid(json){
fmt.Sprintf("json invalid")
}
// 输出 json 行数组的长度
log.Println(gjson.Get(json, "..#"))
// 输出 json 行 数组的第 3 行
log.Println(gjson.Get(json, "..2"))
// 输出 json 每一行 里面的 author 对应的值,组成一个数组
log.Println(gjson.Get(json, "..#.name"))
// 输出输出 json 行 中,author = xiaomotong 所在行
log.Println(gjson.Get(json, `..#(name="rzy")`))
// 遍历 json 行
gjson.ForEachLine(json, func(jLine gjson.Result) bool {
log.Println("author:", gjson.Get(jLine.String(), "hobby"))
return true
})
}