Skip to content

Commit

Permalink
[Heartbeat] Make run_once syntax a boolean (elastic#28548)
Browse files Browse the repository at this point in the history
* [Heartbeat] Make run_once syntax a boolean

Fixes elastic#28437. This is an improvement over
elastic#25972 which had a more complicated
config interface.

* Fix python tests

* Fix python
  • Loading branch information
andrewvc authored and wiwen committed Nov 1, 2021
1 parent a417aa4 commit ac5c7fe
Show file tree
Hide file tree
Showing 8 changed files with 22 additions and 113 deletions.
13 changes: 2 additions & 11 deletions heartbeat/_meta/config/beat.yml.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,8 @@ heartbeat.monitors:
# Name of corresponding APM service, if Elastic APM is in use for the monitored service.
#service.name: my-apm-service-name

# Experimental: Configure monitors that run exactly once.
# If enabled, heartbeat.monitors will be ignored
# Heartbeat will run these monitors once then exit.
#heartbeat.run_once:
#- type: http
#id: my-monitor
#name: My Monitor
#urls: ["http://localhost:9200"]
# NOTE: you must still provide the schedule field! Heartbeat
# Uses this to determine the contents of the monitor.timespan field
#schedule: '@every 10s'
# Experimental: Set this to true to run heartbeat monitors exactly once at startup
#heartbeat.run_once: true

{{header "Elasticsearch template setting"}}

Expand Down
5 changes: 2 additions & 3 deletions heartbeat/beater/heartbeat.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func (bt *Heartbeat) Run(b *beat.Beat) error {
groups, _ := syscall.Getgroups()
logp.Info("Effective user/group ids: %d/%d, with groups: %v", syscall.Geteuid(), syscall.Getegid(), groups)

if bt.config.RunOnce != nil {
if bt.config.RunOnce {
err := bt.runRunOnce(b)
if err != nil {
return err
Expand Down Expand Up @@ -141,7 +141,6 @@ func (bt *Heartbeat) Run(b *beat.Beat) error {
// runRunOnce runs the given config then exits immediately after any queued events have been sent to ES
func (bt *Heartbeat) runRunOnce(b *beat.Beat) error {
logp.Info("Starting run_once run. This is an experimental feature and may be changed or removed in the future!")
cfgs := bt.config.RunOnce

publishClient, err := core.NewSyncClient(logp.NewLogger("run_once mode"), b.Publisher, beat.ClientConfig{})
if err != nil {
Expand All @@ -150,7 +149,7 @@ func (bt *Heartbeat) runRunOnce(b *beat.Beat) error {
defer publishClient.Close()

wg := &sync.WaitGroup{}
for _, cfg := range cfgs {
for _, cfg := range bt.config.Monitors {
err := runRunOnceSingleConfig(cfg, publishClient, wg)
if err != nil {
logp.Warn("error running run_once config: %s", err)
Expand Down
2 changes: 1 addition & 1 deletion heartbeat/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import (

// Config defines the structure of heartbeat.yml.
type Config struct {
RunOnce []*common.Config `config:"run_once"`
RunOnce bool `config:"run_once"`
Monitors []*common.Config `config:"monitors"`
ConfigMonitors *common.Config `config:"config.monitors"`
Scheduler Scheduler `config:"scheduler"`
Expand Down
33 changes: 9 additions & 24 deletions heartbeat/docs/heartbeat-options.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -114,32 +114,17 @@ include::monitors/monitor-browser.asciidoc[]
[[run-once-mode]]
=== Run Once Mode (Experimental)

You can configure {beatname_uc} run monitors exactly once then exit, bypassing the scheduler. This is referred to as running {beatname_uc} in "run once" mode. This is an experimental feature
and is subject to change.
You can configure {beatname_uc} run monitors exactly once then exit, bypassing the scheduler. This is referred to as running {beatname_uc} in
"run once" mode by setting `heartbeat.run_once: true`. All {beatname_uc} monitors will ignore their schedules and run exactly once at startup.
This is an experimental feature and is subject to change.

Note, the `schedule` field is still required and is used by {beatname_uc} to set the expectation around when
the next run will occur. That duration is encoded in the `monitor.timespan` field in the {beatname_uc} output.

[source,yaml]
----------------------------------------------------------------------
# heartbeat.yml
heartbeat.run_once:
- type: icmp
id: ping-myhost
name: My Host Ping
hosts: ["myhost"]
# Note that schedule is still needed to inform heartbeat when the next
# expected check is to be run. This is needed to populate the monitor.timespan field used by the Uptime app.
schedule: '@every 5s'
- type: tcp
id: myhost-tcp-echo
name: My Host TCP Echo
hosts: ["myhost:777"] # default TCP Echo Protocol
check.send: "Check"
check.receive: "Check"
schedule: '@every 5s'
- type: http
id: service-status
name: Service Status
service.name: my-apm-service-name
hosts: ["http://localhost:80/service/status"]
check.response.status: [200]
schedule: '@every 5s'
heartbeat.run_once: true
heartbeat.monitors:
# your monitor config here...
----------------------------------------------------------------------
13 changes: 2 additions & 11 deletions heartbeat/heartbeat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,8 @@ heartbeat.monitors:
# Name of corresponding APM service, if Elastic APM is in use for the monitored service.
#service.name: my-apm-service-name

# Experimental: Configure monitors that run exactly once.
# If enabled, heartbeat.monitors will be ignored
# Heartbeat will run these monitors once then exit.
#heartbeat.run_once:
#- type: http
#id: my-monitor
#name: My Monitor
#urls: ["http://localhost:9200"]
# NOTE: you must still provide the schedule field! Heartbeat
# Uses this to determine the contents of the monitor.timespan field
#schedule: '@every 10s'
# Experimental: Set this to true to run heartbeat monitors exactly once at startup
#heartbeat.run_once: true

# ======================= Elasticsearch template setting =======================

Expand Down
53 changes: 2 additions & 51 deletions heartbeat/tests/system/config/heartbeat.yml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -51,57 +51,8 @@ heartbeat.monitors:
{% endfor -%}

{%- if run_once is defined %}
heartbeat.run_once:
{% for monitor in run_once -%}
- type: {{ monitor.type }}
schedule: '{{ monitor.schedule|default("@every 1s") }}'
{%- if monitor.timeout is defined %}
timeout: {{monitor.timeout}}
{% endif -%}

{%- if monitor.enabled is defined %}
enabled: {{monitor.enabled}}
{% endif -%}

{%- if monitor.tags is defined %}
tags:
{% for tag in monitor.tags -%}
- '{{ tag }}'
{% endfor %}
{% endif -%}

{%- if monitor.hosts is defined %}
hosts:
{%- for host in monitor.hosts %}
- '{{ host }}'
{% endfor -%}
{% endif -%}

{%- if monitor.urls is defined %}
urls:
{%- for url in monitor.urls %}
- '{{ url }}'
{% endfor %}
{% endif -%}


{%- if monitor.check_response_json is defined %}
check.response.json:
{%- for check in monitor.check_response_json %}
- {{check}}
{% endfor %}
{% endif -%}

{%- if monitor.fields is defined %}
{% if monitor.fields_under_root %}fields_under_root: true{% endif %}
fields:
{% for k, v in monitor.fields.items() -%}
{{ k }}: {{ v }}
{% endfor %}
{% endif %}
{% endfor -%}
{% endif %}

heartbeat.run_once: {{run_once}}
{% endif -%}

{% if reload or reload_path -%}
heartbeat.config.monitors:
Expand Down
3 changes: 2 additions & 1 deletion heartbeat/tests/system/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ def test_run_once(self):
"""

config = {
"run_once": [
"run_once": True,
"monitors": [
{
"type": "http",
"id": "http-check",
Expand Down
13 changes: 2 additions & 11 deletions x-pack/heartbeat/heartbeat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,8 @@ heartbeat.monitors:
# Name of corresponding APM service, if Elastic APM is in use for the monitored service.
#service.name: my-apm-service-name

# Experimental: Configure monitors that run exactly once.
# If enabled, heartbeat.monitors will be ignored
# Heartbeat will run these monitors once then exit.
#heartbeat.run_once:
#- type: http
#id: my-monitor
#name: My Monitor
#urls: ["http://localhost:9200"]
# NOTE: you must still provide the schedule field! Heartbeat
# Uses this to determine the contents of the monitor.timespan field
#schedule: '@every 10s'
# Experimental: Set this to true to run heartbeat monitors exactly once at startup
#heartbeat.run_once: true

# ======================= Elasticsearch template setting =======================

Expand Down

0 comments on commit ac5c7fe

Please sign in to comment.