0

I have a class inheriting from threading.Thread. For some reason the thread does not want to start.

Here is my code:

import time,threading,re,socket


class PyWatch(threading.Thread):

    filename = ""


    def __init__(self,filename):
        threading.Thread.__init__(self)
        print "initiating..."
        self.filename = filename


     def run(self):
        print "running..."
        thefile = open (self.filename)
        thefile.seek(0,2)      # Go to the end of the file
        while True:
                line = thefile.readline()
                if not line:
                     time.sleep(0.1)    # Sleep briefly
                     continue
                yield line
                self.process(line)


    def process(self,line):
        ip =  self.filterIPFromLine(line)
        print ip                

    def filterIPFromLine(self,line):
        ip = None
        if '/var/ossec/active-response/bin/firewall-drop.sh' in  str( line ).lower():
            ip = re.match( "(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])" )

            try:
                socket.inet_aton(ip[0])
                ip = ip[0]
            except socket.error:
                pass
        return ip


tom = PyWatch('example.log')
tom.start()

The code is running, it returns no errors, but for some reason it never reaches the run() part.

johnsyweb
  • 136,902
  • 23
  • 188
  • 247
Lucas Kauffman
  • 6,789
  • 15
  • 60
  • 86

2 Answers2

5

You need to remove the line:

            yield line

This is causing run() not to, well... run! It's not obvious why it's there in the first place.

According to the Python Documentation, the yield expression is only used when defining a generator function, and when a generator function is called, it returns an iterator known as a generator. That generator then controls the execution of a generator function. The execution starts when one of the generator's methods is called.

Since you're not calling any generator methods (such as next()), then the function doesn't execute.

Here is a quick demonstration:

Python 2.7.2 (default, Jun 20 2012, 16:23:33) 
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def fun():
...     print 'Starting'
...     for i in range(10):
...             yield i
... 
>>> fun()
<generator object fun at 0x10678c460>
>>> _.next()
Starting
0
>>> 

There is an excellent explanation of the yield expression as an answer to What does the "yield" keyword do in Python? .

Community
  • 1
  • 1
johnsyweb
  • 136,902
  • 23
  • 188
  • 247
2

I can't reproduce the problem:

When I run your code, I get:

initiating...
running...

Which indicates that the run() method does execute correctly.

Did you correctly import the threading module on top of your code ?

import threading
Jeremy
  • 393
  • 3
  • 10
  • Updated the code, this is my full code, if I delete a few methods it does indeed run. I don't get it what adding methods would change :/ – Lucas Kauffman Dec 23 '12 at 22:31
  • @LucasKauffman: It's not adding *methods* that changed your output, but what you have added to **`run()`**. See my answer. – johnsyweb Dec 24 '12 at 01:01