-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcommon.go
108 lines (105 loc) · 5.17 KB
/
common.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package cyberdaemon
// Daemonizer provides methods for daemonizing your application code.
//
// Gotchas
//
// There are several "gotchas" that implementers should be aware of when using
// the Daemonizer.
//
// System V (init.d) on Linux:
// A file known as a "PID file" is used to store the process ID of the running
// daemon's process. Both the init.d script, and daemon must know where this
// file is stored - the script to read it, and the daemon to update it. By
// default, the System V Daemonizer will attempt to find the PID file by
// looking in the init.d script for a Bash variable named:
// 'PID_FILE_PATH'
// If it cannot locate such a variable, it will use:
// "/var/run/<init.d-script-name>.pid"
//
// Windows:
// On Windows, developers must implement a method named 'WindowsDaemonID'
// in their Application implementations. The Windows build of this interface
// differs from the unix variant by this one method. This is needed because
// the Windows service manager needs to know the service name when starting
// the daemon. This was implemented in the Application interface to make it
// a compile-time error if developers try to build for Windows in addition
// to other operating systems.
//
// Implementation details
//
// System V (init.d):
// System V is one of the more complicated daemon implementations in this
// library. This is due to Go's inability to fork, and the tight-knit nature of
// the daemon management script and its corresponding daemon application.
//
// System V works by using a script (typically written in Bourne Shell) to
// manage the daemon. This script is usually stored in '/etc/init.d'. System V
// expects the init.d script to exit after starting the daemon process. This is
// typically implemented using the 'fork' system call, which spawns a new
// process with only one thread. Go's runtime requires multiple threads to run
// (many Go programs rely on more than one thread anyways). An alternate
// solution is to do what is called "fork exec". This means the Go program runs
// a new instance of itself, and the original instance exits. Implementing this
// is tricky because the library cannot rely on settings files, command line
// arguments, or environment variables to determine if init.d started it. Doing
// so would cross an implementation line that would require implementers to
// bake the special business logic into their own independent init.d scripts.
//
// This library's System V daemon implementation checks the parent PID's
// "/proc/<pid>/cmdline" to determine:
// - Is init.d the parent process?
// - If so, where is the init.d script stored?
//
// If started by init.d, the daemon will attempt to parse the PID file path
// from the init.d script. A PID file is used to store the PID of the daemon
// so that the management script can easily determine the status of the daemon.
// Both the init.d script and the daemon need to know where this file is
// located (the script so that it can read it, and the daemon so that it can
// write its PID to it). If the daemon cannot find the PID file path in the
// init.d script, it uses a sane default PID file path.
type Daemonizer interface {
// RunUntilExit runs the provided Application until the daemon is
// instructed to quit. This method blocks until the daemon exits.
RunUntilExit(Application) error
}
// LogConfig configures the logging settings for the daemon.
type LogConfig struct {
// UseNativeLogger specifies whether the operating system's native
// logging tool should be used. When set to 'true', implementers
// should use the standard library's 'log' package to facilitate
// logging. This guarantees that your log messages will reach the
// native logging utility.
//
// For Linux systems, the native logger depends on whether systemd
// or System V is used. Systemd saves stderr output from the daemon.
// These logs are accessed by running:
// journalctl -u myapp
// You can add '-f' to the above command to display log messages
// as they are created.
// System V (init.d), however, does not provide a similar logging
// tool. If the daemon was installed using a Controller, the stderr
// output of the daemon will be redirected to a log file. This log
// file can be found at:
// /var/log/myapp/myapp.log
// If a System V daemon was not installed using a controller, it will
// attempt to output logs to stderr.
//
// macOS, like System V, does not provide a logging tool. If the daemon
// was installed using a Controller, its stderr will be redirected to:
// /Library/Logs/com.github.myapp/com.github.myapp.log
// ... and user daemons will be saved to:
// ~/Library/Logs/com.github.myapp/com.github.myapp.log
// If a macOS daemon was not installed using a controller, it will
// attempt to output logs to stderr.
//
// Windows provides the Event Log utility for saving log messages.
// Log messages can be viewed using either the 'Event Viewer' GUI
// application, or by running:
// TODO: Event viewer CLI command
UseNativeLogger bool
// NativeLogFlags specifies which log flags to use when UserNativeLogger
// is set to 'true'. The value must be greater than zero to take effect.
// See the standard library's 'log' package for more information about
// log flags.
NativeLogFlags int
}