def _ssh_exec_sftp(source, distinct, exec_type, **host): """ 执行文件传输任务 :param source: 源文件 :param distinct: 目标文件 :param exec_type: 执行方式:U:上传 D:下载 :param host: 发送或下载服务器的信息 字典 :return: """ try: ip = host["ip"] port = int(host["port"]) user = host["user"] key = host["hostkey"] hostname = host["hostname"] transport = paramiko.Transport(ip, port) if host["auth_type"] == "1": transport.connect(username=user, password=key) else: pkey = paramiko.RSAKey.from_private_key_file(os.path.join(settings.RSAKEY, "{0}.rsa".format(hostname))) transport.connect(username=user, pkey=pkey) ssh_sftp = paramiko.SFTPClient.from_transport(transport) if exec_type == "U": ssh_sftp.put(source, distinct) print("\033[1;31m\n local[ {0} ] >>>>> upload to >>>>>> {1}[ {2} ] finished \033[0m".format(source, ip, distinct)) else: ssh_sftp.get(source, distinct) print("\033[1;31m\n local[ {0} ] <<<<< download from <<<<<< {1} [ {2} ] finished \033[0m".format(distinct, ip, source)) transport.close() except Exception as e: write_log(e, "error")
def modify_password(self): """ 个人中心 - 修改密码 :return: """ _not_null_flag = False try: while not _not_null_flag: _new_password = input("输入新密码: ").strip() _confirm_password = input("再次输入确认密码:").strip() if not _new_password or not _confirm_password: common.show_message("密码不能为空,请重新输入!", "ERROR") continue if _new_password != _confirm_password: common.show_message("两次输入密码不一致,请重新输入!", "NOTICE") continue _not_null_flag = True self.password = _new_password _password = common.encrypt(self.password) self.dict_user[self.username]["password"] = _password self.update_user() common.show_message("密码修改成功!", "INFORMATIOM") return True except Exception as e: common.write_log(e) return False
def load_host_by_gid(gid): """ 根据组ID返回组下所有的服务器字典列表 :param gid: 组ID e.g: G01 :return: 服务器字典[ {"HIP":"192.168.1.2","HUSER":"******", "HKEY":"123","AUTH_TYPE":"1","HNAME":"MACH01"} ] """ try: host_list = list() xml_file = ET.parse(settings.DB_HOSTS) root = xml_file.getroot() for groups in root: # 如果找到指定gid的节点 if groups.attrib["GID"] == gid: # 开始获取服务器IP 并返回 for child in groups: h_dict = {} for hosts in child: if hosts.tag == "HIP": h_dict["ip"] = hosts.text if hosts.tag == "HNAME": h_dict["hostname"] = hosts.text if hosts.tag == "HUSER": h_dict["user"] = hosts.text if hosts.tag == "AUTH_TYPE": h_dict["auth_type"] = hosts.text if hosts.tag == "HKEY": h_dict["hostkey"] = hosts.text if hosts.tag == "PORT": h_dict["port"] = hosts.text host_list.append(h_dict) if len(host_list) > 0: return host_list else: # 未找到指定组或该组无服务器信息 raise MyException("102") except MyException as e: write_log(e, "info") except Exception as e: write_log(e, "error")
def inner(userobj, input_command_list): try: # 用户输入即无 -h ,也无 -g 语法错误 if input_command_list.count( "-h") == 0 and input_command_list.count("-g") == 0: raise MyException("103") # 用户输入 -h e.g: cmd -h 192.168.1.1,192.168.1.2,存在未授权IP if input_command_list.count("-h") > 0: input_ip_list = input_command_list[ input_command_list.index("-h") + 1].split(",") for ip in input_ip_list: if ip not in userobj.manage_ip: raise MyException("104") # 用户输入 -g e.g: cmd -g gid 存在未授权 组, if input_command_list.count("-g") > 0: # 获取组信息 input_gid_list = input_command_list[ input_command_list.index("-g") + 1].split(",") for gid in input_gid_list: # 如果gid不在用户管理的gid内,报异常 if gid not in userobj.groups: raise MyException("104") return func(userobj, input_command_list) except MyException as e: common.write_log(e, "warning") except Exception as e: common.write_log(e, "error")
def inner(userobj, input_command_list): try: # 用户输入即无 -h ,也无 -g 语法错误 if input_command_list.count("-h") == 0 and input_command_list.count("-g") == 0: raise MyException("103") # 用户输入 -h e.g: cmd -h 192.168.1.1,192.168.1.2,存在未授权IP if input_command_list.count("-h") > 0: input_ip_list = input_command_list[input_command_list.index("-h") + 1].split(",") for ip in input_ip_list: if ip not in userobj.manage_ip: raise MyException("104") # 用户输入 -g e.g: cmd -g gid 存在未授权 组, if input_command_list.count("-g") > 0: # 获取组信息 input_gid_list = input_command_list[input_command_list.index("-g") + 1].split(",") for gid in input_gid_list: # 如果gid不在用户管理的gid内,报异常 if gid not in userobj.groups: raise MyException("104") return func(userobj, input_command_list) except MyException as e: common.write_log(e, "warning") except Exception as e: common.write_log(e, "error")
def updata_user(self): '''用户数据更新''' try: dbapi.write_db_json(self.dict_user,self._database) return True except Exception as e: common.write_log("用户登录页面更新用户数据:{0}".format(e)) return False
def load_data_from_db(tabename): """ 从指定的数据表中获取所有数据,通过 json 方式将数据返回 :param tabename: 数据文件名 :return: 返回所有结果 """ try: with open(tabename, "r+") as f: return json.load(f) except Exception as e: write_log(e)
def load_data_from_db(tabename): """ 从指定的数据表中获取所有数据,通过 json 方式将数据返回 :param tabename: 数据文件名 :return: 返回所有结果 """ try: with open(tabename, 'r+') as f: return json.load(f) except Exception as e: write_log(e)
def write_db_json(contant, filename): """ 将信息以 json 格式写入数据表文件(覆盖) :param contant: 写入的json数据内容 :param filename: 要写入的文件名 :return: 无返回结果 """ try: with open(filename, "w+") as fw: fw.write(json.dumps(contant)) except Exception as e: write_log(e)
def write_db_json(contant, filename): """ 将信息以 json 格式写入数据表文件(覆盖) :param contant: 写入的json数据内容 :param filename: 要写入的文件名 :return: 无返回结果 """ try: with open(filename, 'w+') as fw: fw.write(json.dumps(contant)) except Exception as e: write_log(e)
def init_database(): tables = list(settings.DATABASE['tables'].values()) # 数据表名称列表 database = settings.DATABASE['dbpath'] # 数据表存放路径 for _table in tables: # 如果表不存在 if not os.path.exists(os.path.join(database, "{0}.db".format(_table))): print("Table {0}.db create successfull".format(_table)) # 通过反射初始化数据表 if hasattr(sys.modules[__name__], "init_db_{0}".format(_table)): init_func = getattr(sys.modules[__name__], "init_db_{0}".format(_table)) init_func() else: common.write_log("init table {0} failed,no function init_db_{0} found".format(_table))
def append_db_json(contant, filename): """ 将信息以 json 格式写入数据表文件(追加) :param contant: 要写入的 json 格式内容 :param filename: 要写入的数据表文件名 :return: 无返回 """ try: with open(filename, "a+") as fa: fa.write(json.dumps(contant)) fa.write("\n") except Exception as e: write_log(e)
def append_db_json(contant, filename): """ 将信息以 json 格式写入数据表文件(追加) :param contant: 要写入的 json 格式内容 :param filename: 要写入的数据表文件名 :return: 无返回 """ try: with open(filename, 'a+') as fa: fa.write(json.dumps(contant)) fa.write("\n") except Exception as e: write_log(e)
def sftp(userobj, input_command_list): """ exec sftp operation :param userobj: :param input_command_list: :return: """ exec_host_list = _analyze_command(userobj, input_command_list) try: # 判断是要上传文件还是下载文件 -u 上传 -d 下载,如果既有-u又有-d 命令无效 if input_command_list.count("-u") > 0 and input_command_list.count( "-d") > 0: raise MyException("108") elif input_command_list.count("-u") > 0: # exec upload file exec_type = "U" elif input_command_list.count("-d") > 0: exec_type = "D" else: # no -u and no -d raise MyException("109") # 判断-s -t合法性 if input_command_list.count("-s") < 1 or input_command_list.count( "-t") < 1: raise MyException("110") # 开始执行上传活下载操作 # upload 获取要上传活下载的源文件 source_file = input_command_list[input_command_list.index("-s") + 1].replace('"', '') distinct_file = input_command_list[input_command_list.index("-t") + 1].replace('"', '') # file does exiests?? if exec_type == "U": if not os.path.exists(source_file): raise MyException("107") # 开启5个线程池 pool = Pool(5) for host in exec_host_list: pool.apply_async(_ssh_exec_sftp, args=(source_file, distinct_file, exec_type), kwds=host) pool.close() pool.join() except MyException as e: write_log(e, "info") print(e)
def load_statement_list(cardno): """ 从对账单中获取记录, :param cardno: 对账单文件 :return: 返回一个列表 """ file = os.path.join(settings.REPORT_PATH, "statement_{0}".format(cardno)) result_list = list() try: if os.path.isfile(file): with open(file, 'r+') as f: for line in f: statement = json.loads(line) result_list.append(statement) return result_list except Exception as e: write_log("dbapi > load_statement_list > {0}".format(e))
def load_statement_list(cardno): """ 从对账单中获取记录, :param cardno: 对账单文件 :return: 返回一个列表 """ file = os.path.join(settings.REPORT_PATH, "statement_{0}".format(cardno)) result_list = list() try: if os.path.isfile(file): with open(file, "r+") as f: for line in f: statement = json.loads(line) result_list.append(statement) return result_list except Exception as e: write_log("dbapi > load_statement_list > {0}".format(e))
def sftp(userobj, input_command_list): """ exec sftp operation :param userobj: :param input_command_list: :return: """ exec_host_list = _analyze_command(userobj, input_command_list) try: # 判断是要上传文件还是下载文件 -u 上传 -d 下载,如果既有-u又有-d 命令无效 if input_command_list.count("-u") > 0 and input_command_list.count("-d") > 0: raise MyException("108") elif input_command_list.count("-u") > 0: # exec upload file exec_type = "U" elif input_command_list.count("-d") > 0: exec_type = "D" else: # no -u and no -d raise MyException("109") # 判断-s -t合法性 if input_command_list.count("-s") < 1 or input_command_list.count("-t") < 1: raise MyException("110") # 开始执行上传活下载操作 # upload 获取要上传活下载的源文件 source_file = input_command_list[input_command_list.index("-s") + 1].replace('"', '') distinct_file = input_command_list[input_command_list.index("-t") + 1].replace('"', '') # file does exiests?? if exec_type == "U": if not os.path.exists(source_file): raise MyException("107") # 开启5个线程池 pool = Pool(5) for host in exec_host_list: pool.apply_async(_ssh_exec_sftp, args=(source_file, distinct_file, exec_type), kwds=host) pool.close() pool.join() except MyException as e: write_log(e, "info") print(e)
def user_auth(self, password): """ 登录验证 :param password: 用户输入密码 :return: """ try: if not self.exists: auth_status = False else: encry_passwd = common.encry_sha(password) if self.passwd == encry_passwd: auth_status = True else: auth_status = False return auth_status except Exception as e: common.write_log(e, "error")
def cmd(userobj, input_command_list): """ 在管理的服务器上执行cmd命令,命令支持: cmd -h 192.168.1.100,192.168.1.200 -c "df -hl" cmd -g G01 -c "df -hl" :param userobj: :param input_command_list: :return: """ # 命令 command_str = "" try: # 有命令吗?有的话-c后面的元素在" "之间的都是命令 if input_command_list.count("-c") > 0: start_index = input_command_list.index("-c") + 1 end_index = len(input_command_list) for cmd_str in input_command_list[start_index:end_index]: command_str += " {0}".format(cmd_str) if cmd_str.endswith('"'): break # 去前后的双引号 command_str = command_str.replace('"', '') else: raise MyException("106") # 获取要执行的所有主机列表 exec_host_info = _analyze_command(userobj, input_command_list) # 开始对这些服务器进行命令操作,开启进程池执行服务器登录 pool = Pool(5) for host in exec_host_info: pool.apply_async(_ssh_exec_cmd, args=(command_str,), kwds=host) pool.close() pool.join() # _ssh_exec_cmd(command_str, **host) except MyException as e: write_log(e, "warning") return e except Exception as e: write_log(e, "error")
def load_bill_report(cardno, startdate, enddate): """ 从信用卡对账单中获取指定卡的对账信息数据, 获取某一个时间段内的数据 :param enddate: 查询记录的结束日期 :param startdate: 查询记录的开始日期 :param cardno: 信用卡卡号 :return: 信用卡对账单数据 ,返回结果为 list 数据类型 """ r_file = os.path.join(settings.REPORT_PATH, "report_bill") result = [] try: with open(r_file, "r+") as f: for line in f: _record = json.loads(line) if _record["cardno"] == cardno: if startdate <= _record["starttime"] <= enddate: result.append(_record) return result except Exception as e: write_log(e)
def cmd(userobj, input_command_list): """ 在管理的服务器上执行cmd命令,命令支持: cmd -h 192.168.1.100,192.168.1.200 -c "df -hl" cmd -g G01 -c "df -hl" :param userobj: :param input_command_list: :return: """ # 命令 command_str = "" try: # 有命令吗?有的话-c后面的元素在" "之间的都是命令 if input_command_list.count("-c") > 0: start_index = input_command_list.index("-c") + 1 end_index = len(input_command_list) for cmd_str in input_command_list[start_index:end_index]: command_str += " {0}".format(cmd_str) if cmd_str.endswith('"'): break # 去前后的双引号 command_str = command_str.replace('"', '') else: raise MyException("106") # 获取要执行的所有主机列表 exec_host_info = _analyze_command(userobj, input_command_list) # 开始对这些服务器进行命令操作,开启进程池执行服务器登录 pool = Pool(5) for host in exec_host_info: pool.apply_async(_ssh_exec_cmd, args=(command_str, ), kwds=host) pool.close() pool.join() # _ssh_exec_cmd(command_str, **host) except MyException as e: write_log(e, "warning") return e except Exception as e: write_log(e, "error")
def load_shop_history(user, startdate, enddate): """ 查找报表记录中的指定用户的购物历史记录,将结果存入到列表中 :param user: 用户名 :param startdate: 开始日期 :param enddate: 结束日期 :return: 结果 dict_list """ _file = os.path.join(settings.REPORT_PATH, "shopping_history") result = list() try: with open(_file, "r") as f: for line in f: _record = json.loads(line) # 如果找到指定用户记录 if list(_record.keys())[0] == user: if list(_record.values())[0]["time"] >= startdate <= enddate: result.append(_record) return result except Exception as e: write_log("dbapi > load_shop_history > {0}".format(e))
def _ssh_exec_sftp(source, distinct, exec_type, **host): """ 执行文件传输任务 :param source: 源文件 :param distinct: 目标文件 :param exec_type: 执行方式:U:上传 D:下载 :param host: 发送或下载服务器的信息 字典 :return: """ try: ip = host["ip"] port = int(host["port"]) user = host["user"] key = host["hostkey"] hostname = host["hostname"] transport = paramiko.Transport(ip, port) if host["auth_type"] == "1": transport.connect(username=user, password=key) else: pkey = paramiko.RSAKey.from_private_key_file( os.path.join(settings.RSAKEY, "{0}.rsa".format(hostname))) transport.connect(username=user, pkey=pkey) ssh_sftp = paramiko.SFTPClient.from_transport(transport) if exec_type == "U": ssh_sftp.put(source, distinct) print( "\033[1;31m\n local[ {0} ] >>>>> upload to >>>>>> {1}[ {2} ] finished \033[0m" .format(source, ip, distinct)) else: ssh_sftp.get(source, distinct) print( "\033[1;31m\n local[ {0} ] <<<<< download from <<<<<< {1} [ {2} ] finished \033[0m" .format(distinct, ip, source)) transport.close() except Exception as e: write_log(e, "error")
def update_user(self): """ 用户数据更新方法,用户修改信息、用户账户锁定、解锁等操作之后更新数据库文件 :return: """ try: ''' _password = common.encrypt(self.password) self.dict_user[self.username]["password"] = _password self.dict_user[self.username]["islocked"] = self.islocked self.dict_user[self.username]["name"] = self.name self.dict_user[self.username]["mobile"] = self.mobile self.dict_user[self.username]["bindcard"] = self.bindcard self.dict_user[self.username]["isdel"] = self.isdel self.dict_user[self.username]["role"] = self.role ''' # 写入数据库文件 dbapi.write_db_json(self.dict_user, self.__database) return True except Exception as e: common.write_log(e) return False
def _ssh_exec_cmd(commandstr, **host): """ paramiko 执行命令方法 :param hostlist: 主机列表 :param commandstr: 执行的命令 :return: """ ip = host["ip"] port = int(host["port"]) user = host["user"] key = host["hostkey"] hostname = host["hostname"] try: # 开始登录服务器并执行命令 transport = paramiko.Transport(ip, port) if host["auth_type"] == "1": transport.connect(username=user, password=key) else: pkey = paramiko.RSAKey.from_private_key_file(os.path.join( settings.RSAKEY, "id_rsa"), password=key) transport.connect(username=user, pkey=pkey) ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh._transport = transport stdin, stdout, stderr = ssh.exec_command(command=commandstr) print("\033[1;31m IP -> {0} : \033[0m \n".format(ip)) if len(stderr.read().decode()) > 0: print(stderr.read().decode()) if len(stdout.read().decode()) > 0: print(stdout.read().decode()) transport.close() except Exception as e: print(e) write_log(e, "error")
def load_shop_history(user, startdate, enddate): """ 查找报表记录中的指定用户的购物历史记录,将结果存入到列表中 :param user: 用户名 :param startdate: 开始日期 :param enddate: 结束日期 :return: 结果 dict_list """ _file = os.path.join(settings.REPORT_PATH, "shopping_history") result = list() try: with open(_file, "r") as f: for line in f: _record = json.loads(line) # 如果找到指定用户记录 if list(_record.keys())[0] == user: if list(_record.values() )[0]["time"] >= startdate <= enddate: result.append(_record) return result except Exception as e: write_log("dbapi > load_shop_history > {0}".format(e))
def load_users(username): return_dict = dict() try: xml_file = ET.parse(settings.DB_USERS) root = xml_file.getroot() for child in root: if child.attrib["UNAME"] == username: for protertys in child: if protertys.tag == "NAME": return_dict["name"] = protertys.text if protertys.tag == "UPASS": return_dict["password"] = protertys.text if protertys.tag == "GID": return_dict["groups"] = protertys.text if protertys.tag == "UROLE": return_dict["role"] = protertys.text break if len(return_dict) > 0: return return_dict else: return False except Exception as e: write_log(e, "error")
def exec_cmd(userobj, input_command): """ :param userobj: :param input_command: :return: """ try: # 获取第一个命令指令 command_list = input_command.split() command = command_list[0] if command not in __command__: raise MyException("103") else: # 调用对应的命令 func = getattr(sys.modules[__name__], command) func(userobj, command_list) except MyException as e: write_log(e, "warning") print(e) except Exception as e: write_log(e, "error")
def _ssh_exec_cmd(commandstr, **host): """ paramiko 执行命令方法 :param hostlist: 主机列表 :param commandstr: 执行的命令 :return: """ ip = host["ip"] port = int(host["port"]) user = host["user"] key = host["hostkey"] hostname = host["hostname"] try: # 开始登录服务器并执行命令 transport = paramiko.Transport(ip, port) if host["auth_type"] == "1": transport.connect(username=user, password=key) else: pkey = paramiko.RSAKey.from_private_key_file(os.path.join(settings.RSAKEY, "id_rsa"), password=key) transport.connect(username=user, pkey=pkey) ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh._transport = transport stdin, stdout, stderr = ssh.exec_command(command=commandstr) print("\033[1;31m IP -> {0} : \033[0m \n".format(ip)) if len(stderr.read().decode()) > 0 : print(stderr.read().decode()) if len(stdout.read().decode()) > 0 : print(stdout.read().decode()) transport.close() except Exception as e: print(e) write_log(e, "error")
----------------------------------------- \033[0m''' if __name__ == "__main__": trycount = 3 count = 0 while count < trycount: print(MENU) username = common.inputs("用户名: ").lower() passwd = common.inputs("密码: ") # 实例化一个用户对象 userobj = Users(username) if not userobj.exists: print("用户名或密码错误!\n") common.write_log("用户{0}登录, 用户名不存在".format(username), "info", "op") count += 1 continue else: auth_stat = userobj.user_auth(passwd) if not auth_stat: common.write_log("用户{0}登录, 用户名密码不正确".format(username), "info", "op") print("登录失败!用户名或密码错误!") count += 1 continue else: # 登录成功 common.write_log("用户{0}登录, 登录成功!".format(username), "info", "op") print("欢迎登录堡垒机精简版(v1.0)\n") exit_flag = False while not exit_flag:
def show(userobj, input_command_list): """ 执行show命令,查看当前用户管理的所有服务器信息,可用命令: show hosts -a : 查看所有服务器IP、主机名、所属组 show hosts -g gid: 查看组id(gid) 对应的所有主机信息 show groups: 查看当前用户管理的所有组 如果show跟其它参数 不认识 :param userobj: 用户对象 :param input_command_list: 用户输入的命令,split后的列表 :return: 返回结果信息 """ try: show_args = ["hosts", "groups"] if len(input_command_list) < 2: raise MyException("106") else: input_args = input_command_list[1] if input_args == "hosts": # 如果有 -a if input_command_list.count("-a") > 0: if len(input_command_list) > 3: raise MyException("103") else: # 显示所有主机信息 user_gid_list = userobj.groups.split(",") # 没有 -a, 有 -g 吗 elif input_command_list.count("-g") > 0: user_gid_list = input_command_list[input_command_list.index("-g") + 1].split(",") else: raise MyException("103") # 开始显示信息 for gid in user_gid_list: # 根据用户的组ID,获取组对应的host信息字典 hosts_info = dbapi.load_host_by_gid(gid) for host in hosts_info: print("\033[1;30m \nIP: {0} 主机名: {1} 所属组ID: {2} \033[0m;".format(host["ip"], host["hostname"], gid)) elif input_args == "groups": # 打印所有组信息 user_gid = userobj.groups groups_dict = dbapi.load_group_info() # 从所有组信息中删除不在用户gid中的元素,剩下打印 _total_gid_list = list(groups_dict.keys()) for gid in _total_gid_list: if gid not in user_gid.split(","): del groups_dict[gid] # 显示用户组信息 for k, v in groups_dict.items(): print("\033[1;30m GID: {0}, GNAME: {1}\033[0m;\n".format(k, v)) else: raise MyException("106") except MyException as e: write_log(e, "error") print(e) except Exception as e: write_log(e, "error")
def show(userobj, input_command_list): """ 执行show命令,查看当前用户管理的所有服务器信息,可用命令: show hosts -a : 查看所有服务器IP、主机名、所属组 show hosts -g gid: 查看组id(gid) 对应的所有主机信息 show groups: 查看当前用户管理的所有组 如果show跟其它参数 不认识 :param userobj: 用户对象 :param input_command_list: 用户输入的命令,split后的列表 :return: 返回结果信息 """ try: show_args = ["hosts", "groups"] if len(input_command_list) < 2: raise MyException("106") else: input_args = input_command_list[1] if input_args == "hosts": # 如果有 -a if input_command_list.count("-a") > 0: if len(input_command_list) > 3: raise MyException("103") else: # 显示所有主机信息 user_gid_list = userobj.groups.split(",") # 没有 -a, 有 -g 吗 elif input_command_list.count("-g") > 0: user_gid_list = input_command_list[ input_command_list.index("-g") + 1].split(",") else: raise MyException("103") # 开始显示信息 for gid in user_gid_list: # 根据用户的组ID,获取组对应的host信息字典 hosts_info = dbapi.load_host_by_gid(gid) for host in hosts_info: print( "\033[1;30m \nIP: {0} 主机名: {1} 所属组ID: {2} \033[0m;" .format(host["ip"], host["hostname"], gid)) elif input_args == "groups": # 打印所有组信息 user_gid = userobj.groups groups_dict = dbapi.load_group_info() # 从所有组信息中删除不在用户gid中的元素,剩下打印 _total_gid_list = list(groups_dict.keys()) for gid in _total_gid_list: if gid not in user_gid.split(","): del groups_dict[gid] # 显示用户组信息 for k, v in groups_dict.items(): print("\033[1;30m GID: {0}, GNAME: {1}\033[0m;\n".format( k, v)) else: raise MyException("106") except MyException as e: write_log(e, "error") print(e) except Exception as e: write_log(e, "error")