【发布时间】:2020-07-11 05:24:31
【问题描述】:
我正在尝试编写一个简单的端口检查程序来测试 VMware Horizon 网络端口。端口检查本身工作得很好,但是我的“多线程”日志在第 71 行和第 91 行之间不足。我知道事实上我做错了,因为我将多个帖子中的日志记录部分拼凑在一起在线的。我没有运行记录器的经验,而且我的 Python 在我最好的一天是中级的。无论如何,有人可以帮我清理日志记录部分并使其按预期工作吗?
我在多个线程中运行端口检查以提高速度,随后我想准确记录每个线程的结果。我想我已经让这个工作了一段时间,但是我对我的日志记录代码的开头做了一些修改以“清理”它并且我破坏了一些东西。不幸的是,当时我在 git repo 中没有这个,所以我不能再恢复我的更改了。如果可以的话,请给我更多关于如何修复/重写日志记录部分以完成干净的多线程日志记录的详细信息。我什至有兴趣将线程日志记录分组在一起以提高可读性,但这不是必须的。提前感谢您的帮助。
这是一个抛出错误的示例,整个清理过的代码都在下面。
错误信息:
THREAD INFORMATION PRINT
<Worker(Thread-1, initial)>
THREADRESULT IS:
None
logging_threads is:
[<Worker(Thread-1, started 140445767894784)>]
INFO : pod1.azvd.private.example.com # Checking port: 80 on pod1.azvd.private.example.com
INFO : pod1.azvd.private.example.com # Checking port: 443 on pod1.azvd.private.example.com
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "./horizon_troubleshooter.py", line 41, in run
self.logger.info('Created Log for {}'.format(self.info['pod_name']))
File "/usr/lib/python2.7/logging/__init__.py", line 1455, in info
self.logger.info(msg, *args, **kwargs)
AttributeError: 'NoneType' object has no attribute 'info'
完整代码:
#!/usr/bin/python
# VMware Horizon troubleshooter
# Test port connectivity and call
# and response, then output to file.
import sys
import logging
import socket
import time
import threading
import traceback
from contextlib import closing
logging.basicConfig(level=logging.DEBUG,
format= '%(asctime)-15s %(levelname)-8s: %(thread)x -- %(pod_name)s - %(funcName)s:%(lineno)d # %(message)s',
datefmt='%m-%d %H:%M',
filename='/tmp/horizon-troubleshooter.log',
filemode='w')
console = logging.StreamHandler()
console.setLevel(logging.INFO)
formatter = logging.Formatter('%(levelname)-8s: %(pod_name)-12s # %(message)s')
console.setFormatter(formatter)
logger = logging.getLogger()
logger = logging.getLogger('').addHandler(console)
class Worker(threading.Thread):
def __init__(self, info):
self.running=False
self.info=info
self.logger=logging.LoggerAdapter(logger, self.info)
super(Worker, self).__init__()
def start(self):
self.running=True
super(Worker, self).start()
def stop(self):
self.running=False
def run(self):
while self.running:
self.logger.info('Created Log for {}'.format(self.info['pod_name']))
time.sleep(0.5)
def check_port(host, port):
try:
ip = socket.gethostbyname(host) # get IP address of host
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # TCP
#sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
socket.setdefaulttimeout(2.0) # floating integer for seconds
result = sock.connect_ex((host,port))
if result == 0:
logging.info('Port: %s OPEN', port, extra={'pod_name': host})
return True
else:
logging.info('Port: %s CLOSED', port, extra={'pod_name': host})
return False
sock.close()
logging.debug('Result: %s for port check on: %s', result, port, extra={'pod_name': host})
except:
logging.error('check_port failed for %s', port, extra={'pod_name': host })
# set variables for ports and hosts to check
port_list = [80, 443, 4172, 8443]
domain_name = ".azvd.private.example.com"
hostname_prefix = "pod"
num_pods = 22
logging_threads = []
max_threads = 50 # maximum thread count for multi-threaded port check
# iterate through pods and test ports
for pod_num in range(1, num_pods + 1):
try:
pod_name = (hostname_prefix + str(pod_num) + domain_name)
logging.debug('PODNAME IS %s', pod_name, extra={'pod_name': pod_name})
kwargs = ({'pod_name': pod_name})
logging.debug('KWARGS is %s', kwargs, extra=kwargs)
thread = Worker({'pod_name': pod_name})
print("THREAD INFORMATION PRINT")
print(thread)
threadresult = thread.start()
print('THREADRESULT IS:')
print(threadresult)
logging_threads.append(thread)
print('logging_threads is: ')
print(logging_threads)
logging.debug("Thread started and appended to logging_threads", extra=kwargs)
except NameError:
exc_type, exc_value, exc_traceback = sys.exc_info()
lines = traceback.format_exception(exc_type, exc_value, exc_traceback)
logging.error('\nFailed to create logging thread on %s', pod_name, extra=kwargs)
logging.exception("exception data: %s", lines, extra=kwargs)
for port in port_list:
try:
logging.info('Checking port: %s on %s', port, pod_name, extra={'pod_name': pod_name})
threading.Thread(target=check_port, args=[str(pod_name), port]).start()
except:
logging.error('PORT_LIST FOR-LOOP FAILURE', extra={'pod_name': pod_name})
while threading.active_count() > max_threads :
time.sleep(2)
for lt in logging_threads:
lt.stop()
for lt in logging_threads:
lt.join()
【问题讨论】:
-
我不知道第 70 行是什么,因为 SO 不对代码行编号。还要注意python不能使用多线程并行运行,我强烈建议你使用multiprocessing或concurrent.futures
-
帮助人们帮助您 * 分享您面临的错误 * 如果没有遇到任何错误,请分享您期望的行为以及您得到的结果 * 将您的问题减少到 minimal reproducible example
-
不知道为什么我被否决了。我以为我包含了所有可能的信息,甚至解决了我的问题。我还能做什么?我应该完全删除我的帖子吗?我不想引起任何问题或做错事。在几个月前为一个问题写答案之前,我还没有使用过这个网站。
-
@WilliamSmyth 如果您找到了解决方案,那么您应该将其发布在答案部分,请阅读How to Ask 和How to Answer
标签: python multithreading logging