Archive

Posts Tagged ‘go’

一个简单的rolling filelog,written in go

August 29th, 2014 No comments

使用了go-logging但是发现它只有logging format部分,没有数据输出部分(直接使用os.File进行输出). 所以自己做了一个简单的rolling file log. 可以设置保留的log文件个数,每一个log文件的最大字节数,强制flush的时间间隔.
使用方法如下:

func main() {
    l := rolling_filelog.LogFile{BaseName: "./test.log",
                MaxSize: 5*1024*1024,
                FileCount: 10,
                FlushInterval: 2*time.Second,
                BufferSize: 10*1024,
                BufferCount: 3}
    err := l.Open()
    if err != nil {
        fmt.Printf("failed to open log file,%s: %s\n", l.BaseName, err)
        return
    }
    data := make([]byte,10)
    copy(data[:],"1234567890")

    for i := 0 ; i < 10000000; i ++ {
        n,err := l.Write(data)
        if err != nil {
            fmt.Printf("failed to write data to %s :%s\n", l.BaseName, err )
            return
        }
        if n <= 0 {
            fmt.Printf("failed to write data to %s : %s\n", l.BaseName, "0 bytes written")
            return
        }
    }
    l.Close()

当然了,这个是用作其他logging的backend的,例go-logging

 logFile := utils.LogFile{BaseName: "./test.log",
                MaxSize: 8*1024,
                FileCount: 3,
                FlushInterval: 2*time.Second,
                BufferSize: 1*1024,
                BufferCount: 3}
    if logFile == nil {
        fmt.Println("failed to open log file")
        return nil
    }

    logger := logging.MustGetLogger("")
    if logger == nil {
        logFile.Close()
        return nil
    }

    logging.SetFormatter(logging.MustStringFormatter(" %{level:.4s} %{message}"))
    logBackend := logging.NewLogBackend( logFile, "", stdlog.LstdFlags|stdlog.Lmicroseconds)
    logging.SetBackend(logBackend)
    logging.SetLevel(logging.INFO,"")

这样以来, 日志文件就会保持在FileCount指定的数量上滚动, 以防止日志文件的无限制增长而吃光存储空间.

Categories: programming Tags: , ,

go的测试程序,与预期不符合。不知道是哪里理解不正确了

March 1st, 2014 No comments

在学习go的时候,按照[go语言编程]第94页的例子写了一个测试程序,如下

package main
import  (
    "fmt"
)
func Count( ch chan int, value int ) {
    ch <- value
    fmt.Println("Counting")
}
func main( ) {
    chs :=make( []chan int, 10 )
    for i := 0; i < 10; i++ {
        chs[i] = make(chan int) //请注意这一行
        go Count(chs[i],i)
    }
    var value int
    for _, ch := range(chs) {
        value = <-ch
        fmt.Printf("got value %d\n",value)
    }
}


但是运行的时候发现结果与我预期的不一样。本来我认为这个程序会打印10行Counting, 但实际上只有1行Counting出现。
于是我把标示那一行改成

chs[i] = make(chan int,1)

就这样,运行的时候就可以打印出10行Counting来了。是在不明白这个到底是咋回事啊。
继续修改有标示的那一行发现,如果make( chan int, 0 )或者make( chan int)那么就只会打印一行Counting.如果make的第二个参数>= 1,那么就会如预期一般打印10行Counting.
这让我更加糊涂了,按照书上所讲。make( chan int, x)的方式是建立一个有缓冲区且大小为x的channel。而且测试程序始终能够输出如下:

got value 0
got value 1
got value 2
got value 3
got value 4
got value 5
got value 6
got value 7
got value 8
got value 9

 

那么至少代表建立的10个 go routine是开始执行了的。看起来当make( chan int, 0)的时候只有一个Count的go routine在向channel写入数据以后被切换回去继续执行了,而剩下的Count的go routine都没有得到执行机会。不过这个不能解释为何make( chan int, x) x >=1 的时候所有的go routine就都机会执行完毕了。

嗯,我的go的版本是:

$ go version
go version go1.2 linux/amd64

Written with StackEdit.

Categories: programming Tags: ,