~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to start-loggerhead

  • Committer: Robert Collins
  • Date: 2012-02-02 07:42:24 UTC
  • Revision ID: robertc@robertcollins.net-20120202074224-ujea2ocm1u1ws1en
    - Make tz calculations consistent and use UTC in the UI everywhere we show
      a precise timestamp. (Robert Collins, #594591)

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', 0, 100)
40
 
    elif roll == 'weekly':
41
 
        h = logging.handlers.TimedRotatingFileHandler(filename, 'W0', 0, 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()