问题
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"
回答1:
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.
回答2:
Ruby 2.1 introduced a Process.setproctitle method for this purpose:
Process.setproctitle("My new title")
回答3:
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.
回答4:
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
回答5:
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
回答6:
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
回答7:
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.
- It will change the output in ps top command.
- 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')
来源:https://stackoverflow.com/questions/450620/change-the-ruby-process-name-in-top