We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add timestamps back to human log format
For a human, these are valuable, but as a machine, idgaf because I'm stamping my own.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/sentry/logging/handlers.py`
Content:
```
1 """
2 sentry.logging.handlers
3 ~~~~~~~~~~~~~~~~~~~~~~~
4 :copyright: (c) 2010-2016 by the Sentry Team, see AUTHORS for more details.
5 :license: BSD, see LICENSE for more details.
6 """
7 
8 from simplejson import JSONEncoder
9 import logging
10 
11 from structlog import get_logger
12 from structlog.processors import _json_fallback_handler
13 
14 _default_encoder = JSONEncoder(
15     separators=(',', ':'),
16     ignore_nan=True,
17     skipkeys=False,
18     ensure_ascii=True,
19     check_circular=True,
20     allow_nan=True,
21     indent=None,
22     encoding='utf-8',
23     default=_json_fallback_handler,
24 ).encode
25 
26 # These are values that come default from logging.LogRecord.
27 # They are defined here: https://github.com/python/cpython/blob/2.7/Lib/logging/__init__.py#L237-L310
28 throwaways = frozenset((
29     'threadName', 'thread', 'created', 'process', 'processName', 'args',
30     'module', 'filename', 'levelno', 'exc_text', 'msg', 'pathname', 'lineno',
31     'funcName', 'relativeCreated', 'levelname', 'msecs',
32 ))
33 
34 
35 class JSONRenderer(object):
36     def __call__(self, logger, name, event_dict):
37         return _default_encoder(event_dict)
38 
39 
40 class HumanRenderer(object):
41     def __call__(self, logger, name, event_dict):
42         level = event_dict.pop('level')
43         real_level = (level.upper()
44             if isinstance(level, basestring)
45             else logging.getLevelName(level)
46         )
47         base = '[%s] %s: %s' % (
48             real_level,
49             event_dict.pop('name', 'root'),
50             event_dict.pop('event'),
51         )
52         join = ' '.join(k + '=' + repr(v)
53                for k, v in event_dict.iteritems())
54         return '%s (%s)' % (base, join)
55 
56 
57 class StructLogHandler(logging.StreamHandler):
58     def emit(self, record, logger=get_logger()):
59         # If anyone wants to use the 'extra' kwarg to provide context within
60         # structlog, we have to strip all of the default attributes from
61         # a record because the RootLogger will take the 'extra' dictionary
62         # and just turn them into attributes.
63         kwargs = {
64             k: v
65             for k, v in vars(record).iteritems()
66             if k not in throwaways
67             and v is not None
68         }
69         kwargs.update({
70             'level': record.levelno,
71             'event': record.msg,
72         })
73 
74         if record.args:
75             # record.args inside of LogRecord.__init__ gets unrolled
76             # if it's the shape `({},)`, a single item dictionary.
77             # so we need to check for this, and re-wrap it because
78             # down the line of structlog, it's expected to be this
79             # original shape.
80             if isinstance(record.args, (tuple, list)):
81                 kwargs['positional_args'] = record.args
82             else:
83                 kwargs['positional_args'] = (record.args,)
84 
85         logger.log(**kwargs)
86
```

