문제

HTTP 서버를 포함 해야하는 데몬에서 작업 중입니다. 나는 Basehttpserver로 그것을 시도하고 있습니다. 전경에서 그것을 실행할 때 잘 작동하지만 데몬을 배경으로 시도하고 포크하면 작동이 멈 춥니 다. 내 주요 응용 프로그램은 계속 작동하지만 BaseHttPserver는 그렇지 않습니다.

나는 이것이 basehttpserver가 로그 데이터를 stdout 및 stderr로 보낸다는 사실과 관련이 있다고 생각합니다. 나는 그것들을 파일로 리디렉션하고 있습니다. 코드 스 니펫은 다음과 같습니다.

# Start the HTTP Server
server = HTTPServer((config['HTTPServer']['listen'],config['HTTPServer']['port']),HTTPHandler)

# Fork our process to detach if not told to stay in foreground
if options.foreground is False:
    try:
        pid = os.fork()
        if pid > 0:
            logging.info('Parent process ending.')
            sys.exit(0)            
    except OSError, e:
        sys.stderr.write("Could not fork: %d (%s)\n" % (e.errno, e.strerror))
        sys.exit(1)

    # Second fork to put into daemon mode
    try: 
        pid = os.fork() 
        if pid > 0:
            # exit from second parent, print eventual PID before
            print 'Daemon has started - PID # %d.' % pid
            logging.info('Child forked as PID # %d' % pid)
            sys.exit(0) 
    except OSError, e: 
        sys.stderr.write("Could not fork: %d (%s)\n" % (e.errno, e.strerror))
        sys.exit(1)


    logging.debug('After child fork')

    # Detach from parent environment
    os.chdir('/') 
    os.setsid()
    os.umask(0) 

    # Close stdin       
    sys.stdin.close()

    # Redirect stdout, stderr
    sys.stdout = open('http_access.log', 'w')
    sys.stderr = open('http_errors.log', 'w')    

# Main Thread Object for Stats
threads = []

logging.debug('Kicking off threads')

while ...
  lots of code here
...

server.serve_forever()

내가 여기서 잘못한 일을하고 있습니까?

편집 : 업데이트 된 코드는 이전에 누락 된 추가 코드 흐름과 해당 Log.debug가 포크 후 코드를 치는 내 포크 배경 데몬에 표시됩니다.

도움이 되었습니까?

해결책

약간의 인터넷 검색 후 i 마지막 으로이 BaseHttPserver 문서를 우연히 발견했습니다 그리고 그 후 나는 다음과 같이 끝났다.

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from SocketServer import ThreadingMixIn

class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
  """Handle requests in a separate thread."""

server = ThreadedHTTPServer((config['HTTPServer']['listen'],config['HTTPServer']['port']), HTTPHandler)
server.serve_forever()

대부분의 경우 포크 후에 나온 후 문제를 해결했습니다.

다른 팁

다음은 다음과 같은 방법입니다 파이썬 데몬 도서관:

from BaseHTTPServer import (HTTPServer, BaseHTTPRequestHandler)
import contextlib

import daemon

from my_app_config import config

# Make the HTTP Server instance.
server = HTTPServer(
    (config['HTTPServer']['listen'], config['HTTPServer']['port']),
    BaseHTTPRequestHandler)

# Make the context manager for becoming a daemon process.
daemon_context = daemon.DaemonContext()
daemon_context.files_preserve = [server.fileno()]

# Become a daemon process.
with daemon_context:
    server.serve_forever()

평소와 같이 데몬의 경우, 데몬이 된 후 프로그램과 상호 작용하는 방법을 결정해야합니다. 예를 들어, SystemD 서비스를 등록하거나 PID 파일 등을 작성할 수 있습니다. 그러나 모두 질문의 범위를 벗어납니다.

당신은 httpserver를 인스턴스화하는 것으로 시작합니다. 그러나 실제로 제공된 코드에서 서빙을 시작하라고 말하지는 않습니다. 자녀 과정에서 전화를 시도하십시오 server.serve_forever().

이것 좀 봐 참조

나를 위해 일한 간단한 솔루션은 BaseHTTPRequestHandler 방법 log_message(), 우리는 stdout에 어떤 종류의 글쓰기도 방지하고 악마 화 될 때 문제를 피합니다.

class CustomRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):

    def log_message(self, format, *args):
            pass

...
rest of custom class code
...

그냥 사용하십시오 데몬 토프 또는 자신의 데몬 화 과정을 굴리는 대신 다른 유사한 스크립트. 이것을 스크립트에서 유지하는 것이 훨씬 낫습니다.

또한 최선의 선택 : BaseHttPserver를 사용하지 마십시오. 정말 나쁘다. Python 용 좋은 HTTP 서버가 많이 있습니다. 체리 또는 반죽. 두 가지 모두 사용 가능한 데몬 스크립트가 포함되어 있습니다.

원래 게시 한 이후로 답변을 요청 했으므로 작은 정보를 공유 할 것이라고 생각했습니다.

출력 문제는 로깅 모듈의 기본 핸들러가 Streamhandler를 사용한다는 사실과 관련이 있습니다. 이것을 처리하는 가장 좋은 방법은 자신만의 핸들러를 만드는 것입니다. 기본 로깅 모듈을 사용하려는 경우 다음과 같은 작업을 수행 할 수 있습니다.

# Get the default logger
default_logger = logging.getLogger('')

# Add the handler
default_logger.addHandler(myotherhandler)

# Remove the default stream handler
for handler in default_logger.handlers:
    if isinstance(handler, logging.StreamHandler):
        default_logger.removeHandler(handler)

또한이 시점에서 나는 아주 좋은 것을 사용했습니다. 폭풍 내장 된 HTTP 서버에 대한 프로젝트.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top