2017-02-16 15 views
0

У меня есть сторонний модуль, который открывает файл с использованием logging.FileHandler, я хочу знать, как я могу узнать его fileno с именем файла.Получить fileno() для файла, открытого текущим pid, используя имя файла?

third_party.py:

def setup_loging(logfile): 
    logFormatter = logging.Formatter(
     "%(asctime)s [%(process)d] [%(name)-12.12s] " 
     "[%(levelname)-5.5s] %(message)s") 
    rootLogger = logging.getLogger() 
    rootLogger.setLevel(logging.NOTSET) 
    if logfile: 
     fileHandler = logging.FileHandler(logfile, mode="wt", encoding="utf-8") 
     fileHandler.setFormatter(logFormatter) 
     fileHandler.setLevel(logging.NOTSET) 
     rootLogger.addHandler(fileHandler) 

    consoleHandler = logging.StreamHandler(sys.stdout) 
    if verbose: 
     consoleHandler.setLevel(logging.DEBUG) 
    else: 
     consoleHandler.setLevel(logging.INFO) 
    consolelogFormatter = logging.Formatter(
     "[%(name)-12.12s] [%(levelname)-5.5s] %(message)s") 
    consoleHandler.setFormatter(consolelogFormatter) 
    rootLogger.addHandler(consoleHandler) 

my_script.py:

from third_party import setup_loging 
setup_loging(logfile='/tmp/foo.log') 

# How do I get the fileno for file /tmp/foo.log ? 
# only way i know is doing: lsof /tmp/foo.log 
print get_fileno_from_filename('/tmp/foo.log') 
+1

Однако может быть несколько файловых дескрипторов для данного имени файла. –

+0

Любой способ изменить 'setup_loging()', чтобы он возвращал его вызывающему? – martineau

ответ

1

Попробуйте выхватывая stream свойство от вашего FileHandler, а затем его stream, чтобы добраться до файла объекта:

def setup_loging(logfile): 
    # your code... 
    if logfile: 
     return fileHandler 

logging_handler = setup_loging(logfile='/tmp/foo.log') 
if logging_handler: 
    print("fileno: {}".format(logging_handler.stream.stream.fileno())) 

Немного хакерский, но выполняет свою работу;)

P.S. Если вы не можете каким-либо образом изменить сценарий, вы всегда можете получить все корневые обработчики (logging.getLogger().handlers) и просеять их до тех пор, пока не найдете FileHandler, но может быть более одного, поэтому обязательно проверьте свойство name прежде чем получить его fileno(). Что-то вроде:

import os 

your_log_file = "/tmp/foo.log" 
log_file_path = os.path.realpath(your_log_file) # make sure we have a full path 

setup_loging(log_file_path) # call the third party 

for handler in logging.getLogger().handlers: 
    if isinstance(handler, logging.FileHandler): 
     if handler.stream.stream.name == log_file_path: 
      print("{}, fileno: {}".format(log_file_path, handler.stream.stream.fileno())) 
      break