-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.xml
652 lines (490 loc) · 28.8 KB
/
index.xml
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
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>epazote</title>
<link>https://epazote.io/index.xml</link>
<description>Recent content on epazote</description>
<generator>Hugo -- gohugo.io</generator>
<language>en-us</language>
<copyright> </copyright>
<lastBuildDate>Tue, 20 Sep 2016 21:26:25 +0200</lastBuildDate>
<atom:link href="https://epazote.io/index.xml" rel="self" type="application/rss+xml" />
<item>
<title>🌿 epazote</title>
<link>https://epazote.io/about/</link>
<pubDate>Tue, 20 Sep 2016 21:26:25 +0200</pubDate>
<guid>https://epazote.io/about/</guid>
<description>
<h1 id="what-is-epazote">What is epazote?</h1>
<p>An automated HTTP (microservices) supervisor.</p>
<p><a href="https://asciinema.org/a/86545"><img src="https://asciinema.org/a/86545.png" alt="asciicast" /></a></p>
<h2 id="why">Why ?</h2>
<p>Because of the need to monitor with simplicity for example:</p>
<ul>
<li>A simple check (Status 200 OK) every 30 seconds.</li>
<li>Receive an email/http alert if the SSL certifciate is about to expire.</li>
<li>Check if the application is serving the proper headers.</li>
<li>Restart DB/App/etc based on headers or staus codes.</li>
</ul>
<hr />
<p>Once your site/application is up and running, it can become idle and
unresponsive, your <a href="https://immortal.run">supervisor</a> will not notice
this, since in most of the cases is just responsible for keeping your
application process up and running no matter how it is behaving, therefore
exists the need to monitor the status of the application and based on the
responses take actions, here is where <strong>Epazote</strong> comes into action.</p>
<p>When doing Continuous Deployment
&ldquo;<a href="https://en.wikipedia.org/wiki/Continuous_delivery">CD</a>&rdquo; if the ping,
healthcheck, status, etc; endpoints change, it implies making changes in order
to properly monitor the application, this creates a dependency or extra task
apart from the &ldquo;CD&rdquo; process, therefore exists the need to detect any changes and
automatically apply them upon request, this can be done easily with <strong>Epazote</strong>.</p>
</description>
</item>
<item>
<title>How it works</title>
<link>https://epazote.io/post/how-it-works/</link>
<pubDate>Tue, 20 Sep 2016 04:00:00 +0000</pubDate>
<guid>https://epazote.io/post/how-it-works/</guid>
<description><p>In its basic way of operation, <strong>Epazote</strong> periodically checks the services endpoints
&ldquo;<a href="https://en.wikipedia.org/wiki/Uniform_Resource_Locator">URLs</a>&ldquo;
by doing an <a href="https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods">HTTP GET Request</a>,
based on the response <a href="https://en.wikipedia.org/wiki/List_of_HTTP_status_codes">Status code</a>,
<a href="https://en.wikipedia.org/wiki/List_of_HTTP_header_fields">Headers</a> or
either the
<a href="https://en.wikipedia.org/wiki/HTTP_message_body">body</a>, it executes a command.</p>
<p>In most scenarios, is desired to apply a command directly to the application in
cause, like a signal (<code>kill -HUP</code>), or either a restart, therefore in this
case <strong>Epazote</strong> and the application should be running on the same server.</p>
<p><strong>Epazote</strong> can also work in a standalone mode by only monitoring and sending
alerts if desired.</p>
<p><a href="https://asciinema.org/a/86545"><img src="https://asciinema.org/a/86545.png" alt="asciicast" /></a></p>
</description>
</item>
<item>
<title>How to use it</title>
<link>https://epazote.io/post/how-to-use-it/</link>
<pubDate>Tue, 20 Sep 2016 02:00:00 +0000</pubDate>
<guid>https://epazote.io/post/how-to-use-it/</guid>
<description>
<h1 id="how-to-use-it">How to use it</h1>
<p>First you need to install <strong>Epazote</strong>, either you can compile it from
<a href="https://github.com/epazote/epazote">source</a>
or download a pre-compiled binary matching your operating system from here:
<a href="https://bintray.com/nbari/epazote/epazote/_latestVersion">https://bintray.com/nbari/epazote/epazote/_latestVersion</a></p>
<p>To compile from source, after downloading the sources use <code>make</code> to build the
binary:</p>
<pre><code>~/projects/go/src/github.com/epazote/epazote
$ make
</code></pre>
<p><strong>Epazote</strong> was designed with simplicity in mind, as an easy tool for
<a href="https://en.wikipedia.org/wiki/DevOps">DevOps</a> and as a complement to
infrastructure orchestration tools like <a href="http://www.ansible.com/">Ansible</a> and
<a href="http://saltstack.com/">SaltStack</a>, because of this <a href="http://www.yaml.org/">YAML</a>
is used for the configuration files, avoiding with this, the learn of a new
language or syntax and simplifying the setup.</p>
<h2 id="basic-example">Basic example</h2>
<pre><code>services:
google:
url: https://www.google.com
seconds: 5
expect:
status: 302
ssl:
hours: 72
if_not:
cmd: echo -n &quot;google down&quot;
</code></pre>
<p>To supervise <code>google</code> you would run (basic.yml is a file containing the above code):</p>
<pre><code>$ epazote -f /path/to/yaml/file/basic.yml -d
</code></pre>
<blockquote>
<p>-d is for debugging, will print all output to standard output.</p>
</blockquote>
<p><a href="https://asciinema.org/a/86545"><img src="https://asciinema.org/a/86545.png" alt="asciicast" /></a></p>
<p>This example, will supervise every 5 seconds the service with name
<code>google</code>, it will do an HTTP GET to <code>http://www.google.com</code> and will expect
an <code>302 Status code</code> if not, it will <code>echo -n &quot;google down&quot;</code></p>
<p>The <code>ssl: hours: 72</code> means to send an alert if the certificate is about to
expire in the next 72 hours.</p>
<p>Extending the basic example for receiving notifications:</p>
<pre><code>config:
smtp:
username: [email protected]
password: password
server: mail.example.com
port: 587
headers:
from: [email protected]
subject: &quot;[_name_, _because_]&quot;
services:
google:
url: http://www.google.com
minutes: 3
threshold:
healthy: 2 # consecutive successes
unhealthy: 2 # consecutive failures
expect:
status: 200
if_not:
cmd: echo -n &quot;google down&quot;
notify: yes
</code></pre>
<p>In this case, every 3 minutes the service will be checked and in case of not
receiving a <code>200 Status code</code> more than 2 times:</p>
<pre><code>threshold:
unhealthy: 2
</code></pre>
<p>Besides executing the command: <code>echo -n &quot;google down&quot;</code> an email is going to be
send to <code>[email protected]</code>, this because of the <code>notify: yes</code> setting.</p>
<p>After getting 2 consecutive successful responses <code>200 status code</code>, an alert
is also sent.</p>
<h2 id="the-configuration-file">The configuration file</h2>
<p>The configuration file (<a href="https://en.wikipedia.org/wiki/YAML">YAML formated</a>)
consists of two parts, a <a href="https://epazote.io/post/the-config/">config</a> and a <a href="https://epazote.io/post/the-services">services</a> (Key-value pairs).</p>
</description>
</item>
<item>
<title>The config</title>
<link>https://epazote.io/post/the-config/</link>
<pubDate>Tue, 20 Sep 2016 02:00:00 +0000</pubDate>
<guid>https://epazote.io/post/the-config/</guid>
<description>
<h1 id="the-config-section">The config section</h1>
<p>The <strong>config</strong> section is composed of:</p>
<pre><code>- smtp (Email settings for sending notification)
- scan (Paths used to find the file 'epazote.yml')
</code></pre>
<p>Example:</p>
<pre><code>config:
smtp:
username: [email protected]
password: password
server: mail.example.com
port: 587
headers:
from: [email protected]
subject: &quot;[_name_, _because_]&quot;
scan:
paths:
- /arena/home/sites
- /home/apps
minutes: 5
</code></pre>
<h3 id="config-smtp">config - smtp</h3>
<p>Required to properly send alerts via email, all fields are required, the
<code>headers</code> section can be extended with any desired key-pair values.</p>
<h3 id="config-smtp-subject">config - smtp - subject</h3>
<p>The subject can be formed by using this keywords:</p>
<pre><code class="language-sh"> _because_ _exit_ _name_ _output_ _status_ _url_
</code></pre>
<p>on the previous example, <code>subject: [_name_, _status_]</code> would transform to
<code>[my service - 500]</code> the <code>name</code> has replaced by the service name, <code>my
service</code> and <code>status</code> by the response status code <code>500</code> in this case.</p>
<h3 id="config-scan">config - scan</h3>
<p>Paths to scan every N <code>seconds</code>, <code>minutes</code> or <code>hours</code>, a search for
services specified in a file call <code>epazote.yml</code> is made.</p>
<p>The <strong>scan</strong> setting is optional however is very useful when doing Continues
Deployments. for example if your code is automatically uploaded to the
directory <code>/arena/home/sites/application_1</code> and your scan paths contain
<code>/arena/home/sites</code>, you could simple upload on your application directory a
file named <code>epazote.yml</code> with the service rules, thus achieving the deployment
of your application and the supervising at the same time.</p>
<h3 id="config-optional">config (optional)</h3>
<p>As you may notice the <code>config</code> section contains mainly settings for sending
alerts/notifications apart from the <code>scan</code> setting, therefore is totally
optional, meaning that <strong>Epazote</strong> can still run and check your services without
the need of the <code>config</code> section.</p>
<p>If you want to automatically update/load services you will need the
<code>config - scan</code> setting.</p>
</description>
</item>
<item>
<title>The services</title>
<link>https://epazote.io/post/the-services/</link>
<pubDate>Tue, 20 Sep 2016 01:00:00 +0000</pubDate>
<guid>https://epazote.io/post/the-services/</guid>
<description>
<h1 id="the-services-section">The services section</h1>
<p>Services are the main functionality of <strong>Epazote</strong>, is where the URL&rsquo;s and the
rules based on the response are defined, since options vary from service to
service, an example could help better to understand the setup:</p>
<pre><code>services:
my service 1:
url: http://myservice.domain.tld/_healthcheck_
timeout: 5
seconds: 60
log: http://monitor.domain.tld
expect:
status: 200
header:
content-type: application/json
body: find this string on my site
if_not:
cmd: sv restart /services/my_service_1
notify: [email protected]
msg: |
line 1 bla bla
line 2
if_status:
500:
cmd: reboot
404:
cmd: sv restart /services/cache
msg: restarting cache
notify: [email protected] [email protected]
if_header:
x-amqp-kapputt:
cmd: restart abc
notify: [email protected]
msg: |
The rabbit is angry
&amp; hungry
x-db-kapputt:
cmd: svc restart /services/db
other service:
url: https://self-signed.ssl.tld/ping
header:
Origin: http://localhost
Accept-Encoding: gzip
insecure: true
ssl:
hours: 48
minutes: 3
redirect service:
url: http://test.domain.tld/
follow: yes
hour: 1
threshold:
unhealthy: 1
expect:
status: 302
if_not:
cmd: service restart abc
notify: yes
emoji: 1F600-1F621
salt-master:
test: pgrep -f salt
if_not:
cmd: service restart salt_master
notify: [email protected]
</code></pre>
<h3 id="services-name-of-service-string">services - name of service (string)</h3>
<p>An unique string that identifies your service, in the above example, there are 3
services named:
- my service 1
- other service
- redirect service</p>
<h3 id="services-url-string">services - url (string)</h3>
<p>URL of the service to supervise</p>
<h3 id="services-follow-boolean-true-false">services - follow (boolean true/false)</h3>
<p>By default if a <a href="https://en.wikipedia.org/wiki/HTTP_302">302 Status code</a> is
received, <strong>Epazote</strong> will not follow it, if you would like to follow all
redirects, this setting must be set to <strong>true</strong>.</p>
<h3 id="services-insecure-boolean-true-false">services - insecure (boolean true/false)</h3>
<p>This option explicitly allows <strong>Epazote</strong> to perform &ldquo;insecure&rdquo; SSL connections.
It will disable the certificate verification.</p>
<h3 id="services-ssl-seconds-minutes-hours">services - ssl (seconds, minutes, hours)</h3>
<p>Alert before the certificate expires:</p>
<pre><code>ssl:
hours: 24
</code></pre>
<h3 id="services-stop-int">services - stop (int)</h3>
<p>Defines the number or times the <code>cmd</code> will be executed, by default the <code>cmd</code>
is executed only once, with the intention to avoid indefinitely loops. If value
is set to <code>-1</code> the <code>cmd</code> never stops. defaults to 0, <code>stop 2</code> will execute
&ldquo;0, 1, 2&rdquo; (3 times) the <code>cmd</code>.</p>
<h3 id="services-timeout-in-seconds-int">services - timeout in seconds (int)</h3>
<p>Timeout specifies a time limit for the HTTP requests, A value of zero means no
timeout, defaults to 5 seconds.</p>
<h3 id="services-retry-limit-int">services - retry_limit (int)</h3>
<p>Specifies the number of times to retry an request, defaults to 3.</p>
<h3 id="services-retry-interval-int">services - retry_interval (int)</h3>
<p>Specifies the time between attempts in milliseconds. The default value is 500 (0.5 seconds).</p>
<h3 id="services-read-limit-int">services - read_limit (int)</h3>
<p>Read only <code>N</code> number of bytes instead of the full
body. This helps to make a more &ldquo;complete&rdquo; request and
avoid getting an HTTP status code <a href="http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/ts-el b-error-message.html#ts-elb-errorcodes-http408">408 when testing aws ELB</a>.</p>
<h3 id="services-threshold-healthy-unhealthy">services - threshold (healthy/unhealthy)</h3>
<p>Alert after the threshold has been reached, by default is set to 0 (disabled):</p>
<pre><code>threshold:
healthy: 2
unhealth: 2
</code></pre>
<p>If set to 0 it will be disabled.</p>
<h3 id="services-seconds-minutes-hours">services - seconds, minutes, hours</h3>
<p>How often to check the service, the options are: (Only one should be used)</p>
<ul>
<li>seconds N</li>
<li>minutes N</li>
<li>hours N</li>
</ul>
<p><code>N</code> should be an integer, defaults to 60 seconds.</p>
<h3 id="services-log-url">services - log (URL)</h3>
<p>An URL to post all events, default disabled.</p>
<h3 id="services-expect">services - expect</h3>
<p>The <code>expect</code> block options are:
- status (int)
- header (key, value)
- body (regular expression)
- if_not (Action block)</p>
<h3 id="services-expect-status">services - expect - status</h3>
<p>An Integer representing the expected <a href="https://en.wikipedia.org/wiki/List_of_HTTP_status_codes">HTTP Status Code</a></p>
<h3 id="services-expect-header-start-with-match">services - expect - header (start_with match)</h3>
<p>A key-value map of expected headers, it can be only one or more.</p>
<p>The headers will be considered valid if they starts with the required value,
for example if you want to check for <code>Content-type: application/json; charset=utf-8</code>
you can simple do something like:</p>
<pre><code>header:
Content-Type: application/json
</code></pre>
<p>This helps to simplify the matching and useful in cases where the headers
changes, for example: <code>Content-Range: bytes 100-64656926/64656927</code> can be
matched with:</p>
<pre><code>header:
Content-Range: bytes
</code></pre>
<h3 id="services-expect-body">services - expect - body</h3>
<p>A <a href="https://en.wikipedia.org/wiki/Regular_expression">regular expression</a> used
to match a string on the body of the site, use full in cases you want to ensure
that the content delivered is always the same or keeps a pattern.</p>
<h3 id="services-expect-how-it-works">services - expect (How it works)</h3>
<p>The <code>expect</code> logic tries to implement a
<a href="https://en.wikipedia.org/wiki/if_else">if-else</a> logic <code>status</code>, <code>header</code>,
<code>body</code> are the <strong>if</strong> and the <code>if_not</code> block becomes the <strong>else</strong>.</p>
<pre><code>if
status
header
body
else:
if_not
</code></pre>
<p>In must cases only one option is required, check on the above example for the service named &ldquo;redirect service&rdquo;.</p>
<p>In case that more than one option is used, this is the order in how they are evaluated, no meter how they where introduced on the configuration file:</p>
<pre><code>1. body
2. status
3. header
</code></pre>
<p>The reason for this order is related to performance, at the end we want to
monitor/supervise the services in an efficient way avoiding to waste extra
resources, in must cases only the HTTP Headers are enough to take an action,
therefore we don&rsquo;t need to read the full body page, because of this if no
<code>body</code> is defined, <strong>Epazote</strong> will only read the Headers saving with this
time and process time.</p>
<h3 id="services-expect-if-not">services - expect - if_not</h3>
<p><code>if_not</code> is a block with an action of what to do it we don&rsquo;t get what we where
expecting (<code>expect</code>). See services - Actions</p>
<h3 id="services-if-status-if-header">services - if_status &amp; if_header</h3>
<p>There maybe cases in where third-party dependencies are down and because of this
your application could not be working properly, for this cases the <code>if_status</code>
and <code>if_header</code> could be useful.</p>
<p>For example if the database is your application could start responding an status
code 500 or either a custom header and based on does values take execute an
action:</p>
<p>The format for <code>if_status</code> is a key-pair where key is an int representing an
HTTP status code, and the value an Action option</p>
<p>The format for <code>if_header</code> is a key-pair where key is a string of something
you could relate/match and has in other if_X conditions, value is an Action.</p>
<p>This are the only <code>if's</code> and the order of execution:
1. if_status
2. if_header
3. if_not</p>
<p>This means that if a service uses <code>if_status</code> and <code>if_not</code>, it will
evaluate first the <code>if_status</code> and execute an Action if required, in case
an <code>if_status</code> and <code>if_header</code> are set, same applies, first is evaluated
<code>if_status</code>, then <code>if_header</code> and last <code>if_not</code>.</p>
<h2 id="services-actions">services - Actions</h2>
<p>An Action has five options:
- cmd
- notify
- msg
- emoji
- http</p>
<p>They can be used all together, only one or either none.</p>
<h3 id="services-actions-cmd-string">services - Actions - cmd (string)</h3>
<p><code>cmd</code> Contains the command to be executed.</p>
<h3 id="services-actions-notify-string">services - Actions - notify (string)</h3>
<p><code>notify</code> Should contain <code>yes</code>, the email email address or addresses (space separated)
of the recipients that will be notified when the action is executed.</p>
<p>If the string is <code>yes</code> the global recipients will be used.</p>
<h3 id="services-actions-msg-list">services - Actions - msg (list)</h3>
<pre><code>msg:
- send this if exit 0 (all OK)
- send this if exit 1 (something is wrong)
</code></pre>
<p>Based on the exit status either msg[0] or msg[1] is used,</p>
<h3 id="services-actions-emoji-list">services - Actions - emoji (list)</h3>
<p><code>emoji</code> <a href="https://en.wikipedia.org/wiki/Unicode">Unicode</a> characters
to be used in the subject, example:</p>
<pre><code>emoji:
- 1F600
- 1F621
</code></pre>
<p>If services are OK they will use the first <code>1F600</code> if not they will
use <code>1F621</code>, if set to <code>0</code> no emoji will be used. The idea behind using
<a href="https://en.wikipedia.org/wiki/Emoticons_(Unicode_block)">unicode/emoji</a>
is to cough attention faster and not just ignore the email thinking is spam.</p>
<h3 id="service-actions-http-list-key-value">service - Actions - http (list(key, value))</h3>
<p>A custom URL to GET/POST depending on the exit status, example:</p>
<pre><code>http:
- url: &quot;https://api.hipchat.com/v1/rooms/message?auth_token=your_token&amp;room_id=7&amp;from=Alerts&amp;message=service+OK+_name_+_because_&quot;
- url: &quot;https://api.hipchat.com/&quot;
header:
Content-Type: application/x-www-form-urlencoded
data: |
room_id=10&amp;from=Alerts&amp;message=_name_+exit+code+_exit_
method: POST
</code></pre>
<p>When a service fails or returns an exit 1 the second url
<code>https://api.hipchat.com/</code> with method <code>POST</code> and the custom <code>data</code>
will be used, notice that all the ocurances on the data that are within an
<code>_(key)_</code> will be replaced with the corresponding value, in this case:</p>
<pre><code> room_id=10&amp;from=Alerts&amp;message=_name_+exit+code+_exit_
</code></pre>
<p>will be replaced with:</p>
<pre><code> room_id=10&amp;from=Alerts&amp;message=SERVICE NAME+exit+code+0
</code></pre>
<p>When recovery the first url will be used, in this case will be a GET instead of a post, so:</p>
<pre><code>https://api.hipchat.com/v1/rooms/message?auth_token=your_token&amp;room_id=7&amp;from=Alerts&amp;message=service+OK+_name_+_because_
</code></pre>
<p>becomes:</p>
<pre><code>https://api.hipchat.com/v1/rooms/message?auth_token=your_token&amp;room_id=7&amp;from=Alerts&amp;message=service+OK+SERVICE+NAME+STATUS+200
</code></pre>
<blockquote>
<p>notice that the <em>name</em>, <em>exit</em>, <em>because</em> are been replaced with the values of name, exit, because of the service.</p>
</blockquote>
<h2 id="services-test">services - Test</h2>
<p><strong>Epazote</strong> It is mainly used for HTTP services, for supervising other
applications that don&rsquo;t listen or accept HTTP connections, like a database,
cache engine, etc. There are tools like
<a href="https://cr.yp.to/daemontools.html">daemontools</a>,
<a href="https://immortal.run">immortal</a> as already mentioned, even so, <strong>Epazote</strong>
can eventually be used to execute an action based on the exit of a command
for example:</p>
<pre><code>salt-master:
test: pgrep -f salt
if_not:
cmd: service restart salt_master
notify: [email protected]
</code></pre>
<p>In this case: <code>test: pgrep -f salt</code> will execute the <code>cmd</code> on the <code>if_not</code>
block in case the exit code is &gt; 0, from the <code>pgrep</code> man page:</p>
<pre><code>EXIT STATUS
The pgrep and pkill utilities return one of the following values upon exit:
0 One or more processes were matched.
1 No processes were matched.
2 Invalid options were specified on the command line.
3 An internal error occurred.
</code></pre>
<h2 id="extra-setup">Extra setup</h2>
<p><em>green dots give some comfort</em> &ndash; Because of this when using the <code>log</code>
option an extra service could be configure as a receiver for all the post
that <strong>Epazote</strong> produce and based on the data obtained create a custom
dashboard, something similar to: <a href="https://status.cloud.google.com/">https://status.cloud.google.com/</a> or
<a href="http://status.aws.amazon.com/">http://status.aws.amazon.com/</a></p>
</description>
</item>
</channel>
</rss>