~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to start-loggerhead

  • Committer: Martin Albisetti
  • Date: 2008-09-10 22:53:39 UTC
  • mfrom: (219.1.3 reloader)
  • Revision ID: argentina@gmail.com-20080910225339-p987y5hgtxrq8p5c
Add --reload option to restart LH automatically when developing. (Guillermo Gonzalez)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
# This program is free software; you can redistribute it and/or modify
 
3
# it under the terms of the GNU General Public License as published by
 
4
# the Free Software Foundation; either version 2 of the License, or
 
5
# (at your option) any later version.
 
6
#
 
7
# This program is distributed in the hope that it will be useful,
 
8
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
# GNU General Public License for more details.
 
11
#
 
12
# You should have received a copy of the GNU General Public License
 
13
# along with this program; if not, write to the Free Software
 
14
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
 
 
16
"""A script for starting the loggerhead process."""
 
17
 
 
18
 
 
19
import logging
 
20
import logging.handlers
 
21
from optparse import OptionParser
 
22
import os
 
23
import sys
 
24
import urlparse
 
25
 
 
26
from configobj import ConfigObj
 
27
 
 
28
from paste import httpserver
 
29
from paste.httpexceptions import make_middleware
 
30
from paste.translogger import make_filter
 
31
 
 
32
from loggerhead import daemon
 
33
from loggerhead.apps.config import Root
 
34
 
 
35
 
 
36
def make_handler(config, filename):
 
37
    roll = config.get('log.roll', 'never')
 
38
    if roll == 'daily':
 
39
        h = logging.handlers.TimedRotatingFileHandler(filename, 'midnight', 1, 100)
 
40
    elif roll == 'weekly':
 
41
        h = logging.handlers.TimedRotatingFileHandler(filename, 'W0', 1, 100)
 
42
    else:
 
43
        h = logging.FileHandler(filename)
 
44
    return h
 
45
 
 
46
 
 
47
def setup_logging(log_folder, config, foreground):
 
48
    # i hate that stupid logging config format, so just set up logging here.
 
49
 
 
50
    if not os.path.exists(log_folder):
 
51
        os.mkdir(log_folder)
 
52
 
 
53
    f = logging.Formatter('%(levelname)-.3s [%(asctime)s.%(msecs)03d] %(name)s: %(message)s',
 
54
                          '%Y%m%d-%H:%M:%S')
 
55
    debug_log = make_handler(config, os.path.join(log_folder, 'debug.log'))
 
56
    debug_log.setLevel(logging.DEBUG)
 
57
    debug_log.setFormatter(f)
 
58
    if foreground:
 
59
        stdout_log = logging.StreamHandler(sys.stdout)
 
60
        stdout_log.setLevel(logging.DEBUG)
 
61
        stdout_log.setFormatter(f)
 
62
    f = logging.Formatter('[%(asctime)s.%(msecs)03d] %(message)s',
 
63
                          '%Y%m%d-%H:%M:%S')
 
64
    access_log = make_handler(config, os.path.join(log_folder, 'access.log'))
 
65
    access_log.setLevel(logging.INFO)
 
66
    access_log.setFormatter(f)
 
67
 
 
68
    logging.getLogger('').setLevel(logging.DEBUG)
 
69
    logging.getLogger('').addHandler(debug_log)
 
70
    logging.getLogger('wsgi').addHandler(access_log)
 
71
 
 
72
    if foreground:
 
73
        logging.getLogger('').addHandler(stdout_log)
 
74
 
 
75
 
 
76
 
 
77
def main():
 
78
    home = os.path.realpath(os.path.dirname(__file__))
 
79
    default_pidfile = os.path.join(home, 'loggerhead.pid')
 
80
    default_configfile = os.path.join(home, 'loggerhead.conf')
 
81
    default_log_folder = os.path.join(home, 'logs')
 
82
    parser = OptionParser(usage='usage: %prog [options]', version='%prog')
 
83
    parser.add_option('-f', '--foreground', action='store_true', dest='foreground', default=False,
 
84
                      help="run in the foreground; don't daemonize")
 
85
    parser.add_option('-C', '--check', action='store_true', dest='check', default=False,
 
86
                      help="only start if not already running (useful for cron jobs)")
 
87
    parser.add_option('-p', '--pidfile', dest="pidfile", default=default_pidfile,
 
88
                      type=str, help="override pidfile location")
 
89
    parser.add_option('-c', '--config-file', dest="configfile", default=default_configfile,
 
90
                                          type=str, help="override configuration file location")
 
91
    parser.add_option('-L', '--log-folder', dest="log_folder", default=default_log_folder,
 
92
                      type=str, help="override log file directory")
 
93
    options, args = parser.parse_args()
 
94
    if len(args) > 0:
 
95
        parser.error('No filename arguments are used, only options.')
 
96
 
 
97
    if options.check:
 
98
        if daemon.is_running(options.pidfile):
 
99
            sys.exit(0)
 
100
        sys.stderr.write('Did not find loggerhead running in %r; restarting...\n' % (options.pidfile,))
 
101
 
 
102
    # read loggerhead config
 
103
 
 
104
    config = ConfigObj(options.configfile, encoding='utf-8')
 
105
    extra_path = config.get('bzrpath', None)
 
106
    if extra_path:
 
107
        sys.path.insert(0, extra_path)
 
108
 
 
109
    potential_overrides = [ ('server.socket_port', int),
 
110
                            ('server.webpath', str),
 
111
                            ('server.thread_pool', int),
 
112
                            ('server.socket_host' ,str) ]
 
113
    server_port = int(config.get('server.socket_port', 8080))
 
114
    nworkers = int(config.get('server.thread_pool', 10))
 
115
    server_host = config.get('server.socket_host', '0.0.0.0')
 
116
    webpath = config.get('server.webpath', None)
 
117
 
 
118
    for key, keytype in potential_overrides:
 
119
        value = config.get(key, None)
 
120
        if value is not None:
 
121
            value = keytype(value)
 
122
 
 
123
    if not options.foreground:
 
124
        sys.stderr.write('\n')
 
125
        sys.stderr.write('Launching loggerhead into the background.\n')
 
126
        sys.stderr.write('PID file: %s\n' % (options.pidfile,))
 
127
        sys.stderr.write('\n')
 
128
 
 
129
        daemon.daemonize(options.pidfile, home)
 
130
 
 
131
    setup_logging(options.log_folder, config, foreground=options.foreground)
 
132
 
 
133
    log = logging.getLogger('loggerhead')
 
134
    log.info('Starting up...')
 
135
 
 
136
    app = Root(config)
 
137
 
 
138
    app = app
 
139
    app = make_middleware(app)
 
140
    app = make_filter(app, None)
 
141
 
 
142
    if webpath:
 
143
        scheme, netloc, path, blah, blah, blah = urlparse.urlparse(webpath)
 
144
        def app(environ, start_response, orig=app):
 
145
            environ['SCRIPT_NAME'] = path
 
146
            environ['HTTP_HOST'] = netloc
 
147
            return orig(environ, start_response)
 
148
 
 
149
    try:
 
150
        httpserver.serve(
 
151
            app, host=server_host, port=server_port,
 
152
            threadpool_workers=nworkers)
 
153
    finally:
 
154
        log.info('Shutdown.')
 
155
        try:
 
156
            os.remove(options.pidfile)
 
157
        except OSError:
 
158
            pass
 
159
 
 
160
 
 
161
if __name__ == '__main__':
 
162
    main()