1

Here is my problem. I have an application which prints some traces to the standard output using logging module. Now, I want to be able to read those traces at the same time in order to wait for specific trace I need.

This is for the testing purpose. So for example, if wanted trace does not occur in about 2 seconds, test fails.

I know I can read output of another scripts by using something like this:

import subprocess
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
while True:
    line = p.stdout.readline()
    print line
    if line == '' and p.poll() != None:
        break

But, how can I do something similar from the script itself? Thanks in advance.

EDIT

So, since my problem was expecting certain trace to appear while the Python application is running, and since I couldn't find a simple way to do so from the application itself, I decided to start the application (as suggested in comments) from another script.

The module I found very helpful, and easier to use than subprocess module, is pexpect module.

7
  • 2
    ... this sounds like the XY problem. You want a piece of your program (a thread?) to wait for a certain "state" of an other piece of your program (an other thread)... the proper way to do that is using synchronization primitives. Commented Aug 27, 2018 at 9:42
  • 1
    Wrong design - specially considering that the logger might be reconfigured to write elsewhere. You'd be better using a proper way of signaling a given condition is satisfied. Commented Aug 27, 2018 at 9:43
  • Your script knows when it is logging something, why does it need to read its own logs? Commented Aug 27, 2018 at 9:44
  • It is for the testing purposes. Wait for specific trace, if there is not such trace for about 2 seconds, test fails. Commented Aug 27, 2018 at 9:45
  • Is your testing script a separate file? Commented Aug 27, 2018 at 9:57

3 Answers 3

2

If you want to do some pre-processing of the logger messages you can do something like:

#!/usr/bin/python

import sys
import logging
import time
import types

def debug_wrapper(self,msg):
  if( hasattr(self,'last_time_seen') and 'message' in msg):
    print("INFO: seconds past since last time seen "+str(time.time()-self.last_time_seen))
  self.last_time_seen = time.time()
  self.debug_original(msg)

logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
logger = logging.getLogger("test")

logger.debug_original = logger.debug
logger.debug = types.MethodType(debug_wrapper, logger)

while True:
  logger.debug("INFO: some message.")
  time.sleep(1)

This works by replacing the original debug function of the logger object with your custom debug_wrapper function, in which you can do whatever processing you want, like for example, storing the last time you have seen a message.

Sign up to request clarification or add additional context in comments.

Comments

1

You can store the script output to a file in real-time and then read its content within the script in real-time(as the contents in the output file is updating dynamically).

To store the script output to a file in real-time, you may use unbuffer which comes with the expect package.

sudo apt-get install expect

Then, while running the script use:

unbuffer python script.py > output.txt

You have to just print the output in the script , which will be dynamically updating to the output file. And hence, read that file each time.

Also, use > for overwriting old or creating new file and >> for appending the contents in previously created output.txt file.

Comments

0

If you want to record the output from print statement in other Python code, you can redirect sys.stdout to string like file object as follows:

import io
import sys

def foo():
    print("hello world, what else ?")

stream = io.StringIO()
sys.stdout = stream
try:
    foo()
finally:
    sys.stdout = sys.__stdout__

print(stream.getvalue())

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.