Merge lp:~mwhudson/launchpad/no-hosted-area-join-launchpad-loggerhead into lp:launchpad/db-devel

Proposed by Michael Hudson-Doyle
Status: Rejected
Rejected by: Michael Hudson-Doyle
Proposed branch: lp:~mwhudson/launchpad/no-hosted-area-join-launchpad-loggerhead
Merge into: lp:launchpad/db-devel
Prerequisite: lp:~mwhudson/launchpad/no-hosted-area-server-catchup
Diff against target: 251 lines (+209/-4)
4 files modified
Makefile (+3/-3)
scripts/start-loggerhead.py (+175/-0)
scripts/stop-loggerhead.py (+31/-0)
utilities/sourcedeps.conf (+0/-1)
To merge this branch: bzr merge lp:~mwhudson/launchpad/no-hosted-area-join-launchpad-loggerhead
Reviewer Review Type Date Requested Status
Tim Penhey (community) Needs Information
Review via email: mp+24105@code.launchpad.net

Description of the change

Hi Tim,

This branch makes the launchpad-loggerhead code part of the launchpad tree, something I've been meaning to do for ages. No other changes.

Cheers,
mwh

To post a comment you must log in.
Revision history for this message
Tim Penhey (thumper) wrote :

scripts/start-loggerhead.py
 - Still says
#!/usr/bin/env python2.4
  instead of
#!/usr/bin/env python2.5

same for stop-loggerhead.py

Where is the content of the launchpad-loggerhead directory of the
sourcecode branch that has been removed? Did you forget to add it
in?

review: Needs Information

Unmerged revisions

9727. By Michael Hudson-Doyle

move the rest of the launchpad-loggerhead glue into the tree

9726. By Michael Hudson-Doyle

move launchpad_loggerhead code into lib

9725. By Michael Hudson-Doyle

