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
|
*.exe
|
||||||
*.test
|
*.test
|
||||||
config.json
|
config.json
|
||||||
|
*.log
|
||||||
*.swp
|
*.swp
|
||||||
godns
|
godns
|
||||||
|
|
||||||
@ -29,4 +30,4 @@ vendor/*
|
|||||||
/.idea
|
/.idea
|
||||||
/godns.iml
|
/godns.iml
|
||||||
/godns.ipr
|
/godns.ipr
|
||||||
/godns.iws
|
/godns.iws
|
||||||
|
@ -13,7 +13,7 @@ import (
|
|||||||
"github.com/bitly/go-simplejson"
|
"github.com/bitly/go-simplejson"
|
||||||
)
|
)
|
||||||
|
|
||||||
func get_currentIP(url string) (string, error) {
|
func getCurrentIP(url string) (string, error) {
|
||||||
response, err := http.Get(url)
|
response, err := http.Get(url)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -27,13 +27,13 @@ func get_currentIP(url string) (string, error) {
|
|||||||
return string(body), nil
|
return string(body), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func generate_header(content url.Values) url.Values {
|
func generateHeader(content url.Values) url.Values {
|
||||||
header := url.Values{}
|
header := url.Values{}
|
||||||
if(Configuration.LoginToken!=""){
|
if configuration.LoginToken != "" {
|
||||||
header.Add("login_token", Configuration.LoginToken)
|
header.Add("login_token", configuration.LoginToken)
|
||||||
}else{
|
} else {
|
||||||
header.Add("login_email", Configuration.Email)
|
header.Add("login_email", configuration.Email)
|
||||||
header.Add("login_password", Configuration.Password)
|
header.Add("login_password", configuration.Password)
|
||||||
}
|
}
|
||||||
header.Add("format", "json")
|
header.Add("format", "json")
|
||||||
header.Add("lang", "en")
|
header.Add("lang", "en")
|
||||||
@ -48,11 +48,11 @@ func generate_header(content url.Values) url.Values {
|
|||||||
return header
|
return header
|
||||||
}
|
}
|
||||||
|
|
||||||
func api_version() {
|
func apiVersion() {
|
||||||
post_data("/Info.Version", nil)
|
postData("/Info.Version", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func get_domain(name string) int64 {
|
func getDomain(name string) int64 {
|
||||||
|
|
||||||
var ret int64
|
var ret int64
|
||||||
values := url.Values{}
|
values := url.Values{}
|
||||||
@ -60,17 +60,17 @@ func get_domain(name string) int64 {
|
|||||||
values.Add("offset", "0")
|
values.Add("offset", "0")
|
||||||
values.Add("length", "20")
|
values.Add("length", "20")
|
||||||
|
|
||||||
response, err := post_data("/Domain.List", values)
|
response, err := postData("/Domain.List", values)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Failed to get domain list...")
|
log.Println("Failed to get domain list...")
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
sjson, parse_err := simplejson.NewJson([]byte(response))
|
sjson, parseErr := simplejson.NewJson([]byte(response))
|
||||||
|
|
||||||
if parse_err != nil {
|
if parseErr != nil {
|
||||||
log.Println(parse_err)
|
log.Println(parseErr)
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,16 +100,16 @@ func get_domain(name string) int64 {
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func get_subdomain(domain_id int64, name string) (string, string) {
|
func getSubDomain(domainID int64, name string) (string, string) {
|
||||||
log.Println("debug:", domain_id, name)
|
log.Println("debug:", domainID, name)
|
||||||
var ret, ip string
|
var ret, ip string
|
||||||
value := url.Values{}
|
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("offset", "0")
|
||||||
value.Add("length", "1")
|
value.Add("length", "1")
|
||||||
value.Add("sub_domain", name)
|
value.Add("sub_domain", name)
|
||||||
|
|
||||||
response, err := post_data("/Record.List", value)
|
response, err := postData("/Record.List", value)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Failed to get domain list")
|
log.Println("Failed to get domain list")
|
||||||
@ -144,7 +144,7 @@ func get_subdomain(domain_id int64, name string) (string, string) {
|
|||||||
return ret, ip
|
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 := url.Values{}
|
||||||
value.Add("domain_id", strconv.FormatInt(domain_id, 10))
|
value.Add("domain_id", strconv.FormatInt(domain_id, 10))
|
||||||
value.Add("record_id", sub_domain_id)
|
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("record_line", "默认")
|
||||||
value.Add("value", ip)
|
value.Add("value", ip)
|
||||||
|
|
||||||
response, err := post_data("/Record.Modify", value)
|
response, err := postData("/Record.Modify", value)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Failed to update record to new IP!")
|
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{}
|
client := &http.Client{}
|
||||||
values := generate_header(content)
|
values := generateHeader(content)
|
||||||
req, _ := http.NewRequest("POST", "https://dnsapi.cn"+url, strings.NewReader(values.Encode()))
|
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("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)
|
response, err := client.Do(req)
|
||||||
defer response.Body.Close()
|
defer response.Body.Close()
|
||||||
|
@ -4,8 +4,8 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_get_current_IP(t *testing.T) {
|
func testGetCurrentIP(t *testing.T) {
|
||||||
ip, _ := get_currentIP("http://members.3322.org/dyndns/getip")
|
ip, _ := getCurrentIP("http://members.3322.org/dyndns/getip")
|
||||||
|
|
||||||
if ip == "" {
|
if ip == "" {
|
||||||
t.Log("IP is empty...")
|
t.Log("IP is empty...")
|
||||||
|
18
godns.go
18
godns.go
@ -16,7 +16,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Configuration Settings
|
configuration Settings
|
||||||
optConf = flag.String("c", "./config.json", "config file")
|
optConf = flag.String("c", "./config.json", "config file")
|
||||||
optCommand = flag.String("s", "", "send signal to a master process: stop, quit, reopen, reload")
|
optCommand = flag.String("s", "", "send signal to a master process: stop, quit, reopen, reload")
|
||||||
optHelp = flag.Bool("h", false, "this help")
|
optHelp = flag.Bool("h", false, "this help")
|
||||||
@ -35,7 +35,13 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
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 {
|
if err != nil {
|
||||||
fmt.Println(err.Error())
|
fmt.Println(err.Error())
|
||||||
@ -60,20 +66,20 @@ func dns_loop() {
|
|||||||
|
|
||||||
for {
|
for {
|
||||||
|
|
||||||
domain_id := get_domain(Configuration.Domain)
|
domain_id := getDomain(configuration.Domain)
|
||||||
|
|
||||||
if domain_id == -1 {
|
if domain_id == -1 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
currentIP, err := get_currentIP(Configuration.IP_Url)
|
currentIP, err := getCurrentIP(configuration.IP_Url)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("get_currentIP:", err)
|
log.Println("get_currentIP:", err)
|
||||||
continue
|
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 == "" {
|
if sub_domain_id == "" || ip == "" {
|
||||||
log.Println("sub_domain:", 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
|
//Continue to check the IP of sub-domain
|
||||||
if len(ip) > 0 && !strings.Contains(currentIP, ip) {
|
if len(ip) > 0 && !strings.Contains(currentIP, ip) {
|
||||||
log.Println("Start to update record 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 {
|
} else {
|
||||||
log.Println("Current IP is same as domain IP, no need to update...")
|
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