一个快速上手、轻量级 Golang 公共类库 (golang_common)

栏目: Go · 发布时间: 6年前

内容简介:目录定位功能

目录

定位

功能

安装及使用

其他功能举例

思考

定位

配置 Golang 基础服务(mysql、 redis 、http.client、log)比较繁琐,如果想 快速接入 基础服务可以使用本类库。

没有多余复杂的功能,方便你拓展其他功能。

你可以 import 引入直接使用,也可以拷贝代码到自己项目中使用,也可以用于构建自己的基础类库。

项目地址: https://github.com/e421083458/golang_common

功能

多套配置环境设置,比如:dev、prod。

mysql、redis 多套数据源配置。

支持默认和自定义日志实例,自动滚动日志。

支持 mysql(基于gorm的二次开发支持ctx功能,不影响gorm原功能使用)、redis(redigo)、http.client 请求链路日志输出。

安装及使用

需要确保已经安装了 Go 1.8+,然后执行以下命令

go get -v github.com/e421083458/golang_common

将配置文件拷贝到你的项目中,配置文件请参考: https://github.com/e421083458/golang_common/tree/master/conf/dev

其实只需要base.toml即可,mysql.toml、redis.toml 根据实际需要再配置。

log消息打印代码举例:

package main

import (

"github.com/e421083458/golang_common/lib"

"log"

"time"

)

func main(){

if err:=lib.Init("./conf/dev/");err!=nil{

log.Fatal(err)

}

defer lib.Destroy()

//todo sth
lib.Log.TagInfo(lib.NewTrace(), lib.DLTagUndefind, map[string]interface{}{"message": "todo sth"})
time.Sleep(time.Second)

}

运行代码

go run main.go

输出:

2019/05/21 10:31:08 ------------------------------------------------------------------------

2019/05/21 10:31:08 [INFO] config=./conf/dev/

2019/05/21 10:31:08 [INFO] start loading resources.

2019/05/21 10:31:08 [INFO] success loading resources.

2019/05/21 10:31:08 ------------------------------------------------------------------------

2019-05-21T10:31:08.667 [INFO] log.go:58 _undef||traceid=ac182a1c5ce362ecf9280618104dc7b0||cspanid=||spanid=f0fb48f0380704bb||message=todo sth

2019/05/21 10:31:09 ------------------------------------------------------------------------

2019/05/21 10:31:09 [INFO] start destroy resources.

2019/05/21 10:31:09 [INFO] success destroy resources.

其他功能举例

初始化当前运行环境

//初始化测试用例

func InitTest() {

initOnce.Do(func() {

if err:=lib.Init("../conf/dev/");err!=nil{

log.Fatal(err)

}

})

}

获取当前运行环境

//获取 程序运行环境 dev prod

func Test_GetConfEnv(t *testing.T) {

InitTest()

fmt.Println(lib.GetConfEnv())

DestroyTest()

}

加载自定义配置文件

type HttpConf struct {

ServerAddr string toml:"server_addr"
ReadTimeout int toml:"read_timeout"
WriteTimeout int toml:"write_timeout"
MaxHeaderBytes int toml:"max_header_bytes"
AllowHost []string toml:"allow_host"

}

// 加载自定义配置文件

func Test_ParseLocalConfig(t *testing.T) {

InitTest()

httpProfile := &HttpConf{}

err:=lib.ParseLocalConfig("http.toml",httpProfile)

if err!=nil{

t.Fatal(err)

}

fmt.Println(httpProfile)

DestroyTest()

}

测试PostJson请求

//测试PostJson请求

func TestJson(t *testing.T) {

InitTestServer()

//首次scrollsId不传递

jsonStr := "{\"source\":\"control\",\"cityId\":\"12\",\"trailNum\":10,\"dayTime\":\"2018-11-21 16:08:00\",\"limit\":2,\"andOperations\":{\"cityId\":\"eq\",\"trailNum\":\"gt\",\"dayTime\":\"eq\"}}"

url := " http://"+addr+"/postjson "

_, res, err := lib.HttpJSON(lib.NewTrace(), url, jsonStr, 1000, nil)

fmt.Println(string(res))

if err != nil {

fmt.Println(err.Error())

}

}

