Измените имя процесса ruby сверху
Я хотел бы изменить имя процесса ruby, который отображается в верхней команде linux/unix. Я попробовал
$0='miname'
подход, но он работает только с командой ps, и в верхней части процесс отображается как "ruby"
7 ответов
У Дейва Томаса был интересный пост о том, как делать это на рельсах. Нет ничего особенного в фактическом коде изменения имени процесса. Он использует $0='name'
подход. Когда я следовал его шагам, имя было изменено в ps
а также top
,
В посте он предлагает использовать c
команда клавиатуры, если ваша версия top по умолчанию не отображает короткую версию команды.
Ruby 2.1 представил Process.setproctitle
Метод для этого:
Process.setproctitle("My new title")
Я не думаю, что в Руби есть встроенный объект (setproctitle(3)
). Вы, вероятно, должны попытаться взглянуть на ruby-ffi и создать интерфейс для setproctitle(3)
,
РЕДАКТИРОВАТЬ: Я знаю, что у вас есть ответ, но я хочу показать вам код для использования ffi:
require "ffi"
#
module LibC
extend FFI::Library
attach_function :setproctitle, [:string, :varargs], :void
end
LibC.setproctitle("Ruby: executing %s", :string, $0)
Не работает на OS X, потому что setproctitle(3)
не существует, работает на FreeBSD.
Я знаю, что Keltia уже опубликовала нечто очень похожее, но в Linux нет setproctitle(3). Linux имеет эту функцию в prctl() начиная с версии 2.6.9. Я использовал Fiddle/DL, так как они включены по умолчанию в 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
У меня была похожая проблема, я немного обновил технику из поста Дэйва Томаса, поместив ее в промежуточное ПО стойки, а не в шаблон до / после.
Поместите это в 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
... и это идет в конце config/environment.rb:
Rails.configuration.middleware.insert_after Rack::Lock, Rack::SetProcessTitle
Больше слов в посте блога: http://blog.actbluetech.com/2011/06/set-your-process-name-in-top-and-ps.html
Метод $0 = 'Foo' работает, но во многих версиях top вам потребуется включить режим командной строки с помощью 'c'. У нас этот самый метод здесь с рельсами и CentOS. Работает лакомство
Из ответа @jessehz, следующий код прекрасно работает на моем Linux X86_64. Ruby 1.9.3, 2.0, 2.1, 2.2, 2.3 протестирован.
- Это изменит вывод в команде ps top.
- Это может быть kill или сигнал с помощью pkill, pgrep, killall.
Отлично!
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')