github.com/aldelo/common@v1.5.1/wrapper/systemd/systemd.go (about) 1 package systemd 2 3 /* 4 * Copyright 2020-2023 Aldelo, LP 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 import ( 20 "github.com/kardianos/service" 21 "log" 22 ) 23 24 // ===================================================================================================================== 25 // systemd service setup info 26 // ===================================================================================================================== 27 28 /* 29 xyz.service for linux systemd setup 30 31 1) create file 'xyz.service' with following content: 32 xyz = name of service app program 33 34 [Unit] 35 Description=XYZ App Title 36 After=network.target 37 StartLimitIntervalSec=0 38 39 [Service] 40 Type=simple 41 ExecStart=/home/ubuntu/xyzFolder/xyzAppName -svc -port=8080 42 WorkingDirectory=/home/ubuntu/xyzFolder 43 User=ubuntu 44 StandardOutput=console 45 Restart=always 46 RestartSec=1 47 48 [Install] 49 WantedBy=multi-user.target 50 Alias=xyzAppName.service 51 52 2) place 'xyz.service' file at home directory 53 3) note: port 80 seems to be restricted on ubuntu, so we use port 8080 rather than having to reconfigure the os 54 4) note: -svc -port=8080 are optional based on the xyzAppName flags 55 56 5) place the xyz.service file to '/etc/systemd/system' 57 $> sudo cp xyz.service /etc/systemd/system 58 59 6) to enable and load service 60 $> sudo systemctl enable xyz.service 61 7) to start service 62 $> sudo systemctl start xyz.service 63 8) to stop service 64 $> sudo systemctl stop xyz.service 65 9) to disable service 66 $> sudo systemctl disable xyz.service 67 */ 68 69 /* 70 Windows OS Service Creation 71 72 *) assuming xyz.exe (output from GOOS=windows GOARCH=amd64 go build) is located in windows folder c:\xyzFolder, 73 be sure to place any dependency files into this folder or its sub folders as well. 74 *) assuming the desired windows service name is xyzService (name it any valid windows service name desired) 75 76 Create Windows Service Step: 77 c:\sc.exe create xyzService binpath= c:\xyzFolder\xyz.exe type= own start= auto 78 79 More Info, See https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/sc-create 80 */ 81 82 // ===================================================================================================================== 83 // systemd usage in main.go 84 // ===================================================================================================================== 85 86 /* 87 func main() { 88 // 89 // define service program base 90 // 91 svc := &systemd.ServiceProgram{ 92 ServiceName: "abc.xyz", 93 DisplayName: "App Name Descriptive", 94 Description: "More info about the app service", 95 96 Port: 8080, // port that this service will run on, if port is not used, set to 0 97 StartServiceHandler: startHandler, // startHandler is a function that performs service launch code, such as starting web server or micro service 98 StopServiceHandler: stopHandler, // stopHandler is a function that performs service stop code, such as clean up 99 } 100 101 // 102 // launch service 103 // 104 svc.Launch() 105 } 106 107 func startHandler(port int) { 108 // place application logic in handler 109 // such as setup gin handlers and start logic handling services etc 110 } 111 112 func stopHandler() { 113 // place applicatipn clean up code here 114 } 115 */ 116 117 // --------------------------------------------------------------------------------------------------------------------- 118 // service base definition 119 // --------------------------------------------------------------------------------------------------------------------- 120 121 // define service logger 122 var logger service.Logger 123 124 // ServiceProgram defines service program 125 type ServiceProgram struct { 126 ServiceName string 127 DisplayName string 128 Description string 129 130 Port int 131 StartServiceHandler func(port int) 132 StopServiceHandler func() 133 } 134 135 // Launch will initialize and start the service for operations 136 // 137 // Launch is called from within main() to start the service 138 func (p *ServiceProgram) Launch() { 139 // 140 // define service configuration 141 // 142 svcConfig := &service.Config{ 143 Name: p.ServiceName, 144 DisplayName: p.DisplayName, 145 Description: p.Description, 146 } 147 148 // 149 // instantiate service object 150 // 151 svc, err := service.New(p, svcConfig) 152 153 if err != nil { 154 log.Fatalf("%s Init Service Failed: %s", p.ServiceName, err.Error()) 155 } 156 157 // 158 // setup logger 159 // 160 logger, err = svc.Logger(nil) 161 162 if err != nil { 163 log.Fatalf("%s Init Logger Failed: %s", p.ServiceName, err.Error()) 164 } 165 166 // 167 // run the service 168 // 169 err = svc.Run() 170 171 if err != nil { 172 log.Fatalf("%s Run Service Failed: %s", p.ServiceName, err.Error()) 173 } 174 } 175 176 // Start the service 177 func (p *ServiceProgram) Start(s service.Service) error { 178 // start service - do not block, actual work should be done async 179 go p.run() 180 return nil 181 } 182 183 // run is async goroutine to handle service code 184 func (p *ServiceProgram) run() { 185 // do actual work async in this go-routine 186 log.Println("Starting Service Program...") 187 188 if p != nil { 189 if p.Port >= 0 && p.Port < 65535 { 190 // run service handler 191 if p.StartServiceHandler != nil { 192 log.Println("Start Service Handler Invoked...") 193 p.StartServiceHandler(p.Port) 194 } 195 } 196 } 197 } 198 199 // Stop will stop the service 200 func (p *ServiceProgram) Stop(s service.Service) error { 201 // stop the service, should not block 202 log.Println("Stopping Service Program...") 203 204 if p != nil { 205 if p.StopServiceHandler != nil { 206 log.Println("Stop Service Handler Invoked...") 207 p.StopServiceHandler() 208 } 209 } 210 211 return nil 212 }