2009-05-20 4 views
9

मैं एक डेमॉन जहां मैं एक HTTP सर्वर एम्बेड करने के लिए की जरूरत पर काम कर रहा हूँ। मैं BaseHTTPServer है, जो जब मैं अग्रभूमि में इसे चलाने के लिए, यह ठीक काम करता है के साथ क्या करने की कोशिश कर रहा हूँ, लेकिन जब मैं कोशिश करते हैं और पृष्ठभूमि में डेमॉन कांटे से यह कार्य करना बंद कर। मेरा मुख्य अनुप्रयोग काम करना जारी रखता है, लेकिन बेसएचटीटीपीएसवर नहीं करता है।Daemonizing अजगर के 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() 

Am मैं गलत यहाँ कुछ कर रही है या किसी भी तरह BaseHTTPServer daemonized बनने से रोका जाता है: यहाँ कोड का टुकड़ा है?

संपादित करें: अपडेट किया गया कोड अतिरिक्त, पहले से लापता कोड प्रवाह और मेरी काँटेदार, पृष्ठभूमि डेमॉन में है कि log.debug शो मैं कांटा के बाद कोड मार रहा प्रदर्शित करने के लिए।

उत्तर

0

बस daemontools या बजाय अपने खुद के daemonizing प्रक्रिया रोलिंग के कुछ अन्य इसी तरह के स्क्रिप्ट का उपयोग। इसे अपनी स्क्रिप्ट से दूर रखना बेहतर है।

इसके अलावा, अपने सबसे अच्छा विकल्प: BaseHTTPServer प्रयोग न करें। यह वास्तव में बुरा है। वहाँ अजगर के लिए कई अच्छे HTTP सर्वर, अर्थात cherrypy या paste हैं। दोनों में उपयोग करने के लिए तैयार डेमोनाइजिंग स्क्रिप्ट शामिल हैं।

+1

यह वास्तव में बीएडी क्यों है? कृपया, यह Google में शीर्ष परिणामों में से एक है ... http के लिए प्रीबिल्ट पायथन पुस्तकालय की एक बड़ी मात्रा है, इसलिए उनमें से अधिक विवरण अद्भुत भी होंगे। – nsij22

2

आप एक HTTPServer instantiating द्वारा शुरू करते हैं। लेकिन आप वास्तव में आपूर्ति कोड में से किसी में प्रसारण प्रारम्भ करने की यह पता नहीं चलता। अपने बच्चे को इस प्रक्रिया में server.serve_forever() बुला प्रयास करें।

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() 

अधिकांश भाग के लिए कौन सा के बाद मैं कांटा और मेरी समस्या को हल करने को समाप्त आता है:

मैं finally stumbled over this BaseHTTPServer documentation googling के एक बिट के बाद और है कि मैं के साथ समाप्त हो गया के बाद संदर्भ

के लिए See this
+0

दरअसल, मैं कांटा के बाद दौड़ रहा था, और मेरे डीबग आउटपुट के अनुसार, दूसरे कांटे के बाद, मैं कोड मार रहा हूं। –

+0

आप सही हैं। मैंने अपना जवाब संपादित कर लिया है। – monowerker

4

यहाँ कैसे python-daemon पुस्तकालय के साथ यह करने के लिए है:

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 सेवा रजिस्टर, या एक पीआईडी ​​फ़ाइल, आदि हालांकि सभी प्रश्न के दायरे से बाहर है कि लिख सकते हैं।

+1

डेमॉन शुरू करने के लिए बहुत अच्छा काम करता है लेकिन मैं इसे स्टार्ट और स्टॉप कमांड के साथ कैसे उपयोग करूं? अब तक मैं डेमन को रोकने में सक्षम नहीं था। – anno1337

+0

आप इस डेमॉन को कैसे रोकते हैं? – MohitC

0

इस के बाद से जवाब मांगा गया है के बाद से मैं मूल रूप से पोस्ट, मैंने सोचा था कि मैं एक छोटे से जानकारी साझा करते हैं।

आउटपुट के साथ समस्या को इस तथ्य के साथ करना है कि लॉगिंग मॉड्यूल के लिए डिफ़ॉल्ट हैंडलर 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 सर्वर के लिए बहुत अच्छा है Tornado परियोजना का उपयोग करने के लिए चले गए हैं: इस मामले में जहां आप डिफ़ॉल्ट लॉगिंग मॉड्यूल का उपयोग करना चाहते है, तो आप कुछ इस तरह कर सकते हैं।

1

मेरे लिए काम करने वाला एक साधारण समाधान BaseHTTPRequestHandler विधि log_message() को ओवरराइड करना था, इसलिए हम किसी भी तरह के लेखन को रोकते हैं और राक्षसों के दौरान समस्याओं से बचते हैं।

class CustomRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): 

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

... 
rest of custom class code 
...