hardbyte / python-can

The can package provides controller area network support for Python developers
https://python-can.readthedocs.io
GNU Lesser General Public License v3.0
1.29k stars 602 forks source link

can_logger.py dose not write to file. #72

Closed hardbyte closed 8 years ago

hardbyte commented 8 years ago

Originally reported by: Mathias Giacomuzzi (Bitbucket: mgiaco, GitHub: mgiaco)


So I think there is something wrong with the current implementation of the can_logger. So tried to start a can logger with

#!python

python can_logger.py  -f ./log.txt

So here I get nothing.

#!python

python can_logger.py 

Here I get my messages.

So I dive into the implementation and there I found out that the file write has no flush. And what I read in the docs someone must close the file, otherwise it will not write it if no flush is used. So I see the Printer hast a del (destructor) which should close the file. But this destructor will never be called in this implementation. See also here: http://stackoverflow.com/questions/865115/how-do-i-correctly-clean-up-a-python-object

So dose this really work for other?

Is there a way to change the Listeners to the with statement usage? So I tried that but then I have some problem with the rx thread.

#!python

    with can.Printer(results.log_file) as printer:
        notifier = can.Notifier(bus, [printer], timeout=0.1)

        try:
            while True:
                time.sleep(1)
        except KeyboardInterrupt:
            print('Shutdown Bus and Exit.')
            bus.shutdown()

And in CAN.py I add:

#!python

    def __enter__(self):
        print("enter..")
        return self

    def __exit__(self, type, value, traceback):
        print("exit..")
        self.output_file.write("\n")
        if self.output_file:
            print("close exit ..")
            self.output_file.close()

It works now but I get an exception on close.

#!shell

(py35_python_can) e:\bitbucket_hg\python-can\bin>python can_logger.py  -f ./temp.txt
Can Logger (Started on 2016-07-19 09:49:10.052735)

enter..
Shutdown Bus and Exit.
exit..
close exit ..
Exception in thread Thread-1:
Traceback (most recent call last):
  File "C:\Python35\lib\threading.py", line 914, in _bootstrap_inner
    self.run()
  File "C:\Python35\lib\threading.py", line 862, in run
    self._target(*self._args, **self._kwargs)
  File "e:\bitbucket_hg\python-can\can\notifier.py", line 32, in rx_thread
    msg = self.bus.recv(self.timeout)
  File "e:\bitbucket_hg\python-can\can\interfaces\pcan.py", line 169, in recv
    raise Exception(self._get_formatted_error(result[0]))
Exception: Der PCAN Kanal ist nicht initialisiert oder der Initialisierungsvorgang ist fehlgeschlagen

Exception ignored in: <bound method Printer.__del__ of <can.CAN.Printer object at 0x00000000015C3550>>
Traceback (most recent call last):
  File "e:\bitbucket_hg\python-can\can\CAN.py", line 97, in __del__
ValueError: I/O operation on closed file.

(py35_python_can) e:\bitbucket_hg\python-can\bin>

mathias


hardbyte commented 8 years ago

Original comment by Brian Thorne (Bitbucket: hardbyte, GitHub: hardbyte):


The logger not writing to file has been addressed and will be part of the next release.

hardbyte commented 8 years ago

Original comment by Brian Thorne (Bitbucket: hardbyte, GitHub: hardbyte):


Thanks for the bug report Mathias, sorry it has taken me a while to look at it.

A context manager would indeed be a much nicer api for the Listeners.

In this case I wonder if we gain anything having the Listener's extra thread. Perhaps we can just connect the Printer to the Bus. E.g:


    with can.Printer(results.log_file) as printer:
        for msg in bus:
            printer.on_message_received(msg)

The problem in your solution appears to be that after __exit__ but before the whole program has stopped a message is received by the printer.

I belive the fix being that __exit__ should set something in the Printer that disables handling messages in the on_message_received method. For instance a finished boolean. If you have this all going would you mind contributing it back? Feel free to be more ambitious with changes if you wish!