def get_person_list(): """ 获取项目接收人信息 :return: """ person_list = mongodb.USER.distinct('name') # distinct的是去重,返回结果形式为list。 return SUCCESS(data=person_list)
def log_info_close(): """ 关闭日志问题,迭代后为不再告警,项目相关人认为该日志问题不存在问题隐患,或者是该日志问题为正常写入的日志信息, 可以选择直接关闭问题,status状态设置为3,再次出现后不会触发告警。 同时,日志相关负责人认为不存在安全隐患可以直接关闭。 :return: """ oid = request.json.get('id') note = request.json.get('note') if not all([oid, note]): return ERROR(errno=201, errmsg='参数缺失') log_info = mongodb.LOGINFO.find_one({'_id': ObjectId(oid)}) if not log_info: return ERROR(errno=201, errmsg='设置的日志信息不存在') # 修改对应日志文件的状态,status:0---->1 update_result = mongodb.LOGINFO.update_one({'_id': ObjectId(oid)}, {'$set': {'status': 3}}) if not update_result: return ERROR(errno=201, errmsg='不再告警设置失败') name = session.get('username') time_str = datetime.datetime.strftime(datetime.datetime.now(), "%Y-%m-%d %H:%M:%S") params = { 'info_id': ObjectId(oid), 'name': name, 'tag': name + '设置该条日志为不再告警', 'time': time_str, 'note': note } insert_id = mongodb.HANDLERECORD.insert_one(params) if not insert_id: return ERROR(errno=201, errmsg='设置不再告警日志信息记录失败') return SUCCESS(data='不再告警设置成功')
def logout(): """ 用户退出功能 :return: """ session.pop('username', None) return SUCCESS(data='用户退出成功')
def log_info_resume(): """ 日志恢复告警,为了避免设置为不再告警的日志无法重新监控到,提供了一个恢复告警的状态,该条日志重新恢复到已完成状态,再次捕获的为正常状态。 :return: """ oid = request.json.get('id') note = request.json.get('note') if not all([oid, note]): return ERROR(errno=201, errmsg='参数缺失') log_info = mongodb.LOGINFO.find_one({'_id': ObjectId(oid)}) if not log_info: return ERROR(errno=201, errmsg='恢复告警的日志信息不存在') # 修改对应日志文件的状态,status:0---->1 update_result = mongodb.LOGINFO.update_one({'_id': ObjectId(oid)}, {'$set': {'status': 2}}) if not update_result: return ERROR(errno=201, errmsg='恢复告警设置失败') name = session.get('username') time_str = datetime.datetime.strftime(datetime.datetime.now(), "%Y-%m-%d %H:%M:%S") params = { 'info_id': ObjectId(oid), 'name': name, 'tag': name + '恢复该条日志的告警监控', 'time': time_str, 'note': note } insert_id = mongodb.HANDLERECORD.insert_one(params) if not insert_id: return ERROR(errno=201, errmsg='恢复告警信息记录失败') return SUCCESS(data='恢复告警设置成功')
def batch_closure(): """ 批量设置告警消息处理完成,处理完成的设置int为2。但是不能处理选中的设置为不再告警的日志消息。 :return: """ oids = request.json.get('ids') note = request.json.get('note') if not oids: return ERROR(errno=201, errmsg="请选择需要关闭的告警信息") for oid in oids: log_info = mongodb.LOGINFO.find_one({'_id': ObjectId(oid)}) if not log_info: return ERROR(errno=201, errmsg='待设置的日志信息不存在') status = mongodb.LOGINFO.find_one({'_id': ObjectId(oid)}).get('status') if status == 3: continue mongodb.LOGINFO.update_one({'_id': ObjectId(oid)}, {'$set': {'status': 2}}) # 每一条告警消息对应添加相应的处理记录 name = session.get('username') time_str = datetime.datetime.strftime(datetime.datetime.now(), "%Y-%m-%d %H:%M:%S") params = { 'info_id': ObjectId(oid), 'name': name, 'tag': name + '解决问题', 'time': time_str, 'note': note } insert_id = mongodb.HANDLERECORD.insert_one(params) if not insert_id: return ERROR(errno=201, errmsg='解决日志信息记录失败') return SUCCESS(data='日志问题成功解决')
def get_app_list(): """ 获取所有的项目列表 :return: """ app_list = mongodb.PROJECT.distinct('name') return SUCCESS(data=app_list)
def get_project_list(): """获取项目列表""" keyword = request.json.get('keyword', '') page = request.json.get('page', 1) per_page = request.json.get('per_page', 8) skip = per_page * (page - 1) limit = per_page filters = {} if keyword: # regex 是mongo中的模糊查询,支持字符串形式的值。 filters.update({ '$or': [{ 'app': { '$regex': keyword } }, { 'name': { '$regex': keyword } }] }) total_count = mongodb.PROJECT.find(filters).count() data_list = list(mongodb.PROJECT.find(filters).skip(skip).limit(limit)) result = {'data': data_list, "count": total_count} return SUCCESS(data=result)
def create_project(): """ 新建项目 tasks_num:轮训任务数 count_tasks_num: 统计任务数 :return: """ app = request.json.get("app") # 项目在elk中配置的项目代号 name = request.json.get('name') # 项目的中文名,我们对项目的称呼 if not all([ app, name ]): # python all()函数,用来判断可迭代对象的内部参数是否都为true,但是可迭代对象为空的结果也为true。 return ERROR(errno=201, errmsg='参数缺失') result1 = mongodb.PROJECT.find_one({"app": app}) if result1: return ERROR(errno=201, errmsg='项目代号已经存在') result2 = mongodb.PROJECT.find_one({'name': name}) if result2: return ERROR(errno=201, errmsg='项目名称已经存在') insert = mongodb.PROJECT.insert_one({ 'app': app, "name": name, 'tasks_num': 0, 'count_tasks_num': 0 }) if insert: return SUCCESS(data='新建项目成功') return ERROR(errno=201, errmsg='新建项目失败')
def delete_task(): """ 删除任务,type参数说明,1代表轮训任务,2为统计任务,3为单次执行的统计任务。删除任务可以适应不同类型的任务 :return: """ oid = request.json.get('id') app = request.json.get('app') if not all([oid, app]): return ERROR(errno=201, errmsg='参数缺失') task = mongodb.TASK.find_one({'_id': ObjectId(oid)}) task_type = task.get('type') delete = mongodb.TASK.delete_one({'_id': ObjectId(oid)}) if not delete: return ERROR(errmsg='删除任务失败', errno=201) # mongo的 $inc方法可以对一个值进行数学运算 if task_type == 1: mongodb.PROJECT.find_one_and_update({'app': app}, {"$inc": { "tasks_num": -1 }}) elif task_type == 2: mongodb.PROJECT.find_one_and_update({'app': app}, {"$inc": { "count_tasks_num": -1 }}) # 删除统计任务,需要做记录,要是该项目的统计任务数量为0,那么就自动关闭这个项目的统计。 return SUCCESS()
def loginfo_check(): """ 确认日志告警问题,当出发报警条件,会在这个文档中存在一个字段,status,初始值为0,然后确认问题之后,"status"set为1。 :return: """ oid = request.json.get('id') note = request.json.get('note') if not oid: return ERROR(errno=201, errmsg='参数缺失') log_info = mongodb.LOGINFO.find_one({'_id': ObjectId(oid)}) if not log_info: return ERROR(errno=201, errmsg='待确认的日志信息不存在') update_result = mongodb.LOGINFO.update({'_id': ObjectId(oid), 'status': 0}, {'$set': {'status': 1}}) if not update_result: return ERROR(errno=201, errmsg='待确认操作失败') # 生成处理记录信息 name = session.get('username') time_str = datetime.datetime.strftime(datetime.datetime.now(), "%Y-%m-%d %H:%M:%S") params = { 'info_id': ObjectId(oid), 'name': name, 'tag': name + '确认问题', 'time': time_str, 'note': note } insert_id = mongodb.HANDLERECORD.insert_one(params) if not insert_id: return ERROR(errno=201, errmsg='确认日志信息记录失败') return SUCCESS(data='日志信息确认成功')
def log_info_solve(): """ 解决日志问题,当用户点击对应的已解决按钮,改变对应的文档字段status,1变为2。 :return: """ oid = request.json.get('id') note = request.json.get('note') if not oid: return ERROR(errno=201, errmsg='参数缺失') loginfo = mongodb.LOGINFO.find_one({'_id': ObjectId(oid)}) if not loginfo: return ERROR(errno=201, errmsg='待确认的日志信息不存在') updateresult = mongodb.LOGINFO.update({'_id': ObjectId(oid), 'status': 1}, {'$set': {'status': 2}}) if not updateresult: return ERROR(errno=201, errmsg='日志问题解决失败') name = session.get('username') time_str = datetime.datetime.strftime(datetime.datetime.now(), "%Y-%m-%d %H:%M:%S") params = { 'info_id': ObjectId(oid), 'name': name, 'tag': name + '解决问题', 'time': time_str, 'note': note } insert_id = mongodb.HANDLERECORD.insert_one(params) if not insert_id: return ERROR(errno=201, errmsg='解决日志信息记录失败') return SUCCESS(data='日志问题成功解决')
def change_user_status(): """ 修改用户状态信息 :return: """ id = request.json.get('id') if not id: return ERROR(errno=201, errmsg='参数不全') user = mongodb.USER.find_one({ '_id': ObjectId(id) }) # find_one会返回查询结果的布尔值,找到会true,没有则为false,但是find无论如何都会返回一个查询游标 if not user: return ERROR(errno=201, errmsg='所选操作用不存在') status = user.get('status') # 之前为启用,设置为禁用;之前为禁用,设置为启用 if status: update_id = mongodb.USER.find_one_and_update( {'_id': ObjectId(id)}, {'$set': { 'status': False }}) else: update_id = mongodb.USER.find_one_and_update( {'_id': ObjectId(id)}, {'$set': { 'status': True }}) if not update_id: return ERROR(errno=201, errmsg='用户状态修改失败') return SUCCESS(data='用户状态修改成功')
def get_handle_record_list(): """ 获取日志处理记录详情 :return: """ id = request.json.get('id') if not id: return ERROR(errno=201, errmsg='参数缺失') result_list = list(mongodb.HANDLERECORD.find({'info_id': ObjectId(id)}).sort("time", -1)) return SUCCESS(data=result_list)
def create_task(): """ 新建任务(周期性轮询任务) :return: """ app = request.json.get('app') name = request.json.get('name') timeCell = int( request.json.get('timeCell')) # timeCell 轮训时间执行的时间间隔,单位是minute times = int(request.json.get('times')) # times 触发告警的次数 params = request.json.get('params').strip() # 轮训查询参数 way = request.json.get('way') # 告警通知方式,主要是sms对应短信,email对应邮箱 person = request.json.get('person') if not all([app, name, timeCell, times, params, way, person]): return ERROR(errno=201, errmsg='参数缺失') now = datetime.datetime.now() insert_data = { "app": app, "name": name, 'timeCell': timeCell, 'times': times, 'params': params, 'way': way, 'person': person, "pid": '', 'type': 1, # 用type来区分任务分类,1为正常的轮询任务,2为周期统计任务,3为执行一次的统计任务。 'createAt': now, 'createAtStr': now.strftime('%Y-%m-%d %H:%M:%S'), 'dateStr': now.strftime('%Y-%m-%d') } find_data = { "app": app, "name": name, 'timeCell': timeCell, 'times': times, 'params': params, } result_id = mongodb.TASK.find_one(find_data) if result_id: return ERROR(errmsg="任务已经存在", errno=201) insert_data.update({"status": 0}) # 默认创建任务的时候,初始为停止状态。 insert_id = mongodb.TASK.insert_one(insert_data) if not insert_id: return ERROR(errno=201, errmsg='新建任务失败') else: update = mongodb.PROJECT.find_one_and_update( {'app': app}, {"$inc": { "tasks_num": 1 }}) if not update: return ERROR(errmsg='任务数更新失败', errno=201) return SUCCESS(data='新建任务成功')
def modify_task(): """ 修改任务 :return: """ oid = request.json.get('id') app = request.json.get('app') name = request.json.get('name') timeCell = int(request.json.get('timeCell')) times = int(request.json.get('times')) params = request.json.get('params').strip() way = request.json.get('way') person = request.json.get('person') if not all([oid, app, name, timeCell, times, params, way, person]): return ERROR(errno=201, errmsg='参数缺失') now = datetime.datetime.now() find_data = { "app": app, "name": name, 'timeCell': timeCell, 'times': times, 'params': params, 'way': way, 'person': person } find = mongodb.TASK.find_one(find_data) if find: return ERROR(errno=201, errmsg='任务信息已经存在') insert_data = { "app": app, "name": name, 'timeCell': timeCell, 'times': times, 'params': params, 'way': way, 'person': person, 'createAt': now, 'createAtStr': now.strftime('%Y-%m-%d %H:%M:%S'), 'dateStr': now.strftime('%Y-%m-%d') } insert_data.update({ "status": 0, 'pid': '' }) # 修改时候其实就是任务停止状态,这个可以有可以无。添加保证一下。 mongodb.TASK.find_one_and_update({'_id': ObjectId(oid)}, {'$set': insert_data}) return SUCCESS(data='修改任务成功')
def get_project_detail(): """ 项目管理查看详情 :return: """ id = request.json.get('id') if not id: return ERROR(errno=201, errmsg='参数缺失') project = mongodb.PROJECT.find_one({'_id': ObjectId(id)}) app = project.get('app') find_result = mongodb.TASK.find({ 'app': app }).sort([('type', 1), ('status', -1), ('createAtStr', -1)]) if not find_result: return ERROR(errno=201, errmsg='项目信息查询失败') data = {'project': project, 'task': find_result} return SUCCESS(data=data)
def get_loginfo_list(): """ 获取告警日志信息列表 { msgMD5:{ 'message':[timestamp,tiestamp] }, app:hotel, type:apilog, time:now ==>这个字段是保证能够在轮询任务人为或者是宕机是,根据判断状态重新启动轮询 } :return: """ name = request.json.get('name') status = request.json.get('status') report_time = request.json.get('report_time') keywords = request.json.get('keywords') page = request.json.get('page', 1) per_page = request.json.get('per_page', 8) skip = per_page * (page - 1) limit = per_page filters = {} if name: filters.update({"name": name}) if status != '': filters.update({"status": status}) if report_time: if type(report_time) != list: return ERROR(errno=201, errmsg='时间范围格式错误') begin_str, end_str = report_time filters.update({"update_time": { '$gte': begin_str, '$lte': end_str} }) if keywords: keywords.strip() filters.update({'loginfo.message': {'$regex': keywords}}) total_count = mongodb.LOGINFO.find(filters).count() loginfo_list = list(mongodb.LOGINFO.find(filters).sort([('time', -1)]).skip(skip).limit(limit)) result = { "count": total_count, "data": loginfo_list } return SUCCESS(data=result)
def login(): """ 根据用户登录输入的邮箱名和验证码,验证正确登陆完成。默认用户的登录账号统一为公司邮箱,初始密码默认为admin123。 :return: """ email = request.json.get('email') password = request.json.get('password') if not ([email, password]): return ERROR(errno=201, errmsg='参数缺失') user = mongodb.USER.find_one({'email': email}) if not user: return ERROR(errno=201, errmsg='该用户不存在') if not user.get('status'): return ERROR(errno=201, errmsg='用户被禁用') real_password = user.get('password') if password != real_password: return ERROR(errno=201, errmsg='密码错误') session['username'] = user['name'] return SUCCESS(data='用户登录成功')
def get_user_list(): """ 获取用户列表 :return: """ page = request.json.get('page', 1) # dict.get(key, default=None) per_page = request.json.get('per_page', 8) skip = per_page * ( page - 1 ) # 跳过前多少数据,不建议skip太多数据,会导致速度变慢,但是获取下一页可以使用上一页的最后一个数据的结果来计算下一页的初始数据 limit = per_page total_count = mongodb.USER.find().count() # mongo的find查询返回的是mongo的游标对象,不会立即查询数据库,在需要真的获取结果是才回查询数据库。可以通过curson.next()迭代后续结果 user_list = list(mongodb.USER.find().sort( 'status', -1).skip(skip).limit(limit)) # MONGO排序1为升序,-1为降序 if not user_list: return ERROR(errno=201, errmsg='用户信息列表为空') result = {"data": user_list, "count": total_count} return SUCCESS(data=result)
def create_user(): """ 新增用户 :return: """ body = request.json name = request.json.get('name') mobile = request.json.get('mobile') # 告警触发后短信通知这个手机号 email = request.json.get('email') # 告警触发后或者统计报告邮箱通知 password = request.json.get('password') if not ([name, mobile, email, password]): return ERROR(errno=201, errmsg='新增用户信息不全') body.update({'status': True}) insert_id = mongodb.USER.insert_one( body ) # mongo再插入成功会返回插入文档的ID,mongo在插入只会做一些基本校验,_id重复,以及文档大小。因此很统一插入非法数据 if insert_id: return SUCCESS(data='新增用户成功') return ERROR(errno=201, errmsg='新增用户失败')
def get_loginfo_detail(): """ 获取日志告警信息详情 :return: """ oid = request.json.get('id') per_page = request.json.get('per_page') page = request.json.get('page') if not all([oid, per_page, page]): return ERROR(errno=201, errmsg='参数缺失') result = mongodb.LOGINFO.find_one({"_id": ObjectId(oid)}) timeline = result['loginfo']['timeline'] total_num = len(timeline) timeline.sort(reverse=True) start_index = (page - 1) * page end_index = page * per_page timeline = timeline[start_index: end_index] result['timeline'] = timeline result['total_num'] = total_num if not result: return ERROR(errno=201, errmsg="查询失败") return SUCCESS(data=result)
def modify_project(): """ 修改项目信息 :return: """ id = request.json.get('id') app = request.json.get("app") name = request.json.get('name') if not all([id, app, name]): return ERROR(errno=201, errmsg='参数缺失') old_project = mongodb.PROJECT.find_one({'_id': ObjectId(id)}) old_app = old_project.get('app') old_name = old_project.get('name') if old_app != app or old_name != name: # mongo中find_One_and_update 找到并修改成功会返回修改的文档,否则会返回None update_id = mongodb.PROJECT.find_one_and_update( {"_id": ObjectId(id)}, {'$set': { 'app': app, "name": name }}) if not update_id: return ERROR(errno=201, errmsg="修改项目信息失败") # 修改项目信息需要针对项目app的修改去改正任务中关联的项目 mongodb.TASK.update({'app': old_app}, {'$set': { 'app': app, 'name': name }}, upsert=False, multi=True) mongodb.LOGINFO.update({'app': old_app}, {'$set': { 'app': app, 'name': name }}, upsert=False, multi=True) return SUCCESS()
def modify_tasks_status(): """ 修改任务状态信息, status参数说明,0代表停止,1代表开始。 :return: """ oid = request.json.get("id") status = int(request.json.get("status")) if oid is None or status is None: return ERROR(errno=201, errmsg="参数缺失") task = mongodb.TASK.find_one({'_id': ObjectId(oid)}) pid = task.get('pid') if pid: try: os.kill(pid, signal.SIGKILL) except Exception as e: logger.warning('pid kill failed : {}, error message id {}'.format( pid, e)) mongodb.TASK.find_one_and_update({'_id': ObjectId(oid)}, {'$set': { 'status': status, 'pid': '' }}) return SUCCESS()
def modify_user_info(): """ 修改编辑用户信息 :return: """ id = request.json.get('id') name = request.json.get('name') mobile = request.json.get('mobile') email = request.json.get('email') password = request.json.get('password') if not ([id, name, mobile, email, password]): return ERROR(errno=201, errmsg='修改用户所填信息不全') update_id = mongodb.USER.find_one_and_update({'_id': ObjectId(id)}, { '$set': { 'name': name, 'email': email, 'password': password, 'mobile': mobile } }) if update_id: return SUCCESS(data='用户信息修改成功') return ERROR(errno=201, errmsg='用户信息修改失败')
def batch_not_alert(): """ 批量处理告警消息,批量设置不再告警 ,不再告警的设置int为3。 :return: """ oids = request.json.get('ids') note = request.json.get('note') if not oids: return ERROR(errno=201, errmsg="请选择需要关闭的告警信息") for oid in oids: log_info = mongodb.LOGINFO.find_one({'_id': ObjectId(oid)}) if not log_info: return ERROR(errno=201, errmsg='待设置的日志信息不存在') mongodb.LOGINFO.update_one({'_id': ObjectId(oid)}, {'$set': {'status': 3}}) # 每一条告警消息对应添加相应的处理记录 name = session.get('username') time_str = datetime.datetime.strftime(datetime.datetime.now(), "%Y-%m-%d %H:%M:%S") params = { 'info_id': ObjectId(oid), 'name': name, 'tag': name + '将该条日志设置为不再告警', 'time': time_str, 'note': note } insert_id = mongodb.HANDLERECORD.insert_one(params) if not insert_id: return ERROR(errno=201, errmsg='解决日志信息记录失败') return SUCCESS(data='日志问题成功解决')
def get_index_info(): """ 首页各种数据信息统计展示 :return: """ # 同步月报统计的表格信息展示,展示的数据主要包括,A代表apilog类型,B代表nginx-access类型。 # [项目名称,代号,告警总数,A/B告警数,A/B完成数,A/B未完成数,A/B完成率,总完成率。] select_month = request.json.get('selectMonth') if select_month: mon_start_date = select_month + '.01' mon_end_date = select_month + '.31' else: # 首页默认可是当前月份,不默认统计之前月份信息。 # mon_start_date, mon_end_date = get_last_month_date() tm_year = time.localtime().tm_year # 当前年份 tm_mon = time.localtime().tm_mon # 当前月份 if tm_mon <= 10: tm_mon = '0' + str(tm_mon) mon_start_date = str(tm_year) + '.' + str(tm_mon) + '.01' mon_end_date = str(tm_year) + '.' + str(tm_mon) + '.31' tm_year = mon_start_date.split('.')[0] tm_mon = mon_start_date.split('.')[1] content = '{}年{}月份日志告警信息统计结果如下:\n\n'.format(tm_year, tm_mon) project_list = list(mongodb.PROJECT.find()) data = [] # {"项目名称", "项目代号", "告警总数", "A/N告警数", "A/N完成数", "A/N未完成数", "A/N完成率", "总完成率"} for project in project_list: project_name = project.get('name') # 项目名称 project_app = project.get('app') # 项目代号 log_info_total_num = mongodb.LOGINFO.find({ 'app': project_app, 'update_time': { '$gte': mon_start_date, '$lte': mon_end_date } }).count() api_log_num = mongodb.LOGINFO.find({ 'app': project_app, 'type': 'apilog', 'update_time': { '$gte': mon_start_date, '$lte': mon_end_date } }).count() nginx_access_num = mongodb.LOGINFO.find({ 'app': project_app, 'type': 'nginx-access', 'update_time': { '$gte': mon_start_date, '$lte': mon_end_date } }).count() api_log_solve_num = mongodb.LOGINFO.find({ 'app': project_app, 'type': 'apilog', 'status': { '$in': [2, 3] }, 'update_time': { '$gte': mon_start_date, '$lte': mon_end_date } }).count() nginx_access_solve_num = mongodb.LOGINFO.find({ 'app': project_app, 'type': 'nginx-access', 'status': { '$in': [2, 3] }, 'update_time': { '$gte': mon_start_date, '$lte': mon_end_date } }).count() api_log_not_solve_num = api_log_num - api_log_solve_num nginx_access_not_solve_num = nginx_access_num - nginx_access_solve_num if api_log_num: api_log_solve_percentage = '%.2f%%' % ( (api_log_solve_num / api_log_num) * 100) else: api_log_solve_percentage = '100%' if nginx_access_num: nginx_access_solve_percentage = '%.2f%%' % ( (nginx_access_solve_num / nginx_access_num) * 100) else: nginx_access_solve_percentage = '100%' log_info_total_solve_num = mongodb.LOGINFO.find({ 'app': project_app, 'status': { '$in': [2, 3] }, 'update_time': { '$gte': mon_start_date, '$lte': mon_end_date } }).count() if log_info_total_num: log_info_total_solve_percentage = '%.2f%%' % ( (log_info_total_solve_num / log_info_total_num) * 100) else: log_info_total_solve_percentage = '100%' project_data = { "name": project_name, "app": project_app, "total_num": log_info_total_num, "A/N_total_num": "{}/{}".format(api_log_num, nginx_access_num), "A/N_solve_num": "{}/{}".format(api_log_solve_num, nginx_access_solve_num), "A/N_not_solve_num": "{}/{}".format(api_log_not_solve_num, nginx_access_not_solve_num), "A/N_solve_num_per": "{}/{}".format(api_log_solve_percentage, nginx_access_solve_percentage), "total_per": log_info_total_solve_percentage } data.append(project_data) result = { "data": data, "title": '{}年{}月份日志告警信息统计结果如下:'.format(tm_year, tm_mon) } return SUCCESS(data=result)