Documentation ¶
Overview ¶
Package cronmon is the core of the cronmon application, providing individual components that work independently, while communicating with eachother concurrently over channels.
Mechanism of Operation ¶
Cronmon works similarly to your average service manager: it manages a group of programs to make sure they're alive; however, there are some differences that will be outlined below.
Service Files ¶
In cronmon, a service file is an executable. Cronmon watches for executable files in the "scripts" directory, which is by default "$XDG_CONFIG_HOME/cronmon/scripts/". The directory is actively watched for changes, and service restarts will be performed accordingly.
Note that when a regular editor writes to one of the scripts, it may perform multiple operations for atomicity, which may interfere and cause cronmon to restart the process multiple times rapidly. This is to be expected.
Interruption ¶
When cronmon is suddenly (ungracefully) interrupted, its Pdeathsig mechanism will take down its managed processes as well, meaning that when cronmon is restored, there won't be the same processes running twice. Although this may not be a very ideal and portable solution, it is the simplest one.
When a subprocess is disowned from the processes that cronmon has spawned, its parent process will be cronmon itself, not init (PID 1). This is accomplished using the non-portable SET_CHILD_SUBREAPER feature. This disowned process won't be killed when the process stops, but it will be killed when cronmon is interrupted.
Journal Files ¶
During its operation, cronmon logs its actions into a journal file. Each cronmon process may take exclusive ownership of each journal file. The purpose of this journal file is to allow cronmon access to previous state while also providing a human and machine readable log format. The default path for the log file is "$XDG_CONFIG_HOME/cronmon/journal.json".
Journal events are described in events.go, where each event is prefixed with "Event" and comes with a Type() method to aid writing these events down in any format. An implementation exists in package journal to read and write journals in the line-delimited JSON format.
Index ¶
- Variables
- type Event
- type EventAcquired
- type EventLogTruncated
- type EventProcessExited
- type EventProcessListModify
- type EventProcessSpawnError
- type EventProcessSpawned
- type EventQuit
- type EventWarning
- type JournalReadWriter
- type JournalReader
- type Journaler
- type Monitor
- type PreviousState
- type Process
- type ProcessListModifyOp
- type Watcher
Constants ¶
This section is empty.
Variables ¶
var ProcessRetryBackoff = []time.Duration{ 0, 5 * time.Second, 15 * time.Second, time.Minute, }
ProcessRetryBackoff is a list of backoff durations when a process fails to start. The last duration is used repetitively.
var ProcessWaitTimeout = 3 * time.Second
ProcessWaitTimeout is the time to wait for a process to gracefully exit until forcefully terminating (and finally SIGKILLing) it.
Functions ¶
This section is empty.
Types ¶
type Event ¶
type Event interface { Type() string // contains filtered or unexported methods }
Event is an interface describing known events.
type EventAcquired ¶
type EventAcquired struct {
JournalID string `json:"journal_id"`
}
EventAcquired is emitted when the monitor is started.
func (*EventAcquired) Type ¶
func (ev *EventAcquired) Type() string
type EventLogTruncated ¶
type EventLogTruncated struct {
Reason string `json:"reason"`
}
EventLogTruncated is emitted when the log file has been truncated for any reason, including a corrupted log file.
func (*EventLogTruncated) Type ¶
func (ev *EventLogTruncated) Type() string
type EventProcessExited ¶
type EventProcessExited struct { File string `json:"file"` PID int `json:"pid"` Error string `json:"error,omitempty"` ExitCode int `json:"exit_code"` // -1 if interrupted or terminated }
EventProcessExited is emitted when a process has been stopped for any reason.
func (EventProcessExited) IsGraceful ¶
func (ev EventProcessExited) IsGraceful() bool
IsGraceful returns true if the process stopped gracefully (i.e. on SIGINT).
func (*EventProcessExited) Type ¶
func (ev *EventProcessExited) Type() string
type EventProcessListModify ¶
type EventProcessListModify struct { Op ProcessListModifyOp `json:"op"` File string `json:"file"` }
EventProcessListModify is emitted when the process list is modified to add, update or remove a process from the internal state.
func (*EventProcessListModify) Type ¶
func (ev *EventProcessListModify) Type() string
type EventProcessSpawnError ¶
EventProcessSpawnError is emitted when a process fails to start for any reason.
func (*EventProcessSpawnError) Type ¶
func (ev *EventProcessSpawnError) Type() string
type EventProcessSpawned ¶
EventProcessSpawned is emitted when a process has been started for any reason.
func (*EventProcessSpawned) Type ¶
func (ev *EventProcessSpawned) Type() string
type EventQuit ¶
type EventQuit struct{}
EventQuit is emitted when the monitor has quit and all its processes have been stopped.
type EventWarning ¶
EventWarning is emitted when a non-fatal error occurs.
func (*EventWarning) Type ¶
func (ev *EventWarning) Type() string
type JournalReadWriter ¶
type JournalReadWriter interface { Journaler JournalReader }
JournalReadWriter is a journal reader and writer.
type JournalReader ¶
JournalReader describes a journal reader.
type Journaler ¶
type Journaler interface { // ID returns the ID of the journaler. ID() string // Write writes the event into the journaler. Write(Event) error }
Journaler describes a journal writer/logger.
type Monitor ¶
type Monitor struct {
// contains filtered or unexported fields
}
Monitor is a cronmon instance that keeps a group of processes.
func NewMonitor ¶
NewMonitor creates a new monitor that oversees adding and removing processes. All files in the given directory will be scanned.
type PreviousState ¶
type PreviousState struct { StartedAt time.Time // Processes contains a map of known files to the previous PIDs. Processes map[string]int }
PreviousState parses the last cronmon's previous state to be used by Monitor for restoring.
func ReadPreviousState ¶
func ReadPreviousState(r JournalReader) (*PreviousState, error)
ReadPreviousState reads from the JournalReader the previous state of the cronmon monitor.
type Process ¶
type Process struct { WaitTimeout time.Duration RetryBackoff []time.Duration // contains filtered or unexported fields }
Process monitors an individual process. It is capable of self-monitoring the process, so any commanding operation simply cannot fail but only be delayed.
func NewProcess ¶
NewProcess creates a new process and a background monitor. The process is terminated once the context times out. Wait must be called once the context is canceled to wait for the background routine to exit.
type ProcessListModifyOp ¶
type ProcessListModifyOp string
ProcessListModifyOp contains possible operations that modify the process list, often from changes in the configuration directory.
const ( ProcessListAdd ProcessListModifyOp = "add" ProcessListRemove ProcessListModifyOp = "remove" ProcessListUpdate ProcessListModifyOp = "update" )
type Watcher ¶
type Watcher struct { Events chan EventProcessListModify // contains filtered or unexported fields }
Watcher is a cronmon watcher that watches the configuration directory for new processes.
func NewWatcher ¶
Watch watches the given directory and logs events into the journaler. The watcher is stopped once the given context is canceled.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package exec provides an abstraction around package os' Process implementation for easier testing.
|
Package exec provides an abstraction around package os' Process implementation for easier testing. |
Package journal provides an implementation of cromon's Journaler interface to write to a file.
|
Package journal provides an implementation of cromon's Journaler interface to write to a file. |