You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python服务器监控脚本运行报NameError与AttributeError求助

服务器监控脚本报错修复方案

核心报错修复

  • 第一个报错 NameError: name 'servers' is not defined
    原因:pickle加载语法错误,把模块方法当成了变量的属性调用。
    修复:把 servers.pickle.load(open("servers.pickle","rb")) 改为 servers = pickle.load(open("servers.pickle","rb"))

  • 第二个报错 AttributeError: 'Server' object has no attribute 'name'
    原因:Server类的__init__初始化方法没有给实例属性赋值,仅写了self.name没有关联传入的参数。
    修复:把__init__里的属性声明改为:

    self.name = name
    self.port = port
    self.connection = connection
    self.priority = priority
    

其他隐含bug修复

  • 类方法缩进错误:checkConnection、ping、create_history三个方法目前缩进在__init__方法内部,属于内部函数,实例无法调用,需要把这三个方法的缩进调整到和__init__同级。
  • datetime调用错误:now = datetime.now是获取方法对象,要拿到当前时间需要加括号改为now = datetime.now()
  • 系统判断错误:platform.system.lower()改为platform.system().lower(),system是方法需要调用,同时拼写错误windowns改为windows
  • ping命令语法错误:"ping - {} 1 {}"去掉参数前的空格,改为"ping -{} 1 {}"
  • 告警属性赋值错误:socket.timeout捕获块里的alert = True改为self.alert = True,否则不会修改实例的告警状态
  • 持久化文件名错误:最后dump的文件名serfvers.pickle改为servers.pickle,避免下次加载找不到文件

修复后完整代码

import socket
import ssl
import pickle
from datetime import datetime
import subprocess
import platform

class Server():
    def __init__(self, name, port, connection, priority):
        self.name = name
        self.port = port
        self.connection = connection
        self.priority = priority
        
        self.history = []
        self.alert =  False

    def checkConnection(self):
        msg = ""
        succes = False
        now = datetime.now()

        try:
            if self.connection == "plain":
                socket.create_connection((self.name,self.port),timeout=10)
                msg = f"{self.name} is up. On Port {self.port} with {self.connection}"
                succes = True
                self.alert = False
            elif self.connection == "ssl":
                ssl.wrap_socket(socket.create_connection((self.name,self.port),timeout=10))
                msg = f"{self.name} is up. On Port {self.port} with {self.connection}"
                succes = True
                self.alert = False
            elif succes == False and self.alert == False:
                # 此处可补充邮件告警逻辑
                self.alert = True
                # email_alert(self.name,f"{msg}\n{now}","erik.hoeven@gmail.com")  
            else:
                if self.ping():
                    msg = f"{self.name} 端口{self.port}超时,服务器本身存活"
                    succes = True
                    self.alert = False
            
            self.create_history(msg,succes,now)
        except socket.timeout:
            msg = f"{self.name} 已宕机,端口{self.port}无法连接"
            succes = False
            self.alert = True
        
        except Exception as e:
            pass

    def ping(self):
        try:
            output = subprocess.check_output("ping -{} 1 {}".format('n' if platform.system().lower() == 'windows' else 'c', self.name), shell = True, universal_newlines = True)
            if 'unreachable'  in output:
                return False
            
            else:
                return True

        except Exception:
            return False

    def create_history(self,msg,succes,now):
        history_max = 100
        self.history.append((msg,succes,now))

        while len(self.history) > history_max:
            self.history.pop(0)

if __name__ == "__main__":
    try:
        servers = pickle.load(open("servers.pickle","rb"))
    except:
        servers = [
        Server("servername1",80,"plain","high"),
        Server("servername2",5001,"plain","high")]
    for server in servers:
        server.checkConnection()
        print(len(server.history))
        print(server.history[-1])

    pickle.dump(servers,open("servers.pickle","wb"))

内容的提问来源于stack exchange,提问作者Erik hoeven

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 23:48:04