How to capture STDOUT of a Python process running under IIS, FastCGI, and WSGI?
Asked Answered
S

1

8

I have a Python Flask app. When I run it from PowerShell, I can see the stream of output coming from calls to functions like print() and logging.info() throughout my code.

When I point IIS to my app and have it run through FastCGI with a web.config file, where does that output stream go? How can I capture it to a log file?

Suave answered 6/8, 2015 at 18:9 Comment(0)
T
5

There are 3 kinds of log files when you use FastCGI/WSGI.

Let's name them:

  • WSGI log
    • File name from the example below: wsgi_myapp.log
    • gets the stream (StdOut, StdErr) from wsgi main script
    • For example when you publish new version of your page to the server, wsgi will restart and the messages about restarting goes there.
    • Another example is when your application encounters uncaught error, it saves the traceback into this file
  • App log
    • File name from the example below: myapp.log
    • Here goes everything what you want to log throught app.logger.LEVEL("..."), considering the right LEVEL is set on the logger as well as on the handler
  • HTTP requests log
    • Not a part of my code example below
    • The logs of the requests received by your HTTP server
    • You can change the location and behavior of this log from within IIS Logging settings of the web page
    • you can see these during the development alongside your own prints and log messages
    • Example from flask: "[2019-01-12 21:08:00,748] INFO in _internal: 127.0.0.1 - - [12/Jan/2019 21:08:00] "GET /static/js/jquery-3.3.1.min.js HTTP/1.1" 304 -
    • Example from ISS: 2019-01-12 20:42:41 10.175.214.88 GET /static/js/jquery-ui.min.js 80 ****USER**** ****IP**** Mozilla/5.0+(Windows+NT+10.0;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/70.0.3538.110+Safari/537.36 http://yourweb.com/smthing 304 0 0 1875

See this example:

from flask import Flask
from logging.config import dictConfig

dictConfig({
    'version': 1,
    'formatters': {'default': {
        'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s',
    }},
    'handlers': {
        'wsgi': {
            'class': 'logging.StreamHandler',
            'formatter': 'default'
        },
        'custom_handler': {
            'class': 'logging.FileHandler',
            'formatter': 'default',
            'filename': r'C:\inetpub\wwwroot\myapp\logs\myapp.log'
        }
    },
    'root': {
        'level': 'INFO',
        'handlers': ['wsgi', 'custom_handler']
    }
})

app = Flask(__name__)

# other imports using logger should go here
# from a import b
# ...

and the web.config file:

<configuration>
  <system.webServer>
    <handlers>
      <remove name="Python FastCGI" />
      <add name="Python FastCGI" path="*" verb="*" modules="FastCgiModule" scriptProcessor="E:\Python362_64\python.exe|E:\Python362_64\Lib\site-packages\wfastcgi.py" resourceType="Unspecified" requireAccess="Script" />
    </handlers>
        <urlCompression doStaticCompression="true" doDynamicCompression="true" />
  </system.webServer>
  <appSettings>
    <!-- Required settings -->
    <add key="WSGI_HANDLER" value="myapp.app" />
    <add key="PYTHONPATH" value="C:\inetpub\wwwroot\myapp" />
    <add key="SCRIPT_NAME" value="/myapp" />
    <add key="WSGI_LOG" value="C:\inetpub\wwwroot\myapp\logs\wsgi_myapp.log" />
    <add key="WSGI_RESTART_FILE_REGEX" value=".*((\.py)|(\.config))$" />
  </appSettings>
</configuration>
Twentieth answered 13/11, 2018 at 11:24 Comment(1)
Could you clarify what goes into wsgi_myapp.log vs myapp.log?Meagan

© 2022 - 2024 — McMap. All rights reserved.