0

I want to read the last three lines from the kernel log /var/log/messages in a loop.

for i in xrange(0,100): 
    # do_stuff()
    file = open('/var/log/messages')
    lines = file.readlines()[-3:]
    # analyse_stuff()
    file.close()

But I have a problem with this code:

 [...]
 1013477960613797 1013477960959759 1013477961174602 
 1013477960613797 1013477960959759 1013477961174602 
 1013477960613797 1013477960959759 1013477961174602 
 1013477960613797 1013477960959759 1013477961174602 
 1013477973551967 1013477973773506 1013477977678559 
 1013477973551967 1013477973773506 1013477977678559 
 1013477973551967 1013477973773506 1013477977678559 
 1013477973551967 1013477973773506 1013477977678559 
 1013477973551967 1013477973773506 1013477977678559 
 1013477973551967 1013477973773506 1013477977678559 
 1013477973551967 1013477973773506 1013477977678559 
 1013477973551967 1013477973773506 1013477977678559 
 1013477973551967 1013477973773506 1013477977678559 
 1013477973551967 1013477973773506 1013477977678559 
 1013477973551967 1013477973773506 1013477977678559 
 1013477973551967 1013477973773506 1013477977678559 
 1013477973551967 1013477973773506 1013477977678559 
 1013477973551967 1013477973773506 1013477977678559 
 1013477973551967 1013477973773506 1013477977678559 
 1013477973551967 1013477973773506 1013477977678559 
 1013477973551967 1013477973773506 1013477977678559 
 1013477973551967 1013477973773506 1013477977678559 
 1013477973551967 1013477973773506 1013477977678559 
 1013477973551967 1013477973773506 1013477977678559 
 1013477973551967 1013477973773506 1013477977678559 
 1013477973551967 1013477973773506 1013477977678559 
 1013477973551967 1013477973773506 1013477977678559
 1013477986756370 1013477990527612 1013477990834895 
 1013477986756370 1013477990527612 1013477990834895 
 1013477986756370 1013477990527612 1013477990834895
 1013477986756370 1013477990527612 1013477990834895
 1013477986756370 1013477990527612 1013477990834895
 1013477986756370 1013477990527612 1013477990834895
 1013477986756370 1013477990527612 1013477990834895
 1013477986756370 1013477990527612 1013477990834895
 [...]

As you can see, values are repeated many times. do_stuff() executes a binary, which issues three log messages. analyse_stuff() will analyse the three lines and does magic I always close the file and reopen it, because I thought this would resolve the problem, but it doesn't. Any idea what happens?

samuirai
  • 762
  • 1
  • 9
  • 25
  • 3
    [Why not use tail command?](http://stackoverflow.com/questions/136168/get-last-n-lines-of-a-file-with-python-similar-to-tail) – m0skit0 Jun 22 '12 at 09:40
  • I will probably use `tail`, but I prefer to do it in python directly, because the script has to make some analysis. This is only the important snippet. – samuirai Jun 22 '12 at 09:45
  • Check the [tail recipe](http://code.activestate.com/recipes/157035-tail-f-in-python/) on activestate. – georg Jun 22 '12 at 09:50
  • with that for loop, you open log file for 100 times and read lasts 3 lines for 100 times. I dont know why do have to use loop like that. If you need some delay, just use time.sleep(). – hungnv Jun 22 '12 at 16:39

1 Answers1

4

I would normally use tail, but if you really only want the last 'n' lines, and don't care too much about following (similar to 'tail -f'), then your simplest option is something like:

from collections import deque
last3 = deque(open('/path/to/your/file'), 3)
print last3

deque will consume line by line, discarding the oldest entries to keep a constraint of 3 lines. Look at http://docs.python.org/library/collections.html#collections.deque for more information

Jon Clements
  • 138,671
  • 33
  • 247
  • 280