测试Get请求

//测试Get请求

func TestGet(t *testing.T) {

InitTestServer()

a := url.Values{

"city

id": {"12"},

}

url := " http://"+addr+"/get "

, res, err := lib.HttpGET(lib.NewTrace(), url, a, 1000, nil)

fmt.Println("city_id="+string(res))

if err != nil {

fmt.Println(err.Error())

}

}

测试Post请求

//测试Post请求

func TestPost(t *testing.T) {

InitTestServer()

a := url.Values{

"city

id": {"12"},

}

url := " http://"+addr+"/post "

, res, err := lib.HttpPOST(lib.NewTrace(), url, a, 1000, nil, "")

fmt.Println("city_id="+string(res))

if err != nil {

fmt.Println(err.Error())

}

}

测试默认日志打点

//测试日志打点

func TestDefaultLog(t *testing.T) {

InitTest()

lib.Log.TagInfo(lib.NewTrace(), lib.DLTagMySqlSuccess, map[string]interface{}{

"sql": "sql",

})

time.Sleep(time.Second)

DestroyTest()

}

测试自定义日志实例打点

//测试日志实例打点

func TestLogInstance(t *testing.T) {

nlog:= log.NewLogger()

logConf:= log.LogConfig{

Level:"trace",

FW: log.ConfFileWriter{

On:true,

LogPath:"./log_test.log",

RotateLogPath:"./log_test.log",

WfLogPath:"./log_test.wf.log",

RotateWfLogPath:"./log_test.wf.log",

},

CW: log.ConfConsoleWriter{

On:true,

Color:true,

},

}

log.SetupLogInstanceWithConf(logConf,nlog)

nlog.Info("test message")

nlog.Close()

time.Sleep(time.Second)

}

测试 mysql 普通sql

var (

createTableSQL = "CREATE TABLE test1 ( id int(12) unsigned NOT NULL AUTO_INCREMENT" +

" COMMENT '自增id', name varchar(255) NOT NULL DEFAULT '' COMMENT '姓名'," +

" created_at datetime NOT NULL,PRIMARY KEY ( id )) ENGINE=InnoDB " +

"DEFAULT CHARSET=utf8"

insertSQL = "INSERT INTO test1 ( id , name , created_at ) VALUES (NULL, '111', '2018-08-29 11:01:43');"

dropTableSQL = "DROP TABLE test1 "

beginSQL = "start transaction;"

commitSQL = "commit;"

rollbackSQL = "rollback;"

)

func Test_DBPool(t *testing.T) {

InitTest()

//获取链接池
dbpool, err := lib.GetDBPool("default")
if err != nil {
    t.Fatal(err)
}
//开始事务
trace := lib.NewTrace()
if _, err := lib.DBPoolLogQuery(trace, dbpool, beginSQL); err != nil {
    t.Fatal(err)
}

//创建表
if _, err := lib.DBPoolLogQuery(trace, dbpool, createTableSQL); err != nil {
    lib.DBPoolLogQuery(trace, dbpool, rollbackSQL)
    t.Fatal(err)
}

//插入数据
if _, err := lib.DBPoolLogQuery(trace, dbpool, insertSQL); err != nil {
    lib.DBPoolLogQuery(trace, dbpool, rollbackSQL)
    t.Fatal(err)
}

//循环查询数据
current_id := 0
table_name := "test1"
fmt.Println("begin read table ", table_name, "")
fmt.Println("------------------------------------------------------------------------")
fmt.Printf("%6s | %6s\n", "id", "created_at")
for {
    rows, err := lib.DBPoolLogQuery(trace, dbpool, "SELECT id,created_at FROM test1 WHERE id>? order by id asc", current_id)
    defer rows.Close()
    row_len := 0
    if err != nil {
        lib.DBPoolLogQuery(trace, dbpool, "rollback;")
        t.Fatal(err)
    }
    for rows.Next() {
        var create_time string
        if err := rows.Scan(&current_id, &create_time); err != nil {
            lib.DBPoolLogQuery(trace, dbpool, "rollback;")
            t.Fatal(err)
        }
        fmt.Printf("%6d | %6s\n", current_id, create_time)
        row_len++
    }
    if row_len == 0 {
        break
    }
}
fmt.Println("------------------------------------------------------------------------")
fmt.Println("finish read table ", table_name, "")

//删除表
if _, err := lib.DBPoolLogQuery(trace, dbpool, dropTableSQL); err != nil {
    lib.DBPoolLogQuery(trace, dbpool, rollbackSQL)
    t.Fatal(err)
}

//提交事务
lib.DBPoolLogQuery(trace, dbpool, commitSQL)
DestroyTest()

}

