diff options
author | zheng <Zheng.chai@citrix.com> | 2015-07-16 15:44:59 +0800 |
---|---|---|
committer | zheng <Zheng.chai@citrix.com> | 2015-07-16 15:44:59 +0800 |
commit | 586e9090c1706b9180a7afd4a8d7b80a1c2a51a5 (patch) | |
tree | 8f773d544f9399f0badac2d012ca0d3427d76975 | |
parent | fe78cd379770d32eabb6dc80beaf50a439562ae3 (diff) | |
parent | 9a1317d7733cb07274b5d82873bc3051764586c5 (diff) | |
download | vyos-xe-guest-utilities-586e9090c1706b9180a7afd4a8d7b80a1c2a51a5.tar.gz vyos-xe-guest-utilities-586e9090c1706b9180a7afd4a8d7b80a1c2a51a5.zip |
Merge pull request #9 from xs-nanjing/master
CA-172369: Golang Guest Agent doesn't use print the logs into guest machine syslog
-rw-r--r-- | xe-daemon/syslog.go | 60 | ||||
-rw-r--r-- | xe-daemon/xe-daemon.go | 64 |
2 files changed, 103 insertions, 21 deletions
diff --git a/xe-daemon/syslog.go b/xe-daemon/syslog.go new file mode 100644 index 0000000..a074407 --- /dev/null +++ b/xe-daemon/syslog.go @@ -0,0 +1,60 @@ +// To run 32bit xe-daemon under 64bit system, +// Here we re-implement a syslog writer base on logger CLI. + +package main + +import ( + "io" + "os" + "os/exec" + "time" +) + +const ( + waitLoggerQuitSeconds = 5 +) + +type SysLoggerWriter struct { + cmd *exec.Cmd + stdin io.WriteCloser +} + +func NewSyslogWriter(topic string) (io.Writer, error) { + cmd := exec.Command("logger", "-t", topic) + + stdin, err := cmd.StdinPipe() + if err != nil { + return nil, err + } + + err = cmd.Start() + if err != nil { + return nil, err + } + + return &SysLoggerWriter{cmd, stdin}, nil +} + +func (s *SysLoggerWriter) Write(data []byte) (int, error) { + return s.stdin.Write(data) +} + +func (s *SysLoggerWriter) Close() error { + + s.stdin.Close() + s.cmd.Process.Signal(os.Interrupt) + + done := make(chan error, 1) + go func(c chan<- error) { + c <- s.cmd.Wait() + }(done) + + select { + case <-done: + return nil + case <-time.After(waitLoggerQuitSeconds * time.Second): + return s.cmd.Process.Kill() + } + + return nil +} diff --git a/xe-daemon/xe-daemon.go b/xe-daemon/xe-daemon.go index 1e5fdb1..3ad8c27 100644 --- a/xe-daemon/xe-daemon.go +++ b/xe-daemon/xe-daemon.go @@ -5,23 +5,19 @@ import ( xenstoreclient "../xenstoreclient" "flag" "fmt" + "io" + "io/ioutil" "log" "os" "os/signal" + "strconv" "syscall" "time" ) -func write_pid_file(pid_file string) error { - f, err := os.Create(pid_file) - if err != nil { - return err - } - defer f.Close() - - fmt.Fprintf(f, "%d\n", os.Getpid()) - return nil -} +const ( + LoggerName string = "xe-daemon" +) func main() { var err error @@ -34,17 +30,32 @@ func main() { flag.Parse() if *pid != "" { - write_pid_file(*pid) + if err = ioutil.WriteFile(*pid, []byte(strconv.Itoa(os.Getpid())), 0644); err != nil { + fmt.Fprintf(os.Stderr, "Write pid to %s error: %s\n", *pid, err) + return + } + } + + var loggerWriter io.Writer = os.Stderr + var topic string = LoggerName + if w, err := NewSyslogWriter(topic); err == nil { + loggerWriter = w + topic = "" + } else { + fmt.Fprintf(os.Stderr, "NewSyslogWriter(%s) error: %s, use stderr logging\n", topic, err) + topic = LoggerName + ": " } - logger := log.New(os.Stderr, "xe-daemon", 0) + logger := log.New(loggerWriter, topic, 0) exitChannel := make(chan os.Signal, 1) signal.Notify(exitChannel, syscall.SIGTERM, syscall.SIGINT) xs, err := xenstoreclient.NewCachedXenstore(0) if err != nil { - logger.Printf("NewCachedXenstore error: %v", err) + message := fmt.Sprintf("NewCachedXenstore error: %v\n", err) + logger.Print(message) + fmt.Fprint(os.Stderr, message) return } @@ -68,13 +79,13 @@ func main() { lastUniqueID, err := xs.Read("unique-domain-id") if err != nil { - logger.Printf("xenstore.Read unique-domain-id error: %v", err) + logger.Printf("xenstore.Read unique-domain-id error: %v\n", err) } for count := 0; ; count += 1 { uniqueID, err := xs.Read("unique-domain-id") if err != nil { - logger.Printf("xenstore.Read unique-domain-id error: %v", err) + logger.Printf("xenstore.Read unique-domain-id error: %v\n", err) return } if uniqueID != lastUniqueID { @@ -86,30 +97,41 @@ func main() { } // invoke collectors + updated := false for _, collector := range collectors { if count%collector.divisor == 0 { - logger.Printf("Running %s ...", collector.name) + logger.Printf("Running %s ...\n", collector.name) result, err := collector.Collect() if err != nil { - logger.Printf("%s error: %#v", collector.name, err) + logger.Printf("%s error: %#v\n", collector.name, err) } else { for name, value := range result { err := xs.Write(name, value) if err != nil { - logger.Printf("xenstore.Write error: %v", err) + logger.Printf("xenstore.Write error: %v\n", err) } else { - logger.Printf("xenstore.Write OK: %#v: %#v", name, value) + if *debugFlag { + logger.Printf("xenstore.Write OK: %#v: %#v\n", name, value) + } + updated = true } } } } } - xs.Write("data/updated", time.Now().Format("Mon Jan _2 15:04:05 2006")) + if updated { + xs.Write("data/updated", time.Now().Format("Mon Jan _2 15:04:05 2006")) + } select { case <-exitChannel: - logger.Printf("Received an interrupt, stopping services...") + logger.Printf("Received an interrupt, stopping services...\n") + if c, ok := loggerWriter.(io.Closer); ok { + if err := c.Close(); err != nil { + fmt.Fprintf(os.Stderr, "logger close error: %s\n", err) + } + } return case <-time.After(time.Duration(*sleepInterval) * time.Second): |