Python 2.7 - мгновенно перенаправить вывод в файл журнала - PullRequest
0 голосов
/ 12 февраля 2019

Python test.py скрипт собирает данные непрерывно.Для выхода из скрипта - ожидается ctrl / c.

Файл test.log пуст во время работы скрипта.Вывод в test.log создается только после завершения скрипта.

Он работает на сервере Windows 2008.

Как сохранить выходной файл "на лету", чтобы я мог проверить test.logи видите прогресс?

from time import sleep
import sys

class Logger(object):
 def __init__(self, filename="Default.log"):
     self.terminal = sys.stdout
     self.log = open(filename, "a")

 def write(self, message):
     self.terminal.write(message)
     self.log.write(message)

def main():

 signaled_to_stop = False

 sheep_counter       = 1 

 sys.stdout = Logger("test.log")

 print "Running.. (press CTRL-C to stop)"

 while True:
     try:
         # Wait 3 seconds between each step.

         sleep(3)
         print "Counting sheeps... %s" % sheep_counter
         sheep_counter = sheep_counter + 1
         # If signaled to stop then - Create a peepfile and stop the loop
         if signaled_to_stop:

             print "Stop requested..."
             if signaled_to_stop:
                 break

     except KeyboardInterrupt:
         print "\nStopping (might take some seconds).."
         signaled_to_stop = True

     except SystemExit as err:
         raise err

 print "Process has finished."

# If this file is executed directly then call the main() method
if __name__ == "__main__":
 main()

Вывод похож на:

python test.py

Running.. (press CTRL-C to stop)
Counting sheeps... 1
Counting sheeps... 2
Counting sheeps... 3

Stopping (might take some seconds)..
Counting sheeps... 4
Stop requested...
Process has finished.

Ответы [ 2 ]

0 голосов
/ 06 марта 2019

Решением было использование sys.stdout.flush ().Он обновляет файл журнала "на лету".

Я могу просто перенаправить вывод, используя ">"

python test.py > result.log

test.py

from time import sleep
import sys

signaled_to_stop = False

sheep_counter       = 1 

print "Running.. (press CTRL-C to stop)"

while True:
    try:
        # Wait 3 seconds between each step.

        sleep(3)
        print "Counting sheeps... %s" % sheep_counter
        sys.stdout.flush()
        sheep_counter += 1
        # If signaled to stop then - stop the loop
        if signaled_to_stop:

            print "Stop requested..."
            if signaled_to_stop:
                break

    except KeyboardInterrupt:
        print "\nStopping (might take some seconds).."
        signaled_to_stop = True

    except SystemExit as err:
        raise err

print "Process has finished."
0 голосов
/ 12 февраля 2019

Вам необходимо закрыть файл до того, как в системе произойдет обновление файла.Вы не можете прочитать или записать открытый файл.

def log(self, exampletext):
    with open(self.filename) as fn:
        fn.write(exampletext)

В этом примере файл будет автоматически закрыт после того, как будет написана строка.

Вот что я использую для создания своего собственногофайлы журнала с тем же конечным результатом, который вы ищете.

class Log: #class to write to log file with time stamps
def __init__(self):
    import os, traceback, time
    self.traceback = traceback
    self.os = os
    self.time = time
    if getattr(sys, 'frozen', False): #windows path fix
        self.exe = self.os.path.dirname(sys.executable)
    elif __file__:
        self.exe = self.os.path.dirname(__file__)
    if not os.path.exists(os.path.dirname(str(os.environ['USERPROFILE'])+"\\Documents\\AppName\\")):
        os.makedirs(str(os.environ['USERPROFILE'])+"\\Documents\\AppName\\")
    self.fname = str(os.environ['USERPROFILE'])+"\\Documents\\AppName\\debug.log"
    self.logfile = None
def error(self, error):
    exc_type, exc_obj, exc_tb = sys.exc_info()
    trace_stack = self.traceback.extract_tb(exc_tb)[-1]
    trace_format = "Error in file "+str(trace_stack[0])+"\r     on line "+str(trace_stack[1])+", from module '"+str(trace_stack[2])+"'\r        "+str(trace_stack[3])
    try:
        self.logfile = open(self.fname, "a+")
    except:
        self.logfile = open(self.fname, "w+")
    strtime = str(self.time.strftime("%d-%m-%Y,(%z),%H:%M:%S"))
    self.logfile.write("error: %s, %s, %s\r" %(strtime, error, trace_format))
    self.logfile.close()
    self.logfile = None
def log(self, log):
    try:
        self.logfile = open(self.fname, "a+")
    except:
        self.logfile = open(self.fname, "w+")
    strtime = str(self.time.strftime("%d-%m-%Y,(%z),%H:%M:%S"))
    self.logfile.write("log: %s, %s\r" %(strtime, log))
    self.logfile.close()
    self.logfile = None

, и вот как я использую его в моем приложении

try:
    self.log.log("This is a standard log")
except Exception as err:
    exc_type, exc_obj, exc_tb = sys.exc_info()
    self.log.error("create_options failed\n%s, %s, %s, %s" %(err, exc_type, exc_obj, traceback.print_tb(exc_tb)))

РЕДАКТИРОВАТЬ : дляБолее быстрый (простой) журнал - вот как я бы это сделал.

#logger.py
class log:
    def __init__(self, message):
        f = open("default.log", "a+")
        f.write(message+"\r")
        f.close()

#maincode.py
from logger import log
for i in range(10):
    log("Hello World %s" %i)

Вы можете просто заменить все операторы печати на операторы журнала.

...