Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add serf reporter by https://github.com/patrickviet #82

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,23 @@ If you set your `reporter_type` to `"etcd"` you should also set these parameters
* `etcd_port`: port to connect to etcd.
* `etcd_path`: the path where the registration will be created; nerve will create a node with a 30s ttl that is the registration as a child of this path, and then update it every few seconds

#### Serf Reporter ####

You can use Nerve together with [Serf](https://www.serf.io/), which requires:

* a Serf agent running on the same machine as Nerve
* Setting your `reporter_type` to `"serf"`
* `serf_config_dir`: a directory to place files in that is readable/writable by both Serf and Nerve.
* Nerve will place configuration files named `zzz_nerve_<some-service>_<port>.json` under the directory specified with `serf_config_dir`.
* Serf will read these configurations and must be configured to run with `-config-dir=<serf_config_dir>`
* Please note that it is up to you (through e.g. configuration management code) to ensure no invalid configuration files are left under `serf_config_dir` by wiping all `zzz_nerve*` files when renaming/removing services. (each nerve reporter creates/deletes files for services named `<service-name>`, but renaming `<service-name>` to `<service-name2>` on an existing machine could lead to stale configuration files remaining under `serf_config_dir`).
* Nerve must have permissions to reload the serf process. (can be specified by the `serf_reload_command` parameter - defaults to `/usr/bin/killall -HUP serf`)
* (You can for example install Serf and Nerve to run under the same user)

Configuration management code and example Vagrant setup to use Serf together with Nerve/Synapse can be found here:

* Ansible: https://github.com/AutomationWithAnsible/ansible-smartstack

### Checks ###

The core of nerve is a set of service checks.
Expand Down
16 changes: 16 additions & 0 deletions example/nerve_services/serf_service1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"host": "1.2.3.4",
"port": 3000,
"reporter_type": "serf",
"check_interval": 2,
"weight": 2,
"checks": [
{
"type": "http",
"uri": "/health",
"timeout": 0.2,
"rise": 3,
"fall": 2
}
]
}
51 changes: 51 additions & 0 deletions lib/nerve/reporter/serf.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
require 'nerve/reporter/base'

class Nerve::Reporter
class Serf < Base
def initialize(service)

# Set default parameters - the defaults are sane so nothing needed.
@config_dir = service['serf_config_dir'] || '/etc/serf'
@reload_command = service['serf_reload_command'] || '/usr/bin/killall -HUP serf'
@name = service['name']
# please note that because of
# https://github.com/airbnb/smartstack-cookbook/blob/master/recipes/nerve.rb#L71
# the name won't just be the name you gave but name_port. this allows a same
# service to be on multiple ports of a same machine.

@data = parse_data(get_service_data(service))
@config_file = File.join(@config_dir,"zzz_nerve_#{@name}.json")
File.unlink @config_file if File.exists? @config_file
end

def start()
log.info "nerve: started to maintain the tag #{@name} with Serf"
end

def report_up()
update_data(false)
end

def report_down
File.unlink(@config_file)
reload_serf
end

def update_data(new_data='')
@data = new_data if new_data
data = JSON.parse(@data)
tag = "#{data['host']}:#{data['port']}"
File.write(@config_file, JSON.generate({tags:{"smart:#{@name}" =>tag}}))
reload_serf
end

def reload_serf()
system(@reload_command)
end

def ping?
# for now return true.
return true
end
end
end
2 changes: 1 addition & 1 deletion spec/configuration_manager_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
expect(config_manager.config.keys()).to include('instance_id', 'services')
expect(config_manager.config['services'].keys()).to contain_exactly(
'your_http_service', 'your_tcp_service', 'rabbitmq_service',
'etcd_service1', 'zookeeper_service1'
'etcd_service1', 'serf_service1', 'zookeeper_service1'
)
end
end
Expand Down