2013-10-18 2 views
2

nohup에서 실행되는 동안 Ruby 스크립트와 혼동을주는 행동이 나타납니다. 기본적으로 나는이 일을 해요 :이상한 루비 출력 nohup에서 지연?

require 'logger' 

logger_file = open('/mnt/dbsdata/output.log', File::WRONLY | File::APPEND | File::CREAT) 
LOGGER = Logger.new(logger_file) 
LOGGER.level = Logger::INFO 

    def run_command(cmd,display=true) 
    if display 
     LOGGER.info "Executing: #{cmd}" 
    end 
    output = `#{cmd} 2>&1` ; results=$?.success? 
    if ! results 
     LOGGER.error "FAILED to execute #{cmd}" 
     LOGGER.error output 
     return false 
    end 
    return true 
    end 

begin 
    run_command("some_longrunning_command", true) 
    run_command("some_other_longrunning_command",true) 
    # etc... 
end 

여기에서 이상한 위와 같이 로거를 사용하고 puts STDOUT (nohup.out은) 그냥 보통의 경우 모두, 출력 타이밍 해제 방법 것입니다. 나는 로그 파일을 꼬리를 꼬집고 로그 메시지 (로그 메시지, 명령 실행, 반복)를 볼 수있을 것이라고 생각하지만, 어떤 일이 벌어 지는지는 명령이 오랫동안 한꺼번에 많은 부실 메시지를 기록하는 일괄 플러시입니다. 이미 실행되고 완료되었습니다.

그래서 쉘에서 같은 스크립트를 실행하는 경우 : nohup을 실행할 수 없습니다 때

`nohup ruby myscript.rb &` 

이이 같이 예상 동작합니다.

누구든지이 경험이 있으며 좋은 해결 방법을 알고 있습니까?

답변

2

확실히 말할 수는 없지만 IO sync 문제가있는 것 같습니다. I/O는 일반적으로 속도를 위해 버퍼링됩니다. RAM은 디스크보다 훨씬 빠르기 때문에 코드가 데이터를 요청하거나 디스크를받을 수있을 때까지 읽기 및 쓰기가 일시적으로 저장됩니다. Ruby의 IO 클래스는 sync= 메서드를 사용하여 루비에게 즉시 버퍼를 플러시하도록 지시 할 수 있습니다.

이 작동합니다 :

logger_file = open('/mnt/dbsdata/output.log', File::WRONLY | File::APPEND | File::CREAT) 
logger_file.sync = true 
LOGGER = Logger.new(logger_file) 
LOGGER.level = Logger::INFO 

단순 들어, 사용하여 출력이 원하는 올바른 모드를 만들 수 있습니다

logger_file = File.open('/mnt/dbsdata/output.log', 'a') 
+0

우수, 그 승자입니다. Muchas gracias. – Madmartigan

+1

경고 : 로그에 기록하거나 Logger를 사용할 때와 같이 절대적으로 필요한 경우가 아니라면 강제로 동기화하지 마십시오. 정상적인 입출력을 위해서는 Ruby가 버퍼링하도록하십시오. 귀하의 CPU와 코드 속도는 당신에게 감사 할 것입니다. –

+0

팁 주셔서 감사. 로깅이 지나치게 빈번하지도 않고 장황하지도 않아서,이 경우에 너무 많은 성능 저하가 나타나지 않습니다. 언급했듯이이 문제는 스크립트가 nohup 아래에있을 때만 발생하며 로거뿐만 아니라 정상적인 stdout도 마찬가지입니다. 당신이 그것을 설명 할 수있는 어떤 자원을 알고 있다면, 나는 링크를 고맙게 생각할 것입니다. 그렇지 않으면, 나는 또한 대몬을 고려할 수 있습니다. 다시 한번 감사드립니다. – Madmartigan

0

소리가 버퍼링과 비슷합니다. stderr에 로깅을 시도해보고 도움이되는지 확인하십시오.