10

How can I save the output from the console like

"192.168.1.1 - - [18/Aug/2014 12:05:59] code 404, message File not found"

to a file?

Here is the code:

import SimpleHTTPServer
import SocketServer

PORT = 1548

Handler = SimpleHTTPServer.SimpleHTTPRequestHandler

httpd = SocketServer.TCPServer(("", PORT), Handler)

print "serving at port", PORT

httpd.serve_forever()
Samantha
  • 383
  • 1
  • 2
  • 12
  • if i try LOG_FILENAME = 'logger1.txt' logging.basicConfig(filename=LOG_FILENAME, level=logging.DEBUG) nothing happen. He just creates the file without writing to it. – Samantha Aug 18 '14 at 10:17
  • I can tell you that `python example.py > log.txt 2>&1` does NOT work. I guess the logging mechanism must realize that stderr is not connected to a tty. – Bruno Bronosky Nov 30 '17 at 17:23

2 Answers2

22

BaseHTTPRequestHandler.log_message() prints all log messages by writing to sys.stderr. You have two choices:

1) Continue using BaseHTTPRequestHandler.log_message(), but change the value of sys.stderr:

import SimpleHTTPServer
import SocketServer

PORT = 1548

Handler = SimpleHTTPServer.SimpleHTTPRequestHandler

httpd = SocketServer.TCPServer(("", PORT), Handler)

print "serving at port", PORT

import sys
buffer = 1
sys.stderr = open('logfile.txt', 'w', buffer)
httpd.serve_forever()

2) Create a new xxxRequestHandler class, replacing .log_message():

import SimpleHTTPServer
import SocketServer
import sys

PORT = 1548

class MyHTTPHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
    buffer = 1
    log_file = open('logfile.txt', 'w', buffer)
    def log_message(self, format, *args):
        self.log_file.write("%s - - [%s] %s\n" %
                            (self.client_address[0],
                             self.log_date_time_string(),
                             format%args))

Handler = MyHTTPHandler

httpd = SocketServer.TCPServer(("", PORT), Handler)

print "serving at port", PORT

httpd.serve_forever()
Bruno Bronosky
  • 66,273
  • 12
  • 162
  • 149
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
  • 1
    You should add a `self.log_file.flush()` after the write. – ErikR Aug 02 '16 at 19:58
  • @BrunoBronosky Yes, I tested it with Python 2.7.12. For clarity, I have edited my answer to include a complete program rather than a fragment. – Robᵩ Nov 30 '17 at 20:18
  • Thank you @Robᵩ. Turns out that it was a buffering problem. – Bruno Bronosky Nov 30 '17 at 21:58
  • Using Python 3.4.3 I found that setting the buffer to 1 worked for "line buffering" as [described in the docs](https://docs.python.org/2/library/functions.html#open). But setting it to anything larger (I wanted 512 so logs would get written every ~4 calls) caused it to buffer the full `io.DEFAULT_BUFFER_SIZE` (8192 in my case). In my testing, I never made 131 calls required to fill the buffer. So that was the main reason for my confusion. I think that is a bug in Python or Linux/C/etc. – Bruno Bronosky Dec 01 '17 at 17:01
  • This code works! Thanks ... Btw, what is the meaning of `buffer` in this code? –  Jan 02 '19 at 15:02
1

I have used BaseHTTPServer instead of SimpleHTTPServer.

There you go:

#!/usr/bin/python
from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer

PORT_NUMBER = 5451

#This class will handles any incoming request from
#the browser 
class myHandler(BaseHTTPRequestHandler):

    #Handler for the GET requests
    def do_GET(self):
        self.send_response(200)
        #self.send_header('Content-type','text/html')
        self.end_headers()
        text_file = open("ip.txt", "a")
        text_file.write(str(self.client_address) + "\n")
        text_file.close()
        # Send the html message
        #self.wfile.write("Hello World !")

        return

try:
    #Create a web server and define the handler to manage the
    #incoming request
    server = HTTPServer(('', PORT_NUMBER), myHandler)
    print 'Started httpserver on port ' , PORT_NUMBER

    #Wait forever for incoming htto requests
    server.serve_forever()

except KeyboardInterrupt:
    print '^C received, shutting down the web server'
    server.socket.close()
Samantha
  • 383
  • 1
  • 2
  • 12