ruby - 线程安全 : Capturing the output of $stdout

标签 ruby multithreading debugging thread-safety sidekiq

我想知道如何在 ruby​​ 的线程环境中捕获 $stdout 的输出。

一些细节。我将捕获用于日志记录目的,并且我有 sidekiq 在后台处理作业,因此线程。我编码:

@previous_stdout, $stdout = $stdout, StringIO.new
self.stdout = $stdout.string

它抛出我(对于某些线程):

WARN: undefined method `string' for #<IO:<STDOUT>>

最佳答案

如果您自己记录事情,请为每个作业保留一个 StringIO 日志并写入它:

@log = StringIO.new
@log.write 'debug message'

Sidekiq 还提供日志记录选项:

https://github.com/mperham/sidekiq/wiki/Logging

否则你可以尝试一些真正的 hacky,比如覆盖内核上的打印方法并同步它,这样你就不会不小心写入错误的 $stdout。像这样的东西:

require 'stringio'

module Kernel
  @@io_semaphore = Mutex.new

  [ :printf, :p, :print, :puts ].each do |io_write|
    hidden_io_write = "__#{io_write}__"

    alias_method hidden_io_write, io_write

    define_method(io_write) do |*args|
      @@io_semaphore.synchronize do
        $stdout = Thread.current[:log] || STDOUT
        self.__send__(hidden_io_write, *args)
        $stdout = STDOUT
      end
    end
  end
end

threads = 3.times.map do
  Thread.new do
    Thread.current[:log] = log = StringIO.new
    sleep(rand)
    puts "testing..."
    log.string
  end
end

logs = threads.map(&:value)
p logs
# => ["testing...\n", "testing...\n", "testing...\n"]

关于ruby - 线程安全 : Capturing the output of $stdout,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16183177/

相关文章:

html - 替换 "hover"上的动态背景 - Ruby on Rails

multithreading - 线程/ fork 的效率

python - 新手程序员寻求指导

java - 如何停止烦人的 "The debugger does not support Hot Fix action"调试器控制台弹出窗口?

ruby-on-rails - 如何在生产中的 ruby​​-on-rails 应用程序中运行 rake?

ruby - 拆分字符串时忽略空捕获

ruby - Rails 3 不会用 rvm 安装 sqlite3-ruby gem?

Java套接字编程中的线程间通信问题

java - 如何在Java中实现二进制信号量类?

java - 如何使用调试器添加监视表达式功能在 Eclipse 中监视空指针?