go语言四—脚本二

ciaos · · 3286 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

记录一些go脚本,使用定时器,信号,go轻量级线程,调用系统命令,压缩,计算md5,列表,获取本机IP等功能

(向程序发送信号如:kill -2 进程号)

package main

import (
	"os"; "os/signal"; "os/exec"
	"syscall"
	"net"
	"time"
	"strconv"; "strings"
	"bufio"
	"io/ioutil"
	"fmt"
	"archive/zip"
	"crypto/md5"
	l "container/list"
	"bytes"
//	"encoding/hex"
	"io"
)

const (
	path string = "/root/logs/"

	log_pos string = "log_watcher.pos"
	log_access string = "access.log"
	log_upload string = "upload_access.log"

	salt string = "salt-value"
)

var restarter int = 0
var localip string
var uploadfiles = l.New()

//------------------------------------------------------------------------------

func check(err error) bool {
	if err != nil {
//		panic(err)
		return false
	}
	return true
}

func get_local_ip() (string) {
	ifi, err := net.InterfaceByName("eth0")
	check(err)
	addrs, err := ifi.Addrs()
	check(err)
	for _,a := range addrs {
		if ip := strings.Split(a.String(),"/"); len(ip) > 1 {
			return ip[0]
		}
	}

	ifi, err = net.InterfaceByName("bond0")
	check(err)
	addrs, err = ifi.Addrs()
	check(err)
	for _,a := range addrs {
		if ip := strings.Split(a.String(),"/"); len(ip) > 1 {
			return ip[0]
		}
	}

	ifi, err = net.InterfaceByName("br0")
	check(err)
	addrs, err = ifi.Addrs()
	check(err)
	for _,a := range addrs {
		if ip := strings.Split(a.String(),"/"); len(ip) > 1 {
			return ip[0]
		}
	}

	panic("IP")
}

func load_data(filename string) (string) {
	buff, err := ioutil.ReadFile(filename)
	if !check(err) { return "" }
	return string(buff)
}

func save_data(filename, data string) {
	f, err := os.OpenFile(filename, os.O_WRONLY | os.O_CREATE | os.O_TRUNC , 0755)
	if !check(err) { return }
	defer f.Close()

	f.WriteString(data)
}

//------------------------------------------------------------------------------

func restart() {
	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGINT)
	for {
		<-ch
		restarter = 1
	}
}

//------------------------------------------------------------------------------

func upload_append(filename, line string) {
	f, err := os.OpenFile(filename, os.O_RDWR | os.O_CREATE | os.O_APPEND , 0755)
	if !check(err) { return }
	defer f.Close()

	f.WriteString(line)
}


func worker(pos int64, line string) {

	upload_append(log_upload, line)

	if int(pos) % 10 ==0 {
		save_data(log_pos, strconv.Itoa(int(pos)))
	}
}

//------------------------------------------------------------------------------

func compress() {
	// compress
	t := time.Now().Format("20060102_15_04")
	filename := path + "upload_access_" + t + ".zip"

	outf, err := os.Create(filename)
	if !check(err) { return }
	defer outf.Close()
	//defer os.Remove(filename)

	zw := zip.NewWriter(outf)
	f, err := zw.Create(log_upload)
	if !check(err) { os.Remove(filename); return }

	buff, err := ioutil.ReadFile(log_upload)
	if !check(err) { os.Remove(filename); return }

	_, err = f.Write(buff)
	if !check(err) { os.Remove(filename); return }
	zw.Close()

	os.Remove(log_upload)

	uploadfiles.PushFront(filename)

}

func upload() {

	file := uploadfiles.Back()
	if file != nil {
		filename,_ := file.Value.(string)

		ts := strconv.Itoa(int(time.Now().Unix()) - 8 * 3600)
		h := md5.New()
		io.WriteString(h, salt + string(ts))
		k := fmt.Sprintf("%x", h.Sum(nil))
		k = k[0:10]

		var out bytes.Buffer
		cmd := exec.Command("/bin/sh","-c","curl -F \"action=upload\" -F \"t="+string(ts)+"\" -F \"k="+k+"\" -F \"f="+localip+"\" --limit-rate 50k --connect-timeout 60 --max-time 600 -F \"Filedata=@"+filename+"\" \"http://127.0.0.1/test.php\"")
		cmd.Stdout = &out
		err := cmd.Run()
		if !check(err) { return }
		if out.String() == "1" {
			uploadfiles.Remove(file)
			os.Remove(filename)
		}
	}
}

func compress_timer() {
	for {
		timer := time.NewTicker(250 * time.Second)
		for {
			select {
			case <- timer.C:
				go compress()
			}
		}
	}
}

func upload_timer() {
	for {
		timer := time.NewTicker(30 * time.Second)
		for {
			select {
			case <- timer.C:
				upload()
			}
		}
	}
}

//------------------------------------------------------------------------------

func main() {
	os.Chdir(path)

	//get local ip
	localip = get_local_ip()

	//set timer to upload
	go compress_timer()
	go upload_timer()
	go restart()

	//load info
	cur_pos := load_data(log_pos)

	//read access log
	f, err := os.OpenFile(log_access, os.O_RDONLY, 0)
	if !check(err) { return }

	pos, _ := strconv.ParseInt(cur_pos, 0, 64)
	_, err = f.Seek(pos, os.SEEK_SET)
	if !check(err) { return }

	br := bufio.NewReader(f)
	for {
		line , err := br.ReadString('\n')
		pos, _ = f.Seek(0, os.SEEK_CUR)
		if err == io.EOF {
			time.Sleep(1 * time.Second)
			if restarter == 1 {
				f.Close()
				f, _ = os.OpenFile(log_access,os.O_RDONLY,0)
				_, err = f.Seek(0, os.SEEK_SET)
				br = bufio.NewReader(f)
				restarter = 0
			}
		} else {
			go worker(pos, line)
		}
	}

}

 


有疑问加站长微信联系(非本文作者)

本文来自:ITEYE博客

感谢作者:ciaos

查看原文:go语言四—脚本二

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

3286 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传