go连接mysql,redis并完成日志字符处理实例
package main
import (
"compress/gzip"
"fmt"
"io/ioutil"
"os"
"strings"
"github.com/garyburd/redigo/redis"
"math"
"strconv"
"net/url"
"time"
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
func GetGzFiles(dirPth string) (files []string, err error) {
var dirs []string
dir, err := ioutil.ReadDir(dirPth)
if err != nil {
return nil, err
}
PthSep := string(os.PathSeparator)
for _, fi := range dir {
if fi.IsDir() {
dirs = append(dirs, dirPth+PthSep+fi.Name())
GetGzFiles(dirPth + PthSep + fi.Name())
} else {
ok := strings.HasSuffix(fi.Name(), ".gz")
if ok {
files = append(files, dirPth+PthSep+fi.Name())
}
}
}
for _, dir := range dirs {
tmpFiles, _ := GetGzFiles(dir)
for _, file := range tmpFiles {
files = append(files, file)
}
}
return files, nil
}
type ResInfo struct {
id int
timestamp int64
date string
dnid int
resocde int
cacheCode int
upstreamHttpStatus string
sourceCode int
errorCode int
clientIp string
serverIp string
reponseTime float64
}
var id int = 0
func main() {
db, err := sql.Open("mysql", "user:passwd@tcp(127.0.0.1:65000)/server_conf?charset=utf8")
if err != nil {
fmt.Printf("connect mysql failed! [%s]", err)
return
} else {
fmt.Println("connect mysql ok!")
}
rows, err := db.Query("SELECT d_id, d_dname FROM domain")
if err != nil {
fmt.Printf("select failed! [%s]", err)
return
}
var mapDomain map[string]int
mapDomain = make(map[string]int)
for rows.Next() {
var d_id int
var d_dname string
rows.Columns()
err = rows.Scan(&d_id, &d_dname)
if err != nil {
fmt.Printf("Get domain info failed! [%s]", err)
}
mapDomain[d_dname] = d_id
}
files, _ := GetGzFiles("./gzfiles")
var ResInfoList []ResInfo
for _, fn := range files {
fmt.Printf("开始处理日志文件[%s]\n", fn)
fr, err := os.Open(fn)
if err != nil {
panic(err)
} else {
println("open file success!")
}
defer fr.Close()
gr, err := gzip.NewReader(fr)
if err != nil {
panic(err)
}
defer gr.Close()
rBuf, err := ioutil.ReadAll(gr)
if err != nil {
fmt.Println("[read gzip data err]: ", err)
}
strBuf := string(rBuf)
bufList := strings.Split(strBuf, "\n")
for _, strLine := range bufList {
if len(strLine) == 0 {
continue
}
var dnid int
var errorCode int
var timestamp int64
var resocde int
var cacheCode int
var sourceCode int
var reponseTime float64
var date string
var clientIp string
var serverIp string
var upstreamHttpStatus string
var userDefineList []string
fragList := strings.Split(strLine, "\t")
for i, strFrag := range fragList {
if i == 0 {
strTemp := strings.Split(strFrag, "/")
clientIp = strTemp[0]
fmt.Printf("clientIp=%v\n", clientIp)
} else if i == 1 {
tmp, _ := strconv.ParseFloat(strFrag, 64)
timestamp = int64(math.Trunc(tmp))/60*60
fmt.Printf("timestamp=%v\n", timestamp)
tm := time.Unix(timestamp, 0)
date = tm.Format("20060102")
} else if i == 4 {
resocde, _ = strconv.Atoi(strFrag)
fmt.Printf("resocde=%v\n", resocde)
} else if i == 5 {
upstreamHttpStatus = strFrag
fmt.Printf("upstreamHttpStatus=%v\n", upstreamHttpStatus)
} else if i == 8 {
strTemp := strFrag
u, err := url.Parse(strTemp)
if err != nil {
panic(err)
}
fmt.Printf("url=%v\n", u.Host)
if v, ok := mapDomain[u.Host]; ok {
dnid = v
} else {
fmt.Printf("Domain Not Found!")
}
} else if i == 13 {
serverIp = strFrag
fmt.Printf("serverIp=%v\n", serverIp)
} else if i == 17 {
reponseTime, _ = strconv.ParseFloat(strFrag, 64)
fmt.Printf("reponseTime=%v\n", reponseTime)
} else if i == 29 {
userDefineList = strings.Split(strFrag, "/")
for i, strDefine := range userDefineList {
if i == 5 {
cacheCode, _ = strconv.Atoi(strDefine)
}
}
}
}
errorCode = 9
id++
info := ResInfo{id,timestamp,date,dnid,resocde,cacheCode,upstreamHttpStatus,sourceCode,errorCode,clientIp,serverIp,reponseTime}
ResInfoList = append(ResInfoList, info)
}
break
}
conn, err := redis.Dial("tcp", "127.0.0.1:65000")
if err != nil {
fmt.Println("Connect to redis error", err)
return
} else {
fmt.Println("Connect to redis ok.")
}
defer conn.Close()
conn.Do("AUTH", "xxxxxx")
fmt.Printf("list len=%v\n", len(ResInfoList))
var tm int64 = 0
for _, info := range ResInfoList {
tm = info.timestamp
_, err = conn.Do("LPUSH", info.timestamp, info)
if err != nil {
fmt.Println("redis push list failed:", err)
} else {
}
break
}
infoList, err := redis.Strings(conn.Do("LRANGE", tm, 0, -1))
if err != nil {
fmt.Println("redis get list failed:", err)
}
for _, info := range infoList {
fmt.Printf("values: %v\n", info)
}
}