22

I would like to change the name of the ruby process that gets displayed in the linux/unix top command. I have tried the

$0='miname'

approach but it only works with the ps command and in top the process keeps getting displayed as "ruby"

animuson
  • 53,861
  • 28
  • 137
  • 147
muesan
  • 373
  • 3
  • 8

7 Answers7

17

Dave Thomas had an interesting post on doing this in rails. There's nothing rails specific about the actual process name change code. He uses the $0='name' approach. When I followed his steps the name was changed in ps and top.

In the post he suggests using the c keyboard command if your version of top doesn't show the short version of the command by default.

Gordon Wilson
  • 26,244
  • 11
  • 57
  • 60
  • 1
    I have tried the c keyboard command and it works with Linux machines. The top command from Mac OS X doesn't seem to have an equivalent option. – muesan Jan 17 '09 at 11:46
  • 1
    Link is dead :( Could you maybe show the some code? – Automatico Jun 19 '14 at 09:10
  • 2
    web.archive.org saving lifes: https://web.archive.org/web/20130415202502/http://pragdave.blogs.pragprog.com/pragdave/2008/11/trivial-request-logging-for-rails.html – armoucar Dec 15 '15 at 11:31
  • And that is why you don't just give a link :) – Yasen Mar 29 '17 at 12:28
10

Ruby 2.1 introduced a Process.setproctitle method for this purpose:

Process.setproctitle("My new title")
dubek
  • 11,447
  • 5
  • 30
  • 23
  • I'm using ruby 2.2 on OSX, and `Process.setproctitle` does change what I see in `ps -ef`, whereas `$0 = "something"` (or `$PROGRAM_NAME = "something"`) does not. – Nathan Long Jan 15 '16 at 12:55
  • 1
    I'm using linux, this answer the same as `$0="My new title", it just change ps output, can not work with pgrep or pkill. – zw963 Mar 15 '16 at 16:06
9

I don't think Ruby has the facility builtin (setproctitle(3)). You should probably try to look at ruby-ffi and create the interface to setproctitle(3).

EDIT: I know you have your answer but I want to show you some code to use ffi:

require "ffi"
#
module LibC
  extend FFI::Library

  attach_function :setproctitle, [:string, :varargs], :void
end

LibC.setproctitle("Ruby: executing %s", :string, $0)

Does not work on OS X because setproctitle(3) does not exist, works on FreeBSD.

Keltia
  • 14,535
  • 3
  • 29
  • 30
  • 1
    While this is a nice example of FFI, the function you use is not portable at all. Seems to be freebsd only, and probably other flavors of bsd. No linux (glibc), no OS X, no windows. – dequis Apr 05 '13 at 11:26
2

I know Keltia already posted something very similar, but Linux doesn't have setproctitle(3). Linux has had this functionality in prctl() since version 2.6.9. I used Fiddle/DL since they are included by default with Ruby.

require("fiddle")

def set_process_name_linux(name)
    Fiddle::Function.new(
        Fiddle::Handle["prctl".freeze], [
            Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP,
            Fiddle::TYPE_LONG, Fiddle::TYPE_LONG,
            Fiddle::TYPE_LONG
        ], Fiddle::TYPE_INT
    ).call(15, name, 0, 0, 0)
end

def set_process_name_unknown(name)
    warn("No implementation for this OS.".freeze)
end

def set_process_name(name)
    case RUBY_PLATFORM.split("-".freeze)[1]
    when "linux".freeze
        set_process_name_linux(name)
    else
        set_process_name_unknown(name)
    end
end
Jessehz
  • 5,178
  • 2
  • 15
  • 13
  • 1
    On Ruby 2.2.3, DL is deprecated, one line code need be changed. DL::Handle need change to Fiddle::Handle to work. this answer can work perfect on linux, it does not change ps output, but can work with pgrep. – zw963 Mar 15 '16 at 16:01
2

The $0 = 'Foo' method works -- but many versions of top will require you to toggle command-line mode on with 'c'. We this very method here with rails and CentOS. Works a treat

mikey
  • 216
  • 2
  • 7
2

I had a similar problem, updated the technique from the Dave Thomas post a little by putting it in a rack middleware, rather than the before/after pattern.

Put this in lib/rack/set_process_title.rb:

# Set the process title to the URI being processed 
#- useful for debugging slow requests or those that get stuck
class Rack::SetProcessTitle
  def initialize(app)
    @app = app
  end
  def call(env)
    $0 = env['REQUEST_URI'][0..80]

    @status, @headers, @response = @app.call(env)

    $0 = env['REQUEST_URI'][0..80] + '*'

    [@status, @headers, @response]
  end
end

... and this goes at the end of config/environment.rb:

Rails.configuration.middleware.insert_after Rack::Lock, Rack::SetProcessTitle

More words in the blog post: http://blog.actbluetech.com/2011/06/set-your-process-name-in-top-and-ps.html

cluesque
  • 1,100
  • 11
  • 17
0

From @jessehz answer, following code work perfect on my linux X86_64. Ruby 1.9.3, 2.0, 2.1, 2.2, 2.3 is tested.

  1. It will change the output in ps top command.
  2. It can be kill or signal with pkill, pgrep, killall.

Perfect!

def set_process_name_linux(name)
  handle = defined?(DL::Handle) ? DL::Handle : Fiddle::Handle

  Fiddle::Function.new(
    handle['prctl'.freeze], [
      Fiddle::TYPE_INT, Fiddle::TYPE_VOIDP,
      Fiddle::TYPE_LONG, Fiddle::TYPE_LONG,
      Fiddle::TYPE_LONG
    ], Fiddle::TYPE_INT
  ).call(15, name, 0, 0, 0)
  $PROGRAM_NAME = name
end
set_process_name_linux('dummy')
zw963
  • 1,157
  • 15
  • 11