Path: `src/sentry/runner/commands/devserver.py`
Content:
```
1 """
2 sentry.runner.commands.devserver
3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 
5 :copyright: (c) 2016 by the Sentry Team, see AUTHORS for more details.
6 :license: BSD, see LICENSE for more details.
7 """
8 from __future__ import absolute_import, print_function
9 
10 import click
11 from sentry.runner.decorators import configuration, log_options
12 
13 
14 @click.command()
15 @click.option('--reload/--no-reload', default=True, help='Autoreloading of python files.')
16 @click.option('--watchers/--no-watchers', default=True, help='Watch static files and recompile on changes.')
17 @click.option('--workers/--no-workers', default=False, help='Run asynchronous workers.')
18 @click.argument('bind', default='127.0.0.1:8000', metavar='ADDRESS')
19 @log_options()
20 @configuration
21 def devserver(reload, watchers, workers, bind):
22     "Starts a lightweight web server for development."
23     if ':' in bind:
24         host, port = bind.split(':', 1)
25         port = int(port)
26     else:
27         host = bind
28         port = None
29 
30     import os
31     from django.conf import settings
32     from sentry import options
33     from sentry.services.http import SentryHTTPServer
34 
35     url_prefix = options.get('system.url-prefix', '')
36     needs_https = url_prefix.startswith('https://')
37     has_https = False
38 
39     if needs_https:
40         from subprocess import check_output
41         try:
42             check_output(['which', 'https'])
43             has_https = True
44         except Exception:
45             has_https = False
46             from sentry.runner.initializer import show_big_error
47             show_big_error([
48                 'missing `https` on your `$PATH`, but https is needed',
49                 '`$ brew install mattrobenolt/stuff/https`',
50             ])
51 
52     uwsgi_overrides = {
53         # Make sure we don't try and use uwsgi protocol
54         'protocol': 'http',
55         # Make sure we reload really quickly for local dev in case it
56         # doesn't want to shut down nicely on it's own, NO MERCY
57         'worker-reload-mercy': 2,
58         # We need stdin to support pdb in devserver
59         'honour-stdin': True,
60     }
61 
62     if reload:
63         uwsgi_overrides['py-autoreload'] = 1
64 
65     daemons = []
66 
67     if watchers:
68         daemons += settings.SENTRY_WATCHERS
69 
70     if workers:
71         if settings.CELERY_ALWAYS_EAGER:
72             raise click.ClickException('Disable CELERY_ALWAYS_EAGER in your settings file to spawn workers.')
73 
74         daemons += [
75             ('worker', ['sentry', 'run', 'worker', '-c', '1', '-l', 'INFO', '--autoreload']),
76             ('cron', ['sentry', 'run', 'cron', '-l', 'INFO', '--autoreload']),
77         ]
78 
79     if needs_https and has_https:
80         from urlparse import urlparse
81         parsed_url = urlparse(url_prefix)
82         https_port = str(parsed_url.port or 443)
83         https_host = parsed_url.hostname
84 
85         # Determine a random port for the backend http server
86         import socket
87         s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
88         s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
89         s.bind((host, 0))
90         port = s.getsockname()[1]
91         s.close()
92         bind = '%s:%d' % (host, port)
93 
94         daemons += [
95             ('https', ['https', '-host', https_host, '-listen', host + ':' + https_port, bind]),
96         ]
97 
98     # A better log-format for local dev when running through honcho,
99     # but if there aren't any other daemons, we don't want to override.
100     if daemons:
101         uwsgi_overrides['log-format'] = '"%(method) %(uri) %(proto)" %(status) %(size)'
102     else:
103         uwsgi_overrides['log-format'] = '[%(ltime)] "%(method) %(uri) %(proto)" %(status) %(size)'
104 
105     server = SentryHTTPServer(host=host, port=port, workers=1, extra_options=uwsgi_overrides)
106 
107     # If we don't need any other daemons, just launch a normal uwsgi webserver
108     # and avoid dealing with subprocesses
109     if not daemons:
110         return server.run()
111 
112     import sys
113     from subprocess import list2cmdline
114     from honcho.manager import Manager
115 
116     os.environ['PYTHONUNBUFFERED'] = 'true'
117 
118     # Make sure that the environment is prepared before honcho takes over
119     # This sets all the appropriate uwsgi env vars, etc
120     server.prepare_environment()
121     daemons += [
122         ('server', ['sentry', 'run', 'web']),
123     ]
124 
125     cwd = os.path.realpath(os.path.join(settings.PROJECT_ROOT, os.pardir, os.pardir))
126 
127     manager = Manager()
128     for name, cmd in daemons:
129         manager.add_process(
130             name, list2cmdline(cmd),
131             quiet=False, cwd=cwd,
132         )
133 
134     manager.loop()
135     sys.exit(manager.returncode)
136
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/sentry/logging/handlers.py b/src/sentry/logging/handlers.py
--- a/src/sentry/logging/handlers.py
+++ b/src/sentry/logging/handlers.py
@@ -5,9 +5,11 @@
 :license: BSD, see LICENSE for more details.
 """
 
-from simplejson import JSONEncoder
+
 import logging
 
+from django.utils.timezone import now
+from simplejson import JSONEncoder
 from structlog import get_logger
 from structlog.processors import _json_fallback_handler
 
@@ -44,14 +46,15 @@
             if isinstance(level, basestring)
             else logging.getLevelName(level)
         )
-        base = '[%s] %s: %s' % (
+        base = '%s [%s] %s: %s' % (
+            now().strftime('%H:%M:%S'),
             real_level,
             event_dict.pop('name', 'root'),
             event_dict.pop('event'),
         )
         join = ' '.join(k + '=' + repr(v)
                for k, v in event_dict.iteritems())
-        return '%s (%s)' % (base, join)
+        return '%s%s' % (base, (' (%s)' % join if join else ''))
 
 
 class StructLogHandler(logging.StreamHandler):
diff --git a/src/sentry/runner/commands/devserver.py b/src/sentry/runner/commands/devserver.py
--- a/src/sentry/runner/commands/devserver.py
+++ b/src/sentry/runner/commands/devserver.py
@@ -72,8 +72,8 @@
             raise click.ClickException('Disable CELERY_ALWAYS_EAGER in your settings file to spawn workers.')
 
         daemons += [
-            ('worker', ['sentry', 'run', 'worker', '-c', '1', '-l', 'INFO', '--autoreload']),
-            ('cron', ['sentry', 'run', 'cron', '-l', 'INFO', '--autoreload']),
+            ('worker', ['sentry', 'run', 'worker', '-c', '1', '--autoreload']),
+            ('cron', ['sentry', 'run', 'cron', '--autoreload']),
         ]
 
     if needs_https and has_https:

{"golden_diff": "diff --git a/src/sentry/logging/handlers.py b/src/sentry/logging/handlers.py\n--- a/src/sentry/logging/handlers.py\n+++ b/src/sentry/logging/handlers.py\n@@ -5,9 +5,11 @@\n :license: BSD, see LICENSE for more details.\n \"\"\"\n \n-from simplejson import JSONEncoder\n+\n import logging\n \n+from django.utils.timezone import now\n+from simplejson import JSONEncoder\n from structlog import get_logger\n from structlog.processors import _json_fallback_handler\n \n@@ -44,14 +46,15 @@\n             if isinstance(level, basestring)\n             else logging.getLevelName(level)\n         )\n-        base = '[%s] %s: %s' % (\n+        base = '%s [%s] %s: %s' % (\n+            now().strftime('%H:%M:%S'),\n             real_level,\n             event_dict.pop('name', 'root'),\n             event_dict.pop('event'),\n         )\n         join = ' '.join(k + '=' + repr(v)\n                for k, v in event_dict.iteritems())\n-        return '%s (%s)' % (base, join)\n+        return '%s%s' % (base, (' (%s)' % join if join else ''))\n \n \n class StructLogHandler(logging.StreamHandler):\ndiff --git a/src/sentry/runner/commands/devserver.py b/src/sentry/runner/commands/devserver.py\n--- a/src/sentry/runner/commands/devserver.py\n+++ b/src/sentry/runner/commands/devserver.py\n@@ -72,8 +72,8 @@\n             raise click.ClickException('Disable CELERY_ALWAYS_EAGER in your settings file to spawn workers.')\n \n         daemons += [\n-            ('worker', ['sentry', 'run', 'worker', '-c', '1', '-l', 'INFO', '--autoreload']),\n-            ('cron', ['sentry', 'run', 'cron', '-l', 'INFO', '--autoreload']),\n+            ('worker', ['sentry', 'run', 'worker', '-c', '1', '--autoreload']),\n+            ('cron', ['sentry', 'run', 'cron', '--autoreload']),\n         ]\n \n     if needs_https and has_https:\n", "issue": "Add timestamps back to human log format\nFor a human, these are valuable, but as a machine, idgaf because I'm stamping my own.\n\n", "before_files": [{"content": "\"\"\"\nsentry.logging.handlers\n~~~~~~~~~~~~~~~~~~~~~~~\n:copyright: (c) 2010-2016 by the Sentry Team, see AUTHORS for more details.\n:license: BSD, see LICENSE for more details.\n\"\"\"\n\nfrom simplejson import JSONEncoder\nimport logging\n\nfrom structlog import get_logger\nfrom structlog.processors import _json_fallback_handler\n\n_default_encoder = JSONEncoder(\n    separators=(',', ':'),\n    ignore_nan=True,\n    skipkeys=False,\n    ensure_ascii=True,\n    check_circular=True,\n    allow_nan=True,\n    indent=None,\n    encoding='utf-8',\n    default=_json_fallback_handler,\n).encode\n\n# These are values that come default from logging.LogRecord.\n# They are defined here: https://github.com/python/cpython/blob/2.7/Lib/logging/__init__.py#L237-L310\nthrowaways = frozenset((\n    'threadName', 'thread', 'created', 'process', 'processName', 'args',\n    'module', 'filename', 'levelno', 'exc_text', 'msg', 'pathname', 'lineno',\n    'funcName', 'relativeCreated', 'levelname', 'msecs',\n))\n\n\nclass JSONRenderer(object):\n    def __call__(self, logger, name, event_dict):\n        return _default_encoder(event_dict)\n\n\nclass HumanRenderer(object):\n    def __call__(self, logger, name, event_dict):\n        level = event_dict.pop('level')\n        real_level = (level.upper()\n            if isinstance(level, basestring)\n            else logging.getLevelName(level)\n        )\n        base = '[%s] %s: %s' % (\n            real_level,\n            event_dict.pop('name', 'root'),\n            event_dict.pop('event'),\n        )\n        join = ' '.join(k + '=' + repr(v)\n               for k, v in event_dict.iteritems())\n        return '%s (%s)' % (base, join)\n\n\nclass StructLogHandler(logging.StreamHandler):\n    def emit(self, record, logger=get_logger()):\n        # If anyone wants to use the 'extra' kwarg to provide context within\n        # structlog, we have to strip all of the default attributes from\n        # a record because the RootLogger will take the 'extra' dictionary\n        # and just turn them into attributes.\n        kwargs = {\n            k: v\n            for k, v in vars(record).iteritems()\n            if k not in throwaways\n            and v is not None\n        }\n        kwargs.update({\n            'level': record.levelno,\n            'event': record.msg,\n        })\n\n        if record.args:\n            # record.args inside of LogRecord.__init__ gets unrolled\n            # if it's the shape `({},)`, a single item dictionary.\n            # so we need to check for this, and re-wrap it because\n            # down the line of structlog, it's expected to be this\n            # original shape.\n            if isinstance(record.args, (tuple, list)):\n                kwargs['positional_args'] = record.args\n            else:\n                kwargs['positional_args'] = (record.args,)\n\n        logger.log(**kwargs)\n", "path": "src/sentry/logging/handlers.py"}, {"content": "\"\"\"\nsentry.runner.commands.devserver\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n:copyright: (c) 2016 by the Sentry Team, see AUTHORS for more details.\n:license: BSD, see LICENSE for more details.\n\"\"\"\nfrom __future__ import absolute_import, print_function\n\nimport click\nfrom sentry.runner.decorators import configuration, log_options\n\n\n@click.command()\n@click.option('--reload/--no-reload', default=True, help='Autoreloading of python files.')\n@click.option('--watchers/--no-watchers', default=True, help='Watch static files and recompile on changes.')\n@click.option('--workers/--no-workers', default=False, help='Run asynchronous workers.')\n@click.argument('bind', default='127.0.0.1:8000', metavar='ADDRESS')\n@log_options()\n@configuration\ndef devserver(reload, watchers, workers, bind):\n    \"Starts a lightweight web server for development.\"\n    if ':' in bind:\n        host, port = bind.split(':', 1)\n        port = int(port)\n    else:\n        host = bind\n        port = None\n\n    import os\n    from django.conf import settings\n    from sentry import options\n    from sentry.services.http import SentryHTTPServer\n\n    url_prefix = options.get('system.url-prefix', '')\n    needs_https = url_prefix.startswith('https://')\n    has_https = False\n\n    if needs_https:\n        from subprocess import check_output\n        try:\n            check_output(['which', 'https'])\n            has_https = True\n        except Exception:\n            has_https = False\n            from sentry.runner.initializer import show_big_error\n            show_big_error([\n                'missing `https` on your `$PATH`, but https is needed',\n                '`$ brew install mattrobenolt/stuff/https`',\n            ])\n\n    uwsgi_overrides = {\n        # Make sure we don't try and use uwsgi protocol\n        'protocol': 'http',\n        # Make sure we reload really quickly for local dev in case it\n        # doesn't want to shut down nicely on it's own, NO MERCY\n        'worker-reload-mercy': 2,\n        # We need stdin to support pdb in devserver\n        'honour-stdin': True,\n    }\n\n    if reload:\n        uwsgi_overrides['py-autoreload'] = 1\n\n    daemons = []\n\n    if watchers:\n        daemons += settings.SENTRY_WATCHERS\n\n    if workers:\n        if settings.CELERY_ALWAYS_EAGER:\n            raise click.ClickException('Disable CELERY_ALWAYS_EAGER in your settings file to spawn workers.')\n\n        daemons += [\n            ('worker', ['sentry', 'run', 'worker', '-c', '1', '-l', 'INFO', '--autoreload']),\n            ('cron', ['sentry', 'run', 'cron', '-l', 'INFO', '--autoreload']),\n        ]\n\n    if needs_https and has_https:\n        from urlparse import urlparse\n        parsed_url = urlparse(url_prefix)\n        https_port = str(parsed_url.port or 443)\n        https_host = parsed_url.hostname\n\n        # Determine a random port for the backend http server\n        import socket\n        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n        s.bind((host, 0))\n        port = s.getsockname()[1]\n        s.close()\n        bind = '%s:%d' % (host, port)\n\n        daemons += [\n            ('https', ['https', '-host', https_host, '-listen', host + ':' + https_port, bind]),\n        ]\n\n    # A better log-format for local dev when running through honcho,\n    # but if there aren't any other daemons, we don't want to override.\n    if daemons:\n        uwsgi_overrides['log-format'] = '\"%(method) %(uri) %(proto)\" %(status) %(size)'\n    else:\n        uwsgi_overrides['log-format'] = '[%(ltime)] \"%(method) %(uri) %(proto)\" %(status) %(size)'\n\n    server = SentryHTTPServer(host=host, port=port, workers=1, extra_options=uwsgi_overrides)\n\n    # If we don't need any other daemons, just launch a normal uwsgi webserver\n    # and avoid dealing with subprocesses\n    if not daemons:\n        return server.run()\n\n    import sys\n    from subprocess import list2cmdline\n    from honcho.manager import Manager\n\n    os.environ['PYTHONUNBUFFERED'] = 'true'\n\n    # Make sure that the environment is prepared before honcho takes over\n    # This sets all the appropriate uwsgi env vars, etc\n    server.prepare_environment()\n    daemons += [\n        ('server', ['sentry', 'run', 'web']),\n    ]\n\n    cwd = os.path.realpath(os.path.join(settings.PROJECT_ROOT, os.pardir, os.pardir))\n\n    manager = Manager()\n    for name, cmd in daemons:\n        manager.add_process(\n            name, list2cmdline(cmd),\n            quiet=False, cwd=cwd,\n        )\n\n    manager.loop()\n    sys.exit(manager.returncode)\n", "path": "src/sentry/runner/commands/devserver.py"}], "after_files": [{"content": "\"\"\"\nsentry.logging.handlers\n~~~~~~~~~~~~~~~~~~~~~~~\n:copyright: (c) 2010-2016 by the Sentry Team, see AUTHORS for more details.\n:license: BSD, see LICENSE for more details.\n\"\"\"\n\n\nimport logging\n\nfrom django.utils.timezone import now\nfrom simplejson import JSONEncoder\nfrom structlog import get_logger\nfrom structlog.processors import _json_fallback_handler\n\n_default_encoder = JSONEncoder(\n    separators=(',', ':'),\n    ignore_nan=True,\n    skipkeys=False,\n    ensure_ascii=True,\n    check_circular=True,\n    allow_nan=True,\n    indent=None,\n    encoding='utf-8',\n    default=_json_fallback_handler,\n).encode\n\n# These are values that come default from logging.LogRecord.\n# They are defined here: https://github.com/python/cpython/blob/2.7/Lib/logging/__init__.py#L237-L310\nthrowaways = frozenset((\n    'threadName', 'thread', 'created', 'process', 'processName', 'args',\n    'module', 'filename', 'levelno', 'exc_text', 'msg', 'pathname', 'lineno',\n    'funcName', 'relativeCreated', 'levelname', 'msecs',\n))\n\n\nclass JSONRenderer(object):\n    def __call__(self, logger, name, event_dict):\n        return _default_encoder(event_dict)\n\n\nclass HumanRenderer(object):\n    def __call__(self, logger, name, event_dict):\n        level = event_dict.pop('level')\n        real_level = (level.upper()\n            if isinstance(level, basestring)\n            else logging.getLevelName(level)\n        )\n        base = '%s [%s] %s: %s' % (\n            now().strftime('%H:%M:%S'),\n            real_level,\n            event_dict.pop('name', 'root'),\n            event_dict.pop('event'),\n        )\n        join = ' '.join(k + '=' + repr(v)\n               for k, v in event_dict.iteritems())\n        return '%s%s' % (base, (' (%s)' % join if join else ''))\n\n\nclass StructLogHandler(logging.StreamHandler):\n    def emit(self, record, logger=get_logger()):\n        # If anyone wants to use the 'extra' kwarg to provide context within\n        # structlog, we have to strip all of the default attributes from\n        # a record because the RootLogger will take the 'extra' dictionary\n        # and just turn them into attributes.\n        kwargs = {\n            k: v\n            for k, v in vars(record).iteritems()\n            if k not in throwaways\n            and v is not None\n        }\n        kwargs.update({\n            'level': record.levelno,\n            'event': record.msg,\n        })\n\n        if record.args:\n            # record.args inside of LogRecord.__init__ gets unrolled\n            # if it's the shape `({},)`, a single item dictionary.\n            # so we need to check for this, and re-wrap it because\n            # down the line of structlog, it's expected to be this\n            # original shape.\n            if isinstance(record.args, (tuple, list)):\n                kwargs['positional_args'] = record.args\n            else:\n                kwargs['positional_args'] = (record.args,)\n\n        logger.log(**kwargs)\n", "path": "src/sentry/logging/handlers.py"}, {"content": "\"\"\"\nsentry.runner.commands.devserver\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n:copyright: (c) 2016 by the Sentry Team, see AUTHORS for more details.\n:license: BSD, see LICENSE for more details.\n\"\"\"\nfrom __future__ import absolute_import, print_function\n\nimport click\nfrom sentry.runner.decorators import configuration, log_options\n\n\n@click.command()\n@click.option('--reload/--no-reload', default=True, help='Autoreloading of python files.')\n@click.option('--watchers/--no-watchers', default=True, help='Watch static files and recompile on changes.')\n@click.option('--workers/--no-workers', default=False, help='Run asynchronous workers.')\n@click.argument('bind', default='127.0.0.1:8000', metavar='ADDRESS')\n@log_options()\n@configuration\ndef devserver(reload, watchers, workers, bind):\n    \"Starts a lightweight web server for development.\"\n    if ':' in bind:\n        host, port = bind.split(':', 1)\n        port = int(port)\n    else:\n        host = bind\n        port = None\n\n    import os\n    from django.conf import settings\n    from sentry import options\n    from sentry.services.http import SentryHTTPServer\n\n    url_prefix = options.get('system.url-prefix', '')\n    needs_https = url_prefix.startswith('https://')\n    has_https = False\n\n    if needs_https:\n        from subprocess import check_output\n        try:\n            check_output(['which', 'https'])\n            has_https = True\n        except Exception:\n            has_https = False\n            from sentry.runner.initializer import show_big_error\n            show_big_error([\n                'missing `https` on your `$PATH`, but https is needed',\n                '`$ brew install mattrobenolt/stuff/https`',\n            ])\n\n    uwsgi_overrides = {\n        # Make sure we don't try and use uwsgi protocol\n        'protocol': 'http',\n        # Make sure we reload really quickly for local dev in case it\n        # doesn't want to shut down nicely on it's own, NO MERCY\n        'worker-reload-mercy': 2,\n        # We need stdin to support pdb in devserver\n        'honour-stdin': True,\n    }\n\n    if reload:\n        uwsgi_overrides['py-autoreload'] = 1\n\n    daemons = []\n\n    if watchers:\n        daemons += settings.SENTRY_WATCHERS\n\n    if workers:\n        if settings.CELERY_ALWAYS_EAGER:\n            raise click.ClickException('Disable CELERY_ALWAYS_EAGER in your settings file to spawn workers.')\n\n        daemons += [\n            ('worker', ['sentry', 'run', 'worker', '-c', '1', '--autoreload']),\n            ('cron', ['sentry', 'run', 'cron', '--autoreload']),\n        ]\n\n    if needs_https and has_https:\n        from urlparse import urlparse\n        parsed_url = urlparse(url_prefix)\n        https_port = str(parsed_url.port or 443)\n        https_host = parsed_url.hostname\n\n        # Determine a random port for the backend http server\n        import socket\n        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\n        s.bind((host, 0))\n        port = s.getsockname()[1]\n        s.close()\n        bind = '%s:%d' % (host, port)\n\n        daemons += [\n            ('https', ['https', '-host', https_host, '-listen', host + ':' + https_port, bind]),\n        ]\n\n    # A better log-format for local dev when running through honcho,\n    # but if there aren't any other daemons, we don't want to override.\n    if daemons:\n        uwsgi_overrides['log-format'] = '\"%(method) %(uri) %(proto)\" %(status) %(size)'\n    else:\n        uwsgi_overrides['log-format'] = '[%(ltime)] \"%(method) %(uri) %(proto)\" %(status) %(size)'\n\n    server = SentryHTTPServer(host=host, port=port, workers=1, extra_options=uwsgi_overrides)\n\n    # If we don't need any other daemons, just launch a normal uwsgi webserver\n    # and avoid dealing with subprocesses\n    if not daemons:\n        return server.run()\n\n    import sys\n    from subprocess import list2cmdline\n    from honcho.manager import Manager\n\n    os.environ['PYTHONUNBUFFERED'] = 'true'\n\n    # Make sure that the environment is prepared before honcho takes over\n    # This sets all the appropriate uwsgi env vars, etc\n    server.prepare_environment()\n    daemons += [\n        ('server', ['sentry', 'run', 'web']),\n    ]\n\n    cwd = os.path.realpath(os.path.join(settings.PROJECT_ROOT, os.pardir, os.pardir))\n\n    manager = Manager()\n    for name, cmd in daemons:\n        manager.add_process(\n            name, list2cmdline(cmd),\n            quiet=False, cwd=cwd,\n        )\n\n    manager.loop()\n    sys.exit(manager.returncode)\n", "path": "src/sentry/runner/commands/devserver.py"}]}