110 lines
1.8 KiB
Go
110 lines
1.8 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"github.com/sevlyar/go-daemon"
|
|
"log"
|
|
"os"
|
|
"syscall"
|
|
"time"
|
|
)
|
|
|
|
var (
|
|
signal = flag.String("s", "", `send signal to the daemon
|
|
stop — shutdown`)
|
|
)
|
|
|
|
const logFileName = "log"
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
daemon.AddCommand(daemon.StringFlag(signal, "stop"), syscall.SIGTERM, termHandler)
|
|
|
|
cntxt := &daemon.Context{
|
|
PidFileName: "pid",
|
|
PidFilePerm: 0644,
|
|
LogFileName: logFileName,
|
|
LogFilePerm: 0640,
|
|
WorkDir: "./",
|
|
Umask: 027,
|
|
Args: []string{"[go-daemon sample]"},
|
|
}
|
|
|
|
if len(daemon.ActiveFlags()) > 0 {
|
|
d, err := cntxt.Search()
|
|
if err != nil {
|
|
log.Fatalln("Unable send signal to the daemon:", err)
|
|
}
|
|
daemon.SendCommands(d)
|
|
return
|
|
}
|
|
|
|
d, err := cntxt.Reborn()
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
if d != nil {
|
|
return
|
|
}
|
|
defer cntxt.Release()
|
|
|
|
log.Println("- - - - - - - - - - - - - - -")
|
|
log.Println("daemon started")
|
|
|
|
setupLog()
|
|
|
|
go worker()
|
|
|
|
err = daemon.ServeSignals()
|
|
if err != nil {
|
|
log.Println("Error:", err)
|
|
}
|
|
log.Println("daemon terminated")
|
|
}
|
|
|
|
func setupLog() {
|
|
lf, err := NewLogFile(logFileName, os.Stderr)
|
|
if err != nil {
|
|
log.Fatal("Unable to create log file: ", err)
|
|
}
|
|
log.SetOutput(lf)
|
|
// rotate log every 30 seconds.
|
|
rotateLogSignal := time.Tick(30 * time.Second)
|
|
go func() {
|
|
for {
|
|
<-rotateLogSignal
|
|
if err := lf.Rotate(); err != nil {
|
|
log.Fatal("Unable to rotate log: ", err)
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
|
|
var (
|
|
stop = make(chan struct{})
|
|
done = make(chan struct{})
|
|
)
|
|
|
|
func worker() {
|
|
LOOP:
|
|
for {
|
|
// spam to log every one second (as payload).
|
|
log.Print("+ ", time.Now().Unix())
|
|
time.Sleep(time.Second)
|
|
select {
|
|
case <-stop:
|
|
break LOOP
|
|
default:
|
|
}
|
|
}
|
|
done <- struct{}{}
|
|
}
|
|
|
|
func termHandler(sig os.Signal) error {
|
|
log.Println("terminating...")
|
|
stop <- struct{}{}
|
|
if sig == syscall.SIGQUIT {
|
|
<-done
|
|
}
|
|
return daemon.ErrStop
|
|
}
|