gitee.com/quant1x/gox@v1.21.2/daemon/README.md (about) 1 # Go Daemon 2 3 A daemon package for use with Go (golang) services 4 5 [![GoDoc](https://godoc.org/github.com/takama/daemon?status.svg)](https://godoc.org/github.com/takama/daemon) 6 7 ## Examples 8 9 ### Simplest example (just install self as daemon) 10 11 ```go 12 package main 13 14 import ( 15 "fmt" 16 "log" 17 18 "github.com/takama/daemon" 19 ) 20 21 func main() { 22 service, err := daemon.New("name", "description", daemon.SystemDaemon) 23 if err != nil { 24 log.Fatal("Error: ", err) 25 } 26 status, err := service.Install() 27 if err != nil { 28 log.Fatal(status, "\nError: ", err) 29 } 30 fmt.Println(status) 31 } 32 ``` 33 34 ### Real example 35 36 ```go 37 // Example of a daemon with echo service 38 package main 39 40 import ( 41 "fmt" 42 "log" 43 "net" 44 "os" 45 "os/signal" 46 "syscall" 47 48 "github.com/takama/daemon" 49 ) 50 51 const ( 52 53 // name of the service 54 name = "myservice" 55 description = "My Echo Service" 56 57 // port which daemon should be listen 58 port = ":9977" 59 ) 60 61 // dependencies that are NOT required by the service, but might be used 62 var dependencies = []string{"dummy.service"} 63 64 var stdlog, errlog *log.Logger 65 66 // Service has embedded daemon 67 type Service struct { 68 daemon.Daemon 69 } 70 71 // Manage by daemon commands or run the daemon 72 func (service *Service) Manage() (string, error) { 73 74 usage := "Usage: myservice install | remove | start | stop | status" 75 76 // if received any kind of command, do it 77 if len(os.Args) > 1 { 78 command := os.Args[1] 79 switch command { 80 case "install": 81 return service.Install() 82 case "remove": 83 return service.Remove() 84 case "start": 85 return service.Start() 86 case "stop": 87 return service.Stop() 88 case "status": 89 return service.Status() 90 default: 91 return usage, nil 92 } 93 } 94 95 // Do something, call your goroutines, etc 96 97 // Set up channel on which to send signal notifications. 98 // We must use a buffered channel or risk missing the signal 99 // if we're not ready to receive when the signal is sent. 100 interrupt := make(chan os.Signal, 1) 101 signal.Notify(interrupt, os.Interrupt, os.Kill, syscall.SIGTERM) 102 103 // Set up listener for defined host and port 104 listener, err := net.Listen("tcp", port) 105 if err != nil { 106 return "Possibly was a problem with the port binding", err 107 } 108 109 // set up channel on which to send accepted connections 110 listen := make(chan net.Conn, 100) 111 go acceptConnection(listener, listen) 112 113 // loop work cycle with accept connections or interrupt 114 // by system signal 115 for { 116 select { 117 case conn := <-listen: 118 go handleClient(conn) 119 case killSignal := <-interrupt: 120 stdlog.Println("Got signal:", killSignal) 121 stdlog.Println("Stoping listening on ", listener.Addr()) 122 listener.Close() 123 if killSignal == os.Interrupt { 124 return "Daemon was interruped by system signal", nil 125 } 126 return "Daemon was killed", nil 127 } 128 } 129 130 // never happen, but need to complete code 131 return usage, nil 132 } 133 134 // Accept a client connection and collect it in a channel 135 func acceptConnection(listener net.Listener, listen chan<- net.Conn) { 136 for { 137 conn, err := listener.Accept() 138 if err != nil { 139 continue 140 } 141 listen <- conn 142 } 143 } 144 145 func handleClient(client net.Conn) { 146 for { 147 buf := make([]byte, 4096) 148 numbytes, err := client.Read(buf) 149 if numbytes == 0 || err != nil { 150 return 151 } 152 client.Write(buf[:numbytes]) 153 } 154 } 155 156 func init() { 157 stdlog = log.New(os.Stdout, "", log.Ldate|log.Ltime) 158 errlog = log.New(os.Stderr, "", log.Ldate|log.Ltime) 159 } 160 161 func main() { 162 srv, err := daemon.New(name, description, daemon.SystemDaemon, dependencies...) 163 if err != nil { 164 errlog.Println("Error: ", err) 165 os.Exit(1) 166 } 167 service := &Service{srv} 168 status, err := service.Manage() 169 if err != nil { 170 errlog.Println(status, "\nError: ", err) 171 os.Exit(1) 172 } 173 fmt.Println(status) 174 } 175 ``` 176 177 ### Service config file 178 179 Optionally, service config file can be retrieved or updated by calling 180 `GetTemplate() string` and `SetTemplate(string)` methods(except MS 181 Windows). Template will be a default Go Template(`"text/template"`). 182 183 If `SetTemplate` is not called, default template content will be used 184 while creating service. 185 186 | Variable | Description | 187 |--------------|----------------------------------| 188 | Description | Description for service | 189 | Dependencies | Service dependencies | 190 | Name | Service name | 191 | Path | Path of service executable | 192 | Args | Arguments for service executable | 193 194 #### Example template(for linux systemv) 195 196 ```ini 197 [Unit] 198 Description={{.Description}} 199 Requires={{.Dependencies}} 200 After={{.Dependencies}} 201 202 [Service] 203 PIDFile=/var/run/{{.Name}}.pid 204 ExecStartPre=/bin/rm -f /var/run/{{.Name}}.pid 205 ExecStart={{.Path}} {{.Args}} 206 Restart=on-failure 207 208 [Install] 209 WantedBy=multi-user.target 210 ``` 211 212 ### Cron example 213 214 See `examples/cron/cron_job.go` 215 216 ## Contributors (unsorted) 217 218 - [Sheile](https://github.com/Sheile) 219 - [Nguyen Trung Loi](https://github.com/loint) 220 - [Donny Prasetyobudi](https://github.com/donnpebe) 221 - [Mark Berner](https://github.com/mark2b) 222 - [Fatih Kaya](https://github.com/fatihky) 223 - [Jannick Fahlbusch](https://github.com/jannickfahlbusch) 224 - [TobyZXJ](https://github.com/tobyzxj) 225 - [Pichu Chen](https://github.com/PichuChen) 226 - [Eric Halpern](https://github.com/ehalpern) 227 - [Yota](https://github.com/nus) 228 - [Erkan Durmus](https://github.com/derkan) 229 - [maxxant](https://github.com/maxxant) 230 - [1for](https://github.com/1for) 231 - [okamura](https://github.com/sidepelican) 232 - [0X8C - Demired](https://github.com/Demired) 233 - [Maximus](https://github.com/maximus12793) 234 - [AlgorathDev](https://github.com/AlgorathDev) 235 - [Alexis Camilleri](https://github.com/krysennn) 236 - [neverland4u](https://github.com/neverland4u) 237 - [Rustam](https://github.com/rusq) 238 - [King'ori Maina](https://github.com/itskingori) 239 240 All the contributors are welcome. If you would like to be the contributor please accept some rules. 241 242 - The pull requests will be accepted only in `develop` branch 243 - All modifications or additions should be tested 244 - Sorry, We will not accept code with any dependency, only standard library 245 246 Thank you for your understanding! 247 248 ## License 249 250 [MIT Public License](https://github.com/takama/daemon/blob/master/LICENSE)