-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcwrap.py.1
More file actions
283 lines (283 loc) · 10.7 KB
/
cwrap.py.1
File metadata and controls
283 lines (283 loc) · 10.7 KB
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
.TH cwrap.py 1 "September 9, 2013" "version 0.6.2" "USER COMMANDS"
.SH NAME
cwrap.py \- A cron job wrapper used to suppress output
.SH SYNOPSIS
.B cwrap.py [options] (command [cmd-arg [cmd-arg ...]] | 'command [cmd-arg [cmd-arg ...]]')
.SH DESCRIPTION
"Obviously, you're not a golfer". But you are probably a sysadmin.
.PP
The
.I cwrap.py
script is meant to be used as a wrapper for cron jobs. The idea
here is that you use this script to wrap whatever would be a normal cronjob
for you to perform functions based on what options are specified. I think
this is best explained with an example.
.PP
I have a cronjob that runs every minute. First, I don't want
"overlap", a second instance is run while the first one is still running,
if a single run takes a long time. Solved. The nature of my cronjob (just
a script that is being run) is such that there will be an occasional failure,
but an occasional failure, in this case, can be ignored. Instead, I only want
to know when the script has failed 5 times in a row. Solved. By default,
cwrap.py will also swallow all the output for the occasional fails, but I
at least want a record of those failures so that I can determine whether
the intermittent fails are happening more frequently and constitute a
different problem. Solved (by turning on the syslog option).
.PP
This script may not be useful for everyone, but for some out there, it will
save you a lot of time, effort and probably emails in your inbox.
.PP
See the EXAMPLE section for a short example
.SH FAILURES
The concept of a failure is simple. The exit code of the script that cwrap.py
is running must be non-zero for cwrap.py to call it a "failure".
.SH OPTIONS
.SS "General Options"
.TP 8
.BR \-h ", " \-\-help
display a short help
.TP
.BR \-V "," \-\-version
Print the version number and exit [default: False]
.SS "State Options"
.TP 8
.BI \-d\ PATH \fR,\ \fB\-\-state\-directory= PATH
The directory to write the state file to. There is a state file created for
each command-line that
.I cwrap.py
is running. This specifies the directory to create those in.
[default: /var/tmp]
.TP
.BI \-F\ FILE \fR,\ \fB\-\-lock\-file= FILE
Set a specific lock file to use. This is useful when running 2 different
scripts, or the same script with different command-line opts, that cannot
run at the same time. By default, a lock file will be automatically
generated. [default: <auto-gen lockfile>]
.SS "Retry Options"
.TP 8
.BI \-r\ INT \fR,\ \fB\-\-num\-retries= INT
The number of times to retry this if a previous instance is running.
The script will retry every "-s" seconds if this is greater than zero.
This, like all the retry options, only pertains to retries of
.I cwrap.py
when it encounters a lock file. The default here is not to retry at all, and
instead just die. [default: 0]
.TP
.BI \-s\ INT \fR,\ \fB\-\-retry\-seconds= INT
This is the number of seconds between retries. This only matters if the
.B \-\-num\-retries
option is set to greater than zero. [default: 10]
.TP
.BR \-i ", " \-\-ignore\-retry\-fails
Ignore the failures which occur because this tried to run while a
previous instance was still running. Basically, an error will not be
printed if the
.B \-\-num\-retries
are exceeded. The default behavior is to treat this as a failure.
[default: False]
.SS "Failure Options"
.TP 8
.BI \-n\ INT \fR,\ \fB\-\-num\-fails= INT
The number of consecutive failures that must occur before a report is
printed. The behavior of
.I cwrap.py
can be set to store all of the failures until this number is reached. At that
point, all of the consecutive failures will be printed. [default: 1]
.TP
.BR \-f ", " \-\-first\-fail
The default is to print a failure report only when a multiple of the
.B \-\-num\-fails
threshold is reached. If this is set, a report will
.B also
be printed on the first failure. Note that this really only matters if
you set the
.B \-\-num\-fails
greater than 1. [default: False]
.TP
.BR \-b ", " \-\-backoff
Instead of sending an email out every
.B \-\-num\-fails
failures, if this is set, emails will be sent out at an exponentially
decaying rate. Example: if you set the
.B \-\-num\-fails
to 3, then an email would be sent at 3 fails, 6 fails, 12 fails, etc.
[default: False]
.SS "Command Options"
.TP 8
.BI \-p\ CMD_PATH \fR,\ \fB\-\-path= CMD_PATH
Use this for command path instead of the environment $PATH. This will be set
to the environment PATH of whatever user is running this, or whatever the
PATH variable is set to in your crontab.
.TP
.BR \-g ", " \-\-single\-string
This says that you are passing in a command line as a single string.
This means that the entire command (with args) MUST be encased in quotes!
This is handy if you want to encapsulate a pipe ("|") in your command
to be run:
.PP
.nf
"cat /tmp/file | grep stuff"
.fi
.PP
That would be passed directly, as a string, to a subshell for execution. This
allows for a lot of flexibility in how you use this. By default, the
command is interpretted as it is "seen". [default: False]
.TP
.BI \-t\ INT \fR,\ \fB\-\-timeout= INT
The number of seconds to allow the your command to run before terminating.
Set to zero to disable timeouts. This is the length of time that
.I cwrap.py
will allow the command to run before
.I cwrap.py
terminates it. The default is to let it run forever. [default: 0]
.TP
.BI \-z\ INT \fR,\ \fB\-\-fuzz= INT
This will add a random sleep between 0 and N seconds
before executing the command. Note that the --timeout
is only valid in regards to when the command is
actually run. To calculate run time, you should add
timeout + fuzz + command run time [default: 0]
.TP
.BR \-q ", " \-\-quiet
Only output error reports. If this is set and the command runs successfully,
nothing will be printed, even if the command had stdout or stderr output.
The default is to print any output from the command. If you are only
interested in error output, just set this. [default: False]
.SS "Syslog Options"
.TP 8
.BR \-S ", " \-\-syslog
Turn on syslogging. This will log
.B all
failures to syslog. This is useful for diagnosing intermittent issues that
don't necessarily reach the
.B --num-fails
limit. See
.B \-C
and
.B \-P
for facility and priority options [default: False]
.TP
.BI \-C\ FACILITY \fR,\ \fB\-\-syslog\-facility= FACILITY
The syslog facility to use. See the facility section in
.I man syslog
for a list of choices. You must use
.B \-\-syslog
with this. [default: LOG_LOCAL7]
.TP
.BI \-P\ PRIORITY \fR,\ \fB\-\-syslog\-priority= PRIORITY
Sets the priority for the syslog messages. See the level section in
.I man syslog
for a list of choices. You must use
.B \-\-syslog
with this. [default: LOG_INFO]
.TP
.BR \-O ", " \-\-num\-fails\-only
Only log an item when the number of failures is reached.
Normally,
.B all
failures are logged, but you can use this option to
only write to syslog only when
.B \-\-num\-fails
is reached [default: False]
.SS "Email Options"
.TP 8
.BR \-M ", " \-\-send\-mail
Send an email from within cwrap itself. This option
is *required* if you wish to use the email options
below. Any other email options will be ignored if
this option is not specified. Note that this can be
used with -N to disable normal output and just use
cwrap to send an email [default: False]
.TP
.BR \-N ", " \-\-suppress\-normal\-output
Suppress the normal output to STDOUT that would
normally cause crond to send an email. This can
*only* be specified if you are using cwrap to send an
email (
.B \-M
). [default: False]
.TP
.BI \-E\ EMAIL_ADDR \fR,\ \fB\-\-email\-from= EMAIL_ADDR
The email address to use as the sending address. It
is advised that you set this to a non-default as the default
will be your user at localhost.localdomain
.TP
.BI \-R\ EMAIL_ADDR \fR,\ \fB\-\-email\-recipient= EMAIL_ADDR
The recipient(s) to send the email to. This options can
be specified multiple times to send to multiple addresses.
.TP
.BI \-J\ SUBJECT \fR,\ \fB\-\-email\-subject= SUBJECT
The subject of the email to be sent [default: cwrap.py failure report]
.TP
.BI \-X\ HOSTNAME|IP \fR,\ \fB\-\-smtp\-server= HOSTNAME|IP
The SMTP server to use to send the email. If this option is not
set, the local "sendmail" command will be used instead. Note that
the sendmail command must be in your PATH!
.TP
.BI \-T\ INT \fR,\ \fB\-\-smtp\-port= INT
The SMTP port to use [default: 25]
.TP
.BR \-L ", " \-\-ssl
Use SSL for the SMTP server connection
.TP
.BR \-Z ", " \-\-starttls
Use STARTTLS during the SMTP server connection
.TP
.BI \-U\ USERNAME \fR,\ \fB\-\-smtp\-username= USERNAME
An SMTP username to use for auth SMTP.
.TP
.BI \-W\ PASSWORD \fR,\ \fB\-\-smtp\-password= PASSWORD
A password to use with
.B \-U
for auth SMTP. It is recommended that you use
.B \-D
instead and set tight read permissions on the creds file. This
is generally preferred instead of specifying a username and password
on the command-line.
.TP
.BI \-D\ FILE \fR,\ \fB\-\-smtp\-creds\-file= FILE
This is recommended instead of specifying a username and password on the
command-line when using authenticated SMTP to send email. That way you
can set read only access for the user running cwrap and not have to
expose the username and password. All you should have in your creds.
file is: USERNAME:PASSWORD
.SH EXAMPLE
Here is a short example of how you would run a cron job with
.I cwrap.py.
.PP
For the purpose of this example, we'll say that the normal cronjob is run as
.PP
.nf
cron.sh -a do_stuff
.fi
.PP
Let's say that we always want to see the first failure in a string of
failures (-f). Beyond the first failure, we don't want to be notified until
the 10th consecutive failure (-n 10). This script can take a while to run so
I want any other runs to retry two times (-r 2), but if it wasn't able to run
because another instance was running, I don't want to hear about it (-i). I
also don't want to see any normal output from it, but just when it fails (-q).
I also want
.B all
errors to be logged to syslog (-S) under LOCAL1 (-C LOG_LOCAL1).
.PP
On top of
that, I want to send an email to (-R [email protected]) and (-R [email protected])
with the same output that is going to the configure cron email address.
To do that we specify that we will send an email from cwrap itself (-M)
and we are going to connect to the local relay server to send the email
(-X 192.168.0.2) with the subject set to a custom string (-J "widget failure detected") and this will have the sender email address set
(-E [email protected]) and finally, we will do all of this securely with
STARTTLS (-Z). Here would be the example:
.PP
.nf
cwrap.py -fSiqMZ -n 10 -r 2 -C LOG_LOCAL1 -R [email protected] \\
-R [email protected] -J "widget failure detected" \\
-E [email protected] -X 192.168.0.2 cron.sh -a do_stuff
.fi
.SH AUTHOR
Jay Deiman (admin (at) splitstreams.com)
.PP
http://stuffivelearned.org
.SH SEE ALSO
cron(8), crontab(1), crontab(5), syslog(3)