golang windows 服务失败,没有任何错误
golang windows service fails without any error
我使用 golang 编写了一个简单的 windows 服务。
package main
import "golang.org/x/sys/windows/svc"
import "io/ioutil"
import "log"
import "encoding/json"
import "time"
import "strconv"
import "os"
import "./cmd"
import "golang.org/x/sys/windows/svc/eventlog"
import "fmt"
type myservice struct{}
func (m *myservice) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) {
log.Println("Starting service")
const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown | svc.AcceptPauseAndContinue
changes <- svc.Status{State: svc.StartPending}
changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
StartService(r, changes)
return
}
//RunService Runs the current application as a service.It will send the necessary flags to windows.
func RunService(maintServiceName string) {
//var elog eventlog
elog, evtErr := eventlog.Open(maintServiceName)
if evtErr != nil {
return
}
defer elog.Close()
log.Println("Running service")
elog.Info(1, fmt.Sprintf("starting %s service", maintServiceName))
run := svc.Run
sererr := run(maintServiceName, &myservice{})
if sererr != nil {
elog.Error(1, fmt.Sprintf("%s service failed: %v", maintServiceName, sererr))
}
}
//StartService Starts the Service
func StartService(r <-chan svc.ChangeRequest, changes chan<- svc.Status) {
const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown | svc.AcceptPauseAndContinue
jsonFile, err := os.Open("config.json")
if err != nil {
log.Fatalln("No configuration found")
}
byteVal, _ := ioutil.ReadAll(jsonFile)
var result map[string]interface{}
json.Unmarshal([]byte(byteVal), &result)
var serverURL = result["serverURL"]
var serviceName = result["serviceName"]
var intervalStr = result["interval"].(string)
var intervalInt, parseErr = strconv.ParseInt(intervalStr, 10, 32)
if parseErr != nil {
intervalInt = 60
}
log.Println("server Url ", serverURL)
log.Println("service name ", serviceName)
cmd.SetServerURL(serverURL.(string))
cmd.SetServiceName(serviceName.(string))
log.Println("Running Thread")
go func() {
for {
log.Println("sleeping ")
time.Sleep(time.Duration(intervalInt) * time.Second)
cmd.Connect()
}
}()
select {
case c := <-r:
if c.Cmd == svc.Stop || c.Cmd == svc.Shutdown {
break
}
if c.Cmd == svc.Interrogate {
changes <- c.CurrentStatus
time.Sleep(100 * time.Millisecond)
changes <- c.CurrentStatus
}
if c.Cmd == svc.Pause {
changes <- svc.Status{State: svc.Paused, Accepts: cmdsAccepted}
}
if c.Cmd == svc.Continue {
changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
}
}
}
该应用程序大多数情况下可以正常运行一两天,但之后会停止运行而不会出现任何错误。当它发生时,日志中的睡眠行之后没有日志。我可以添加任何内容以获取有关服务失败的更多信息吗?这可能是什么问题?
我将从在 StartService
中围绕 select
添加一个循环开始(请参阅 this example)。从您提供的代码看来,您的服务将在收到任何可能是问题的信号(包括 pause/Interrogate)后退出。在 StartService
中添加一些进一步的日志记录也可能是有益的(任何提供有关正在发生的事情的更多信息的东西都有帮助!)
如果这不能解决问题,那么值得在 go 例程中添加一个 defer/recover 和 StartService
来检查是否是恐慌导致了问题(可能只是向日志中写入一些内容)足够了)。
我使用 golang 编写了一个简单的 windows 服务。
package main
import "golang.org/x/sys/windows/svc"
import "io/ioutil"
import "log"
import "encoding/json"
import "time"
import "strconv"
import "os"
import "./cmd"
import "golang.org/x/sys/windows/svc/eventlog"
import "fmt"
type myservice struct{}
func (m *myservice) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) {
log.Println("Starting service")
const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown | svc.AcceptPauseAndContinue
changes <- svc.Status{State: svc.StartPending}
changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
StartService(r, changes)
return
}
//RunService Runs the current application as a service.It will send the necessary flags to windows.
func RunService(maintServiceName string) {
//var elog eventlog
elog, evtErr := eventlog.Open(maintServiceName)
if evtErr != nil {
return
}
defer elog.Close()
log.Println("Running service")
elog.Info(1, fmt.Sprintf("starting %s service", maintServiceName))
run := svc.Run
sererr := run(maintServiceName, &myservice{})
if sererr != nil {
elog.Error(1, fmt.Sprintf("%s service failed: %v", maintServiceName, sererr))
}
}
//StartService Starts the Service
func StartService(r <-chan svc.ChangeRequest, changes chan<- svc.Status) {
const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown | svc.AcceptPauseAndContinue
jsonFile, err := os.Open("config.json")
if err != nil {
log.Fatalln("No configuration found")
}
byteVal, _ := ioutil.ReadAll(jsonFile)
var result map[string]interface{}
json.Unmarshal([]byte(byteVal), &result)
var serverURL = result["serverURL"]
var serviceName = result["serviceName"]
var intervalStr = result["interval"].(string)
var intervalInt, parseErr = strconv.ParseInt(intervalStr, 10, 32)
if parseErr != nil {
intervalInt = 60
}
log.Println("server Url ", serverURL)
log.Println("service name ", serviceName)
cmd.SetServerURL(serverURL.(string))
cmd.SetServiceName(serviceName.(string))
log.Println("Running Thread")
go func() {
for {
log.Println("sleeping ")
time.Sleep(time.Duration(intervalInt) * time.Second)
cmd.Connect()
}
}()
select {
case c := <-r:
if c.Cmd == svc.Stop || c.Cmd == svc.Shutdown {
break
}
if c.Cmd == svc.Interrogate {
changes <- c.CurrentStatus
time.Sleep(100 * time.Millisecond)
changes <- c.CurrentStatus
}
if c.Cmd == svc.Pause {
changes <- svc.Status{State: svc.Paused, Accepts: cmdsAccepted}
}
if c.Cmd == svc.Continue {
changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
}
}
}
该应用程序大多数情况下可以正常运行一两天,但之后会停止运行而不会出现任何错误。当它发生时,日志中的睡眠行之后没有日志。我可以添加任何内容以获取有关服务失败的更多信息吗?这可能是什么问题?
我将从在 StartService
中围绕 select
添加一个循环开始(请参阅 this example)。从您提供的代码看来,您的服务将在收到任何可能是问题的信号(包括 pause/Interrogate)后退出。在 StartService
中添加一些进一步的日志记录也可能是有益的(任何提供有关正在发生的事情的更多信息的东西都有帮助!)
如果这不能解决问题,那么值得在 go 例程中添加一个 defer/recover 和 StartService
来检查是否是恐慌导致了问题(可能只是向日志中写入一些内容)足够了)。