join launchpad-loggerhead into the launchpad tree

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Makefile'
--- Makefile 2010-04-22 12:03:33 +0000
+++ Makefile 2010-04-27 02:02:42 +0000
@@ -229,13 +229,13 @@
229 -i $(LPCONFIG)229 -i $(LPCONFIG)
230230
231run_codebrowse: build231run_codebrowse: build
232 BZR_PLUGIN_PATH=bzrplugins $(PY) sourcecode/launchpad-loggerhead/start-loggerhead.py -f232 BZR_PLUGIN_PATH=bzrplugins $(PY) scripts/start-loggerhead.py -f
233233
234start_codebrowse: build234start_codebrowse: build
235 BZR_PLUGIN_PATH=$(shell pwd)/bzrplugins $(PY) sourcecode/launchpad-loggerhead/start-loggerhead.py235 BZR_PLUGIN_PATH=$(shell pwd)/bzrplugins $(PY) scripts/start-loggerhead.py
236236
237stop_codebrowse:237stop_codebrowse:
238 $(PY) sourcecode/launchpad-loggerhead/stop-loggerhead.py238 $(PY) scripts/stop-loggerhead.py
239239
240run_codehosting: check_schema inplace stop hosted_branches240run_codehosting: check_schema inplace stop hosted_branches
241 $(RM) thread*.request241 $(RM) thread*.request
242242
=== removed directory 'lib/canonical/launchpad/apidoc'
=== removed symlink 'lib/launchpad_loggerhead'
=== target was u'../sourcecode/launchpad-loggerhead/launchpad_loggerhead/'
=== added file 'scripts/start-loggerhead.py'
--- scripts/start-loggerhead.py 1970-01-01 00:00:00 +0000
+++ scripts/start-loggerhead.py 2010-04-27 02:02:42 +0000
@@ -0,0 +1,175 @@
1#!/usr/bin/env python2.4
2#
3# Copyright 2009 Canonical Ltd. This software is licensed under the
4# GNU Affero General Public License version 3 (see the file LICENSE).
5
6import logging
7import os
8import sys
9
10from paste import httpserver
11from paste.deploy.config import PrefixMiddleware
12from paste.httpexceptions import HTTPExceptionHandler
13from paste.request import construct_url
14from paste.translogger import TransLogger
15
16from canonical.config import config
17import lp.codehosting
18
19LISTEN_HOST = '0.0.0.0'
20LISTEN_PORT = 8080
21THREADPOOL_WORKERS = 10
22
23
24class NoLockingFileHandler(logging.FileHandler):
25 """A version of logging.FileHandler that doesn't do it's own locking.
26
27 We experienced occasional hangs in production where gdb-ery on the server
28 revealed that we sometimes end up with many threads blocking on the RLock
29 held by the logging file handler, and log reading finds that an exception
30 managed to kill a thread in an unsafe window for RLock's.
31
32 Luckily, there's no real reason for us to take a lock during logging as
33 each log message translates to one call to .write on a file object, which
34 translates to one fwrite call, and it seems that this does enough locking
35 itself for our purposes.
36
37 So this handler just doesn't lock in log message handling.
38 """
39
40 def acquire(self):
41 pass
42
43 def release(self):
44 pass
45
46
47def setup_logging(home, foreground):
48 # i hate that stupid logging config format, so just set up logging here.
49
50 log_folder = config.codebrowse.log_folder
51 if not log_folder:
52 log_folder = os.path.join(home, 'logs')
53 if not os.path.exists(log_folder):
54 os.mkdir(log_folder)
55
56 f = logging.Formatter(
57 '%(levelname)-.3s [%(asctime)s.%(msecs)03d] [%(thread)d] %(name)s: %(message)s',
58 '%Y%m%d-%H:%M:%S')
59 debug_log = NoLockingFileHandler(os.path.join(log_folder, 'debug.log'))
60 debug_log.setLevel(logging.DEBUG)
61 debug_log.setFormatter(f)
62 if foreground:
63 stdout_log = logging.StreamHandler(sys.stdout)
64 stdout_log.setLevel(logging.DEBUG)
65 stdout_log.setFormatter(f)
66 f = logging.Formatter('[%(asctime)s.%(msecs)03d] %(message)s',
67 '%Y%m%d-%H:%M:%S')
68 access_log = NoLockingFileHandler(os.path.join(log_folder, 'access.log'))
69 access_log.setLevel(logging.INFO)
70 access_log.setFormatter(f)
71
72 logging.getLogger('').setLevel(logging.DEBUG)
73 logging.getLogger('').addHandler(debug_log)
74 logging.getLogger('wsgi').addHandler(access_log)
75
76 if foreground:
77 logging.getLogger('').addHandler(stdout_log)
78 else:
79 class S(object):
80 def write(self, str):
81 logging.getLogger().error(str.rstrip('\n'))
82 def flush(self):
83 pass
84 sys.stderr = S()
85
86
87
88foreground = False
89if len(sys.argv) > 1:
90 if sys.argv[1] == '-f':
91 foreground = True
92
93home = os.path.realpath(os.path.dirname(__file__))
94pidfile = os.path.join(home, 'loggerhead.pid')
95
96if not foreground:
97 sys.stderr.write('\n')
98 sys.stderr.write('Launching loggerhead into the background.\n')
99 sys.stderr.write('PID file: %s\n' % (pidfile,))
100 sys.stderr.write('\n')
101
102 from loggerhead.daemon import daemonize
103 daemonize(pidfile, home)
104
105setup_logging(home, foreground=foreground)
106
107log = logging.getLogger('loggerhead')
108log.info('Starting up...')
109
110log.info('Loading the bzr plugins...')
111from bzrlib.plugin import load_plugins
112load_plugins()
113
114import bzrlib.plugins
115if getattr(bzrlib.plugins, 'loom', None) is None:
116 log.error('Loom plugin loading failed.')
117
118from launchpad_loggerhead.debug import (
119 change_kill_thread_criteria, threadpool_debug)
120from launchpad_loggerhead.app import RootApp
121from launchpad_loggerhead.session import SessionHandler
122
123SESSION_VAR = 'lh.session'
124
125secret = open(os.path.join(config.root, config.codebrowse.secret_path)).read()
126
127app = RootApp(SESSION_VAR)
128app = HTTPExceptionHandler(app)
129app = SessionHandler(app, SESSION_VAR, secret)
130def log_on_request_start(app):
131 def wrapped(environ, start_response):
132 log = logging.getLogger('loggerhead')
133 log.info("Starting to process %s", construct_url(environ))
134 return app(environ, start_response)
135 return wrapped
136app = log_on_request_start(app)
137app = PrefixMiddleware(app)
138app = TransLogger(app)
139app = threadpool_debug(app)
140
141def set_scheme(app):
142 """Set wsgi.url_scheme in the environment correctly.
143
144 We serve requests that originated from both http and https, and
145 distinguish between them by adding a header in the https Apache config.
146 """
147 def wrapped(environ, start_response):
148 environ['wsgi.url_scheme'] = environ.pop(
149 'HTTP_X_FORWARDED_SCHEME', 'http')
150 return app(environ, start_response)
151 return wrapped
152app = set_scheme(app)
153app = change_kill_thread_criteria(app)
154
155try:
156 httpserver.serve(
157 app, host=LISTEN_HOST, port=LISTEN_PORT,
158 threadpool_workers=THREADPOOL_WORKERS,
159 threadpool_options={
160 # Kill threads after 300 seconds. This is insanely high, but
161 # lower enough than the default (1800 seconds!) that evidence
162 # suggests it will be hit occasionally, and there's very little
163 # chance of it having negative consequences.
164 'kill_thread_limit': 300,
165 # Check for threads that should be killed every 10 requests. The
166 # default is every 100, which is easily long enough for things to
167 # gum up completely in between checks.
168 'hung_check_period': 10,
169 })
170finally:
171 log.info('Shutdown.')
172 try:
173 os.remove(pidfile)
174 except OSError:
175 pass
0176
=== added file 'scripts/stop-loggerhead.py'
--- scripts/stop-loggerhead.py 1970-01-01 00:00:00 +0000
+++ scripts/stop-loggerhead.py 2010-04-27 02:02:42 +0000
@@ -0,0 +1,31 @@
1#!/usr/bin/env python2.4
2#
3# Copyright 2009 Canonical Ltd. This software is licensed under the
4# GNU Affero General Public License version 3 (see the file LICENSE).
5
6import os
7import sys
8
9home = os.path.realpath(os.path.dirname(__file__))
10pidfile = os.path.join(home, 'loggerhead.pid')
11
12try:
13 f = open(pidfile, 'r')
14except IOError, e:
15 print 'No pid file found.'
16 sys.exit(1)
17
18pid = int(f.readline())
19
20try:
21 os.kill(pid, 0)
22except OSError, e:
23 print 'Stale pid file; server is not running.'
24 sys.exit(1)
25
26print
27print 'Shutting down previous server @ pid %d.' % (pid,)
28print
29
30import signal
31os.kill(pid, signal.SIGTERM)
032
=== modified file 'utilities/sourcedeps.conf'
--- utilities/sourcedeps.conf 2010-04-21 12:30:48 +0000
+++ utilities/sourcedeps.conf 2010-04-27 02:02:42 +0000
@@ -5,7 +5,6 @@
5bzr-svn lp:~launchpad-pqm/bzr-svn/devel;revno=27085bzr-svn lp:~launchpad-pqm/bzr-svn/devel;revno=2708
6cscvs lp:~launchpad-pqm/launchpad-cscvs/devel;revno=4326cscvs lp:~launchpad-pqm/launchpad-cscvs/devel;revno=432
7dulwich lp:~launchpad-pqm/dulwich/devel;revno=4187dulwich lp:~launchpad-pqm/dulwich/devel;revno=418
8launchpad-loggerhead lp:~launchpad-pqm/launchpad-loggerhead/devel;revno=54
9loggerhead lp:~launchpad-pqm/loggerhead/devel;revno=1748loggerhead lp:~launchpad-pqm/loggerhead/devel;revno=174
10lpreview lp:~launchpad-pqm/bzr-lpreview/devel;revno=239lpreview lp:~launchpad-pqm/bzr-lpreview/devel;revno=23
11mailman lp:~launchpad-pqm/mailman/2.1;revno=97610mailman lp:~launchpad-pqm/mailman/2.1;revno=976

Subscribers

People subscribed via source and target branches

to status/vote changes: