mirror of
https://github.com/taigrr/godns
synced 2025-01-18 04:03:25 -08:00
Add logger back, do more optimization
This commit is contained in:
parent
72706fe0ed
commit
47f4ccd08d
3
.gitignore
vendored
3
.gitignore
vendored
@ -22,6 +22,7 @@ _testmain.go
|
||||
*.exe
|
||||
*.test
|
||||
config.json
|
||||
*.log
|
||||
*.swp
|
||||
godns
|
||||
|
||||
@ -29,4 +30,4 @@ vendor/*
|
||||
/.idea
|
||||
/godns.iml
|
||||
/godns.ipr
|
||||
/godns.iws
|
||||
/godns.iws
|
||||
|
@ -13,7 +13,7 @@ import (
|
||||
"github.com/bitly/go-simplejson"
|
||||
)
|
||||
|
||||
func get_currentIP(url string) (string, error) {
|
||||
func getCurrentIP(url string) (string, error) {
|
||||
response, err := http.Get(url)
|
||||
|
||||
if err != nil {
|
||||
@ -27,13 +27,13 @@ func get_currentIP(url string) (string, error) {
|
||||
return string(body), nil
|
||||
}
|
||||
|
||||
func generate_header(content url.Values) url.Values {
|
||||
func generateHeader(content url.Values) url.Values {
|
||||
header := url.Values{}
|
||||
if(Configuration.LoginToken!=""){
|
||||
header.Add("login_token", Configuration.LoginToken)
|
||||
}else{
|
||||
header.Add("login_email", Configuration.Email)
|
||||
header.Add("login_password", Configuration.Password)
|
||||
if configuration.LoginToken != "" {
|
||||
header.Add("login_token", configuration.LoginToken)
|
||||
} else {
|
||||
header.Add("login_email", configuration.Email)
|
||||
header.Add("login_password", configuration.Password)
|
||||
}
|
||||
header.Add("format", "json")
|
||||
header.Add("lang", "en")
|
||||
@ -48,11 +48,11 @@ func generate_header(content url.Values) url.Values {
|
||||
return header
|
||||
}
|
||||
|
||||
func api_version() {
|
||||
post_data("/Info.Version", nil)
|
||||
func apiVersion() {
|
||||
postData("/Info.Version", nil)
|
||||
}
|
||||
|
||||
func get_domain(name string) int64 {
|
||||
func getDomain(name string) int64 {
|
||||
|
||||
var ret int64
|
||||
values := url.Values{}
|
||||
@ -60,17 +60,17 @@ func get_domain(name string) int64 {
|
||||
values.Add("offset", "0")
|
||||
values.Add("length", "20")
|
||||
|
||||
response, err := post_data("/Domain.List", values)
|
||||
response, err := postData("/Domain.List", values)
|
||||
|
||||
if err != nil {
|
||||
log.Println("Failed to get domain list...")
|
||||
return -1
|
||||
}
|
||||
|
||||
sjson, parse_err := simplejson.NewJson([]byte(response))
|
||||
sjson, parseErr := simplejson.NewJson([]byte(response))
|
||||
|
||||
if parse_err != nil {
|
||||
log.Println(parse_err)
|
||||
if parseErr != nil {
|
||||
log.Println(parseErr)
|
||||
return -1
|
||||
}
|
||||
|
||||
@ -100,16 +100,16 @@ func get_domain(name string) int64 {
|
||||
return ret
|
||||
}
|
||||
|
||||
func get_subdomain(domain_id int64, name string) (string, string) {
|
||||
log.Println("debug:", domain_id, name)
|
||||
func getSubDomain(domainID int64, name string) (string, string) {
|
||||
log.Println("debug:", domainID, name)
|
||||
var ret, ip string
|
||||
value := url.Values{}
|
||||
value.Add("domain_id", strconv.FormatInt(domain_id, 10))
|
||||
value.Add("domain_id", strconv.FormatInt(domainID, 10))
|
||||
value.Add("offset", "0")
|
||||
value.Add("length", "1")
|
||||
value.Add("sub_domain", name)
|
||||
|
||||
response, err := post_data("/Record.List", value)
|
||||
response, err := postData("/Record.List", value)
|
||||
|
||||
if err != nil {
|
||||
log.Println("Failed to get domain list")
|
||||
@ -144,7 +144,7 @@ func get_subdomain(domain_id int64, name string) (string, string) {
|
||||
return ret, ip
|
||||
}
|
||||
|
||||
func update_ip(domain_id int64, sub_domain_id string, sub_domain_name string, ip string) {
|
||||
func updateIP(domain_id int64, sub_domain_id string, sub_domain_name string, ip string) {
|
||||
value := url.Values{}
|
||||
value.Add("domain_id", strconv.FormatInt(domain_id, 10))
|
||||
value.Add("record_id", sub_domain_id)
|
||||
@ -153,7 +153,7 @@ func update_ip(domain_id int64, sub_domain_id string, sub_domain_name string, ip
|
||||
value.Add("record_line", "默认")
|
||||
value.Add("value", ip)
|
||||
|
||||
response, err := post_data("/Record.Modify", value)
|
||||
response, err := postData("/Record.Modify", value)
|
||||
|
||||
if err != nil {
|
||||
log.Println("Failed to update record to new IP!")
|
||||
@ -174,13 +174,13 @@ func update_ip(domain_id int64, sub_domain_id string, sub_domain_name string, ip
|
||||
|
||||
}
|
||||
|
||||
func post_data(url string, content url.Values) (string, error) {
|
||||
func postData(url string, content url.Values) (string, error) {
|
||||
client := &http.Client{}
|
||||
values := generate_header(content)
|
||||
values := generateHeader(content)
|
||||
req, _ := http.NewRequest("POST", "https://dnsapi.cn"+url, strings.NewReader(values.Encode()))
|
||||
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
req.Header.Set("User-Agent", fmt.Sprintf("GoDNS/0.1 (%s)", Configuration.Email))
|
||||
req.Header.Set("User-Agent", fmt.Sprintf("GoDNS/0.1 (%s)", configuration.Email))
|
||||
|
||||
response, err := client.Do(req)
|
||||
defer response.Body.Close()
|
||||
|
@ -4,8 +4,8 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_get_current_IP(t *testing.T) {
|
||||
ip, _ := get_currentIP("http://members.3322.org/dyndns/getip")
|
||||
func testGetCurrentIP(t *testing.T) {
|
||||
ip, _ := getCurrentIP("http://members.3322.org/dyndns/getip")
|
||||
|
||||
if ip == "" {
|
||||
t.Log("IP is empty...")
|
||||
|
18
godns.go
18
godns.go
@ -16,7 +16,7 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
Configuration Settings
|
||||
configuration Settings
|
||||
optConf = flag.String("c", "./config.json", "config file")
|
||||
optCommand = flag.String("s", "", "send signal to a master process: stop, quit, reopen, reload")
|
||||
optHelp = flag.Bool("h", false, "this help")
|
||||
@ -35,7 +35,13 @@ func main() {
|
||||
}
|
||||
|
||||
var err error
|
||||
Configuration, err = LoadSettings(*optConf)
|
||||
configuration, err = LoadSettings(*optConf)
|
||||
|
||||
err = InitLogger(configuration.Log_Path, configuration.Log_Size, configuration.Log_Num)
|
||||
if err != nil {
|
||||
log.Println("InitLogger error:", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
@ -60,20 +66,20 @@ func dns_loop() {
|
||||
|
||||
for {
|
||||
|
||||
domain_id := get_domain(Configuration.Domain)
|
||||
domain_id := getDomain(configuration.Domain)
|
||||
|
||||
if domain_id == -1 {
|
||||
continue
|
||||
}
|
||||
|
||||
currentIP, err := get_currentIP(Configuration.IP_Url)
|
||||
currentIP, err := getCurrentIP(configuration.IP_Url)
|
||||
|
||||
if err != nil {
|
||||
log.Println("get_currentIP:", err)
|
||||
continue
|
||||
}
|
||||
|
||||
sub_domain_id, ip := get_subdomain(domain_id, Configuration.Sub_domain)
|
||||
sub_domain_id, ip := getSubDomain(domain_id, configuration.Sub_domain)
|
||||
|
||||
if sub_domain_id == "" || ip == "" {
|
||||
log.Println("sub_domain:", sub_domain_id, ip)
|
||||
@ -85,7 +91,7 @@ func dns_loop() {
|
||||
//Continue to check the IP of sub-domain
|
||||
if len(ip) > 0 && !strings.Contains(currentIP, ip) {
|
||||
log.Println("Start to update record IP...")
|
||||
update_ip(domain_id, sub_domain_id, Configuration.Sub_domain, currentIP)
|
||||
updateIP(domain_id, sub_domain_id, configuration.Sub_domain, currentIP)
|
||||
} else {
|
||||
log.Println("Current IP is same as domain IP, no need to update...")
|
||||
}
|
||||
|
292
logger.go
Normal file
292
logger.go
Normal file
@ -0,0 +1,292 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"runtime/debug"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
L_INFO int = iota
|
||||
L_WARNING
|
||||
L_DEBUG
|
||||
PRE_INFO = "[ INFO]"
|
||||
PRE_WARNING = "[WARNING]"
|
||||
PRE_DEBUG = "[ DEBUG]"
|
||||
)
|
||||
|
||||
type Logger struct {
|
||||
DEV_MODE bool
|
||||
fd *os.File
|
||||
size int
|
||||
num int
|
||||
level int
|
||||
mu sync.Mutex
|
||||
muSplit sync.Mutex
|
||||
flushInterval int64 //Second
|
||||
flushSize int
|
||||
buf *bytes.Buffer
|
||||
log *log.Logger
|
||||
}
|
||||
|
||||
func NewLogger(logfile string, size, num int, level int, flushInterval int64, flushSize int) (logger *Logger, err error) {
|
||||
if size < 1 || num < 1 || level < L_INFO || len(logfile) < 1 {
|
||||
err = errors.New("NewLogWriter:param error.")
|
||||
return
|
||||
}
|
||||
logger = &Logger{size: size * 1024, num: num, level: level, DEV_MODE: false}
|
||||
logger.fd, err = os.OpenFile(logfile, os.O_WRONLY|os.O_APPEND|os.O_CREATE, os.ModeAppend|0666)
|
||||
if err != nil {
|
||||
logger = nil
|
||||
return
|
||||
}
|
||||
log.SetOutput(logger)
|
||||
if flushInterval > 0 && flushSize > 0 {
|
||||
logger.buf = new(bytes.Buffer)
|
||||
logger.log = log.New(logger.buf, "", log.LstdFlags)
|
||||
|
||||
go func(interval int64, logger *Logger) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Printf("logger Tick, Recovered in %v:\n %s", r, debug.Stack())
|
||||
}
|
||||
}()
|
||||
c := time.Tick(time.Duration(interval) * time.Second)
|
||||
for _ = range c {
|
||||
logger.Flush()
|
||||
}
|
||||
}(flushInterval, logger)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func InitLogger(logfile string, size, num int) (err error) {
|
||||
logger, err := NewLogger(logfile, size, num, L_INFO, -1, -1)
|
||||
if logger != nil {
|
||||
logger.level = L_INFO - 1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//immplement write
|
||||
func (this *Logger) Write(p []byte) (n int, err error) {
|
||||
if this.DEV_MODE {
|
||||
n, err = os.Stdout.Write(p)
|
||||
return
|
||||
}
|
||||
n, err = this.fd.Write(p)
|
||||
if err == nil {
|
||||
fi, e := this.fd.Stat()
|
||||
if e != nil {
|
||||
err = e
|
||||
return
|
||||
}
|
||||
if fi.Size() > int64(this.size) {
|
||||
this.muSplit.Lock()
|
||||
defer this.muSplit.Unlock()
|
||||
|
||||
fname := fi.Name()
|
||||
strings.HasSuffix(fname, ".log")
|
||||
fbase := fname[:len(fname)-3]
|
||||
|
||||
oldBs := make([]byte, 0, this.size)
|
||||
newBs := []byte{}
|
||||
fd, e := os.Open(fname)
|
||||
if e != nil {
|
||||
err = e
|
||||
return
|
||||
}
|
||||
rd := bufio.NewReader(fd)
|
||||
for {
|
||||
line, e := rd.ReadBytes('\n')
|
||||
if e == io.EOF {
|
||||
break
|
||||
}
|
||||
if e != nil {
|
||||
err = e
|
||||
return
|
||||
}
|
||||
if len(oldBs)+len(line) > this.size {
|
||||
newBs = append(newBs, line...)
|
||||
} else {
|
||||
oldBs = append(oldBs, line...)
|
||||
}
|
||||
}
|
||||
fd.Close()
|
||||
|
||||
_, err = this.saveLog(1, fbase, oldBs)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = this.fd.Close()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = os.Remove(fname)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
this.fd, err = os.OpenFile(fname, os.O_WRONLY|os.O_APPEND|os.O_CREATE, os.ModeAppend|0666)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
_, err = this.fd.Write(newBs)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (this *Logger) saveLog(index int, fbase string, data []byte) (n int, err error) {
|
||||
fn := fbase + strconv.Itoa(index) + ".log"
|
||||
_, err = os.Stat(fn)
|
||||
if index < this.num && err == nil {
|
||||
var b []byte
|
||||
b, err = ioutil.ReadFile(fn)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
n, err = this.saveLog(index+1, fbase, b)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
fd, err := os.OpenFile(fn, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, os.ModePerm|0666)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer fd.Close()
|
||||
n, err = fd.Write(data)
|
||||
return
|
||||
}
|
||||
|
||||
//flush buf data to std log
|
||||
func (this *Logger) Flush() {
|
||||
if this.buf.Len() > 0 {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
|
||||
log.SetFlags(0)
|
||||
log.Print(this.buf)
|
||||
log.SetFlags(log.LstdFlags)
|
||||
this.buf.Reset()
|
||||
}
|
||||
}
|
||||
|
||||
//clean prefix and check buf size
|
||||
func (this *Logger) clean() {
|
||||
this.log.SetPrefix("")
|
||||
if this.buf.Len()/1024 > this.flushSize {
|
||||
go this.Flush()
|
||||
}
|
||||
}
|
||||
|
||||
func (this *Logger) setPrefix(lv int) bool {
|
||||
if lv > this.level {
|
||||
return false
|
||||
}
|
||||
|
||||
switch lv {
|
||||
case L_INFO:
|
||||
this.log.SetPrefix(PRE_INFO)
|
||||
case L_WARNING:
|
||||
this.log.SetPrefix(PRE_WARNING)
|
||||
case L_DEBUG:
|
||||
this.log.SetPrefix(PRE_DEBUG)
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (this *Logger) logPrint(lv int, args ...interface{}) {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
|
||||
if !this.setPrefix(lv) {
|
||||
return
|
||||
}
|
||||
this.log.Print(args...)
|
||||
this.clean()
|
||||
}
|
||||
|
||||
func (this *Logger) logPrintln(lv int, args ...interface{}) {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
|
||||
if !this.setPrefix(lv) {
|
||||
return
|
||||
}
|
||||
this.log.Println(args...)
|
||||
this.clean()
|
||||
}
|
||||
|
||||
func (this *Logger) logPrintf(lv int, format string, args ...interface{}) {
|
||||
this.mu.Lock()
|
||||
defer this.mu.Unlock()
|
||||
|
||||
if !this.setPrefix(lv) {
|
||||
return
|
||||
}
|
||||
this.log.Printf(format, args...)
|
||||
this.clean()
|
||||
}
|
||||
|
||||
//close fd
|
||||
func (this *Logger) Close() {
|
||||
if this.fd != nil {
|
||||
this.Flush()
|
||||
this.fd.Close()
|
||||
}
|
||||
}
|
||||
|
||||
func (this *Logger) Info(args ...interface{}) {
|
||||
this.logPrint(L_INFO, args...)
|
||||
}
|
||||
|
||||
func (this *Logger) Infoln(args ...interface{}) {
|
||||
this.logPrintln(L_INFO, args...)
|
||||
}
|
||||
|
||||
func (this *Logger) Infof(format string, args ...interface{}) {
|
||||
this.logPrintf(L_INFO, format, args...)
|
||||
}
|
||||
|
||||
func (this *Logger) Warning(args ...interface{}) {
|
||||
this.logPrint(L_WARNING, args...)
|
||||
}
|
||||
|
||||
func (this *Logger) Warningln(args ...interface{}) {
|
||||
this.logPrintln(L_WARNING, args...)
|
||||
}
|
||||
|
||||
func (this *Logger) Warningf(format string, args ...interface{}) {
|
||||
this.logPrintf(L_WARNING, format, args...)
|
||||
}
|
||||
|
||||
func (this *Logger) Debug(args ...interface{}) {
|
||||
this.logPrint(L_DEBUG, args...)
|
||||
this.Flush()
|
||||
}
|
||||
|
||||
func (this *Logger) Debugln(args ...interface{}) {
|
||||
this.logPrintln(L_DEBUG, args...)
|
||||
this.Flush()
|
||||
}
|
||||
|
||||
func (this *Logger) Debugf(format string, args ...interface{}) {
|
||||
this.logPrintf(L_DEBUG, format, args...)
|
||||
this.Flush()
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user