Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also .

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also .
...
  • 20 commits
  • 21 files changed
  • 0 commit comments
  • 8 contributors
View
1 MANIFEST.in
@@ -6,5 +6,4 @@ include THANKS
recursive-include tests *
recursive-include examples *
recursive-include doc *
-recursive-include debian *
recursive-include examples/frameworks *
View
1 THANKS
@@ -39,3 +39,4 @@ Kristian Glass <git@doismellburning.co.uk>
Mazdak Rezvani <mazdak@mac.com>
Maxim Kamenkov <mkamenkov@gmail.com>
Konstantin Kapustin <sirkonst@gmail.com>
+Djoume Salvetti <djoume@freshbooks.com>
View
52 doc/htdocs/css/index.css
@@ -1,4 +1,4 @@
-/* line 17, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
+/* line 17, /Library/Ruby/Gems/1.8/gems/compass-0.12.1/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
@@ -20,45 +20,45 @@ time, mark, audio, video {
vertical-align: baseline;
}
-/* line 20, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
+/* line 20, /Library/Ruby/Gems/1.8/gems/compass-0.12.1/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
body {
line-height: 1;
}
-/* line 22, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
+/* line 22, /Library/Ruby/Gems/1.8/gems/compass-0.12.1/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
ol, ul {
list-style: none;
}
-/* line 24, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
+/* line 24, /Library/Ruby/Gems/1.8/gems/compass-0.12.1/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
table {
border-collapse: collapse;
border-spacing: 0;
}
-/* line 26, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
+/* line 26, /Library/Ruby/Gems/1.8/gems/compass-0.12.1/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
caption, th, td {
text-align: left;
font-weight: normal;
vertical-align: middle;
}
-/* line 28, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
+/* line 28, /Library/Ruby/Gems/1.8/gems/compass-0.12.1/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
q, blockquote {
quotes: none;
}
-/* line 101, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
+/* line 101, /Library/Ruby/Gems/1.8/gems/compass-0.12.1/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
q:before, q:after, blockquote:before, blockquote:after {
content: "";
content: none;
}
-/* line 30, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
+/* line 30, /Library/Ruby/Gems/1.8/gems/compass-0.12.1/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
a img {
border: none;
}
-/* line 114, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
+/* line 114, /Library/Ruby/Gems/1.8/gems/compass-0.12.1/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section, summary {
display: block;
}
@@ -89,17 +89,17 @@ article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav,
width: 620px;
}
-/* line 4, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
+/* line 4, /Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
body {
font: 13px/1.5 Helvetica, Arial, 'Liberation Sans', FreeSans, sans-serif;
}
-/* line 6, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
+/* line 6, /Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
a:focus {
outline: 1px dotted invert;
}
-/* line 8, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
+/* line 8, /Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
hr {
border-color: #cccccc;
border-style: solid;
@@ -108,52 +108,52 @@ hr {
height: 0;
}
-/* line 14, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
+/* line 14, /Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
h1 {
font-size: 25px;
}
-/* line 16, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
+/* line 16, /Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
h2 {
font-size: 23px;
}
-/* line 18, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
+/* line 18, /Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
h3 {
font-size: 21px;
}
-/* line 20, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
+/* line 20, /Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
h4 {
font-size: 19px;
}
-/* line 22, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
+/* line 22, /Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
h5 {
font-size: 17px;
}
-/* line 24, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
+/* line 24, /Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
h6 {
font-size: 15px;
}
-/* line 26, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
+/* line 26, /Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
ol {
list-style: decimal;
}
-/* line 28, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
+/* line 28, /Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
ul {
list-style: square;
}
-/* line 30, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
+/* line 30, /Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
li {
margin-left: 30px;
}
-/* line 32, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
+/* line 32, /Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
p,
dl,
hr,
@@ -188,15 +188,13 @@ a, a:visited, a:hover, a:active {
margin-bottom: 23px;
-moz-border-radius-bottomleft: 10px;
-webkit-border-bottom-left-radius: 10px;
- -o-border-bottom-left-radius: 10px;
-ms-border-bottom-left-radius: 10px;
- -khtml-border-bottom-left-radius: 10px;
+ -o-border-bottom-left-radius: 10px;
border-bottom-left-radius: 10px;
-moz-border-radius-bottomright: 10px;
-webkit-border-bottom-right-radius: 10px;
- -o-border-bottom-right-radius: 10px;
-ms-border-bottom-right-radius: 10px;
- -khtml-border-bottom-right-radius: 10px;
+ -o-border-bottom-right-radius: 10px;
border-bottom-right-radius: 10px;
background-color: #959595;
text-align: right;
@@ -213,7 +211,7 @@ a, a:visited, a:hover, a:active {
margin-right: 10px;
list-style: none;
}
-/* line 11, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/typography/lists/_bullets.scss */
+/* line 11, /Library/Ruby/Gems/1.8/gems/compass-0.12.1/frameworks/compass/stylesheets/compass/typography/lists/_bullets.scss */
#menu ul li {
list-style-image: none;
list-style-type: none;
View
52 doc/htdocs/css/style.css
@@ -1,4 +1,4 @@
-/* line 17, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
+/* line 17, /Library/Ruby/Gems/1.8/gems/compass-0.12.1/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
@@ -20,45 +20,45 @@ time, mark, audio, video {
vertical-align: baseline;
}
-/* line 20, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
+/* line 20, /Library/Ruby/Gems/1.8/gems/compass-0.12.1/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
body {
line-height: 1;
}
-/* line 22, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
+/* line 22, /Library/Ruby/Gems/1.8/gems/compass-0.12.1/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
ol, ul {
list-style: none;
}
-/* line 24, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
+/* line 24, /Library/Ruby/Gems/1.8/gems/compass-0.12.1/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
table {
border-collapse: collapse;
border-spacing: 0;
}
-/* line 26, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
+/* line 26, /Library/Ruby/Gems/1.8/gems/compass-0.12.1/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
caption, th, td {
text-align: left;
font-weight: normal;
vertical-align: middle;
}
-/* line 28, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
+/* line 28, /Library/Ruby/Gems/1.8/gems/compass-0.12.1/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
q, blockquote {
quotes: none;
}
-/* line 101, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
+/* line 101, /Library/Ruby/Gems/1.8/gems/compass-0.12.1/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
q:before, q:after, blockquote:before, blockquote:after {
content: "";
content: none;
}
-/* line 30, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
+/* line 30, /Library/Ruby/Gems/1.8/gems/compass-0.12.1/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
a img {
border: none;
}
-/* line 114, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
+/* line 114, /Library/Ruby/Gems/1.8/gems/compass-0.12.1/frameworks/compass/stylesheets/compass/reset/_utilities.scss */
article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section, summary {
display: block;
}
@@ -89,17 +89,17 @@ article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav,
width: 620px;
}
-/* line 4, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
+/* line 4, /Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
body {
font: 13px/1.5 Helvetica, Arial, 'Liberation Sans', FreeSans, sans-serif;
}
-/* line 6, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
+/* line 6, /Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
a:focus {
outline: 1px dotted invert;
}
-/* line 8, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
+/* line 8, /Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
hr {
border-color: #cccccc;
border-style: solid;
@@ -108,52 +108,52 @@ hr {
height: 0;
}
-/* line 14, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
+/* line 14, /Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
h1 {
font-size: 25px;
}
-/* line 16, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
+/* line 16, /Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
h2 {
font-size: 23px;
}
-/* line 18, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
+/* line 18, /Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
h3 {
font-size: 21px;
}
-/* line 20, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
+/* line 20, /Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
h4 {
font-size: 19px;
}
-/* line 22, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
+/* line 22, /Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
h5 {
font-size: 17px;
}
-/* line 24, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
+/* line 24, /Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
h6 {
font-size: 15px;
}
-/* line 26, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
+/* line 26, /Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
ol {
list-style: decimal;
}
-/* line 28, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
+/* line 28, /Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
ul {
list-style: square;
}
-/* line 30, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
+/* line 30, /Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
li {
margin-left: 30px;
}
-/* line 32, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
+/* line 32, /Library/Ruby/Gems/1.8/gems/compass-960-plugin-0.10.4/stylesheets/960/_text.sass */
p,
dl,
hr,
@@ -188,15 +188,13 @@ a, a:visited, a:hover, a:active {
margin-bottom: 23px;
-moz-border-radius-bottomleft: 10px;
-webkit-border-bottom-left-radius: 10px;
- -o-border-bottom-left-radius: 10px;
-ms-border-bottom-left-radius: 10px;
- -khtml-border-bottom-left-radius: 10px;
+ -o-border-bottom-left-radius: 10px;
border-bottom-left-radius: 10px;
-moz-border-radius-bottomright: 10px;
-webkit-border-bottom-right-radius: 10px;
- -o-border-bottom-right-radius: 10px;
-ms-border-bottom-right-radius: 10px;
- -khtml-border-bottom-right-radius: 10px;
+ -o-border-bottom-right-radius: 10px;
border-bottom-right-radius: 10px;
background-color: #959595;
text-align: right;
@@ -213,7 +211,7 @@ a, a:visited, a:hover, a:active {
margin-right: 10px;
list-style: none;
}
-/* line 11, ../../../../../../../../../Library/Ruby/Gems/1.8/gems/compass-0.11.7/frameworks/compass/stylesheets/compass/typography/lists/_bullets.scss */
+/* line 11, /Library/Ruby/Gems/1.8/gems/compass-0.12.1/frameworks/compass/stylesheets/compass/typography/lists/_bullets.scss */
#menu ul li {
list-style-image: none;
list-style-type: none;
View
23 doc/htdocs/deploy.html
@@ -145,6 +145,18 @@
will fork-exec which creates an unmonitored process and generally just
confuses the monitor services.</p>
</div>
+<div class="section" id="circus">
+<h3><a class="toc-backref" href="#contents">Circus</a></h3>
+<p><a class="reference external" href="http://circus.readthedocs.org/en/latest/index.html">Circus</a> can be
+used to monitor gunicorn. A simple configuration is:</p>
+<pre class="literal-block">
+[watcher:mywebapp]
+cmd = gunicorn -w 3 test:app
+working_dir = /Users/benoitc/work/gunicorn/examples
+send_hup = true
+</pre>
+<p>Then you can easily manage Gunicorn using the <a class="reference external" href="http://circus.readthedocs.org/en/latest/commands/#cli">circusctl</a> command.</p>
+</div>
<div class="section" id="runit">
<h3><a class="toc-backref" href="#contents">Runit</a></h3>
<p>A popular method for deploying Gunicorn is to have it monitored by <a class="reference external" href="http://smarden.org/runit/">runit</a>.
@@ -191,11 +203,12 @@
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
-<li><a class="reference internal" href="#nginx-configuration" id="id3">Nginx Configuration</a></li>
-<li><a class="reference internal" href="#using-virtualenv" id="id4">Using Virtualenv</a></li>
-<li><a class="reference internal" href="#monitoring" id="id5">Monitoring</a><ul>
-<li><a class="reference internal" href="#runit" id="id6">Runit</a></li>
-<li><a class="reference internal" href="#supervisor" id="id7">Supervisor</a></li>
+<li><a class="reference internal" href="#nginx-configuration" id="id4">Nginx Configuration</a></li>
+<li><a class="reference internal" href="#using-virtualenv" id="id5">Using Virtualenv</a></li>
+<li><a class="reference internal" href="#monitoring" id="id6">Monitoring</a><ul>
+<li><a class="reference internal" href="#circus" id="id7">Circus</a></li>
+<li><a class="reference internal" href="#runit" id="id8">Runit</a></li>
+<li><a class="reference internal" href="#supervisor" id="id9">Supervisor</a></li>
</ul>
</li>
</ul>
View
18 doc/htdocs/install.html
@@ -158,25 +158,29 @@
</div>
<div class="section" id="ubuntu">
<h2><a class="toc-backref" href="#contents">Ubuntu</a></h2>
-<p>If you use <a class="reference external" href="http://www.ubuntu.com/">Ubuntu</a> karmic, you can update your system with packages from
-our <a class="reference external" href="https://launchpad.net/~bchesneau/+archive/gunicorn">PPA</a> by adding <tt class="docutils literal">ppa:bchesneau/gunicorn</tt> to your system's Software
-Sources.</p>
+<p>If you use <a class="reference external" href="http://www.ubuntu.com/">Ubuntu</a>, you can update your system with packages from
+our <a class="reference external" href="https://launchpad.net/~bchesneau/+archive/gunicorn">PPA</a> by adding <tt class="docutils literal">ppa:gunicorn/ppa</tt> to your system's Software
+Sources. Use the <tt class="docutils literal"><span class="pre">apt-add-repository</span></tt> command from the
+<tt class="docutils literal"><span class="pre">python-software-properties</span></tt> package to add the Gunicorn software source.</p>
+<blockquote>
+$ sudo apt-add-repository ppa:gunicorn/ppa</blockquote>
<p>Or this PPA can be added to your system manually by copying the lines below
and adding them to your system's software sources:</p>
<pre class="literal-block">
-deb http://ppa.launchpad.net/bchesneau/gunicorn/ubuntu karmic main
-deb-src http://ppa.launchpad.net/bchesneau/gunicorn/ubuntu karmic main
+deb http://ppa.launchpad.net/gunicorn/ppa/ubuntu lucid main
+deb-src http://ppa.launchpad.net/gunicorn/ppa/ubuntu lucid main
</pre>
+<p>Replace 'lucid' with your Ubuntu distribution series.</p>
<div class="section" id="signing-key">
<h3><a class="toc-backref" href="#contents">Signing key</a></h3>
<pre class="literal-block">
-1024R/15E5EB06
+1024R/5370FF2A
</pre>
</div>
<div class="section" id="fingerprint">
<h3><a class="toc-backref" href="#contents">Fingerprint</a></h3>
<pre class="literal-block">
-49AEEDFF5CDCD82CEA8AB4DABC981A8115E5EB06
+FC7B41B54C9B8476D9EC22A2C6773E575370FF2A
</pre>
</div>
</div>
View
23 doc/site/deploy.rst
@@ -129,6 +129,18 @@ Monitoring
will fork-exec which creates an unmonitored process and generally just
confuses the monitor services.
+Circus
+++++++
+
+`Circus <http://circus.readthedocs.org/en/latest/index.html>`_ can be
+used to monitor gunicorn. A simple configuration is::
+
+ [watcher:mywebapp]
+ cmd = gunicorn -w 3 test:app
+ working_dir = /Users/benoitc/work/gunicorn/examples
+ send_hup = true
+
+Then you can easily manage Gunicorn using the `circusctl <http://circus.readthedocs.org/en/latest/commands/#cli>`_ command.
Runit
+++++
@@ -172,6 +184,15 @@ Another useful tool to monitor and control Gunicorn is Supervisor_. A
autorestart=true
redirect_stderr=True
+Logging
+-------
+
+Logging can be configured by using various flags detailed in the
+`configuration documentation`_ or by creating a `logging configuration file`_.
+Send the ``USR1`` signal to rotate logs if you are using the logrotate
+utility::
+
+ kill -USR1 $(cat /var/run/gunicorn.pid)
.. _Nginx: http://www.nginx.org
.. _slowloris: http://ha.ckers.org/slowloris/
@@ -180,4 +201,6 @@ Another useful tool to monitor and control Gunicorn is Supervisor_. A
.. _`example service`: http://github.com/benoitc/gunicorn/blob/master/examples/gunicorn_rc
.. _Supervisor: http://supervisord.org
.. _`simple configuration`: http://github.com/benoitc/gunicorn/blob/master/examples/supervisor.conf
+.. _`configuration documentation`: http://gunicorn.org/configure.html#logging
+.. _`logging configuration file`: https://github.com/benoitc/gunicorn/blob/master/examples/logging.conf
.. _Virtualenv: http://pypi.python.org/pypi/virtualenv
View
19 doc/site/install.rst
@@ -142,29 +142,34 @@ install it in the usual way::
Ubuntu
------
-If you use Ubuntu_ karmic, you can update your system with packages from
-our PPA_ by adding ``ppa:bchesneau/gunicorn`` to your system's Software
-Sources.
+If you use Ubuntu_, you can update your system with packages from
+our PPA_ by adding ``ppa:gunicorn/ppa`` to your system's Software
+Sources. Use the ``apt-add-repository`` command from the
+``python-software-properties`` package to add the Gunicorn software source.
+
+ $ sudo apt-add-repository ppa:gunicorn/ppa
Or this PPA can be added to your system manually by copying the lines below
and adding them to your system's software sources::
- deb http://ppa.launchpad.net/bchesneau/gunicorn/ubuntu karmic main
- deb-src http://ppa.launchpad.net/bchesneau/gunicorn/ubuntu karmic main
+ deb http://ppa.launchpad.net/gunicorn/ppa/ubuntu lucid main
+ deb-src http://ppa.launchpad.net/gunicorn/ppa/ubuntu lucid main
+
+Replace 'lucid' with your Ubuntu distribution series.
Signing key
+++++++++++
::
- 1024R/15E5EB06
+ 1024R/5370FF2A
Fingerprint
+++++++++++
::
- 49AEEDFF5CDCD82CEA8AB4DABC981A8115E5EB06
+ FC7B41B54C9B8476D9EC22A2C6773E575370FF2A
.. _`GitHub Downloads`: http://github.com/benoitc/gunicorn/downloads
.. _`design docs`: design.html
View
1 examples/test.py
@@ -21,6 +21,5 @@ def app(environ, start_response):
('Content-Length', str(len(data))),
('X-Gunicorn-Version', __version__)
]
-
start_response(status, response_headers)
return iter([data])
View
6 gunicorn/app/django_wsgi.py
@@ -17,12 +17,13 @@
from django.conf import settings
from django.core.management.validation import get_validation_errors
from django.utils import translation
-from django.core.servers.basehttp import AdminMediaHandler
+
try:
from django.core.servers.basehttp import get_internal_wsgi_application
django14 = True
except ImportError:
from django.core.handlers.wsgi import WSGIHandler
+ from django.core.servers.basehttp import AdminMediaHandler
django14 = False
from gunicorn import util
@@ -108,4 +109,7 @@ def reload_django_settings():
def make_command_wsgi_application(admin_mediapath):
reload_django_settings()
+ if django14:
+ return make_wsgi_application()
+
return AdminMediaHandler(make_wsgi_application(), admin_mediapath)
View
3 gunicorn/arbiter.py
@@ -455,7 +455,8 @@ def spawn_worker(self):
except SystemExit:
raise
except:
- self.log.exception("Exception in worker process:")
+ self.log.debug("Exception in worker process:\n%s",
+ traceback.format_exc())
if not worker.booted:
sys.exit(self.WORKER_BOOT_ERROR)
sys.exit(-1)
View
2 gunicorn/config.py
@@ -273,7 +273,7 @@ def _wrapped(instance, req, environ):
elif largs == 2:
return wrap_post_request(val)
else:
- raise TypeError("Value must have an arity of: 3")
+ raise TypeError("Value must have an arity of: 3")
View
2 gunicorn/glogging.py
@@ -157,7 +157,7 @@ def access(self, resp, req, environ, request_time):
status = resp.status.split(None, 1)[0]
atoms = {
- 'h': environ['REMOTE_ADDR'],
+ 'h': environ.get('REMOTE_ADDR', '-'),
'l': '-',
'u': '-', # would be cool to get username from basic auth header
't': self.now(),
View
22 gunicorn/http/body.py
@@ -228,24 +228,20 @@ def readline(self, size=None):
return ""
line = self.buf.getvalue()
+ self.buf.truncate(0)
+ if len(line) < size:
+ line += self.reader.read(size - len(line))
+ extra_buf_data = line[size:]
+ line = line[:size]
+
idx = line.find("\n")
if idx >= 0:
ret = line[:idx+1]
- self.buf.truncate(0)
self.buf.write(line[idx+1:])
+ self.buf.write(extra_buf_data)
return ret
-
- self.buf.truncate(0)
- ch = ""
- buf = [line]
- lsize = len(line)
- while lsize < size and ch != "\n":
- ch = self.reader.read(1)
- if not len(ch):
- break
- lsize += 1
- buf.append(ch)
- return "".join(buf)
+ self.buf.write(extra_buf_data)
+ return line
def readlines(self, size=None):
ret = []
View
11 gunicorn/http/wsgi.py
@@ -39,10 +39,9 @@ def __getitem__(self, key):
return data
raise IndexError
-def create(req, sock, client, server, cfg):
- resp = Response(req, sock)
- environ = {
+def default_environ(req, sock, cfg):
+ return {
"wsgi.input": req.body,
"wsgi.errors": sys.stderr,
"wsgi.version": (1, 0),
@@ -58,6 +57,12 @@ def create(req, sock, client, server, cfg):
"SERVER_PROTOCOL": "HTTP/%s" % ".".join(map(str, req.version))
}
+
+def create(req, sock, client, server, cfg):
+ resp = Response(req, sock)
+
+ environ = default_environ(req, sock, cfg)
+
# authors should be aware that REMOTE_HOST and REMOTE_ADDR
# may not qualify the remote addr:
# http://www.ietf.org/rfc/rfc3875
View
7 gunicorn/util.py
@@ -125,8 +125,9 @@ def load_class(uri, default="sync", section="gunicorn.workers"):
return pkg_resources.load_entry_point("gunicorn",
section, uri)
- except ImportError:
- raise RuntimeError("class uri invalid or not found")
+ except ImportError, e:
+ raise RuntimeError("class uri invalid or not found: " +
+ "[%s]" % str(e))
klass = components.pop(-1)
mod = __import__('.'.join(components))
for comp in components[1:]:
@@ -343,7 +344,7 @@ def seed():
try:
random.seed(os.urandom(64))
except NotImplementedError:
- random.seed(random.random())
+ random.seed('%s.%s' % (time.time(), os.getpid()))
def check_is_writeable(path):
View
7 gunicorn/workers/async.py
@@ -26,6 +26,7 @@ def timeout_ctx(self):
raise NotImplementedError()
def handle(self, client, addr):
+ req = None
try:
parser = http.RequestParser(self.cfg, client)
try:
@@ -38,6 +39,8 @@ def handle(self, client, addr):
self.handle_request(req, client, addr)
except StopIteration, e:
self.log.debug("Closing connection. %s", e)
+ except Exception, e:
+ self.handle_error(req, client, addr, e)
except socket.error, e:
if e[0] not in (errno.EPIPE, errno.ECONNRESET):
self.log.exception("Socket error processing request.")
@@ -47,14 +50,14 @@ def handle(self, client, addr):
else:
self.log.debug("Ignoring EPIPE")
except Exception, e:
- self.handle_error(client, e)
+ self.handle_error(req, client, addr, e)
finally:
util.close(client)
def handle_request(self, req, sock, addr):
+ request_start = datetime.now()
try:
self.cfg.pre_request(self, req)
- request_start = datetime.now()
resp, environ = wsgi.create(req, sock, addr, self.address, self.cfg)
# rewrite client info (proxy mode)
View
75 gunicorn/workers/base.py
@@ -3,6 +3,7 @@
# This file is part of gunicorn released under the MIT license.
# See the NOTICE for more information.
+from datetime import datetime
import os
import signal
import sys
@@ -11,12 +12,11 @@
from gunicorn import util
from gunicorn.workers.workertmp import WorkerTmp
-
from gunicorn.http.errors import InvalidHeader, InvalidHeaderName, \
InvalidRequestLine, InvalidRequestMethod, InvalidHTTPVersion, \
LimitRequestLine, LimitRequestHeaders, \
InvalidProxyLine, ForbiddenProxyRequest
-
+from gunicorn.http.wsgi import default_environ, Response
class Worker(object):
@@ -126,42 +126,55 @@ def handle_exit(self, sig, frame):
self.alive = False
sys.exit(0)
- def handle_error(self, client, exc):
- status_int = 400
- reason = "Bad Request"
- unknownexc = False
-
- if isinstance(exc, InvalidRequestLine):
- mesg = "<p>Invalid Request Line '%s'</p>" % str(exc)
- elif isinstance(exc, InvalidRequestMethod):
- mesg = "<p>Invalid Method '%s'</p>" % str(exc)
- elif isinstance(exc, InvalidHTTPVersion):
- mesg = "<p>Invalid HTTP Version '%s'</p>" % str(exc)
- elif isinstance(exc, (InvalidHeaderName, InvalidHeader,)):
- mesg = "<p>Invalid Header '%s'</p>" % str(exc)
- elif isinstance(exc, LimitRequestLine):
- mesg = "<p>%s</p>" % str(exc)
- elif isinstance(exc, LimitRequestHeaders):
- mesg = "<p>Error parsing headers: '%s'</p>" % str(exc)
- elif isinstance(exc, InvalidProxyLine):
- mesg = "<p>Invalid Proxy Line '%s'</p>" % str(exc)
- elif isinstance(exc, ForbiddenProxyRequest):
- mesg = "<p>Request forbidden</p>"
- status_int = 403
- reason = "Forbidden"
+ def handle_error(self, req, client, addr, exc):
+ request_start = datetime.now()
+ if isinstance(exc, (InvalidRequestLine, InvalidRequestMethod,
+ InvalidHTTPVersion, InvalidHeader, InvalidHeaderName,
+ InvalidProxyLine, ForbiddenProxyRequest)):
+
+ status_int = 400
+ reason = "Bad Request"
+
+ if isinstance(exc, InvalidRequestLine):
+ mesg = "<p>Invalid Request Line '%s'</p>" % str(exc)
+ elif isinstance(exc, InvalidRequestMethod):
+ mesg = "<p>Invalid Method '%s'</p>" % str(exc)
+ elif isinstance(exc, InvalidHTTPVersion):
+ mesg = "<p>Invalid HTTP Version '%s'</p>" % str(exc)
+ elif isinstance(exc, (InvalidHeaderName, InvalidHeader,)):
+ mesg = "<p>Invalid Header '%s'</p>" % str(exc)
+ elif isinstance(exc, LimitRequestLine):
+ mesg = "<p>%s</p>" % str(exc)
+ elif isinstance(exc, LimitRequestHeaders):
+ mesg = "<p>Error parsing headers: '%s'</p>" % str(exc)
+ elif isinstance(exc, InvalidProxyLine):
+ mesg = "<p>Invalid Proxy Line '%s'</p>" % str(exc)
+ elif isinstance(exc, ForbiddenProxyRequest):
+ mesg = "<p>Request forbidden</p>"
+ status_int = 403
+ reason = "Forbidden"
+
+ self.log.debug("Invalid request from ip={ip}: {error}"\
+ "".format(ip=client.getpeername()[0],
+ error=repr(exc),
+ )
+ )
else:
self.log.exception("Error handling request")
status_int = 500
reason = "Internal Server Error"
mesg = ""
- unknownexc = True
- if not unknownexc:
- self.log.debug("Invalid request from ip={ip}: {error}"\
- "".format(ip=client.getpeername()[0],
- error=str(exc))
- )
+ if req is not None:
+ request_time = datetime.now() - request_start
+ environ = default_environ(req, client, self.cfg)
+ environ['REMOTE_ADDR'] = addr[0]
+ environ['REMOTE_PORT'] = str(addr[1])
+ resp = Response(req, client)
+ resp.status = "%s %s" % (status_int, reason)
+ resp.response_length = len(mesg)
+ self.log.access(resp, req, environ, request_time)
if self.debug:
tb = traceback.format_exc()
View
2 gunicorn/workers/ggevent.py
@@ -87,7 +87,7 @@ def handle_request(self, *args):
except gevent.GreenletExit:
pass
- if hasattr(gevent.core, 'dns_shutdown'):
+ if gevent.version_info[0] == 0:
def init_process(self):
#gevent 0.13 and older doesn't reinitialize dns for us after forking
View
5 gunicorn/workers/sync.py
@@ -65,6 +65,7 @@ def run(self):
raise
def handle(self, client, addr):
+ req = None
try:
parser = http.RequestParser(self.cfg, client)
req = parser.next()
@@ -77,7 +78,7 @@ def handle(self, client, addr):
else:
self.log.debug("Ignoring EPIPE")
except Exception, e:
- self.handle_error(client, e)
+ self.handle_error(req, client, addr, e)
finally:
util.close(client)
@@ -123,7 +124,7 @@ def handle_request(self, req, client, addr):
raise
except Exception, e:
# Only send back traceback in HTTP in debug mode.
- self.handle_error(client, e)
+ self.handle_error(req, client, addr, e)
return
finally:
try:
View
61 tests/004-test-http-body.py
@@ -0,0 +1,61 @@
+from StringIO import StringIO
+
+import t
+from gunicorn.http.body import Body
+
+
+def assert_readline(payload, size, expected):
+ body = Body(StringIO(payload))
+ t.eq(body.readline(size), expected)
+
+
+def test_readline_empty_body():
+ assert_readline("", None, "")
+ assert_readline("", 1, "")
+
+
+def test_readline_zero_size():
+ assert_readline("abc", 0, "")
+ assert_readline("\n", 0, "")
+
+
+def test_readline_new_line_before_size():
+ body = Body(StringIO("abc\ndef"))
+ t.eq(body.readline(4), "abc\n")
+ t.eq(body.readline(), "def")
+
+
+def test_readline_new_line_after_size():
+ body = Body(StringIO("abc\ndef"))
+ t.eq(body.readline(2), "ab")
+ t.eq(body.readline(), "c\n")
+
+
+def test_readline_no_new_line():
+ body = Body(StringIO("abcdef"))
+ t.eq(body.readline(), "abcdef")
+ body = Body(StringIO("abcdef"))
+ t.eq(body.readline(2), "ab")
+ t.eq(body.readline(2), "cd")
+ t.eq(body.readline(2), "ef")
+
+
+def test_readline_buffer_loaded():
+ reader = StringIO("abc\ndef")
+ body = Body(reader)
+ body.read(1) # load internal buffer
+ reader.write("g\nhi")
+ reader.seek(7)
+ t.eq(body.readline(), "bc\n")
+ t.eq(body.readline(), "defg\n")
+ t.eq(body.readline(), "hi")
+
+
+def test_readline_buffer_loaded_with_size():
+ body = Body(StringIO("abc\ndef"))
+ body.read(1) # load internal buffer
+ t.eq(body.readline(2), "bc")
+ t.eq(body.readline(2), "\n")
+ t.eq(body.readline(2), "de")
+ t.eq(body.readline(2), "f")
+

No commit comments for this range

Something went wrong with that request. Please try again.