Garey's Blog–FreeBSD/PHP/GoLang

十一月 7th, 2013

第一个Go程序:UDP日志服务器

10,870 views, GoLang, by garey.

一个简单的UDP日志服务器,用来收集其他程序的字符串日志消息并保存到日志文件中。网络通信基于UDP协议,文件保存方式比较简单,只能作为简单测试使用,不适合线上大规模使用。

package main

import (
    “fmt”
    “math/rand”
    “net”
    “os”
    “strconv”
    “syscall”
    “time”
)

const (
    serverPort string = “:8001″
)

type Server struct {
    conn *net.UDPConn //UDP连接
    logs chan string //日志消息
}

func (s *Server) readLog() {
    var buf [2048]byte
    
        n, _, err := s.conn.ReadFromUDP(buf[0:])
        if err != nil {
            return
        }
    
        log := string(buf[0:n])
        
        s.logs <- log
    }
    
    func (s *Server) handleLog() {
    
    for {
        log := <-s.logs
        writeLog(log)
    }

}

func writeLog(log string) {
    var mode os.FileMode
    flag := syscall.O_RDWR | syscall.O_APPEND | syscall.O_CREAT
    mode = 0666
    const layout = “2006_01_02_15″
    num := getRandId()
    
    logFile := “log/log_” + strconv.Itoa(num) + “_” + time.Now().Format(layout)
    
    logstr := log + “rn”
    
    file, err := os.OpenFile(logFile, flag, mode)
    defer file.Close()
    if err != nil {
        fmt.Println(logFile, err)
        return
    }
    file.WriteString(logstr)
}

func checkError(err error) {
    if err != nil {
        fmt.Fprintf(os.Stderr, “Fatal error:%s”, err.Error())
        os.Exit(1)
    }
}

func getRandId() int {
    r := rand.New(rand.NewSource(time.Now().UnixNano()))
    num := r.Intn(10)
    return num
}

func main() {
    udpAddr, err := net.ResolveUDPAddr(“udp4″, serverPort)
    checkError(err)
    
    var s Server
    s.logs = make(chan string, 200)
    
    s.conn, err = net.ListenUDP(“udp”, udpAddr)
    checkError(err)
    
    go s.readLog()
    
    for {
        s.handleLog()
    }
}

 

Back Top

发表评论