Skip to content

Repository files navigation

Go Daemon

A daemon package for use with Go (golang) services

GoDoc

Examples

Simplest example (just install self as daemon)

package main
import (
"fmt""log""github.com/takama/daemon"
)
funcmain() {
service, err:=daemon.New("name", "description", daemon.SystemDaemon)
iferr!=nil {
log.Fatal("Error: ", err)
}
status, err:=service.Install()
iferr!=nil {
log.Fatal(status, "\nError: ", err)
}
fmt.Println(status)
}

Real example

// Example of a daemon with echo servicepackage main
import (
"fmt""log""net""os""os/signal""syscall""github.com/takama/daemon"
)
const (
// name of the servicename="myservice"description="My Echo Service"// port which daemon should be listenport=":9977"
)
// dependencies that are NOT required by the service, but might be usedvardependencies= []string{"dummy.service"}
varstdlog, errlog*log.Logger// Service has embedded daemontypeServicestruct {
daemon.Daemon
}
// Manage by daemon commands or run the daemonfunc (service*Service) Manage() (string, error) {
usage:="Usage: myservice install | remove | start | stop | status"// if received any kind of command, do itiflen(os.Args) >1 {
command:=os.Args[1]
switchcommand {
case"install":
returnservice.Install()
case"remove":
returnservice.Remove()
case"start":
returnservice.Start()
case"stop":
returnservice.Stop()
case"status":
returnservice.Status()
default:
returnusage, nil
}
}
// Do something, call your goroutines, etc// Set up channel on which to send signal notifications.// We must use a buffered channel or risk missing the signal// if we're not ready to receive when the signal is sent.interrupt:=make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt, os.Kill, syscall.SIGTERM)
// Set up listener for defined host and portlistener, err:=net.Listen("tcp", port)
iferr!=nil {
return"Possibly was a problem with the port binding", err
}
// set up channel on which to send accepted connectionslisten:=make(chan net.Conn, 100)
goacceptConnection(listener, listen)
// loop work cycle with accept connections or interrupt// by system signalfor {
select {
caseconn:=<-listen:
gohandleClient(conn)
casekillSignal:=<-interrupt:
stdlog.Println("Got signal:", killSignal)
stdlog.Println("Stoping listening on ", listener.Addr())
listener.Close()
ifkillSignal==os.Interrupt {
return"Daemon was interruped by system signal", nil
}
return"Daemon was killed", nil
}
}
// never happen, but need to complete codereturnusage, nil
}
// Accept a client connection and collect it in a channelfuncacceptConnection(listener net.Listener, listenchan<- net.Conn) {
for {
conn, err:=listener.Accept()
iferr!=nil {
continue
}
listen<-conn
}
}
funchandleClient(client net.Conn) {
for {
buf:=make([]byte, 4096)
numbytes, err:=client.Read(buf)
ifnumbytes==0||err!=nil {
return
}
client.Write(buf[:numbytes])
}
}
funcinit() {
stdlog=log.New(os.Stdout, "", log.Ldate|log.Ltime)
errlog=log.New(os.Stderr, "", log.Ldate|log.Ltime)
}
funcmain() {
srv, err:=daemon.New(name, description, daemon.SystemDaemon, dependencies...)
iferr!=nil {
errlog.Println("Error: ", err)
os.Exit(1)
}
service:=&Service{srv}
status, err:=service.Manage()
iferr!=nil {
errlog.Println(status, "\nError: ", err)
os.Exit(1)
}
fmt.Println(status)
}

Service config file

Optionally, service config file can be retrieved or updated by calling GetTemplate() string and SetTemplate(string) methods(except MS Windows). Template will be a default Go Template("text/template").

If SetTemplate is not called, default template content will be used while creating service.

VariableDescription
DescriptionDescription for service
DependenciesService dependencies
NameService name
PathPath of service executable
ArgsArguments for service executable

Example template(for linux systemv)

[Unit]Description={{.Description}}
Requires={{.Dependencies}}
After={{.Dependencies}}
[Service]PIDFile=/var/run/{{.Name}}.pid
ExecStartPre=/bin/rm -f /var/run/{{.Name}}.pid
ExecStart={{.Path}} {{.Args}}
Restart=on-failure
[Install]WantedBy=multi-user.target

Cron example

See examples/cron/cron_job.go

Contributors (unsorted)

All the contributors are welcome. If you would like to be the contributor please accept some rules.

  • The pull requests will be accepted only in develop branch
  • All modifications or additions should be tested
  • Sorry, We will not accept code with any dependency, only standard library

Thank you for your understanding!

License

MIT Public License

About

A daemon package for use with Go (golang) services

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages