log 下面还有个子库,也就是这个 syslog,据说这个库只在 Windows 上没有实现,看了下源码,应该确实只能工作在 *nix 系。这个库是用于连接到远程日志 daemon 进程,也就是把日志打到远程去,要打在本地当然也可以。

syslog.go

结构体和接口都很简单

  1. // src/log/syslog/syslog.go ---- line 75
  2. // A Writer is a connection to a syslog server.
  3. type Writer struct {
  4. priority Priority
  5. tag string
  6. hostname string
  7. network string
  8. raddr string
  9. mu sync.Mutex // guards conn
  10. conn serverConn
  11. }
  12. // This interface and the separate syslog_unix.go file exist for
  13. // Solaris support as implemented by gccgo. On Solaris you cannot
  14. // simply open a TCP connection to the syslog daemon. The gccgo
  15. // sources have a syslog_solaris.go file that implements unixSyslog to
  16. // return a type that satisfies this interface and simply calls the C
  17. // library syslog function.
  18. type serverConn interface {
  19. writeString(p Priority, hostname, tag, s, nl string) error
  20. close() error
  21. }
  22. type netConn struct {
  23. local bool
  24. conn net.Conn
  25. }

就简单看一下 connect 方法就行了

  1. // src/log/syslog/syslog.go ---- line 146
  2. // connect makes a connection to the syslog server.
  3. // It must be called with w.mu held.
  4. func (w *Writer) connect() (err error) {
  5. if w.conn != nil {
  6. // ignore err from close, it makes sense to continue anyway
  7. w.conn.close()
  8. w.conn = nil
  9. }
  10. if w.network == "" {
  11. w.conn, err = unixSyslog()
  12. if w.hostname == "" {
  13. w.hostname = "localhost"
  14. }
  15. } else {
  16. var c net.Conn
  17. c, err = net.Dial(w.network, w.raddr)
  18. if err == nil {
  19. w.conn = &netConn{conn: c}
  20. if w.hostname == "" {
  21. w.hostname = c.LocalAddr().String()
  22. }
  23. }
  24. }
  25. return
  26. }

如果没有指定远程服务器的时候,调用的是 unixSyslog 函数,那么这个函数又是干嘛的呢,它的定义在 syslog_unix.go 文件里

syslog_unix.go

  1. // src/log/syslog/syslog_unix.go ---- line 14
  2. // unixSyslog opens a connection to the syslog daemon running on the
  3. // local machine using a Unix domain socket.
  4. func unixSyslog() (conn serverConn, err error) {
  5. logTypes := []string{"unixgram", "unix"}
  6. logPaths := []string{"/dev/log", "/var/run/syslog", "/var/run/log"}
  7. for _, network := range logTypes {
  8. for _, path := range logPaths {
  9. conn, err := net.Dial(network, path)
  10. if err == nil {
  11. return &netConn{conn: conn, local: true}, nil
  12. }
  13. }
  14. }
  15. return nil, errors.New("Unix syslog delivery error")
  16. }

是吧,所以说要在本地打日志的话,这种代码在 Win 上肯定是不行的呀。


不过有一说一,自己写了测试代码,在本地的时候,当 netword=”unixgram” path=”/dev/log” 连接成功了,没有返回 err,但是在对应目录找不到日志文件。看了网上别人的测试,日志都很正常。针对我?这里还得再看看,为啥打不出日志。