为什么Go的日志记录器没有关闭与syslog的连接?

huangapple go评论79阅读模式
英文:

Why is Go's Logger not closing connections to syslog?

问题

我正在写一个服务时遇到了问题。我使用以下方式将其记录到syslog中:http://technosophos.com/2013/09/14/using-gos-built-logger-log-syslog.html

但是当我通过CTRL-C杀死服务时,有些连接仍然保持打开状态,连接到syslogd。我无法找到任何方法来进行清理。我错过了什么?

例如:syslog.Writer.Close() 对我来说似乎无法访问,但我可以确定清理操作没有发生。我看到连接处于CLOSE_WAIT状态,我的syslogd开始变得缓慢和不合作。

示例代码:

package main

import (
	"github.com/davecgh/go-spew/spew" // DEBUG
	"log"
	"log/syslog"
	"os"
	"os/signal"
	"syscall"
)

func main() {
	logWriter, err := syslog.New(syslog.LOG_NOTICE, "mybrokenprog")
	spew.Dump(logWriter) // DEBUG
	spew.Dump(err)       // DEBUG
	if err == nil {
		log.SetOutput(logWriter)
	}

	chansigs := make(chan os.Signal, 1)
	signal.Notify(chansigs, os.Interrupt, syscall.SIGTERM, syscall.SIGKILL)
	log.Print("writing to syslog. waiting for shutdown signal")
	for {
		sig := <-chansigs // 我们在这里等待关闭信号
		log.Print("signal received...shutting down")
		logWriter.Close() // 但是这会引发下面摘录的panic
		if sig == os.Interrupt {
			os.Exit(0)
		}
		os.Exit(1)
	}
}

编辑:上面的代码修复了问题。请参考注释。重启以清除与syslog的卡住的连接可以解决问题。一旦它们存在,它们就是持久的。即使OS X的重新启动syslogd的指令也没有帮助。
编辑:这是错误信息:panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0xcb4fe]

goroutine 1 [running]:
log/syslog.(*Writer).Close(0x0, 0x0, 0x0)
/usr/local/Cellar/go/1.5.1/libexec/src/log/syslog/syslog.go:177 +0x10e
main.main(0x3)

我毫不怀疑我做错了。只是一个还没有看到问题所在的新手。

英文:

I’m having trouble with a service i’m writing. I have it logging to syslog like this: http://technosophos.com/2013/09/14/using-gos-built-logger-log-syslog.html

but when i kill the service via CTRL-C something is leaving connections open to syslogd. I can’t see anyway to initiate a cleanup. What am I missing

e.g. syslog.Writer.Close() seems inaccessible to me but i can say the cleanup isn’t happening. I’m seeing connections stuck in a CLOSE_WAIT state and my syslogd starts bogging down and becoming uncooperative.

example:

package main

import (
	"github.com/davecgh/go-spew/spew" // DEBUG
	"log"
	"log/syslog"
	"os"
	"os/signal"
	"syscall"
)

func main() {
	logWriter, err := syslog.New(syslog.LOG_NOTICE, "mybrokenprog")
	spew.Dump(logWriter) // DEBUG
	spew.Dump(err)       // DEBUG
	if err == nil {
		log.SetOutput(logWriter)
	}

	chansigs := make(chan os.Signal, 1)
	signal.Notify(chansigs, os.Interrupt, syscall.SIGTERM, syscall.SIGKILL)
	log.Print("writing to syslog. waiting for shutdown signal")
	for {
		sig := <-chansigs // we just wait here for a signal to shutdown
		log.Print("signal received...shutting down")
		logWriter.Close() // but this throws the panic excerpted below
		if sig == os.Interrupt {
			os.Exit(0)
		}
		os.Exit(1)
	}
}

EDIT: the above code fixes the problem. see the comments. Rebooting to clear the stuck connections to syslog fixed the problem. Once they're there, they're persistent. Even OS X's instructions for retarting syslogd did not help.
EDIT: this was the error: panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0xcb4fe]

goroutine 1 [running]:
log/syslog.(*Writer).Close(0x0, 0x0, 0x0)
/usr/local/Cellar/go/1.5.1/libexec/src/log/syslog/syslog.go:177 +0x10e
main.main(0x3)

I've no doubt I'm doing it wrong. Just a newb who doesn't yet see where.

答案1

得分: 0

问题出在程序最初的结构上。在主线程(main())退出之前,日志协程(logging goroutine)就已经退出了,从而导致连接被孤立。在重构代码以防止这种情况发生后,问题就解决了。

英文:

The problem was with the way the program was originally structured. The main() thread was exiting before the logging goroutine and thus orphaning connections. After refactoring to prevent that, the problem went away.

huangapple
  • 本文由 发表于 2015年10月31日 04:17:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/33444249.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定