您的位置:首页 > 编程语言

golang日志中心取日志代码分享

2016-03-22 21:11 375 查看
/*
请求使用方法:
Id要唯一
Tag:有两个值"listfile,getfile,或者"
源地址必须是在:192.168.0.0/24,172.18.0.0/24,10.0.0.0/24网段.不接受公网地址.

event := job{Id: "cp_19216823", Name: []string{`game/logs/log`,
`gate/logs/log`, `game-fight`, `mail/logs/log`, `room-manage/logs/log`, `/oem8.log`},
Path: `C:\test\server`, Tag: "listfile"}
b, _ := json.Marshal(event)
buf := bytes.NewReader(b)
resp, err := http.Post("http://172.18.80.247:1789/", bodyType, buf)
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
b, _ = ioutil.ReadAll(resp.Body)
fmt.Println(string(b))
*/

package main

import (
"archive/zip"
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"os"
"path/filepath"
"runtime"
"strings"
"time"
)

func main() {
go Server(":1789")
go Init()
var x job = job{Id: "cp_19216823", Name: []string{`game/logs/log`,
`gate/logs/log`, `game-fight`, `mail/logs/log`, `room-manage/logs/log`, `C:\oem8.log`},
Path: `C:\test\server`, Tag: ""}
b, _ := json.Marshal(x)
buf := bytes.NewReader(b)
resp, err := http.Post("http://172.18.80.247:1789/", bodyType, buf)
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
b, _ = ioutil.ReadAll(resp.Body)
fmt.Println(string(b))
time.Sleep(3e9)
}

var (
JobChan chan *job = make(chan *job, 5)
stdout  io.Writer = os.Stdout
debug   bool      = true
)

func init() {
os.MkdirAll(tempDir, 0644)
}

func Init() {
for {
j := <-JobChan
go j.Run()
}
}

const (
zone     int64 = +8
bodyType       = "application/x-www-form-urlencoded"
tempDir        = "tmp"
)

type job struct {
Id   string   `json:id`
Name []string `json:name`
Path string   `json:path`
Tag  string   `json:"tag"`
temp string   `json:tempfile`
}

func (self *job) Init() {
self.Path = filepath.ToSlash(self.Path)
if !filepath.HasPrefix(self.Path, "/") {
self.Path = self.Path + "/"
}
self.temp = tempDir + "/" + self.Id + "/"
os.MkdirAll(self.temp, 0644)
}

//返回两个值,分别为未成功copy的路径,另外一个是成功copy的路径
func (self *job) Copy() ([]string, []string) {
var uncopylist, pathlist []string
for _, v := range self.Name {
v = filepath.ToSlash(v)
var path, dst string
if filepath.IsAbs(v) {
list := strings.Split(v, "/")
if len(list) <= 1 {
continue
}
dst = self.temp + strings.Join(list[1:], "/")
pathlist = append(pathlist, dst)
err := copyFile(v, dst)
if err != nil {
if debug {
currentLine(err)
}
uncopylist = append(uncopylist, v)
}
continue
}
path = self.Path + v
basedir := filepath.ToSlash(filepath.Dir(v))
if basedir != filepath.Base(v) {
os.MkdirAll(self.temp+basedir, 0644)
}
dst = self.temp + v
pathlist = append(pathlist, dst)
err := copyFile(path, dst)
if err != nil {
if debug {
currentLine(err)
}
uncopylist = append(uncopylist, v)
continue
}
}
return uncopylist, pathlist
}

func (self *job) ListFile() map[string][]string {
var m map[string][]string = make(map[string][]string)
for _, v := range self.Name {
var list []string
v = filepath.ToSlash(v)
if filepath.IsAbs(v) {
_, err := os.Stat(v)
if err != nil {
if debug {
currentLine(err)
}
continue
}
m[v] = append(list, v)
continue
}
path := self.Path + v
info, err := os.Stat(path)
if err != nil {
if debug {
currentLine(err)
}
continue
}
if !info.IsDir() {
list = append(list, path)
m[path] = list
continue
}
l, err := ioutil.ReadDir(path)
if err != nil {
if debug {
currentLine(err)
}
continue
}
for _, name := range l {
list = append(list, name.Name())
}
m[path] = list
}
return m
}

func (self *job) Run() {
_, path := self.Copy()
if debug {
currentLine(path)
}
switch self.Tag {
case "getfile":
tZip(tempDir+"/"+self.Id, tempDir+"/"+self.Id+".zip")
os.RemoveAll(tempDir + "/" + self.Id)
default:
}
}

func copyFile(src, dst string) error {
sFile, err := os.Open(src)
if err != nil {
return err
}
defer sFile.Close()
dFile, err := os.Create(dst)
if err != nil {
return err
}
defer dFile.Close()
io.Copy(dFile, sFile)
return nil
}

func tZip(source, target string) error {
zipfile, err := os.Create(target)
if err != nil {
return err
}
defer zipfile.Close()
archive := zip.NewWriter(zipfile)
defer archive.Close()

return filepath.Walk(source, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
header, err := zip.FileInfoHeader(info)
if err != nil {
return err
}
if !info.IsDir() {
header.Method = zip.Deflate
}
header.SetModTime(time.Unix(info.ModTime().Unix()+(zone*60*60), 0))
header.Name = path
writer, err := archive.CreateHeader(header)
if err != nil {
return err
}
if info.IsDir() {
return nil
}
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
_, err = io.Copy(writer, file)
return err
})
}

const (
ForbiddenAccess = 403
MarshalError    = 550
UnmarshalError  = 551
ReadBodyError   = 552
)

func route(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
ip, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil || !ipIsLanIP(ip) {
http.Error(w, "ForbiddenAccess", ForbiddenAccess)
return
}
buf, err := ioutil.ReadAll(r.Body)
if err != nil {
http.Error(w, "ReadBodyError", ReadBodyError)
return
}
Job := new(job)
err = json.Unmarshal(buf, Job)
if err != nil {
http.Error(w, "UnmarshalError", UnmarshalError)
return
}
Job.Init()
if Job.Tag == "listfile" {
buf, err = json.Marshal(Job.ListFile())
if err != nil {
http.Error(w, "MarshalError", MarshalError)
return
}
w.Write(buf)
return
} else {
JobChan <- Job
w.Write([]byte("job is running,wait a moment"))
}
}

func Server(ip string) {
http.HandleFunc("/", route)
http.ListenAndServe(ip, nil)
}

//安全起见,设置允许的网段,只允许内网.
var (
mask  net.IPMask = net.CIDRMask(16, 32)
IP192 net.IPNet  = net.IPNet{net.ParseIP("192.168.0.0"), mask}
IP172 net.IPNet  = net.IPNet{net.ParseIP("172.18.0.0"), mask}
IP10  net.IPNet  = net.IPNet{net.ParseIP("10.0.0.0"), mask}
)

func ipIsLanIP(str string) bool {
ip := net.ParseIP(str)
return IP192.Contains(ip) || IP172.Contains(ip) || IP10.Contains(ip)
}

func currentLine(info interface{}) {
_, file, line, ok := runtime.Caller(1)
if ok {
fmt.Fprintf(stdout, "File:%s Line:%d \nInfo: %v\n", file, line, info)
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息