How to add response time in gunicorn access log - python

I have a gunicorn *config.py and need to add response time to gunicorn access log:
Here's what I have:
...
accesslog = some_path/filename
access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"'
...
gunicorn version 19.7.1
Some more details:
*config.py didn't contain the seting access_log_format before, and I thought adding it might help, but even after I added and restarted the process, the access log contains the same parameters as before:
<ip> - - [16/Aug/2020:14:11:35 XDT] "POST /ws/v1/sessions?userId=<username> HTTP/1.1" 200 537 "-" "python-requests/2.22.0"
<ip> - - [16/Aug/2020:14:11:56 XDT] "DELETE /ws/v1/sessions HTTP/1.1" 200 139 "-" "python-requests/2.22.0"
<ip> - - [17/Aug/2020:04:05:40 XDT] "GET /ws/v1/data-specs HTTP/1.1" 200 35097 "-" "python-requests/2.22.0"
<ip> - - [17/Aug/2020:09:30:31 XDT] "GET /ws/v1/data-specs HTTP/1.1" 200 35097 "-" "python-requests/2.22.0"
I am new to python, gunicorn and web apis. I am unable to figure out how to add response time to the log. What am I doing wrong here? Please help.

From the documentation (https://docs.gunicorn.org/en/stable/settings.html#access-log-format)
The corresponding value for response time miliseconds is %(D)s

Related

Unable to get millisecond reading for gunicorn access log response time

I have altered gunicorn_config.py to have:
access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" %(T)s %(M)s %(D)s %(L)s'
T request time in seconds,
M request time in milliseconds,
D request time in microseconds,
L request time in decimal seconds
I want the response time.
I tested, and here is the output that I get
<ip> - - [19/Aug/2020:06:11:04 CDT] "DELETE /ws/v1/sessions HTTP/1.1" 200 139 "-" "python-requests/2.22.0" 0 - 13127 0.013127
<ip> - - [19/Aug/2020:06:11:12 CDT] "POST /ws/v1/sessions?userId=<name> HTTP/1.1" 200 928 "-" "python-requests/2.22.0" 0 - 36 518 0.036518
In the last part of the lines (say, 0 - 13127 0.013127), why does the millisecond reading give a "-"? I could not find out anything from the documentation. I am a novice to both gunicorn and python. Please help. Gunicorn version is 19.7.1, python3.4
Checked from gunicorn/config.py and gunicorn/glogging.py that millisecond is not implemented in the gunicorn version that I use.

websocket on port 443 with /socket.io under kubernetes not working

Trying to move my development environment to run on minikube.
The page loads but my page uses websockets on the same port/protocol that the index.html is loaded with (https in this case), and the websockets do no seem to be working correctly.
Here is an example of the correct output when run through nginx / python on my local development box.
127.0.0.1 - - [14/Sep/2018 14:14:35] "GET / HTTP/1.0" 200 -
127.0.0.1 - - [14/Sep/2018 14:14:35] "GET /static/jquery.min.js HTTP/1.0" 200 -
127.0.0.1 - - [14/Sep/2018 14:14:35] "GET /static/socket.io.min.js HTTP/1.0" 200 -
127.0.0.1 - - [14/Sep/2018 14:14:35] "GET /socket.io/?EIO=3&transport=polling&t=MNPIg-N HTTP/1.0" 200 -
127.0.0.1 - - [14/Sep/2018 14:14:35] "GET /favicon.ico HTTP/1.0" 404 -
127.0.0.1 - - [14/Sep/2018 14:14:35] "GET /favicon.ico HTTP/1.0" 404 -
127.0.0.1 - - [14/Sep/2018 14:14:35] "POST /socket.io/?EIO=3&transport=polling&t=MNPIg-o&sid=0570b4fe27f345e9b11858b3acb40a6e HTTP/1.0" 200 -
127.0.0.1 - - [14/Sep/2018 14:14:35] "GET /socket.io/?EIO=3&transport=polling&t=MNPIg-r&sid=0570b4fe27f345e9b11858b3acb40a6e HTTP/1.0" 200 -
127.0.0.1 - - [14/Sep/2018 14:14:35] "POST /socket.io/?EIO=3&transport=polling&t=MNPIg_x&sid=0570b4fe27f345e9b11858b3acb40a6e HTTP/1.0" 200 -
127.0.0.1 - - [14/Sep/2018 14:14:35] "GET /socket.io/?EIO=3&transport=polling&t=MNPIg_w&sid=0570b4fe27f345e9b11858b3acb40a6e HTTP/1.0" 200 -
127.0.0.1 - - [14/Sep/2018 14:14:40] "GET /socket.io/?EIO=3&transport=polling&t=MNPIh0L&sid=0570b4fe27f345e9b11858b3acb40a6e HTTP/1.0" 200 -
127.0.0.1 - - [14/Sep/2018 14:14:45] "GET /socket.io/?EIO=3&transport=polling&t=MNPIiE3&sid=0570b4fe27f345e9b11858b3acb40a6e HTTP/1.0" 200 -
127.0.0.1 - - [14/Sep/2018 14:14:50] "GET /socket.io/?EIO=3&transport=polling&t=MNPIjSI&sid=0570b4fe27f345e9b11858b3acb40a6e HTTP/1.0" 200 -
127.0.0.1 - - [14/Sep/2018 14:14:55] "GET /socket.io/?EIO=3&transport=polling&t=MNPIkgS&sid=0570b4fe27f345e9b11858b3acb40a6e HTTP/1.0" 200 -
Notice how there is a GET every 5 seconds (that's a timer running on the page)
When running on Kubernetes, The page loads and the timer shows up as if the websocket has worked, however I show no logs where the websocket is having a GET or POST after the initial one.
192.168.99.1,172.17.0.7 - - [14/Sep/2018 18:24:03] "GET /static/jquery.min.js HTTP/1.1" 304 1210 0.008244
192.168.99.1,172.17.0.7 - - [14/Sep/2018 18:24:03] "GET /static/socket.io.min.js HTTP/1.1" 304 1210 0.009271
(10) accepted ('172.17.0.7', 34444)
192.168.99.1,172.17.0.7 - - [14/Sep/2018 18:24:04] "GET /socket.io/?EIO=3&transport=polling&t=MNPKrsy HTTP/1.1" 200 379 0.003682
(10) accepted ('172.17.0.7', 34446)
192.168.99.1,172.17.0.7 - - [14/Sep/2018 18:24:04] "GET /favicon.ico HTTP/1.1" 404 1314 0.004694
(10) accepted ('172.17.0.7', 34448)
(10) accepted ('172.17.0.7', 34450)
(10) accepted ('172.17.0.7', 34452)
192.168.99.1,172.17.0.7 - - [14/Sep/2018 18:24:04] "GET /socket.io/?EIO=3&transport=polling&t=MNPKrtD&sid=77d4755c524f47c2948b9c36da007b85 HTTP/1.1" 200 210 0.000749
192.168.99.1,172.17.0.7 - - [14/Sep/2018 18:24:04] "POST /socket.io/?EIO=3&transport=polling&t=MNPKrtB&sid=77d4755c524f47c2948b9c36da007b85 HTTP/1.1" 200 194 0.002632
(10) accepted ('172.17.0.7', 34454)
192.168.99.1,172.17.0.7 - - [14/Sep/2018 18:24:04] "GET /favicon.ico HTTP/1.1" 404 1314 0.002388
The Ingress is setup as follows:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-service
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: websitev2-cluster-ip-service
servicePort: 8080
As mentioned before, the websocket does not reside on a different port and it is instanciated in javascript as:
namespace = '/socket';
var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace);
Are there any special requirements to get websockets to work? I do not believe i need a special route because the URI needs to be sent to the same location as everything else, and on the same port.
EDIT: MORE DETAILS
My website has a form, that when submitted, executes the following code:
$('form#job').submit(function(event) {
var nameValue = JSON.stringify($(event.target).serializeArray());
console.log(nameValue)
socket.emit('job_submit', {data: nameValue});
return false;
});
On the python side, I have my socket code, which should get hit once a user clicks the submit button.
#socketio.on('job_submit', namespace='/socket')
def job_submit(message):
print('recieved job_submit message from client')
# kick off subjob in celery task
data = unstringify(message)
print('data = {0}'.format(data))
sessiondata = dict(session)
print('sessiondata = {}'.format(sessiondata))
subjobstart.delay(sessiondata, request.sid, data)
In my logs I am not receiving any "recieved job_submit message from client" messages when the submit button is clicked, which means the javascript is trying to send a websocket emit to the python server, but the message is never getting there.
Emits from python to the client page are working as the time is getting updated on the site.
So not exactly sure what changed as it worked on test box, apparently the issue lied in the form validation I was doing. Once I put in a novalidate option to temporarily bypass the form checking, the form was then able to be submitted and I did not have any websocket issues after all.
Hopefully this post can help someone with the code posted instead.

Periodic Django Logs in Terminal

I am new to Django and this question may seem to be easy. In the terminal where "python manage.py runserver" is executed, the following logs periodically appear.
[30/Sep/2015 02:36:02] "GET /messages/check/?_=1443574208652 HTTP/1.1" 200 1
[30/Sep/2015 02:36:08] "GET /notifications/check/?_=1443574208653 HTTP/1.1" 200 1
[30/Sep/2015 02:36:08] "GET /feeds/update/?first_feed=13&last_feed=6&feed_source=all&_=1443574208655 HTTP/1.1" 200 173
[30/Sep/2015 02:36:08] "GET /feeds/check/?last_feed=13&feed_source=all&_=1443574208654 HTTP/1.1" 200 1
[30/Sep/2015 02:36:39] "GET /notifications/check/?_=1443574208656 HTTP/1.1" 200 1
[30/Sep/2015 02:36:39] "GET /feeds/check/?last_feed=13&feed_source=all&_=1443574208658 HTTP/1.1" 200 1
[30/Sep/2015 02:36:39] "GET /feeds/update/?first_feed=13&last_feed=6&feed_source=all&_=1443574208657 HTTP/1.1" 200 173
[30/Sep/2015 02:37:03] "GET /messages/check/?_=1443574208659 HTTP/1.1" 200 1
My Django virtual environment is as follows:
bleach==1.4
dj-database-url==0.3.0
dj-static==0.0.6
Django==1.6.5
gunicorn==19.3.0
html5lib==0.9999999
Markdown==2.4.1
Pillow==2.4.0
psycopg2==2.6.1
python-decouple==2.2
six==1.9.0
South==0.8.4
static3==0.6.1
Unipath==1.0
Questions are:
Why does the logs periodically appear? I guess there is a background task running.But Celery package is not used here.
How to configure the logs, for example, displaying one more logs such as:
/followers/check/?_=9896886900907 HTTP/1.1
What do "?_" and the long string of numbers stand for? I can understand the "?first_feed=13" means the querying parameter in Django request object.
GET /notifications/check/?_=1443574208656
When Django is run in development mode (with runserver) it prints a line for all HTTP requests received to the console.
All of them are coming from the outside, browsers, feed readers...
The parameters you are wondering about are GET query parameters. The ? is the delimiter so, _ is the key of the argument.
In development mode the logging is defined by default. If you want to have logging on your production system or more logging, read https://docs.djangoproject.com/en/1.8/topics/logging/ .

Degguging bottle does not work

I cannot debug bottle. I have 500 errors in dev. I am using the latest bottle wit the debug=True flag.
if __name__ == "__main__":
# Interactive mode
run(host='localhost', port=8049,debug=True)
This is what I get.....
Bottle v0.11.rc1 server starting up (using WSGIRefServer())...
Listening on http://localhost:8049/
Hit Ctrl-C to quit.
localhost - - [30/Sep/2012 18:59:13] "POST /bidder/ HTTP/1.1" 500 1407
localhost - - [30/Sep/2012 18:59:14] "POST /bidder/ HTTP/1.1" 500 1407
localhost - - [30/Sep/2012 18:59:14] "POST /bidder/ HTTP/1.1" 500 1407
localhost - - [30/Sep/2012 18:59:15] "POST /bidder/ HTTP/1.1" 500 1407
localhost - - [30/Sep/2012 18:59:15] "POST /bidder/ HTTP/1.1" 500 1407
I don't mind the 500 as long I can find out why?
The debug=False keyword parameter in the run() function is only available in the current development version; the current 0.10.x code itself ignores doesn't yet support it.
Instead, use the debug() function instead:
if __name__ == "__main__":
# Interactive mode
run(host='localhost', port=8049)
debug(True)
or run with the --debug command-line flag.
You may have to import the debug function from bottle if you haven't done so already. The tutorial explains debug mode in more detail.

Every request hits server twice in Appengine

I have small app in appengine. Every request hits the server twice in my local dev server.
In debug mode i can see that the get method called twice.
Its happening in both chrome and firefox browsers.
here is the log from my localserver..
INFO 2011-03-12 00:44:31,076 dev_appserver.py:3317] "GET /movie/tanu_weds_manu/rating-review-video HTTP/1.1" 200 -
INFO 2011-03-12 00:44:32,345 dev_appserver.py:3317] "GET /css/fb.css HTTP/1.1" 200 -
INFO 2011-03-12 00:44:32,588 dev_appserver.py:3317] "GET /css/wianga-movie.0.1.css HTTP/1.1" 200 -
INFO 2011-03-12 00:45:46,648 dev_appserver.py:3317] "GET /movie/tanu_weds_manu/rating-review-video HTTP/1.1" 200 -
INFO 2011-03-12 00:45:46,911 dev_appserver.py:3317] "GET /img/wianga-fb-50.gif HTTP/1.1" 200 -
INFO 2011-03-12 00:45:47,177 dev_appserver.py:3317] "GET /img/arrow_green.gif HTTP/1.1" 200 -
INFO 2011-03-12 00:45:47,470 dev_appserver.py:3317] "GET /image/movie/tanu_weds_manu HTTP/1.1" 200 -
INFO 2011-03-12 00:45:47,717 dev_appserver.py:3317] "GET /js/jquery.qtip-1.0.0-rc3.min.js HTTP/1.1" 200 -
INFO 2011-03-12 00:45:47,970 dev_appserver.py:3317] "GET /js/wianga.0.1.js HTTP/1.1" 200 -
INFO 2011-03-12 00:46:37,473 dev_appserver.py:3317] "GET /movie/tanu_weds_manu/rating-review-video HTTP/1.1" 200 -
Updated: Its getting worse,i cheked the logs in app console.There it hits more than 3 times for a request.
handlers:
- url: /favicon.ico
static_files: static/img/favicon.ico
upload: static/img/favicon.ico
- url: /robots.txt
static_files: static/robots.txt
upload: static/robots.txt
- url: /img
static_dir: static/img
- url: /images
static_dir: static/images
- url: /css
static_dir: static/css
- url: /js
static_dir: static/js
- url: /image/.*
script: /wianga/pages/common/ImageController.py
- url: /task/.*
script: /wianga/pages/task/TaskController.py
- url: /browse/.*
script: /wianga/site/Browse.py
- url: /movie/(.*)/rating-review-video/
script: /wianga/site/MoviePage.py
- url: /movie/(.*)/rating-review-video
script: /wianga/site/MoviePage.py
- url: /404
script: /wianga/404/404.py
- url: /api/.*
script: /wianga/api/ApiController.py
- url: /.*
script: /wianga/site/Home.py
Am getting same behavior in hellowrld application from appengine turorial...
App.yaml
version: 1
runtime: python
api_version: 1
handlers:
- url: /.*
script: helloworld.py
Log for hello world example for single request...
INFO 2011-03-12 06:08:06,299 dev_appserver_main.py:507] Running application wianga-movie on port 8080: http://localhost:8080
INFO 2011-03-12 06:08:12,506 dev_appserver.py:3317] "GET / HTTP/1.1" 200 -
INFO 2011-03-12 06:08:13,721 dev_appserver.py:3317] "GET / HTTP/1.1" 200 -
INFO 2011-03-12 06:08:13,838 dev_appserver.py:3317] "GET /favicon.ico HTTP/1.1" 200 -
INFO 2011-03-12 06:08:13,953 dev_appserver.py:3317] "GET / HTTP/1.1" 200 -
When I set up my app.yaml I just poured through this page: http://code.google.com/appengine/docs/python/config/appconfig.html
You have to think like a regular expression parser. Anything that fails to match the preceding expressions will fall through to your wildcard handler and cause weirdness.
One thing I notice is that you should add login: admin to your task queue handler. This will prevent external requests from hitting that URL accidentally.
Also, when you are submitting tasks to your handler, if you don't include the trailing slash (/task?blah=something instead of /task/?blah=something) the request would fall through to your wildcard handler and get sent to Home.py. That could also happen for /image/, /browse/ and /api/. You should put logging calls into those handlers to make sure they are getting called when expected.
Nothing jumps out at me as obviously wrong in your app.yaml though. But since there are GETs showing up in your log, that indicates that something is requesting that URL, and it's not just the get method getting called twice internally.
Edit:
Hold on a sec, just noticed that you have this in your app.yaml twice. You shouldn't need to do that.
- url: /movie/(.*)/rating-review-video/
script: /wianga/site/MoviePage.py
- url: /movie/(.*)/rating-review-video
script: /wianga/site/MoviePage.py`
Try replacing with:
- url: /movie/(.*)/rating-review-video.*
script: /wianga/site/MoviePage.py`
Edit2:
Try adding this to the top of your get method:
logging.info('environ: ' + str(self.request._environ))
Pop the output into a beautifier ( http://jsbeautifier.org/ ) to make it more readable, and take a look at the REQUEST_METHOD, QUERY_STRING, HTTP_USER_AGENT, HTTP_COOKIE, PATH_INFO, and HTTP_REFERER params to see where the requests are actually coming from. If they are all coming from your browser then there is something weird in your html, like hidden iframes (are you using Channel API?).
Also, try going to http://localhost:8080/_ah/admin/queues and making sure there aren't any old tasks hanging around.

Categories