测试Gorm

func Test_GORM(t *testing.T) {

InitTest()

//获取链接池
dbpool, err := lib.GetGormPool("default")
if err != nil {
    t.Fatal(err)
}
db := dbpool.Begin()
traceCtx := lib.NewTrace()

//设置trace信息
db = db.SetCtx(traceCtx)
if err := db.Exec(createTableSQL).Error; err != nil {
    db.Rollback()
    t.Fatal(err)
}郑                 :https://yyk.familydoctor.com.cn/21521/

//插入数据
t1 := &Test1{Name: "test_name", CreatedAt: time.Now()}
if err := db.Save(t1).Error; err != nil {
    db.Rollback()
    t.Fatal(err)
}

//查询数据
list := []Test1{}
if err := db.Where("name=?", "test_name").Find(&list).Error; err != nil {
    db.Rollback()
    t.Fatal(err)
}
fmt.Println(list)

//删除表数据
if err := db.Exec(dropTableSQL).Error; err != nil {
    db.Rollback()
    t.Fatal(err)
}
db.Commit()
DestroyTest()

}

测试redis查询

func Test_Redis(t *testing.T) {

InitTest()

c, err := lib.RedisConnFactory("default")
if err != nil {
    t.Fatal(err)
}
defer c.Close()

// 调用SET
trace := lib.NewTrace()
redisKey := "test_key1"
lib.RedisLogDo(trace, c, "SET", redisKey, "test_dpool")
lib.RedisLogDo(trace, c, "expire", "test_key1", 10)

// 调用GET
v, err := redis.String(lib.RedisLogDo(trace, c, "GET", redisKey))
fmt.Println(v)
if v != "test_dpool" || err != nil {
    t.Fatal("test redis get fatal!")
}

DestroyTest()

}

销毁当前运行环境

//销毁测试用例

func DestroyTest() {

Destroy()

}思考

怎么样才能让类库做的更通用?

有人说简洁才是golang特性,不需要做通用类库。如果你想加一个功能直接引一个包用即可。比如:日志那就引日志包、redis就引redis包。

我赞同此观点,但是引入包后要面临的问题是功能改造和代码适配,并且每做一个项目都要搞上一套。这意味着需要耗费一定的时间在重复的工作上。

我感觉类库应该有一下特点:

轻量级,没有太多依赖,否则容易有类库依赖冲突。

只封装重复使用率高的功能。

拓展性强。

作者:e421083458

来源:CSDN

原文: https://blog.csdn.net/e421083458/article/details/90346968

版权声明:本文为博主原创文章,转载请附上博文链接!


以上所述就是小编给大家介绍的《一个快速上手、轻量级 Golang 公共类库 (golang_common)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Haskell

Haskell

Simon Thompson / Addison-Wesley / 1999-3-16 / GBP 40.99

The second edition of Haskell: The Craft of Functional Programming is essential reading for beginners to functional programming and newcomers to the Haskell programming language. The emphasis is on th......一起来看看 《Haskell》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试