Change the ruby process name in top

2019-04-03 06:30发布

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"

7条回答
Luminary・发光体
2楼-- · 2019-04-03 07:05

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

Process.setproctitle("My new title")
查看更多
在下西门庆
3楼-- · 2019-04-03 07:10

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

查看更多
Luminary・发光体
4楼-- · 2019-04-03 07:11

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.

查看更多
我想做一个坏孩纸
5楼-- · 2019-04-03 07:23

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
查看更多
Lonely孤独者°
6楼-- · 2019-04-03 07:24

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.

查看更多
在下西门庆
7楼-- · 2019-04-03 07:26

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

查看更多
登录 后发表回答