Here’s a quick and easy way to tail log files from multiple hosts using Capistrano and the Foreman gem.
Capistrano Task
First you’ll need to make sure the foreman
gem is installed. This can be done globally using gem install foreman
, or by adding gem 'foreman'
to your Gemfile
.
Next, create a new Capistrano task file called tail.rake
and place it in the lib/capistrano/tasks
directory; Copy & paste the following code into that file.
require 'tempfile' namespace :tail do # == Tasks == desc "Tail syslogs from all hosts" task :syslog do foremanize! do |foreman| on roles(:all) do |server| name = capture("hostname").chomp.gsub(/[^0-9a-z\-]/, "_") command = ssh_cmd(server, "sudo tail -f /var/log/syslog") foreman[name] = command end end end # == Helpers == def ssh_cmd(server, command) "ssh %{user}@%{host} -o StrictHostKeyChecking=no %{command}" % { :user => server.user, :host => server.netssh_options[:host_name], :command => command } end def foremanize! tasks = {} yield(tasks) file = Tempfile.new("pf") tasks.each {|name, command| file.write("#{name}: #{command} \n") } file.close exec "foreman start --procfile=#{file.path}" end end
Command & Result
cap production tail:syslog 21:34:23 production_web_000.1 | started with pid 27053 21:34:23 production_worker_000.1 | started with pid 27054 21:34:23 production_web_001.1 | started with pid 27055 21:34:23 production_worker_000.1 | Aug 11 21:33:29 supervisord: ... 21:34:23 production_worker_000.1 | Aug 11 21:34:01 CRON[17904]: ... 21:35:02 production_web_001.1 | Aug 11 21:35:01 CRON[21946]: ... 21:35:02 production_web_000.1 | Aug 11 21:35:01 CRON[20170]: ... 21:35:03 production_web_001.1 | Aug 11 21:35:02 WEB[19793]: ...
Press CTRL+C when you’re done tailing the logs.
Environment
This post was written for, and tested under, the following technologies…
- Ruby (>= 1.9)
- Capistrano (3)
- Foreman (0.84.0)
- Ubuntu (>= 12.04) – OS of Remote Hosts
Summary
I’ve been using this technique since 2015 and it has made debugging issues occurring across multiple hosts a breeze. If you would like to tail other types of logs just duplicate the :syslog
task and change the name and log file path.