Измените имя процесса ruby ​​сверху - PullRequest
22 голосов
/ 16 января 2009

Я хотел бы изменить имя процесса ruby, отображаемого в верхней команде linux / unix. Я попробовал

$0='miname'

подход, но он работает только с командой ps, и в верхней части процесс отображается как "ruby"

Ответы [ 7 ]

17 голосов
/ 16 января 2009

У Дейва Томаса был интересный пост о том, как делать это в рельсах. Нет ничего особенного в фактическом коде изменения имени процесса. Он использует $0='name' подход. Когда я следовал его шагам, имя было изменено на ps и top.

В посте он предлагает использовать команду клавиатуры c, если ваша версия top не отображает сокращенную версию команды по умолчанию.

10 голосов
/ 12 марта 2015

Ruby 2.1 введен a Process.setproctitle метод для этой цели:

Process.setproctitle("My new title")
9 голосов
/ 16 января 2009

Я не думаю, что в Ruby есть встроенные средства (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.

2 голосов
/ 10 мая 2012

Я знаю, что 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
2 голосов
/ 09 июня 2011

У меня была похожая проблема, я немного обновил технику из поста Дэйва Томаса, поместив ее в промежуточное ПО стойки, а не в шаблон до / после.

Поместите это в 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

2 голосов
/ 22 мая 2010

Метод $ 0 = 'Foo' работает, но во многих версиях top вам потребуется включить режим командной строки с помощью 'c'. У нас этот самый метод здесь с рельсами и CentOS. Работает угощение

0 голосов
/ 15 марта 2016

Из ответа @jessehz, следующий код прекрасно работает на моем linux X86_64. Ruby 1.9.3, 2.0, 2.1, 2.2, 2.3 протестирован.

  1. Это изменит вывод в команде ps top.
  2. Это может быть 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')
...