From 87795e1a7e04c0a76bc674ac66d9ce286b39664c Mon Sep 17 00:00:00 2001 From: TsMask <340112800@qq.com> Date: Fri, 9 May 2025 18:46:25 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=B0=83=E5=BA=A6=E4=BB=BB=E5=8A=A1-?= =?UTF-8?q?=E5=91=8A=E8=AD=A6=E6=A3=80=E6=9F=A5CPU/License/=E5=AF=BC?= =?UTF-8?q?=E5=87=BA=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- database/install/sys_dict_data1_i18n_zh.sql | 20 +- database/install/sys_dict_data2_i18n_en.sql | 20 +- database/install/sys_job.sql | 25 +- .../upgrade/upg_sys_dict_data1_i18n_zh.sql | 24 +- .../upgrade/upg_sys_dict_data2_i18n_en.sql | 18 +- database/upgrade/upg_sys_job.sql | 25 +- .../backup_export_cdr/backup_export_cdr.go | 1442 +++++++++++++++++ .../backup_export_log/backup_export_log.go | 367 +++++ .../backup_export_udm/backup_export_udm.go | 273 ++++ .../backup_remove_file/backup_remove_file.go | 113 ++ .../ne_alarm_state_check.go | 172 ++ .../ne_alarm_state_check_cmd.go | 288 ++++ .../ne_alarm_state_check_license.go | 213 +++ src/modules/crontask/processor/processor.go | 22 +- .../network_data/model/cdr_event_sgwc.go | 2 + 15 files changed, 2991 insertions(+), 33 deletions(-) create mode 100644 src/modules/crontask/processor/backup_export_cdr/backup_export_cdr.go create mode 100644 src/modules/crontask/processor/backup_export_log/backup_export_log.go create mode 100644 src/modules/crontask/processor/backup_export_udm/backup_export_udm.go create mode 100644 src/modules/crontask/processor/backup_remove_file/backup_remove_file.go create mode 100644 src/modules/crontask/processor/ne_alarm_state_check/ne_alarm_state_check.go create mode 100644 src/modules/crontask/processor/ne_alarm_state_check_cmd/ne_alarm_state_check_cmd.go create mode 100644 src/modules/crontask/processor/ne_alarm_state_check_license/ne_alarm_state_check_license.go diff --git a/database/install/sys_dict_data1_i18n_zh.sql b/database/install/sys_dict_data1_i18n_zh.sql index aa7e5122..893ac34a 100644 --- a/database/install/sys_dict_data1_i18n_zh.sql +++ b/database/install/sys_dict_data1_i18n_zh.sql @@ -70,10 +70,10 @@ INSERT INTO `sys_dict_data` VALUES (1062, 1062, 'menu.ueUser.authUDMRemark', 'UD INSERT INTO `sys_dict_data` VALUES (1063, 1063, 'menu.ueUser.subUDMRemark', 'UDM签约用户菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (1064, 1064, 'dictData.cdr_sip_code_cause.202', 'The request has been accepted for processing, but it hasn’t completed yet ', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (1065, 1065, 'dictData.cdr_sip_code_cause.0', 'Call failure for other reason', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); --- INSERT INTO `sys_dict_data` VALUES (1066, 1066, 'menu.config.neManageRemark', '网元管理菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); --- INSERT INTO `sys_dict_data` VALUES (1067, 1067, 'menu.config.configNERemark', '参数配置菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); --- INSERT INTO `sys_dict_data` VALUES (1068, 1068, 'menu.config.backupManage', '备份管理', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); --- INSERT INTO `sys_dict_data` VALUES (1069, 1069, 'menu.config.softwareManage', '软件管理', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +INSERT INTO `sys_dict_data` VALUES (1066, 1066, 'config.neData.backupDataFTP', '备份网元数据-同步FTP服务', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +INSERT INTO `sys_dict_data` VALUES (1067, 1067, 'config.neData.backupDataFTPRemark', '请通过系统页面进行设置FTP信息', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +INSERT INTO `sys_dict_data` VALUES (1068, 1068, 'job.backup_export_log', '备份-日志数据定期导出', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +INSERT INTO `sys_dict_data` VALUES (1069, 1069, 'job.backup_export_log_remark', 'dataType: 类型支持 operate/login\nfileType: 文件类型 csv/xlsx\nhour: 数据时间从任务执行时间前的小时数', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (1070, 1070, 'menu.ueUser.onlineIMS', 'IMS在线用户', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (1071, 1071, 'menu.ueUser.onlineUE', 'UE在线信息', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (1072, 1072, 'menu.ueUser.base5G', '基站信息', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); @@ -733,6 +733,18 @@ INSERT INTO `sys_dict_data` VALUES (2222, 2222, 'dictData.trace_interfaces.17', INSERT INTO `sys_dict_data` VALUES (2223, 2223, 'dictData.trace_interfaces.20', 'N20', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); INSERT INTO `sys_dict_data` VALUES (2224, 2224, 'dictData.trace_interfaces.22', 'N22', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); INSERT INTO `sys_dict_data` VALUES (2225, 2225, 'dictData.trace_interfaces.40', 'N40', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2226, 2226, 'job.ne_alarm_state_check_cmd', '网元告警-内存/CPU/磁盘检查', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2227, 2227, 'job.ne_alarm_state_check_cmd_remark', '检查网元的内存/CPU/磁盘检查健康状况,在出现过阈值时发出警报。\r\n\r\nAlarm type:\r\nCommunicationAlarm=1\r\nEquipmentAlarm=2\r\nProcessingFailure=3\r\nEnvironmentalAlarm=4\r\nQualityOfServiceAlarm=5\r\n\r\nSeverity:\r\nCritical=1\r\nMajor=2\r\nMinor=3\r\nWarning=4\r\n\r\nAddInfo: 告警补充信息\r\ncpuUseGt: CPU使用率大于, 范围0~100%\r\nmemUseGt: 内存使用率大于, 范围0~100%\r\ndiskUseGt: 磁盘使用率大于, 范围0~100%', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2228, 2228, 'job.ne_alarm_state_check_license', '网元告警-License到期检查', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2229, 2229, 'job.ne_alarm_state_check_license_remark', '检查网元的License是否即将到期,在出现过阈值时发出警报。\r\n\r\nAlarm type:\r\nCommunicationAlarm=1\r\nEquipmentAlarm=2\r\nProcessingFailure=3\r\nEnvironmentalAlarm=4\r\nQualityOfServiceAlarm=5\r\n\r\nSeverity:\r\nCritical=1\r\nMajor=2\r\nMinor=3\r\nWarning=4\r\n\r\nAddInfo: 告警补充信息\r\ndayLt: 天数小于,默认30天', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2230, 2230, 'job.ne_alarm_state_check', '网元告警-状态检查', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2231, 2231, 'job.ne_alarm_state_check_remark', '检查网元的健康状况,在出现异常时发出警报。\r\n\r\nAlarm type:\r\nCommunicationAlarm=1\r\nEquipmentAlarm=2\r\nProcessingFailure=3\r\nEnvironmentalAlarm=4\r\nQualityOfServiceAlarm=5\r\n\r\nSeverity:\r\nCritical=1\r\nMajor=2\r\nMinor=3\r\nWarning=4', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2232, 2232, 'job.backup_export_udm', '备份-UDM数据定期导出', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2233, 2233, 'job.backup_export_udm_remark', 'dataType: 类型支持 auth/sub/voip/volte\nfileType: 文件类型 csv/txt', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2234, 2234, 'job.backup_remove_file', '备份-定期删除备份目录下文件', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2235, 2235, 'job.backup_remove_file_remark', 'backupPath: 备份路径 /usr/local/omc/backup/{backupPath}\nstoreDays: 保留天数\nstoreNum: 保留数量,默认保留7', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2236, 2236, 'job.backup_export_cdr', '备份-CDR数据定期导出', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (2237, 2237, 'job.backup_export_cdr_remark', 'dataType: 类型支持 ims/smf/sgwc/smsc\nfileType: 文件类型 csv/xlsx\nhour: 数据时间从任务执行时间前的小时数', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); -- multi-tenancy INSERT INTO `sys_dict_data` VALUES (11000, 11000, 'menu.security.tenant', '租户管理', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); diff --git a/database/install/sys_dict_data2_i18n_en.sql b/database/install/sys_dict_data2_i18n_en.sql index 87451498..824f937b 100644 --- a/database/install/sys_dict_data2_i18n_en.sql +++ b/database/install/sys_dict_data2_i18n_en.sql @@ -70,10 +70,10 @@ INSERT INTO `sys_dict_data` VALUES (3062, 3062, 'menu.ueUser.authUDMRemark', 'UD INSERT INTO `sys_dict_data` VALUES (3063, 3063, 'menu.ueUser.subUDMRemark', 'UDM Subscriber Menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3064, 3064, 'dictData.cdr_sip_code_cause.202', 'The request has been accepted for processing, but it hasn’t completed yet ', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3065, 3065, 'dictData.cdr_sip_code_cause.0', 'Call failure for other reason', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); --- INSERT INTO `sys_dict_data` VALUES (3066, 3066, 'menu.config.neManageRemark', 'Network Element Management Menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); --- INSERT INTO `sys_dict_data` VALUES (3067, 3067, 'menu.config.configNERemark', 'Parameter Configuration Menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); --- INSERT INTO `sys_dict_data` VALUES (3068, 3068, 'menu.config.backupManage', 'Backup Management', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); --- INSERT INTO `sys_dict_data` VALUES (3069, 3069, 'menu.config.softwareManage', 'Software Management', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +INSERT INTO `sys_dict_data` VALUES (3066, 3066, 'config.neData.backupDataFTP', 'Backup NE Data - Sync Data FTP Service', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +INSERT INTO `sys_dict_data` VALUES (3067, 3067, 'config.neData.backupDataFTPRemark', 'Please set the FTP information through the system page.', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +INSERT INTO `sys_dict_data` VALUES (3068, 3068, 'job.backup_export_log', 'Backup-Periodic export of Log Data', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +INSERT INTO `sys_dict_data` VALUES (3069, 3069, 'job.backup_export_log_remark', 'Backup-Periodic export of dataType: type support operate/login\nfileType: file type csv/xlsx\nhour: data time from the hour before the task execution time', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3070, 3070, 'menu.ueUser.onlineIMS', 'IMS Online Users', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3071, 3071, 'menu.ueUser.onlineUE', 'UE Online Information', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); INSERT INTO `sys_dict_data` VALUES (3072, 3072, 'menu.ueUser.base5G', 'Radio Information', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); @@ -733,6 +733,18 @@ INSERT INTO `sys_dict_data` VALUES (4222, 4222, 'dictData.trace_interfaces.17', INSERT INTO `sys_dict_data` VALUES (4223, 4223, 'dictData.trace_interfaces.20', 'N20', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); INSERT INTO `sys_dict_data` VALUES (4224, 4224, 'dictData.trace_interfaces.22', 'N22', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); INSERT INTO `sys_dict_data` VALUES (4225, 4225, 'dictData.trace_interfaces.40', 'N40', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4226, 4226, 'job.ne_alarm_state_check_cmd', 'NE Alarm-Memory/CPU/Disk Checks', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4227, 4227, 'job.ne_alarm_state_check_cmd_remark', 'Checks the memory/CPU/disk check health of the network element and sends alerts when thresholds are crossed.\n\nAlarm type:\nCommunicationAlarm=1\nEquipmentAlarm=2\nProcessingFailure=3\nEnvironmentalAlarm=4\nQualityOfServiceAlarm=5\n\nSeverity:\nCritical=1\nMajor=2\nMinor=3\nWarning=4\r\n\r\nAddInfo: Additional information on alarms\r\ncpuUseGt: CPU utilization greater than, range 0 to 100%\r\nmemUseGt: Memory utilization greater than, range 0 to 100%\r\ndiskUseGt: Disk utilization greater than, range 0 to 100%', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4228, 4228, 'job.ne_alarm_state_check_license', 'NE Alarm-License Expire Check', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4229, 4229, 'job.ne_alarm_state_check_license_remark', 'Checks if the network element is License is about to expire and sends an alert if a threshold is crossed.\n\nAlarm type:\nCommunicationAlarm=1\nEquipmentAlarm=2\nProcessingFailure=3\nEnvironmentalAlarm=4\nQualityOfServiceAlarm=5\n\nSeverity:\nCritical=1\nMajor=2\nMinor=3\nWarning=4\r\n\r\nAddInfo: Additional information on alarms\r\ndayLt: Days less than, default 30 days', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4230, 4230, 'job.ne_alarm_state_check', 'NE Alarm-Health State Check', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4231, 4231, 'job.ne_alarm_state_check_remark', 'Checks the health of network elements and sends alerts in case of anomalies.\n\nAlarm type:\nCommunicationAlarm=1\nEquipmentAlarm=2\nProcessingFailure=3\nEnvironmentalAlarm=4\nQualityOfServiceAlarm=5\n\nSeverity:\nCritical=1\nMajor=2\nMinor=3\nWarning=4', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4232, 4232, 'job.backup_export_udm', 'Backup-Periodic export of UDM Data', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4233, 4233, 'job.backup_export_udm_remark', 'backupPath: backup path /usr/local/omc/backup/{backupPath}\nstoreDays: retention days\nstoreNum: retention number, default retention 7', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4234, 4234, 'job.backup_remove_file', 'Backup-Periodically Delete Directory Files', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4235, 4235, 'job.backup_remove_file_remark', 'backupPath: backup path /usr/local/omc/backup/{backupPath}\nstoreDays: retention days\nstoreNum: retention number, default retention 7', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4236, 4236, 'job.backup_export_cdr', 'Backup-Periodic export of CDR Data', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +INSERT INTO `sys_dict_data` VALUES (4237, 4237, 'job.backup_export_cdr_remark', 'Backup-Periodic export of dataType: type support ims/smf/sgwc/smsc\nfileType: file type csv/xlsx\nhour: data time from the hour before the task execution time', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); -- 多租户 INSERT INTO `sys_dict_data` VALUES (14000, 14000, 'menu.security.tenant', 'Tenant Management', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); diff --git a/database/install/sys_job.sql b/database/install/sys_job.sql index 3505d1a3..c08e9648 100644 --- a/database/install/sys_job.sql +++ b/database/install/sys_job.sql @@ -37,13 +37,22 @@ INSERT INTO `sys_job` VALUES (6, 'job.deleteExpiredKpiRecord', 'SYSTEM', 'delete -- INSERT INTO `sys_job` VALUES (7, 'job.backupEtcFromNE', 'SYSTEM', 'backupEtcFromNE', NULL, '0 30 0 * * ?', '3', '0', '0', '1', 'supervisor', 1698478134843, NULL, 0, 'job.backupEtcFromNERemark'); INSERT INTO `sys_job` VALUES (8, 'job.deleteExpiredNeStateRecord', 'SYSTEM', 'deleteExpiredRecord', '{\"duration\":1,\"tableName\":\"ne_state\",\"colName\":\"timestamp\"}', '0 25 0 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1703668901929, 'job.deleteExpiredNeStateRecordRemark'); INSERT INTO `sys_job` VALUES (9, 'job.getStateFromNE', 'SYSTEM', 'getStateFromNE', '', '0/10 * * * * ?', '3', '0', '0', '0', 'supervisor', 1698478134842, 'admin', 1713231120503, 'job.getStateFromNERemark'); -INSERT INTO `sys_job` VALUES (10, 'job.genNeStateAlarm', 'SYSTEM', 'genNeStateAlarm', '{\"alarmID\":\"HXEMSSM10000\",\"alarmCode\":10000,\"alarmTitle\":\"The system state is abnormal\",\"neType\":\"OMC\",\"alarmType\":\"EquipmentAlarm\",\"origSeverity\": \"Major\",\"objectName\":\"EMS;SystemManagement;Heartbeat\",\"objectType\":\"SystemState\",\"specificProblem\":\"Alarm cause: the system state of target NE has not been received for {threshold} seconds\", \"specificProblemID\":\"AC10000\",\"threshold\":30}', '0/5 * * * * ?', '3', '0', '1', '0', 'supervisor', 1698478134842, 'admin', 1713781643031, 'job.genNeStateAlarmRemark'); -INSERT INTO `sys_job` VALUES (11, 'job.exportOperateLog', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"sys_log_operate\",\"timeCol\":\"oper_time\",\"timeUnit\":\"milli\",\"columns\":\"oper_id,omc_get_dict_value(title, \\\"i18n_en\\\") as title,business_type,method,request_method,operator_type,oper_name,dept_name,oper_url,oper_ip,oper_location,oper_param,oper_msg,status,oper_time,cost_time,tenant_id\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/operate_log\"}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1724833786290, 'job.exportOperateLog'); -INSERT INTO `sys_job` VALUES (12, 'job.exportIMSCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_ims\",\"columns\":\"id,ne_name,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) as record_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callType\')) as call_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callerParty\')) as caller_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.calledParty\')) as called_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callDuration\')) as call_duration,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.serviceResult\')) as service_result,DATE_FORMAT(FROM_UNIXTIME(timestamp), \'%Y-%m-%d %H:%i:%s\') AS timestamp\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/ims_cdr\"}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1722224659251, ''); -INSERT INTO `sys_job` VALUES (13, 'job.exportSMFCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_smf\",\"columns\":\"id,ne_type,ne_name,rm_uid,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) AS record_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.chargingID\')) AS charging_id,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.subscriberIdentifier.subscriptionIDType\')) AS subscriber_id_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.subscriberIdentifier.subscriptionIDData\')) AS subscriber_id_data,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.duration\')) AS duration,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.invocationTimestamp\')) as invocationTimestamp,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataVolumeUplink\')) AS data_volume_uplink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataVolumeDownlink\')) AS data_volume_downlink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataTotalVolume\')) AS data_total_volume,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.pDUSessionChargingInformation.pDUAddress.pDUIPv4Address\')) AS pdu_ipv4_address,timestamp\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/smf_cdr\"}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1724309047797, ''); -INSERT INTO `sys_job` VALUES (14, 'job.exportSMSCCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_smsc\",\"columns\":\"id,ne_name,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) as record_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.serviceType\')) as service_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callerParty\')) as caller_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.calledParty\')) as called_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.result\')) as result,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.updateTime\')) as update_time\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/smsc_cdr\"}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1724309047797, ''); -INSERT INTO `sys_job` VALUES (15, 'job.removeExportedFiles', 'SYSTEM', 'removeFile', '[{\"filePath\":\"/usr/local/omc/backup/operate_log\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/ims_cdr\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/smf_cdr\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/smsc_cdr\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/u_auth_user\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/u_sub_user\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/u_voip_auth\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/u_ims_user\",\"maxDays\":30}]', '0 10 0 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1728634085631, ''); -INSERT INTO `sys_job` VALUES (16, 'job.exportSGWCCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_sgwc\",\"columns\":\"id,ne_name,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) as recordType,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.accessPointNameNI\')) as accessPointNameNI,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.servedIMSI\')) as IMSI,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.servedMSISDN\')) as MSISDN,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.servedPDPPDNAddress\')) as PdpAddress,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.duration\')) as duration,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordOpeningTime\')) as recordOpeningTime,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.chargingID\')) as chargingID,JSON_UNQUOTE(JSON_EXTRACT(cdr_json, \'$.listOfTrafficVolumes[0].dataVolumeGPRSDownlink\')) AS dataVolumeGPRSDownlink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json, \'$.listOfTrafficVolumes[0].dataVolumeGPRsUplink\')) as dataVolumeGPRsUplink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.userLocationInformation.tai.tac\')) as tac,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.userLocationInformation.ecgi.eutraCellId\')) as cellID\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/sgwc_cdr\"}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1724309047797, ''); -INSERT INTO `sys_job` VALUES (17, 'job.backup.ue.data', 'SYSTEM', 'exportUEData', '[{\"tableName\":\"u_auth_user\",\"columns\":\"imsi,ki,amf,algo_index,opc\",\"extras\":\"\",\"serviceName\":\"UDMAuthUser\",\"orderBy\":\"imsi\",\"orderType\":\"desc\", \"fileType\":\"txt\",\"filePath\":\"/usr/local/omc/backup/u_auth_user\"},{\"tableName\":\"u_sub_user\",\"columns\":\"imsi,msisdn,ambr,nssai,arfb,sar,rat,cn_type,smf_sel,sm_data,eps_flag,eps_odb,hplmn_odb,ard,epstpl,context_id,apn_context,static_ip\",\"extras\":\"\",\"serviceName\":\"UDMSubUser\",\"orderBy\":\"imsi\",\"orderType\":\"desc\", \"fileType\":\"txt\",\"filePath\":\"/usr/local/omc/backup/u_sub_user\"},{\"tableName\":\"u_voip_auth\",\"columns\":\"user_name,password\",\"extras\":\"\",\"serviceName\":\"UDMVoIPAuth\",\"orderBy\":\"user_name\",\"orderType\":\"desc\", \"fileType\":\"txt\",\"filePath\":\"/usr/local/omc/backup/u_voip_auth\"},{\"tableName\":\"u_ims_user\",\"columns\":\"imsi,msisdn,tag,vni\",\"extras\":\"\",\"serviceName\":\"UDMIMSUser\",\"orderBy\":\"imsi\",\"orderType\":\"desc\", \"fileType\":\"txt\",\"filePath\":\"/usr/local/omc/backup/u_ims_user\"}]', '0 35 0 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1743479268652, ''); +INSERT INTO `sys_job` VALUES (10, 'job.genNeStateAlarm', 'SYSTEM', 'genNeStateAlarm', '{\"alarmID\":\"HXEMSSM10000\",\"alarmCode\":10000,\"alarmTitle\":\"The system state is abnormal\",\"neType\":\"OMC\",\"alarmType\":\"EquipmentAlarm\",\"origSeverity\": \"Major\",\"objectName\":\"EMS;SystemManagement;Heartbeat\",\"objectType\":\"SystemState\",\"specificProblem\":\"Alarm cause: the system state of target NE has not been received for {threshold} seconds\", \"specificProblemID\":\"AC10000\",\"threshold\":30}', '0/5 * * * * ?', '3', '0', '0', '0', 'supervisor', 1698478134842, 'admin', 1713781643031, 'job.genNeStateAlarmRemark'); +INSERT INTO `sys_job` VALUES (11, 'job.exportOperateLog', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"sys_log_operate\",\"timeCol\":\"oper_time\",\"timeUnit\":\"milli\",\"columns\":\"oper_id,omc_get_dict_value(title, \\\"i18n_en\\\") as title,business_type,method,request_method,operator_type,oper_name,dept_name,oper_url,oper_ip,oper_location,oper_param,oper_msg,status,oper_time,cost_time,tenant_id\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/operate_log\"}', '0 0 0/1 * * ?', '3', '0', '0', '1', 'supervisor', 1698478134842, 'admin', 1724833786290, 'job.exportOperateLog'); +INSERT INTO `sys_job` VALUES (12, 'job.exportIMSCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_ims\",\"columns\":\"id,ne_name,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) as record_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callType\')) as call_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callerParty\')) as caller_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.calledParty\')) as called_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callDuration\')) as call_duration,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.serviceResult\')) as service_result,DATE_FORMAT(FROM_UNIXTIME(timestamp), \'%Y-%m-%d %H:%i:%s\') AS timestamp\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/ims_cdr\"}', '0 0 0/1 * * ?', '3', '0', '0', '1', 'supervisor', 1698478134842, 'admin', 1722224659251, ''); +INSERT INTO `sys_job` VALUES (13, 'job.exportSMFCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_smf\",\"columns\":\"id,ne_type,ne_name,rm_uid,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) AS record_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.chargingID\')) AS charging_id,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.subscriberIdentifier.subscriptionIDType\')) AS subscriber_id_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.subscriberIdentifier.subscriptionIDData\')) AS subscriber_id_data,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.duration\')) AS duration,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.invocationTimestamp\')) as invocationTimestamp,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataVolumeUplink\')) AS data_volume_uplink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataVolumeDownlink\')) AS data_volume_downlink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataTotalVolume\')) AS data_total_volume,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.pDUSessionChargingInformation.pDUAddress.pDUIPv4Address\')) AS pdu_ipv4_address,timestamp\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/smf_cdr\"}', '0 0 0/1 * * ?', '3', '0', '0', '1', 'supervisor', 1698478134842, 'admin', 1724309047797, ''); +INSERT INTO `sys_job` VALUES (14, 'job.exportSMSCCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_smsc\",\"columns\":\"id,ne_name,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) as record_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.serviceType\')) as service_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callerParty\')) as caller_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.calledParty\')) as called_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.result\')) as result,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.updateTime\')) as update_time\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/smsc_cdr\"}', '0 0 0/1 * * ?', '3', '0', '0', '1', 'supervisor', 1698478134842, 'admin', 1724309047797, ''); +INSERT INTO `sys_job` VALUES (15, 'job.removeExportedFiles', 'SYSTEM', 'removeFile', '[{\"filePath\":\"/usr/local/omc/backup/operate_log\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/ims_cdr\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/smf_cdr\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/smsc_cdr\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/u_auth_user\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/u_sub_user\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/u_voip_auth\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/u_ims_user\",\"maxDays\":30}]', '0 10 0 * * ?', '3', '0', '0', '1', 'supervisor', 1698478134842, 'admin', 1728634085631, ''); +INSERT INTO `sys_job` VALUES (16, 'job.exportSGWCCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_sgwc\",\"columns\":\"id,ne_name,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) as recordType,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.accessPointNameNI\')) as accessPointNameNI,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.servedIMSI\')) as IMSI,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.servedMSISDN\')) as MSISDN,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.servedPDPPDNAddress\')) as PdpAddress,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.duration\')) as duration,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordOpeningTime\')) as recordOpeningTime,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.chargingID\')) as chargingID,JSON_UNQUOTE(JSON_EXTRACT(cdr_json, \'$.listOfTrafficVolumes[0].dataVolumeGPRSDownlink\')) AS dataVolumeGPRSDownlink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json, \'$.listOfTrafficVolumes[0].dataVolumeGPRsUplink\')) as dataVolumeGPRsUplink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.userLocationInformation.tai.tac\')) as tac,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.userLocationInformation.ecgi.eutraCellId\')) as cellID\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/sgwc_cdr\"}', '0 0 0/1 * * ?', '3', '0', '0', '1', 'supervisor', 1698478134842, 'admin', 1724309047797, ''); +INSERT INTO `sys_job` VALUES (17, 'job.backup.ue.data', 'SYSTEM', 'exportUEData', '[{\"tableName\":\"u_auth_user\",\"columns\":\"imsi,ki,amf,algo_index,opc\",\"extras\":\"\",\"serviceName\":\"UDMAuthUser\",\"orderBy\":\"imsi\",\"orderType\":\"desc\", \"fileType\":\"txt\",\"filePath\":\"/usr/local/omc/backup/u_auth_user\"},{\"tableName\":\"u_sub_user\",\"columns\":\"imsi,msisdn,ambr,nssai,arfb,sar,rat,cn_type,smf_sel,sm_data,eps_flag,eps_odb,hplmn_odb,ard,epstpl,context_id,apn_context,static_ip\",\"extras\":\"\",\"serviceName\":\"UDMSubUser\",\"orderBy\":\"imsi\",\"orderType\":\"desc\", \"fileType\":\"txt\",\"filePath\":\"/usr/local/omc/backup/u_sub_user\"},{\"tableName\":\"u_voip_auth\",\"columns\":\"user_name,password\",\"extras\":\"\",\"serviceName\":\"UDMVoIPAuth\",\"orderBy\":\"user_name\",\"orderType\":\"desc\", \"fileType\":\"txt\",\"filePath\":\"/usr/local/omc/backup/u_voip_auth\"},{\"tableName\":\"u_ims_user\",\"columns\":\"imsi,msisdn,tag,vni\",\"extras\":\"\",\"serviceName\":\"UDMIMSUser\",\"orderBy\":\"imsi\",\"orderType\":\"desc\", \"fileType\":\"txt\",\"filePath\":\"/usr/local/omc/backup/u_ims_user\"}]', '0 35 0 * * ?', '3', '0', '0', '1', 'supervisor', 1698478134842, 'admin', 1743479268652, ''); + +INSERT INTO `sys_job` VALUES (20, 'job.ne_alarm_state_check', 'SYSTEM', 'ne_alarm_state_check', '{\"alarmTitle\":\"NE State Check Alarm\",\"alarmType\":\"2\",\"origSeverity\":\"2\",\"specificProblem\":\"alarm cause: the system state of target NE has not been received\",\"specificProblemId\":\"AC10000\",\"addInfo\":\"\"}', '0/30 * * * * ?', '3', '0', '1', '0', 'system', 1698478134839, 'system', 1698478134839, 'job.ne_alarm_state_check_remark'); +INSERT INTO `sys_job` VALUES (21, 'job.ne_alarm_state_check_cmd', 'SYSTEM', 'ne_alarm_state_check_cmd', '{\"alarmTitle\":\"NE State Check Alarm CPU/Menory/Disk\",\"alarmType\":\"2\",\"origSeverity\":\"2\",\"specificProblem\":\"Alarm Cause: CPU/Menory/Disk status received from target NE reaches the threshold\",\"specificProblemId\":\"AC10100\",\"addInfo\":\"\",\"cpuUseGt\":70,\"memUseGt\":70,\"diskUseGt\":70}', '0/15 * * * * ?', '3', '0', '1', '0', 'system', 1698478134839, 'system', 1698478134839, 'job.ne_alarm_state_check_cmd_remark'); +INSERT INTO `sys_job` VALUES (22, 'job.ne_alarm_state_check_license', 'SYSTEM', 'ne_alarm_state_check_license', '{\"alarmTitle\":\"NE State Check Alarm License\",\"alarmType\":\"2\",\"origSeverity\":\"2\",\"specificProblem\":\"Alarm Cause: License received from target NE is about to expire\",\"specificProblemId\":\"AC10200\",\"addInfo\":\"\",\"dayLt\":7}', '0 5 0 * * ?', '3', '0', '1', '0', 'system', 1698478134839, 'system', 1698478134839, 'job.ne_alarm_state_check_license_remark'); + +INSERT INTO `sys_job` VALUES (30, 'job.backup_remove_file', 'SYSTEM', 'backup_remove_file', '[{\"backupPath\":\"/udm_data/auth\",\"storeDays\":30},{\"backupPath\":\"/udm_data/sub\",\"storeDays\":30},{\"backupPath\":\"/udm_data/voip\",\"storeDays\":30},{\"backupPath\":\"/udm_data/volte\",\"storeDays\":30},{\"backupPath\":\"/cdr/ims_cdr_event\",\"storeDays\":30},{\"backupPath\":\"/cdr/smsc_cdr_event\",\"storeDays\":30},{\"backupPath\":\"/cdr/smf_cdr_event\",\"storeDays\":30},{\"backupPath\":\"/cdr/sgwc_cdr_event\",\"storeDays\":30},{\"backupPath\":\"/log/sys_log_operate\",\"storeDays\":30,\"storeNum\":7},{\"backupPath\":\"/log/sys_log_login\",\"storeDays\":30,\"storeNum\":7}]', '0 10 0 * * ?', '3', '0', '1', '1', 'system', 1698478134839, 'system', 1698478134839, 'job.backup_remove_file_remark'); +INSERT INTO `sys_job` VALUES (31, 'job.backup_export_udm', 'SYSTEM', 'backup_export_udm', '{\"dataType\":[\"auth\",\"sub\",\"voip\",\"volte\"],\"fileType\":\"txt\"}', '0 35 0 * * ?', '3', '0', '1', '1', 'system', 1698478134839, 'supervisor', 1745481169354, 'job.backup_export_udm_remark'); +INSERT INTO `sys_job` VALUES (32, 'job.backup_export_cdr', 'SYSTEM', 'backup_export_cdr', '{\"dataType\":[\"ims\",\"smf\",\"sgwc\",\"smsc\"],\"fileType\":\"xlsx\",\"hour\":1}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'system', 1698478134839, 'supervisor', 1745481169354, 'job.backup_export_cdr_remark'); +INSERT INTO `sys_job` VALUES (33, 'job.backup_export_log', 'SYSTEM', 'backup_export_log', '{\"dataType\":[\"operate\",\"login\"],\"fileType\":\"xlsx\",\"hour\":1}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'system', 1698478134839, 'supervisor', 1745481169354, 'job.backup_export_log_remark'); SET FOREIGN_KEY_CHECKS = 1; diff --git a/database/upgrade/upg_sys_dict_data1_i18n_zh.sql b/database/upgrade/upg_sys_dict_data1_i18n_zh.sql index fcc72341..a9dbdd86 100644 --- a/database/upgrade/upg_sys_dict_data1_i18n_zh.sql +++ b/database/upgrade/upg_sys_dict_data1_i18n_zh.sql @@ -83,10 +83,10 @@ REPLACE INTO `sys_dict_data` VALUES (1062, 1062, 'menu.ueUser.authUDMRemark', 'U REPLACE INTO `sys_dict_data` VALUES (1063, 1063, 'menu.ueUser.subUDMRemark', 'UDM签约用户菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (1064, 1064, 'dictData.cdr_sip_code_cause.202', 'The request has been accepted for processing, but it hasn’t completed yet ', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (1065, 1065, 'dictData.cdr_sip_code_cause.0', 'Call failure for other reason', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); --- REPLACE INTO `sys_dict_data` VALUES (1066, 1066, 'menu.config.neManageRemark', '网元管理菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); --- REPLACE INTO `sys_dict_data` VALUES (1067, 1067, 'menu.config.configNERemark', '参数配置菜单', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); --- REPLACE INTO `sys_dict_data` VALUES (1068, 1068, 'menu.config.backupManage', '备份管理', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); --- REPLACE INTO `sys_dict_data` VALUES (1069, 1069, 'menu.config.softwareManage', '软件管理', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +REPLACE INTO `sys_dict_data` VALUES (1066, 1066, 'config.neData.backupDataFTP', '备份网元数据-同步FTP服务', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +REPLACE INTO `sys_dict_data` VALUES (1067, 1067, 'config.neData.backupDataFTPRemark', '请通过系统页面进行设置FTP信息', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +REPLACE INTO `sys_dict_data` VALUES (1068, 1068, 'job.backup_export_log', '备份-日志数据定期导出', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +REPLACE INTO `sys_dict_data` VALUES (1069, 1069, 'job.backup_export_log_remark', 'dataType: 类型支持 operate/login\nfileType: 文件类型 csv/xlsx\nhour: 数据时间从任务执行时间前的小时数', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (1070, 1070, 'menu.ueUser.onlineIMS', 'IMS在线用户', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (1071, 1071, 'menu.ueUser.onlineUE', 'UE在线信息', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (1072, 1072, 'menu.ueUser.base5G', '基站信息', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); @@ -246,9 +246,9 @@ REPLACE INTO `sys_dict_data` VALUES (1505, 1505, 'dictType.sys_yes_no', '系统 REPLACE INTO `sys_dict_data` VALUES (1506, 1506, 'dictType.sys_oper_type', '操作类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (1507, 1507, 'dictType.sys_common_status', '系统状态', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (1508, 1508, 'dictType.trace_type', '跟踪类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); --- REPLACE INTO `sys_dict_data` VALUES (1509, 1509, 'dictType.operation_log_type', '操作日志类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +REPLACE INTO `sys_dict_data` VALUES (1509, 1509, 'menu.tools.ps', '进程运行程序', 'i18n_zh', '', '', '1', 'supervisor', 1728640045875, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (1510, 1510, 'dictType.alarm_status', '告警日志类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); --- REPLACE INTO `sys_dict_data` VALUES (1511, 1511, 'dictType.security_log_type', '安全日志类型', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +REPLACE INTO `sys_dict_data` VALUES (1511, 1511, 'menu.tools.net', '进程网络连接', 'i18n_zh', '', '', '1', 'supervisor', 1728640045875, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (1512, 1512, 'dictType.ne_version_status', '网元软件版本状态', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (1513, 1513, 'dictType.i18n_en', '多语言-英文', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (1514, 1514, 'dictType.i18n_zh', '多语言-中文', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); @@ -740,6 +740,18 @@ REPLACE INTO `sys_dict_data` VALUES (2222, 2222, 'dictData.trace_interfaces.17', REPLACE INTO `sys_dict_data` VALUES (2223, 2223, 'dictData.trace_interfaces.20', 'N20', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (2224, 2224, 'dictData.trace_interfaces.22', 'N22', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (2225, 2225, 'dictData.trace_interfaces.40', 'N40', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2226, 2226, 'job.ne_alarm_state_check_cmd', '网元告警-内存/CPU/磁盘检查', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2227, 2227, 'job.ne_alarm_state_check_cmd_remark', '检查网元的内存/CPU/磁盘检查健康状况,在出现过阈值时发出警报。\r\n\r\nAlarm type:\r\nCommunicationAlarm=1\r\nEquipmentAlarm=2\r\nProcessingFailure=3\r\nEnvironmentalAlarm=4\r\nQualityOfServiceAlarm=5\r\n\r\nSeverity:\r\nCritical=1\r\nMajor=2\r\nMinor=3\r\nWarning=4\r\n\r\nAddInfo: 告警补充信息\r\ncpuUseGt: CPU使用率大于, 范围0~100%\r\nmemUseGt: 内存使用率大于, 范围0~100%\r\ndiskUseGt: 磁盘使用率大于, 范围0~100%', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2228, 2228, 'job.ne_alarm_state_check_license', '网元告警-License到期检查', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2229, 2229, 'job.ne_alarm_state_check_license_remark', '检查网元的License是否即将到期,在出现过阈值时发出警报。\r\n\r\nAlarm type:\r\nCommunicationAlarm=1\r\nEquipmentAlarm=2\r\nProcessingFailure=3\r\nEnvironmentalAlarm=4\r\nQualityOfServiceAlarm=5\r\n\r\nSeverity:\r\nCritical=1\r\nMajor=2\r\nMinor=3\r\nWarning=4\r\n\r\nAddInfo: 告警补充信息\r\ndayLt: 天数小于,默认30天', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2230, 2230, 'job.ne_alarm_state_check', '网元告警-状态检查', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2231, 2231, 'job.ne_alarm_state_check_remark', '检查网元的健康状况,在出现异常时发出警报。\r\n\r\nAlarm type:\r\nCommunicationAlarm=1\r\nEquipmentAlarm=2\r\nProcessingFailure=3\r\nEnvironmentalAlarm=4\r\nQualityOfServiceAlarm=5\r\n\r\nSeverity:\r\nCritical=1\r\nMajor=2\r\nMinor=3\r\nWarning=4', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2232, 2232, 'job.backup_export_udm', '备份-UDM数据定期导出', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2233, 2233, 'job.backup_export_udm_remark', 'dataType: 类型支持 auth/sub/voip/volte\nfileType: 文件类型 csv/txt', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2234, 2234, 'job.backup_remove_file', '备份-定期删除备份目录下文件', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2235, 2235, 'job.backup_remove_file_remark', 'backupPath: 备份路径 /usr/local/omc/backup/{backupPath}\nstoreDays: 保留天数\nstoreNum: 保留数量,默认保留7', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2236, 2236, 'job.backup_export_cdr', '备份-CDR数据定期导出', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (2237, 2237, 'job.backup_export_cdr_remark', 'dataType: 类型支持 ims/smf/sgwc/smsc\nfileType: 文件类型 csv/xlsx\nhour: 数据时间从任务执行时间前的小时数', 'i18n_zh', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); -- multi-tenancy REPLACE INTO `sys_dict_data` VALUES (11000, 11000, 'menu.security.tenant', '租户管理', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); diff --git a/database/upgrade/upg_sys_dict_data2_i18n_en.sql b/database/upgrade/upg_sys_dict_data2_i18n_en.sql index ab573e7b..29a36e9f 100644 --- a/database/upgrade/upg_sys_dict_data2_i18n_en.sql +++ b/database/upgrade/upg_sys_dict_data2_i18n_en.sql @@ -83,8 +83,10 @@ REPLACE INTO `sys_dict_data` VALUES (3062, 3062, 'menu.ueUser.authUDMRemark', 'U REPLACE INTO `sys_dict_data` VALUES (3063, 3063, 'menu.ueUser.subUDMRemark', 'UDM Subscriber Menu', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3064, 3064, 'dictData.cdr_sip_code_cause.202', 'The request has been accepted for processing, but it hasn’t completed yet ', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3066, 3066, 'dictData.cdr_sip_code_cause.0', 'Call failure for other reason', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); --- REPLACE INTO `sys_dict_data` VALUES (3068, 3068, 'menu.config.backupManage', 'Backup Management', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); --- REPLACE INTO `sys_dict_data` VALUES (3069, 3069, 'menu.config.softwareManage', 'Software Management', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +REPLACE INTO `sys_dict_data` VALUES (3066, 3066, 'config.neData.backupDataFTP', 'Backup NE Data - Sync Data FTP Service', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +REPLACE INTO `sys_dict_data` VALUES (3067, 3067, 'config.neData.backupDataFTPRemark', 'Please set the FTP information through the system page.', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +REPLACE INTO `sys_dict_data` VALUES (3068, 3068, 'job.backup_export_log', 'Backup-Periodic export of Log Data', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); +REPLACE INTO `sys_dict_data` VALUES (3069, 3069, 'job.backup_export_log_remark', 'Backup-Periodic export of dataType: type support operate/login\nfileType: file type csv/xlsx\nhour: data time from the hour before the task execution time', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3070, 3070, 'menu.ueUser.onlineIMS', 'IMS Online Users', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3071, 3071, 'menu.ueUser.onlineUE', 'UE Online Information', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); REPLACE INTO `sys_dict_data` VALUES (3072, 3072, 'menu.ueUser.base5G', 'Radio Information', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL); @@ -739,6 +741,18 @@ REPLACE INTO `sys_dict_data` VALUES (4222, 4222, 'dictData.trace_interfaces.17', REPLACE INTO `sys_dict_data` VALUES (4223, 4223, 'dictData.trace_interfaces.20', 'N20', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (4224, 4224, 'dictData.trace_interfaces.22', 'N22', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); REPLACE INTO `sys_dict_data` VALUES (4225, 4225, 'dictData.trace_interfaces.40', 'N40', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4226, 4226, 'job.ne_alarm_state_check_cmd', 'NE Alarm-Memory/CPU/Disk Checks', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4227, 4227, 'job.ne_alarm_state_check_cmd_remark', 'Checks the memory/CPU/disk check health of the network element and sends alerts when thresholds are crossed.\n\nAlarm type:\nCommunicationAlarm=1\nEquipmentAlarm=2\nProcessingFailure=3\nEnvironmentalAlarm=4\nQualityOfServiceAlarm=5\n\nSeverity:\nCritical=1\nMajor=2\nMinor=3\nWarning=4\r\n\r\nAddInfo: Additional information on alarms\r\ncpuUseGt: CPU utilization greater than, range 0 to 100%\r\nmemUseGt: Memory utilization greater than, range 0 to 100%\r\ndiskUseGt: Disk utilization greater than, range 0 to 100%', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4228, 4228, 'job.ne_alarm_state_check_license', 'NE Alarm-License Expire Check', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4229, 4229, 'job.ne_alarm_state_check_license_remark', 'Checks if the network element is License is about to expire and sends an alert if a threshold is crossed.\n\nAlarm type:\nCommunicationAlarm=1\nEquipmentAlarm=2\nProcessingFailure=3\nEnvironmentalAlarm=4\nQualityOfServiceAlarm=5\n\nSeverity:\nCritical=1\nMajor=2\nMinor=3\nWarning=4\r\n\r\nAddInfo: Additional information on alarms\r\ndayLt: Days less than, default 30 days', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4230, 4230, 'job.ne_alarm_state_check', 'NE Alarm-Health State Check', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4231, 4231, 'job.ne_alarm_state_check_remark', 'Checks the health of network elements and sends alerts in case of anomalies.\n\nAlarm type:\nCommunicationAlarm=1\nEquipmentAlarm=2\nProcessingFailure=3\nEnvironmentalAlarm=4\nQualityOfServiceAlarm=5\n\nSeverity:\nCritical=1\nMajor=2\nMinor=3\nWarning=4', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4232, 4232, 'job.backup_export_udm', 'Backup-Periodic export of UDM Data', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4233, 4233, 'job.backup_export_udm_remark', 'backupPath: backup path /usr/local/omc/backup/{backupPath}\nstoreDays: retention days\nstoreNum: retention number, default retention 7', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4234, 4234, 'job.backup_remove_file', 'Backup-Periodically Delete Directory Files', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4235, 4235, 'job.backup_remove_file_remark', 'backupPath: backup path /usr/local/omc/backup/{backupPath}\nstoreDays: retention days\nstoreNum: retention number, default retention 7', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4236, 4236, 'job.backup_export_cdr', 'Backup-Periodic export of CDR Data', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); +REPLACE INTO `sys_dict_data` VALUES (4237, 4237, 'job.backup_export_cdr_remark', 'Backup-Periodic export of dataType: type support ims/smf/sgwc/smsc\nfileType: file type csv/xlsx\nhour: data time from the hour before the task execution time', 'i18n_en', '', '', '1', 'supervisor', 1721902269805, '', 0, ''); -- 多租户 REPLACE INTO `sys_dict_data` VALUES (14000, 14000, 'menu.security.tenant', 'Tenant Management', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, ''); diff --git a/database/upgrade/upg_sys_job.sql b/database/upgrade/upg_sys_job.sql index 3295eb61..754cbd94 100644 --- a/database/upgrade/upg_sys_job.sql +++ b/database/upgrade/upg_sys_job.sql @@ -41,13 +41,22 @@ REPLACE INTO `sys_job` VALUES (6, 'job.deleteExpiredKpiRecord', 'SYSTEM', 'delet -- REPLACE INTO `sys_job` VALUES (7, 'job.backupEtcFromNE', 'SYSTEM', 'backupEtcFromNE', NULL, '0 30 0 * * ?', '3', '0', '0', '1', 'supervisor', 1698478134843, NULL, 0, 'job.backupEtcFromNERemark'); REPLACE INTO `sys_job` VALUES (8, 'job.deleteExpiredNeStateRecord', 'SYSTEM', 'deleteExpiredRecord', '{\"duration\":1,\"tableName\":\"ne_state\",\"colName\":\"timestamp\"}', '0 25 0 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1703668901929, 'job.deleteExpiredNeStateRecordRemark'); REPLACE INTO `sys_job` VALUES (9, 'job.getStateFromNE', 'SYSTEM', 'getStateFromNE', '', '0/10 * * * * ?', '3', '0', '0', '0', 'supervisor', 1698478134842, 'admin', 1713231120503, 'job.getStateFromNERemark'); -REPLACE INTO `sys_job` VALUES (10, 'job.genNeStateAlarm', 'SYSTEM', 'genNeStateAlarm', '{\"alarmID\":\"HXEMSSM10000\",\"alarmCode\":10000,\"alarmTitle\":\"The system state is abnormal\",\"neType\":\"OMC\",\"alarmType\":\"EquipmentAlarm\",\"origSeverity\": \"Major\",\"objectName\":\"EMS;SystemManagement;Heartbeat\",\"objectType\":\"SystemState\",\"specificProblem\":\"Alarm cause: the system state of target NE has not been received for {threshold} seconds\", \"specificProblemID\":\"AC10000\",\"threshold\":30}', '0/5 * * * * ?', '3', '0', '1', '0', 'supervisor', 1698478134842, 'admin', 1713781643031, 'job.genNeStateAlarmRemark'); -REPLACE INTO `sys_job` VALUES (11, 'job.exportOperateLog', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"sys_log_operate\",\"timeCol\":\"oper_time\",\"timeUnit\":\"milli\",\"columns\":\"oper_id,omc_get_dict_value(title, \\\"i18n_en\\\") as title,business_type,method,request_method,operator_type,oper_name,dept_name,oper_url,oper_ip,oper_location,oper_param,oper_msg,status,oper_time,cost_time,tenant_id\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/operate_log\"}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1724833786290, 'job.exportOperateLog'); -REPLACE INTO `sys_job` VALUES (12, 'job.exportIMSCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_ims\",\"columns\":\"id,ne_name,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) as record_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callType\')) as call_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callerParty\')) as caller_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.calledParty\')) as called_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callDuration\')) as call_duration,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.serviceResult\')) as service_result,DATE_FORMAT(FROM_UNIXTIME(timestamp), \'%Y-%m-%d %H:%i:%s\') AS timestamp\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/ims_cdr\"}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1722224659251, ''); -REPLACE INTO `sys_job` VALUES (13, 'job.exportSMFCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_smf\",\"columns\":\"id,ne_type,ne_name,rm_uid,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) AS record_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.chargingID\')) AS charging_id,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.subscriberIdentifier.subscriptionIDType\')) AS subscriber_id_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.subscriberIdentifier.subscriptionIDData\')) AS subscriber_id_data,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.duration\')) AS duration,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.invocationTimestamp\')) as invocationTimestamp,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataVolumeUplink\')) AS data_volume_uplink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataVolumeDownlink\')) AS data_volume_downlink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataTotalVolume\')) AS data_total_volume,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.pDUSessionChargingInformation.pDUAddress.pDUIPv4Address\')) AS pdu_ipv4_address,timestamp\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/smf_cdr\"}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1724309047797, ''); -REPLACE INTO `sys_job` VALUES (14, 'job.exportSMSCCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_smsc\",\"columns\":\"id,ne_name,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) as record_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.serviceType\')) as service_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callerParty\')) as caller_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.calledParty\')) as called_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.result\')) as result,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.updateTime\')) as update_time\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/smsc_cdr\"}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1724309047797, ''); -REPLACE INTO `sys_job` VALUES (15, 'job.removeExportedFiles', 'SYSTEM', 'removeFile', '[{\"filePath\":\"/usr/local/omc/backup/operate_log\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/ims_cdr\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/smf_cdr\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/smsc_cdr\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/u_auth_user\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/u_sub_user\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/u_voip_auth\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/u_ims_user\",\"maxDays\":30}]', '0 10 0 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1728634085631, ''); -REPLACE INTO `sys_job` VALUES (16, 'job.exportSGWCCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_sgwc\",\"columns\":\"id,ne_name,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) as recordType,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.accessPointNameNI\')) as accessPointNameNI,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.servedIMSI\')) as IMSI,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.servedMSISDN\')) as MSISDN,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.servedPDPPDNAddress\')) as PdpAddress,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.duration\')) as duration,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordOpeningTime\')) as recordOpeningTime,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.chargingID\')) as chargingID,JSON_UNQUOTE(JSON_EXTRACT(cdr_json, \'$.listOfTrafficVolumes[0].dataVolumeGPRSDownlink\')) AS dataVolumeGPRSDownlink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json, \'$.listOfTrafficVolumes[0].dataVolumeGPRsUplink\')) as dataVolumeGPRsUplink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.userLocationInformation.tai.tac\')) as tac,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.userLocationInformation.ecgi.eutraCellId\')) as cellID\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/sgwc_cdr\"}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1724309047797, ''); -REPLACE INTO `sys_job` VALUES (17, 'job.backup.ue.data', 'SYSTEM', 'exportUEData', '[{\"tableName\":\"u_auth_user\",\"columns\":\"imsi,ki,amf,algo_index,opc\",\"extras\":\"\",\"serviceName\":\"UDMAuthUser\",\"orderBy\":\"imsi\",\"orderType\":\"desc\", \"fileType\":\"txt\",\"filePath\":\"/usr/local/omc/backup/u_auth_user\"},{\"tableName\":\"u_sub_user\",\"columns\":\"imsi,msisdn,ambr,nssai,arfb,sar,rat,cn_type,smf_sel,sm_data,eps_flag,eps_odb,hplmn_odb,ard,epstpl,context_id,apn_context,static_ip\",\"extras\":\"\",\"serviceName\":\"UDMSubUser\",\"orderBy\":\"imsi\",\"orderType\":\"desc\", \"fileType\":\"txt\",\"filePath\":\"/usr/local/omc/backup/u_sub_user\"},{\"tableName\":\"u_voip_auth\",\"columns\":\"user_name,password\",\"extras\":\"\",\"serviceName\":\"UDMVoIPAuth\",\"orderBy\":\"user_name\",\"orderType\":\"desc\", \"fileType\":\"txt\",\"filePath\":\"/usr/local/omc/backup/u_voip_auth\"},{\"tableName\":\"u_ims_user\",\"columns\":\"imsi,msisdn,tag,vni\",\"extras\":\"\",\"serviceName\":\"UDMIMSUser\",\"orderBy\":\"imsi\",\"orderType\":\"desc\", \"fileType\":\"txt\",\"filePath\":\"/usr/local/omc/backup/u_ims_user\"}]', '0 35 0 * * ?', '3', '0', '1', '1', 'supervisor', 1698478134842, 'admin', 1743479268652, ''); +REPLACE INTO `sys_job` VALUES (10, 'job.genNeStateAlarm', 'SYSTEM', 'genNeStateAlarm', '{\"alarmID\":\"HXEMSSM10000\",\"alarmCode\":10000,\"alarmTitle\":\"The system state is abnormal\",\"neType\":\"OMC\",\"alarmType\":\"EquipmentAlarm\",\"origSeverity\": \"Major\",\"objectName\":\"EMS;SystemManagement;Heartbeat\",\"objectType\":\"SystemState\",\"specificProblem\":\"Alarm cause: the system state of target NE has not been received for {threshold} seconds\", \"specificProblemID\":\"AC10000\",\"threshold\":30}', '0/5 * * * * ?', '3', '0', '0', '0', 'supervisor', 1698478134842, 'admin', 1713781643031, 'job.genNeStateAlarmRemark'); +REPLACE INTO `sys_job` VALUES (11, 'job.exportOperateLog', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"sys_log_operate\",\"timeCol\":\"oper_time\",\"timeUnit\":\"milli\",\"columns\":\"oper_id,omc_get_dict_value(title, \\\"i18n_en\\\") as title,business_type,method,request_method,operator_type,oper_name,dept_name,oper_url,oper_ip,oper_location,oper_param,oper_msg,status,oper_time,cost_time,tenant_id\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/operate_log\"}', '0 0 0/1 * * ?', '3', '0', '0', '1', 'supervisor', 1698478134842, 'admin', 1724833786290, 'job.exportOperateLog'); +REPLACE INTO `sys_job` VALUES (12, 'job.exportIMSCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_ims\",\"columns\":\"id,ne_name,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) as record_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callType\')) as call_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callerParty\')) as caller_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.calledParty\')) as called_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callDuration\')) as call_duration,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.serviceResult\')) as service_result,DATE_FORMAT(FROM_UNIXTIME(timestamp), \'%Y-%m-%d %H:%i:%s\') AS timestamp\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/ims_cdr\"}', '0 0 0/1 * * ?', '3', '0', '0', '1', 'supervisor', 1698478134842, 'admin', 1722224659251, ''); +REPLACE INTO `sys_job` VALUES (13, 'job.exportSMFCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_smf\",\"columns\":\"id,ne_type,ne_name,rm_uid,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) AS record_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.chargingID\')) AS charging_id,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.subscriberIdentifier.subscriptionIDType\')) AS subscriber_id_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.subscriberIdentifier.subscriptionIDData\')) AS subscriber_id_data,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.duration\')) AS duration,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.invocationTimestamp\')) as invocationTimestamp,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataVolumeUplink\')) AS data_volume_uplink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataVolumeDownlink\')) AS data_volume_downlink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.listOfMultipleUnitUsage[*].usedUnitContainer[*].dataTotalVolume\')) AS data_total_volume,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.pDUSessionChargingInformation.pDUAddress.pDUIPv4Address\')) AS pdu_ipv4_address,timestamp\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/smf_cdr\"}', '0 0 0/1 * * ?', '3', '0', '0', '1', 'supervisor', 1698478134842, 'admin', 1724309047797, ''); +REPLACE INTO `sys_job` VALUES (14, 'job.exportSMSCCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_smsc\",\"columns\":\"id,ne_name,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) as record_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.serviceType\')) as service_type,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.callerParty\')) as caller_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.calledParty\')) as called_party,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.result\')) as result,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.updateTime\')) as update_time\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/smsc_cdr\"}', '0 0 0/1 * * ?', '3', '0', '0', '1', 'supervisor', 1698478134842, 'admin', 1724309047797, ''); +REPLACE INTO `sys_job` VALUES (15, 'job.removeExportedFiles', 'SYSTEM', 'removeFile', '[{\"filePath\":\"/usr/local/omc/backup/operate_log\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/ims_cdr\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/smf_cdr\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/smsc_cdr\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/u_auth_user\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/u_sub_user\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/u_voip_auth\",\"maxDays\":30},{\"filePath\":\"/usr/local/omc/backup/u_ims_user\",\"maxDays\":30}]', '0 10 0 * * ?', '3', '0', '0', '1', 'supervisor', 1698478134842, 'admin', 1728634085631, ''); +REPLACE INTO `sys_job` VALUES (16, 'job.exportSGWCCDR', 'SYSTEM', 'exportTable', '{\"duration\":1,\"tableName\":\"cdr_event_sgwc\",\"columns\":\"id,ne_name,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordType\')) as recordType,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.accessPointNameNI\')) as accessPointNameNI,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.servedIMSI\')) as IMSI,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.servedMSISDN\')) as MSISDN,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.servedPDPPDNAddress\')) as PdpAddress,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.duration\')) as duration,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.recordOpeningTime\')) as recordOpeningTime,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.chargingID\')) as chargingID,JSON_UNQUOTE(JSON_EXTRACT(cdr_json, \'$.listOfTrafficVolumes[0].dataVolumeGPRSDownlink\')) AS dataVolumeGPRSDownlink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json, \'$.listOfTrafficVolumes[0].dataVolumeGPRsUplink\')) as dataVolumeGPRsUplink,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.userLocationInformation.tai.tac\')) as tac,JSON_UNQUOTE(JSON_EXTRACT(cdr_json,\'$.userLocationInformation.ecgi.eutraCellId\')) as cellID\",\"timeCol\":\"timestamp\",\"timeUnit\":\"second\",\"extras\":\"\",\"filePath\":\"/usr/local/omc/backup/sgwc_cdr\"}', '0 0 0/1 * * ?', '3', '0', '0', '1', 'supervisor', 1698478134842, 'admin', 1724309047797, ''); +REPLACE INTO `sys_job` VALUES (17, 'job.backup.ue.data', 'SYSTEM', 'exportUEData', '[{\"tableName\":\"u_auth_user\",\"columns\":\"imsi,ki,amf,algo_index,opc\",\"extras\":\"\",\"serviceName\":\"UDMAuthUser\",\"orderBy\":\"imsi\",\"orderType\":\"desc\", \"fileType\":\"txt\",\"filePath\":\"/usr/local/omc/backup/u_auth_user\"},{\"tableName\":\"u_sub_user\",\"columns\":\"imsi,msisdn,ambr,nssai,arfb,sar,rat,cn_type,smf_sel,sm_data,eps_flag,eps_odb,hplmn_odb,ard,epstpl,context_id,apn_context,static_ip\",\"extras\":\"\",\"serviceName\":\"UDMSubUser\",\"orderBy\":\"imsi\",\"orderType\":\"desc\", \"fileType\":\"txt\",\"filePath\":\"/usr/local/omc/backup/u_sub_user\"},{\"tableName\":\"u_voip_auth\",\"columns\":\"user_name,password\",\"extras\":\"\",\"serviceName\":\"UDMVoIPAuth\",\"orderBy\":\"user_name\",\"orderType\":\"desc\", \"fileType\":\"txt\",\"filePath\":\"/usr/local/omc/backup/u_voip_auth\"},{\"tableName\":\"u_ims_user\",\"columns\":\"imsi,msisdn,tag,vni\",\"extras\":\"\",\"serviceName\":\"UDMIMSUser\",\"orderBy\":\"imsi\",\"orderType\":\"desc\", \"fileType\":\"txt\",\"filePath\":\"/usr/local/omc/backup/u_ims_user\"}]', '0 35 0 * * ?', '3', '0', '0', '1', 'supervisor', 1698478134842, 'admin', 1743479268652, ''); + +REPLACE INTO `sys_job` VALUES (20, 'job.ne_alarm_state_check', 'SYSTEM', 'ne_alarm_state_check', '{\"alarmTitle\":\"NE State Check Alarm\",\"alarmType\":\"2\",\"origSeverity\":\"2\",\"specificProblem\":\"alarm cause: the system state of target NE has not been received\",\"specificProblemId\":\"AC10000\",\"addInfo\":\"\"}', '0/30 * * * * ?', '3', '0', '1', '0', 'system', 1698478134839, 'system', 1698478134839, 'job.ne_alarm_state_check_remark'); +REPLACE INTO `sys_job` VALUES (21, 'job.ne_alarm_state_check_cmd', 'SYSTEM', 'ne_alarm_state_check_cmd', '{\"alarmTitle\":\"NE State Check Alarm CPU/Menory/Disk\",\"alarmType\":\"2\",\"origSeverity\":\"2\",\"specificProblem\":\"Alarm Cause: CPU/Menory/Disk status received from target NE reaches the threshold\",\"specificProblemId\":\"AC10100\",\"addInfo\":\"\",\"cpuUseGt\":70,\"memUseGt\":70,\"diskUseGt\":70}', '0/15 * * * * ?', '3', '0', '1', '0', 'system', 1698478134839, 'system', 1698478134839, 'job.ne_alarm_state_check_cmd_remark'); +REPLACE INTO `sys_job` VALUES (22, 'job.ne_alarm_state_check_license', 'SYSTEM', 'ne_alarm_state_check_license', '{\"alarmTitle\":\"NE State Check Alarm License\",\"alarmType\":\"2\",\"origSeverity\":\"2\",\"specificProblem\":\"Alarm Cause: License received from target NE is about to expire\",\"specificProblemId\":\"AC10200\",\"addInfo\":\"\",\"dayLt\":7}', '0 5 0 * * ?', '3', '0', '1', '0', 'system', 1698478134839, 'system', 1698478134839, 'job.ne_alarm_state_check_license_remark'); + +REPLACE INTO `sys_job` VALUES (30, 'job.backup_remove_file', 'SYSTEM', 'backup_remove_file', '[{\"backupPath\":\"/udm_data/auth\",\"storeDays\":30},{\"backupPath\":\"/udm_data/sub\",\"storeDays\":30},{\"backupPath\":\"/udm_data/voip\",\"storeDays\":30},{\"backupPath\":\"/udm_data/volte\",\"storeDays\":30},{\"backupPath\":\"/cdr/ims_cdr_event\",\"storeDays\":30},{\"backupPath\":\"/cdr/smsc_cdr_event\",\"storeDays\":30},{\"backupPath\":\"/cdr/smf_cdr_event\",\"storeDays\":30},{\"backupPath\":\"/cdr/sgwc_cdr_event\",\"storeDays\":30},{\"backupPath\":\"/log/sys_log_operate\",\"storeDays\":30,\"storeNum\":7},{\"backupPath\":\"/log/sys_log_login\",\"storeDays\":30,\"storeNum\":7}]', '0 10 0 * * ?', '3', '0', '1', '1', 'system', 1698478134839, 'system', 1698478134839, 'job.backup_remove_file_remark'); +REPLACE INTO `sys_job` VALUES (31, 'job.backup_export_udm', 'SYSTEM', 'backup_export_udm', '{\"dataType\":[\"auth\",\"sub\",\"voip\",\"volte\"],\"fileType\":\"txt\"}', '0 35 0 * * ?', '3', '0', '1', '1', 'system', 1698478134839, 'supervisor', 1745481169354, 'job.backup_export_udm_remark'); +REPLACE INTO `sys_job` VALUES (32, 'job.backup_export_cdr', 'SYSTEM', 'backup_export_cdr', '{\"dataType\":[\"ims\",\"smf\",\"sgwc\",\"smsc\"],\"fileType\":\"xlsx\",\"hour\":1}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'system', 1698478134839, 'supervisor', 1745481169354, 'job.backup_export_cdr_remark'); +REPLACE INTO `sys_job` VALUES (33, 'job.backup_export_log', 'SYSTEM', 'backup_export_log', '{\"dataType\":[\"operate\",\"login\"],\"fileType\":\"xlsx\",\"hour\":1}', '0 0 0/1 * * ?', '3', '0', '1', '1', 'system', 1698478134839, 'supervisor', 1745481169354, 'job.backup_export_log_remark'); SET FOREIGN_KEY_CHECKS = 1; \ No newline at end of file diff --git a/src/modules/crontask/processor/backup_export_cdr/backup_export_cdr.go b/src/modules/crontask/processor/backup_export_cdr/backup_export_cdr.go new file mode 100644 index 00000000..7bb33dfe --- /dev/null +++ b/src/modules/crontask/processor/backup_export_cdr/backup_export_cdr.go @@ -0,0 +1,1442 @@ +package backup_export_cdr + +import ( + "encoding/json" + "fmt" + "path/filepath" + "runtime" + "strconv" + "strings" + "time" + + "be.ems/src/framework/cron" + "be.ems/src/framework/i18n" + "be.ems/src/framework/logger" + "be.ems/src/framework/utils/date" + "be.ems/src/framework/utils/file" + "be.ems/src/framework/utils/parse" + neDataModel "be.ems/src/modules/network_data/model" + neDataService "be.ems/src/modules/network_data/service" + neModel "be.ems/src/modules/network_element/model" + neService "be.ems/src/modules/network_element/service" + systemService "be.ems/src/modules/system/service" +) + +var NewProcessor = &BackupExportCDRProcessor{ + count: 0, + backupService: neDataService.NewBackup, + sysDictService: systemService.NewSysDictData, + neInfoService: neService.NewNeInfo, + imsCDREventService: neDataService.NewCDREventIMS, + smscCDREventService: neDataService.NewCDREventSMSC, + smfCDREventService: neDataService.NewCDREventSMF, + sgwcCDREventService: neDataService.NewCDREventSGWC, +} + +// BackupExportCDR 队列任务处理 +type BackupExportCDRProcessor struct { + count int // 执行次数 + backupService *neDataService.Backup // 备份相关服务 + sysDictService *systemService.SysDictData // 字典类型数据服务 + neInfoService *neService.NeInfo // 网元信息服务 + imsCDREventService *neDataService.CDREventIMS // IMS-CDR会话事件服务 + smscCDREventService *neDataService.CDREventSMSC // SMSC-CDR会话事件服务 + smfCDREventService *neDataService.CDREventSMF // SMF-CDR会话事件服务 + sgwcCDREventService *neDataService.CDREventSGWC // SGWC-CDR会话事件服务 +} + +func (s *BackupExportCDRProcessor) Execute(data any) (any, error) { + s.count++ // 执行次数加一 + options := data.(cron.JobData) + sysJob := options.SysJob + logger.Infof("重复:%v 任务ID:%s 执行次数:%d", options.Repeat, sysJob.JobID, s.count) + // 返回结果,用于记录执行结果 + result := map[string]any{ + "count": s.count, + } + + var params struct { + DataType []string `json:"dataType"` // 类型支持 ims/smsc/smf/sgwc + FileType string `json:"fileType"` // 文件类型 csv/xlsx + Hour int `json:"hour"` // 数据时间从任务执行时间前的小时数 + } + if err := json.Unmarshal([]byte(sysJob.TargetParams), ¶ms); err != nil { + return nil, err + } + if !(params.FileType == "csv" || params.FileType == "xlsx") { + return nil, fmt.Errorf("file type error, only support csv,xlsx") + } + + for _, v := range params.DataType { + switch v { + case "ims": + neList := s.neInfoService.SelectList(neModel.NeInfo{NeType: "IMS"}, false, false) + for _, ne := range neList { + result[ne.NeName] = s.exportIMS(params.Hour, ne.RmUID, params.FileType) + } + case "smsc": + neList := s.neInfoService.SelectList(neModel.NeInfo{NeType: "SMSC"}, false, false) + for _, ne := range neList { + result[ne.NeName] = s.exportSMSC(params.Hour, ne.RmUID, params.FileType) + } + case "smf": + neList := s.neInfoService.SelectList(neModel.NeInfo{NeType: "SMF"}, false, false) + for _, ne := range neList { + result[ne.NeName] = s.exportSMF(params.Hour, ne.RmUID, params.FileType) + } + case "sgwc": + neList := s.neInfoService.SelectList(neModel.NeInfo{NeType: "SGWC"}, false, false) + for _, ne := range neList { + result[ne.NeName] = s.exportSGWC(params.Hour, ne.RmUID, params.FileType) + } + } + } + + // 返回结果,用于记录执行结果 + return result, nil +} + +// exportIMS 导出IMS-CDR会话事件数据 +func (s BackupExportCDRProcessor) exportIMS(hour int, rmUID, fileType string) string { + // 前 hour 小时 + now := time.Now() + end := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), 0, 0, 0, now.Location()) + start := end.Add(-time.Duration(hour) * time.Hour) + + language := "en" + query := neDataModel.CDREventIMSQuery{ + SortField: "timestamp", + SortOrder: "asc", + RmUID: rmUID, + StartTime: start.UnixMilli(), + EndTime: end.UnixMilli(), + PageNum: 1, + PageSize: 30000, + } + rows, total := s.imsCDREventService.SelectPage(query) + if total == 0 { + return "no data" + } + + // 导出文件名称 + fileName := fmt.Sprintf("ims_cdr_event_export_%d_%s.%s", len(rows), date.ParseDateToStr(end, date.YYYYMMDDHHMMSS), fileType) + filePath := filepath.Join(s.backupService.BACKUP_DIR, "/cdr/ims_cdr_event", fileName) + if runtime.GOOS == "windows" { + filePath = fmt.Sprintf("C:%s", filePath) + } + + if fileType == "csv" { + // 转换数据 + data := [][]string{ + { + "ID", + "NE Name", + "Record Behavior", + "Type", + "Caller", + "Called", + "Duration", + "Result Code", + "Result Cause", + "Call Start Time", + "Hangup Time", + "Tenant Name", // for multi-tenancy + }, + } + // 读取字典数据 CDR SIP响应代码类别类型 + dictCDRSipCode := s.sysDictService.SelectDictDataByType("cdr_sip_code") + // 读取字典数据 CDR SIP响应代码类别类型原因 + dictCDRSipCodeCause := s.sysDictService.SelectDictDataByType("cdr_sip_code_cause") + // 读取字典数据 CDR 呼叫类型 + dictCDRCallType := s.sysDictService.SelectDictDataByType("cdr_call_type") + for _, row := range rows { + // 解析 JSON 字符串为 map + var cdrJSON map[string]any + err := json.Unmarshal([]byte(row.CDRJSONStr), &cdrJSON) + if err != nil { + logger.Warnf("CDRExport Error parsing JSON: %s", err.Error()) + continue + } + // 记录类型 + recordType := "" + if v, ok := cdrJSON["recordType"]; ok && v != nil { + recordType = v.(string) + } + // 呼叫类型 + callType := "sms" + callTypeLable := "SMS" + if v, ok := cdrJSON["callType"]; ok && v != nil { + callType = v.(string) + for _, v := range dictCDRCallType { + if callType == v.DictValue { + callTypeLable = i18n.TKey(language, v.DictLabel) + break + } + } + } + // 被叫 + called := "" + if v, ok := cdrJSON["calledParty"]; ok && v != nil { + called = v.(string) + } + // 主叫 + caller := "" + if v, ok := cdrJSON["callerParty"]; ok && v != nil { + caller = v.(string) + } + // 时长 + duration := "-" + if v, ok := cdrJSON["callDuration"]; ok && v != nil && callType != "sms" { + duration = fmt.Sprintf("%ds", parse.Number(v)) + } + // 呼叫结果 非短信都有code作为结果 sms短信都ok + callResult := "Other" + callCause := "Call failure for other reason" + if callType == "sms" { + callResult = "Success" + callCause = "Normal Send" + } else { + if v, ok := cdrJSON["cause"]; ok && v != nil { + cause := fmt.Sprint(v) + for _, v := range dictCDRSipCode { + if cause == v.DictValue { + callResult = i18n.TKey(language, v.DictLabel) + break + } + } + for _, v := range dictCDRSipCodeCause { + if cause == v.DictValue { + callCause = i18n.TKey(language, v.DictLabel) + break + } + } + } + } + // 呼叫时间 + seizureTimeStr := "" + if v, ok := cdrJSON["seizureTime"]; ok && v != nil { + if seizureTime := parse.Number(v); seizureTime > 0 { + seizureTimeStr = date.ParseDateToStr(seizureTime, date.YYYY_MM_DDTHH_MM_SSZ) + } else { + seizureTimeStr = v.(string) + } + } + // 挂断时间 + releaseTimeStr := "" + if v, ok := cdrJSON["releaseTime"]; ok && v != nil { + if releaseTime := parse.Number(v); releaseTime > 0 { + releaseTimeStr = date.ParseDateToStr(releaseTime, date.YYYY_MM_DDTHH_MM_SSZ) + } else { + releaseTimeStr = v.(string) + } + } + + data = append(data, []string{ + fmt.Sprint(row.ID), + row.NeName, + recordType, + callTypeLable, + caller, + called, + duration, + callResult, + callCause, + seizureTimeStr, + releaseTimeStr, + row.TenantName, + }) + } + // 输出到文件 + if err := file.WriterFileCSV(data, filePath); err != nil { + logger.Errorf("export operate log err => %v", err.Error()) + return "export err" + } + } + + if fileType == "xlsx" { + // 第一行表头标题 + headerCells := map[string]string{ + "A1": "ID", + "B1": "NE Name", + "C1": "Record Behavior", + "D1": "Type", + "E1": "Caller", + "F1": "Called", + "G1": "Duration", + "H1": "Result Code", + "I1": "Result Cause", + "J1": "Call Start Time", + "K1": "Hangup Time", + "L1": "Tenant Name", // for multi-tenancy + } + // 读取字典数据 CDR SIP响应代码类别类型 + dictCDRSipCode := s.sysDictService.SelectDictDataByType("cdr_sip_code") + // 读取字典数据 CDR SIP响应代码类别类型原因 + dictCDRSipCodeCause := s.sysDictService.SelectDictDataByType("cdr_sip_code_cause") + // 读取字典数据 CDR 呼叫类型 + dictCDRCallType := s.sysDictService.SelectDictDataByType("cdr_call_type") + // 从第二行开始的数据 + dataCells := make([]map[string]any, 0) + for i, row := range rows { + idx := strconv.Itoa(i + 2) + // 解析 JSON 字符串为 map + var cdrJSON map[string]any + err := json.Unmarshal([]byte(row.CDRJSONStr), &cdrJSON) + if err != nil { + logger.Warnf("CDRExport Error parsing JSON: %s", err.Error()) + continue + } + // 记录类型 + recordType := "" + if v, ok := cdrJSON["recordType"]; ok && v != nil { + recordType = v.(string) + } + // 呼叫类型 + callType := "sms" + callTypeLable := "SMS" + if v, ok := cdrJSON["callType"]; ok && v != nil { + callType = v.(string) + for _, v := range dictCDRCallType { + if callType == v.DictValue { + callTypeLable = i18n.TKey(language, v.DictLabel) + break + } + } + } + // 被叫 + called := "" + if v, ok := cdrJSON["calledParty"]; ok && v != nil { + called = v.(string) + } + // 主叫 + caller := "" + if v, ok := cdrJSON["callerParty"]; ok && v != nil { + caller = v.(string) + } + // 时长 + duration := "-" + if v, ok := cdrJSON["callDuration"]; ok && v != nil && callType != "sms" { + duration = fmt.Sprintf("%ds", parse.Number(v)) + } + // 呼叫结果 非短信都有code作为结果 sms短信都ok + callResult := "Other" + callCause := "Call failure for other reason" + if callType == "sms" { + callResult = "Success" + callCause = "Normal Send" + } else { + if v, ok := cdrJSON["cause"]; ok && v != nil { + cause := fmt.Sprint(v) + for _, v := range dictCDRSipCode { + if cause == v.DictValue { + callResult = i18n.TKey(language, v.DictLabel) + break + } + } + for _, v := range dictCDRSipCodeCause { + if cause == v.DictValue { + callCause = i18n.TKey(language, v.DictLabel) + break + } + } + } + } + // 呼叫时间 + seizureTimeStr := "" + if v, ok := cdrJSON["seizureTime"]; ok && v != nil { + if seizureTime := parse.Number(v); seizureTime > 0 { + seizureTimeStr = date.ParseDateToStr(seizureTime, date.YYYY_MM_DDTHH_MM_SSZ) + } else { + seizureTimeStr = v.(string) + } + } + // 挂断时间 + releaseTimeStr := "" + if v, ok := cdrJSON["releaseTime"]; ok && v != nil { + if releaseTime := parse.Number(v); releaseTime > 0 { + releaseTimeStr = date.ParseDateToStr(releaseTime, date.YYYY_MM_DDTHH_MM_SSZ) + } else { + releaseTimeStr = v.(string) + } + } + + dataCells = append(dataCells, map[string]any{ + "A" + idx: row.ID, + "B" + idx: row.NeName, + "C" + idx: recordType, + "D" + idx: callTypeLable, + "E" + idx: caller, + "F" + idx: called, + "G" + idx: duration, + "H" + idx: callResult, + "I" + idx: callCause, + "J" + idx: seizureTimeStr, + "K" + idx: releaseTimeStr, + "L" + idx: row.TenantName, + }) + } + // 导出数据表格 + if err := file.WriterFileExecl(headerCells, dataCells, filePath, ""); err != nil { + logger.Errorf("export operate log err => %v", err.Error()) + return "export err" + } + } + + // 上传到FTP服务器 + if err := s.backupService.FTPPushFile(filePath, "cdr"); err != nil { + return "ok, ftp err:" + err.Error() + } + return "ok" +} + +// exportSMSC 导出SMSC-CDR会话事件数据 +func (s BackupExportCDRProcessor) exportSMSC(hour int, rmUID, fileType string) string { + // 前 hour 小时 + now := time.Now() + end := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), 0, 0, 0, now.Location()) + start := end.Add(-time.Duration(hour) * time.Hour) + + language := "en" + query := neDataModel.CDREventSMSCQuery{ + SortField: "timestamp", + SortOrder: "asc", + RmUID: rmUID, + StartTime: start.UnixMilli(), + EndTime: end.UnixMilli(), + PageNum: 1, + PageSize: 30000, + } + rows, total := s.smscCDREventService.SelectPage(query) + if total == 0 { + return "no data" + } + + // 导出文件名称 + fileName := fmt.Sprintf("smsc_cdr_event_export_%d_%s.%s", len(rows), date.ParseDateToStr(end, date.YYYYMMDDHHMMSS), fileType) + filePath := filepath.Join(s.backupService.BACKUP_DIR, "/cdr/smsc_cdr_event", fileName) + if runtime.GOOS == "windows" { + filePath = fmt.Sprintf("C:%s", filePath) + } + + if fileType == "csv" { + // 转换数据 + data := [][]string{ + { + "ID", + "NE Name", + "Record Behavior", + "Service Type", + "Caller", + "Called", + "Result", + "Time", + "Tenant Name", // for multi-tenancy + }, + } + // 读取字典数据 CDR 原因码 + dictCDRCauseCode := s.sysDictService.SelectDictDataByType("cdr_cause_code") + for _, row := range rows { + // 解析 JSON 字符串为 map + var cdrJSON map[string]interface{} + err := json.Unmarshal([]byte(row.CDRJSONStr), &cdrJSON) + if err != nil { + logger.Warnf("CDRExport Error parsing JSON: %s", err.Error()) + continue + } + // 记录类型 + recordType := "" + if v, ok := cdrJSON["recordType"]; ok && v != nil { + recordType = v.(string) + } + // 服务类型 + serviceType := "" + if v, ok := cdrJSON["serviceType"]; ok && v != nil { + serviceType = v.(string) + } + // 被叫 + called := "" + if v, ok := cdrJSON["calledParty"]; ok && v != nil { + called = v.(string) + } + // 主叫 + caller := "" + if v, ok := cdrJSON["callerParty"]; ok && v != nil { + caller = v.(string) + } + // 呼叫结果 0失败,1成功 + callResult := "Fail" + if v, ok := cdrJSON["result"]; ok && v != nil { + resultVal := parse.Number(v) + if resultVal == 1 { + callResult = "Success" + } + } + // 结果原因 + if v, ok := cdrJSON["cause"]; ok && v != nil && callResult == "Fail" { + cause := fmt.Sprint(v) + for _, v := range dictCDRCauseCode { + if cause == v.DictValue { + callResult = fmt.Sprintf("%s, %s", callResult, i18n.TKey(language, v.DictLabel)) + break + } + } + } + // 取时间 + timeStr := "" + if v, ok := cdrJSON["updateTime"]; ok && v != nil { + if releaseTime := parse.Number(v); releaseTime > 0 { + timeStr = date.ParseDateToStr(releaseTime, date.YYYY_MM_DDTHH_MM_SSZ) + } else { + timeStr = v.(string) + } + } + + data = append(data, []string{ + fmt.Sprint(row.ID), + row.NeName, + recordType, + serviceType, + caller, + called, + callResult, + timeStr, + row.TenantName, + }) + } + // 输出到文件 + if err := file.WriterFileCSV(data, filePath); err != nil { + logger.Errorf("export operate log err => %v", err.Error()) + return "export err" + } + } + + if fileType == "xlsx" { + // 第一行表头标题 + headerCells := map[string]string{ + "A1": "ID", + "B1": "NE Name", + "C1": "Record Behavior", + "D1": "Service Type", + "E1": "Caller", + "F1": "Called", + "G1": "Result", + "H1": "Time", + "I1": "Tenant Name", // for multi-tenancy + } + // 读取字典数据 CDR 原因码 + dictCDRCauseCode := s.sysDictService.SelectDictDataByType("cdr_cause_code") + // 从第二行开始的数据 + dataCells := make([]map[string]any, 0) + for i, row := range rows { + idx := strconv.Itoa(i + 2) + // 解析 JSON 字符串为 map + var cdrJSON map[string]interface{} + err := json.Unmarshal([]byte(row.CDRJSONStr), &cdrJSON) + if err != nil { + logger.Warnf("CDRExport Error parsing JSON: %s", err.Error()) + continue + } + // 记录类型 + recordType := "" + if v, ok := cdrJSON["recordType"]; ok && v != nil { + recordType = v.(string) + } + // 服务类型 + serviceType := "" + if v, ok := cdrJSON["serviceType"]; ok && v != nil { + serviceType = v.(string) + } + // 被叫 + called := "" + if v, ok := cdrJSON["calledParty"]; ok && v != nil { + called = v.(string) + } + // 主叫 + caller := "" + if v, ok := cdrJSON["callerParty"]; ok && v != nil { + caller = v.(string) + } + // 呼叫结果 0失败,1成功 + callResult := "Fail" + if v, ok := cdrJSON["result"]; ok && v != nil { + resultVal := parse.Number(v) + if resultVal == 1 { + callResult = "Success" + } + } + // 结果原因 + if v, ok := cdrJSON["cause"]; ok && v != nil && callResult == "Fail" { + cause := fmt.Sprint(v) + for _, v := range dictCDRCauseCode { + if cause == v.DictValue { + callResult = fmt.Sprintf("%s, %s", callResult, i18n.TKey(language, v.DictLabel)) + break + } + } + } + // 取时间 + timeStr := "" + if v, ok := cdrJSON["updateTime"]; ok && v != nil { + if releaseTime := parse.Number(v); releaseTime > 0 { + timeStr = date.ParseDateToStr(releaseTime, date.YYYY_MM_DDTHH_MM_SSZ) + } else { + timeStr = v.(string) + } + } + + dataCells = append(dataCells, map[string]any{ + "A" + idx: row.ID, + "B" + idx: row.NeName, + "C" + idx: recordType, + "D" + idx: serviceType, + "E" + idx: caller, + "F" + idx: called, + "G" + idx: callResult, + "H" + idx: timeStr, + "I" + idx: row.TenantName, + }) + } + // 导出数据表格 + if err := file.WriterFileExecl(headerCells, dataCells, filePath, ""); err != nil { + logger.Errorf("export operate log err => %v", err.Error()) + return "export err" + } + } + + // 上传到FTP服务器 + if err := s.backupService.FTPPushFile(filePath, "cdr"); err != nil { + return "ok, ftp err:" + err.Error() + } + return "ok" +} + +// exportSMF 导出SMF-CDR会话事件数据 +func (s BackupExportCDRProcessor) exportSMF(hour int, rmUID, fileType string) string { + // 前 hour 小时 + now := time.Now() + end := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), 0, 0, 0, now.Location()) + start := end.Add(-time.Duration(hour) * time.Hour) + + query := neDataModel.CDREventSMFQuery{ + SortField: "timestamp", + SortOrder: "asc", + RmUID: rmUID, + StartTime: start.UnixMilli(), + EndTime: end.UnixMilli(), + PageNum: 1, + PageSize: 30000, + } + rows, total := s.smfCDREventService.SelectPage(query) + if total == 0 { + return "no data" + } + + // 导出文件名称 + fileName := fmt.Sprintf("smf_cdr_event_export_%d_%s.%s", len(rows), date.ParseDateToStr(end, date.YYYYMMDDHHMMSS), fileType) + filePath := filepath.Join(s.backupService.BACKUP_DIR, "/cdr/smf_cdr_event", fileName) + if runtime.GOOS == "windows" { + filePath = fmt.Sprintf("C:%s", filePath) + } + + if fileType == "csv" { + // 转换数据 + data := [][]string{ + { + "ID", + "Charging ID", + "NE Name", + "Resource Unique ID", + "Subscriber ID Data", + "Subscriber ID Type", + "Data Volume Uplink", + "Data Volume Downlink", + "Data Total Volume", + "Duration", + "Invocation Time", + "User Identifier", + "SSC Mode", + "DNN ID", + "PDU Type", + "RAT Type", + "PDU IPv4 Address", + "Network Function IPv4", + "PDU IPv6 Address Swith Prefix", + "Record Network Function ID", + "Record Type", + "Record Opening Time", + "Tenant Name", // for multi-tenancy + }, + } + for _, row := range rows { + // 解析 JSON 字符串为 map + var cdrJSON map[string]interface{} + err := json.Unmarshal([]byte(row.CDRJSONStr), &cdrJSON) + if err != nil { + logger.Warnf("CDRExport Error parsing JSON: %s", err.Error()) + continue + } + // 计费ID + chargingID := "" + if v, ok := cdrJSON["chargingID"]; ok && v != nil { + chargingID = fmt.Sprint(parse.Number(v)) + } + // 订阅 ID 类型 + subscriptionIDType := "-" + // 订阅 ID 数据 + subscriptionIDData := "-" + if v, ok := cdrJSON["subscriberIdentifier"]; ok && v != nil { + if sub, subOk := v.(map[string]any); subOk && sub != nil { + subscriptionIDType = sub["subscriptionIDType"].(string) + subscriptionIDData = sub["subscriptionIDData"].(string) + } + } + + // 网络功能 IPv4 地址 + networkFunctionIPv4Address := "" + if v, ok := cdrJSON["nFunctionConsumerInformation"]; ok && v != nil { + if conInfo, conInfoOk := v.(map[string]any); conInfoOk && conInfo != nil { + networkFunctionIPv4Address = conInfo["networkFunctionIPv4Address"].(string) + } + } + + // 数据量上行链路 + var dataVolumeUplink int64 = 0 + // 数据量下行链路 + var dataVolumeDownlink int64 = 0 + // 数据总量 + var dataTotalVolume int64 = 0 + if v, ok := cdrJSON["listOfMultipleUnitUsage"]; ok && v != nil { + usageList := v.([]any) + if len(usageList) > 0 { + for _, used := range usageList { + usedUnit := used.(map[string]any) + usedUnitList := usedUnit["usedUnitContainer"].([]any) + if len(usedUnitList) > 0 { + for _, data := range usedUnitList { + udata := data.(map[string]any) + if dup, dupOk := udata["dataVolumeUplink"]; dupOk { + dataVolumeUplink += parse.Number(dup) + } + if ddown, ddownOk := udata["dataVolumeDownlink"]; ddownOk { + dataVolumeDownlink += parse.Number(ddown) + } + if dt, dtOk := udata["dataTotalVolume"]; dtOk { + dataTotalVolume += parse.Number(dt) + } + } + } + } + } + } + // 时长 + duration := "-" + if v, ok := cdrJSON["duration"]; ok && v != nil { + duration = fmt.Sprint(parse.Number(v)) + } + // 调用时间 + invocationTimestamp := "" + if v, ok := cdrJSON["invocationTimestamp"]; ok && v != nil { + invocationTimestamp = v.(string) + } + // 记录打开时间 + User_Identifier := "" + SSC_Mode := "" + RAT_Type := "" + DNN_ID := "" + PDU_Type := "" + PDU_IPv4 := "" + PDU_IPv6 := "" + if v, ok := cdrJSON["pDUSessionChargingInformation"]; ok && v != nil { + pduInfo := v.(map[string]any) + + if v, ok := pduInfo["userIdentifier"]; ok && v != nil { + User_Identifier = v.(string) + } + if v, ok := pduInfo["sSCMode"]; ok && v != nil { + SSC_Mode = v.(string) + } + if v, ok := pduInfo["rATType"]; ok && v != nil { + RAT_Type = v.(string) + } + if v, ok := pduInfo["dNNID"]; ok && v != nil { + DNN_ID = v.(string) + } + if v, ok := pduInfo["pDUType"]; ok && v != nil { + PDU_Type = v.(string) + } + if v, ok := pduInfo["pDUAddress"]; ok && v != nil { + pDUAddress := v.(map[string]any) + if addr, ok := pDUAddress["pDUIPv4Address"]; ok && addr != nil { + PDU_IPv4 = addr.(string) + } + if addr, ok := pDUAddress["pDUIPv6AddresswithPrefix"]; ok && addr != nil { + PDU_IPv6 = addr.(string) + } + } + } + + // 记录网络参数ID + recordNFID := "" + if v, ok := cdrJSON["recordingNetworkFunctionID"]; ok && v != nil { + recordNFID = v.(string) + } + + //记录开始时间 + recordOpeningTime := "" + if v, ok := cdrJSON["recordOpeningTime"]; ok && v != nil { + recordOpeningTime = v.(string) + } + + //记录类型 + recordType := "" + if v, ok := cdrJSON["recordType"]; ok && v != nil { + recordType = v.(string) + } + + data = append(data, []string{ + fmt.Sprint(row.ID), + chargingID, + row.NeName, + row.RmUID, + subscriptionIDData, + subscriptionIDType, + fmt.Sprint(dataVolumeUplink), + fmt.Sprint(dataVolumeDownlink), + fmt.Sprint(dataTotalVolume), + duration, + invocationTimestamp, + User_Identifier, + SSC_Mode, + DNN_ID, + PDU_Type, + RAT_Type, + PDU_IPv4, + networkFunctionIPv4Address, + PDU_IPv6, + recordNFID, + recordType, + recordOpeningTime, + row.TenantName, // for multi-tenancy + }) + } + // 输出到文件 + if err := file.WriterFileCSV(data, filePath); err != nil { + logger.Errorf("export operate log err => %v", err.Error()) + return "export err" + } + } + + if fileType == "xlsx" { + // 第一行表头标题 + headerCells := map[string]string{ + "A1": "ID", + "B1": "Charging ID", + "C1": "NE Name", + "D1": "Resource Unique ID", + "E1": "Subscriber ID Data", + "F1": "Subscriber ID Type", + "G1": "Data Volume Uplink", + "H1": "Data Volume Downlink", + "I1": "Data Total Volume", + "J1": "Duration", + "K1": "Invocation Time", + "L1": "User Identifier", + "M1": "SSC Mode", + "N1": "DNN ID", + "O1": "PDU Type", + "P1": "RAT Type", + "Q1": "PDU IPv4 Address", + "R1": "Network Function IPv4", + "S1": "PDU IPv6 Address Swith Prefix", + "T1": "Record Network Function ID", + "U1": "Record Type", + "V1": "Record Opening Time", + "W1": "Tenant Name", // for multi-tenancy + } + // 从第二行开始的数据 + dataCells := make([]map[string]any, 0) + for i, row := range rows { + idx := strconv.Itoa(i + 2) + // 解析 JSON 字符串为 map + var cdrJSON map[string]interface{} + err := json.Unmarshal([]byte(row.CDRJSONStr), &cdrJSON) + if err != nil { + logger.Warnf("CDRExport Error parsing JSON: %s", err.Error()) + continue + } + // 计费ID + chargingID := "" + if v, ok := cdrJSON["chargingID"]; ok && v != nil { + chargingID = fmt.Sprint(parse.Number(v)) + } + // 订阅 ID 类型 + subscriptionIDType := "-" + // 订阅 ID 数据 + subscriptionIDData := "-" + if v, ok := cdrJSON["subscriberIdentifier"]; ok && v != nil { + if sub, subOk := v.(map[string]any); subOk && sub != nil { + subscriptionIDType = sub["subscriptionIDType"].(string) + subscriptionIDData = sub["subscriptionIDData"].(string) + } + } + + // 网络功能 IPv4 地址 + networkFunctionIPv4Address := "" + if v, ok := cdrJSON["nFunctionConsumerInformation"]; ok && v != nil { + if conInfo, conInfoOk := v.(map[string]any); conInfoOk && conInfo != nil { + networkFunctionIPv4Address = conInfo["networkFunctionIPv4Address"].(string) + } + } + + // 数据量上行链路 + var dataVolumeUplink int64 = 0 + // 数据量下行链路 + var dataVolumeDownlink int64 = 0 + // 数据总量 + var dataTotalVolume int64 = 0 + if v, ok := cdrJSON["listOfMultipleUnitUsage"]; ok && v != nil { + usageList := v.([]any) + if len(usageList) > 0 { + for _, used := range usageList { + usedUnit := used.(map[string]any) + usedUnitList := usedUnit["usedUnitContainer"].([]any) + if len(usedUnitList) > 0 { + for _, data := range usedUnitList { + udata := data.(map[string]any) + if dup, dupOk := udata["dataVolumeUplink"]; dupOk { + dataVolumeUplink += parse.Number(dup) + } + if ddown, ddownOk := udata["dataVolumeDownlink"]; ddownOk { + dataVolumeDownlink += parse.Number(ddown) + } + if dt, dtOk := udata["dataTotalVolume"]; dtOk { + dataTotalVolume += parse.Number(dt) + } + } + } + } + } + } + // 时长 + duration := "-" + if v, ok := cdrJSON["duration"]; ok && v != nil { + duration = fmt.Sprint(parse.Number(v)) + } + // 调用时间 + invocationTimestamp := "" + if v, ok := cdrJSON["invocationTimestamp"]; ok && v != nil { + invocationTimestamp = v.(string) + } + // 记录打开时间 + User_Identifier := "" + SSC_Mode := "" + RAT_Type := "" + DNN_ID := "" + PDU_Type := "" + PDU_IPv4 := "" + PDU_IPv6 := "" + if v, ok := cdrJSON["pDUSessionChargingInformation"]; ok && v != nil { + pduInfo := v.(map[string]any) + + if v, ok := pduInfo["userIdentifier"]; ok && v != nil { + User_Identifier = v.(string) + } + if v, ok := pduInfo["sSCMode"]; ok && v != nil { + SSC_Mode = v.(string) + } + if v, ok := pduInfo["rATType"]; ok && v != nil { + RAT_Type = v.(string) + } + if v, ok := pduInfo["dNNID"]; ok && v != nil { + DNN_ID = v.(string) + } + if v, ok := pduInfo["pDUType"]; ok && v != nil { + PDU_Type = v.(string) + } + if v, ok := pduInfo["pDUAddress"]; ok && v != nil { + pDUAddress := v.(map[string]any) + if addr, ok := pDUAddress["pDUIPv4Address"]; ok && addr != nil { + PDU_IPv4 = addr.(string) + } + if addr, ok := pDUAddress["pDUIPv6AddresswithPrefix"]; ok && addr != nil { + PDU_IPv6 = addr.(string) + } + } + } + + // 记录网络参数ID + recordNFID := "" + if v, ok := cdrJSON["recordingNetworkFunctionID"]; ok && v != nil { + recordNFID = v.(string) + } + + //记录开始时间 + recordOpeningTime := "" + if v, ok := cdrJSON["recordOpeningTime"]; ok && v != nil { + recordOpeningTime = v.(string) + } + + //记录类型 + recordType := "" + if v, ok := cdrJSON["recordType"]; ok && v != nil { + recordType = v.(string) + } + + dataCells = append(dataCells, map[string]any{ + "A" + idx: row.ID, + "B" + idx: chargingID, + "C" + idx: row.NeName, + "D" + idx: row.RmUID, + "E" + idx: subscriptionIDData, + "F" + idx: subscriptionIDType, + "G" + idx: dataVolumeUplink, + "H" + idx: dataVolumeDownlink, + "I" + idx: dataTotalVolume, + "J" + idx: duration, + "K" + idx: invocationTimestamp, + "L" + idx: User_Identifier, + "M" + idx: SSC_Mode, + "N" + idx: DNN_ID, + "O" + idx: PDU_Type, + "P" + idx: RAT_Type, + "Q" + idx: PDU_IPv4, + "R" + idx: networkFunctionIPv4Address, + "S" + idx: PDU_IPv6, + "T" + idx: recordNFID, + "U" + idx: recordType, + "V" + idx: recordOpeningTime, + "W" + idx: row.TenantName, + }) + } + // 导出数据表格 + if err := file.WriterFileExecl(headerCells, dataCells, filePath, ""); err != nil { + logger.Errorf("export operate log err => %v", err.Error()) + return "export err" + } + } + + // 上传到FTP服务器 + if err := s.backupService.FTPPushFile(filePath, "cdr"); err != nil { + return "ok, ftp err:" + err.Error() + } + return "ok" +} + +// exportSGWC 导出SGWC-CDR会话事件数据 +func (s BackupExportCDRProcessor) exportSGWC(hour int, rmUID, fileType string) string { + // 前 hour 小时 + now := time.Now() + end := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), 0, 0, 0, now.Location()) + start := end.Add(-time.Duration(hour) * time.Hour) + + query := neDataModel.CDREventSGWCQuery{ + SortField: "timestamp", + SortOrder: "asc", + RmUID: rmUID, + StartTime: start.UnixMilli(), + EndTime: end.UnixMilli(), + PageNum: 1, + PageSize: 30000, + } + rows, total := s.sgwcCDREventService.SelectPage(query) + if total == 0 { + return "no data" + } + + // 导出文件名称 + fileName := fmt.Sprintf("sgwc_cdr_event_export_%d_%s.%s", len(rows), date.ParseDateToStr(end, date.YYYYMMDDHHMMSS), fileType) + filePath := filepath.Join(s.backupService.BACKUP_DIR, "/cdr/sgwc_cdr_event", fileName) + if runtime.GOOS == "windows" { + filePath = fmt.Sprintf("C:%s", filePath) + } + + if fileType == "csv" { + // 转换数据 + data := [][]string{ + { + "ID", + "NE Name", + "Resource Unique ID", + "Charging ID", + "IMSI", + "MSISDN", + "GPRS Uplink", + "GPRS Downlink", + "Duration", + "Invocation Time", + "PGW Address", + "SGW Address", + "RAT Type", + "PDPPDN Type", + "PDPPDN Address", + "Node Address", + "Node Type", + "Record Access Point Name NI", + "Record Cause For Rec Closing", + "Record Sequence Number", + "Local Record Sequence Number", + "Record Type", + "Record Opening Time", + "Tenant Name", // for multi-tenancy + }, + } + for _, row := range rows { + // 解析 JSON 字符串为 map + var cdrJSON map[string]interface{} + err := json.Unmarshal([]byte(row.CDRJSONStr), &cdrJSON) + if err != nil { + logger.Warnf("CDRExport Error parsing JSON: %s", err.Error()) + continue + } + // 计费ID + chargingID := "" + if v, ok := cdrJSON["chargingID"]; ok && v != nil { + chargingID = fmt.Sprint(parse.Number(v)) + } + // IMSI + servedIMSI := "" + if v, ok := cdrJSON["servedIMSI"]; ok && v != nil { + servedIMSI = fmt.Sprint(v) + } + // MSISDN + servedMSISDN := "" + if v, ok := cdrJSON["servedMSISDN"]; ok && v != nil { + servedMSISDN = fmt.Sprint(v) + } + // pGWAddressUsed + pGWAddressUsed := "" + if v, ok := cdrJSON["pGWAddressUsed"]; ok && v != nil { + pGWAddressUsed = fmt.Sprint(v) + data[0][10] = "PGW Address" + } + if v, ok := cdrJSON["GGSNAddress"]; ok && v != nil { + pGWAddressUsed = fmt.Sprint(v) + data[0][10] = "GGSN Address" + } + // sGWAddress + sGWAddress := "" + if v, ok := cdrJSON["sGWAddress"]; ok && v != nil { + sGWAddress = fmt.Sprint(v) + data[0][11] = "SGW Address" + } + if v, ok := cdrJSON["SGSNAddress"]; ok && v != nil { + sGWAddress = fmt.Sprint(v) + data[0][11] = "SGSN Address" + } + // recordType + recordType := "" + if v, ok := cdrJSON["recordType"]; ok && v != nil { + recordType = fmt.Sprint(v) + } + // rATType + rATType := "" + if v, ok := cdrJSON["rATType"]; ok && v != nil { + rATType = fmt.Sprint(v) + } + // pdpPDNType + pdpPDNType := "" + if v, ok := cdrJSON["pdpPDNType"]; ok && v != nil { + pdpPDNType = fmt.Sprint(v) + } + // servedPDPPDNAddress + servedPDPPDNAddress := "" + if v, ok := cdrJSON["servedPDPPDNAddress"]; ok && v != nil { + servedPDPPDNAddress = fmt.Sprint(v) + } + // servedPDPPDNAddress + servingNodeAddress := []string{} + if v, ok := cdrJSON["servingNodeAddress"]; ok && v != nil { + for _, v := range v.([]any) { + servingNodeAddress = append(servingNodeAddress, fmt.Sprint(v)) + } + } + // servingNodeType + servingNodeType := []string{} + if v, ok := cdrJSON["servingNodeType"]; ok && v != nil { + for _, v := range v.([]any) { + if v, ok := v.(map[string]any)["servingNodeType"]; ok && v != nil { + servingNodeType = append(servingNodeType, fmt.Sprint(v)) + } + } + } + // accessPointNameNI + accessPointNameNI := "" + if v, ok := cdrJSON["accessPointNameNI"]; ok && v != nil { + accessPointNameNI = fmt.Sprint(v) + } + // causeForRecClosing + causeForRecClosing := "" + if v, ok := cdrJSON["causeForRecClosing"]; ok && v != nil { + causeForRecClosing = fmt.Sprint(v) + } + // recordSequenceNumber + recordSequenceNumber := "" + if v, ok := cdrJSON["recordSequenceNumber"]; ok && v != nil { + recordSequenceNumber = fmt.Sprint(v) + } + // localRecordSequenceNumber + localRecordSequenceNumber := "" + if v, ok := cdrJSON["localRecordSequenceNumber"]; ok && v != nil { + localRecordSequenceNumber = fmt.Sprint(v) + } + // 数据量上行链路 + var dataVolumeGPRSUplink int64 = 0 + // 数据量下行链路 + var dataVolumeGPRSDownlink int64 = 0 + if v, ok := cdrJSON["listOfTrafficVolumes"]; ok && v != nil { + usageList := v.([]any) + if len(usageList) > 0 { + for _, used := range usageList { + usedUnit := used.(map[string]any) + if dup, dupOk := usedUnit["dataVolumeGPRSUplink"]; dupOk { + dataVolumeGPRSUplink = parse.Number(dup) + } + if ddown, ddownOk := usedUnit["dataVolumeGPRSDownlink"]; ddownOk { + dataVolumeGPRSDownlink = parse.Number(ddown) + } + } + } + } + // 时长 + duration := "-" + if v, ok := cdrJSON["duration"]; ok && v != nil { + duration = fmt.Sprint(parse.Number(v)) + } + // 调用时间 + invocationTimestamp := "" + if v, ok := cdrJSON["recordOpeningTime"]; ok && v != nil { + invocationTimestamp = v.(string) + } + + data = append(data, []string{ + fmt.Sprint(row.ID), + row.NeName, + row.RmUID, + chargingID, + servedIMSI, + servedMSISDN, + fmt.Sprint(dataVolumeGPRSUplink), + fmt.Sprint(dataVolumeGPRSDownlink), + duration, + invocationTimestamp, + pGWAddressUsed, + sGWAddress, + rATType, + pdpPDNType, + servedPDPPDNAddress, + strings.Join(servingNodeAddress, ","), + strings.Join(servingNodeType, ","), + accessPointNameNI, + causeForRecClosing, + recordSequenceNumber, + localRecordSequenceNumber, + recordType, + invocationTimestamp, + }) + } + // 输出到文件 + if err := file.WriterFileCSV(data, filePath); err != nil { + logger.Errorf("export operate log err => %v", err.Error()) + return "export err" + } + } + + if fileType == "xlsx" { + // 第一行表头标题 + headerCells := map[string]string{ + "A1": "ID", + "B1": "NE Name", + "C1": "Resource Unique ID", + "D1": "Charging ID", + "E1": "IMSI", + "F1": "MSISDN", + "G1": "GPRS Uplink", + "H1": "GPRS Downlink", + "I1": "Duration", + "J1": "Invocation Time", + "K1": "PGW Address", + "L1": "SGW Address", + "M1": "RAT Type", + "N1": "PDPPDN Type", + "O1": "PDPPDN Address", + "P1": "Node Address", + "Q1": "Node Type", + "R1": "Record Access Point Name NI", + "S1": "Record Cause For Rec Closing", + "T1": "Record Sequence Number", + "U1": "Local Record Sequence Number", + "V1": "Record Type", + "W1": "Record Opening Time", + "X1": "Tenant Name", // for multi-tenancy + } + // 从第二行开始的数据 + dataCells := make([]map[string]any, 0) + for i, row := range rows { + idx := strconv.Itoa(i + 2) + // 解析 JSON 字符串为 map + var cdrJSON map[string]interface{} + err := json.Unmarshal([]byte(row.CDRJSONStr), &cdrJSON) + if err != nil { + logger.Warnf("CDRExport Error parsing JSON: %s", err.Error()) + continue + } + // 计费ID + chargingID := "" + if v, ok := cdrJSON["chargingID"]; ok && v != nil { + chargingID = fmt.Sprint(parse.Number(v)) + } + // IMSI + servedIMSI := "" + if v, ok := cdrJSON["servedIMSI"]; ok && v != nil { + servedIMSI = fmt.Sprint(v) + } + // MSISDN + servedMSISDN := "" + if v, ok := cdrJSON["servedMSISDN"]; ok && v != nil { + servedMSISDN = fmt.Sprint(v) + } + // pGWAddressUsed + pGWAddressUsed := "" + if v, ok := cdrJSON["pGWAddressUsed"]; ok && v != nil { + pGWAddressUsed = fmt.Sprint(v) + headerCells["K1"] = "PGW Address" + } + if v, ok := cdrJSON["GGSNAddress"]; ok && v != nil { + pGWAddressUsed = fmt.Sprint(v) + headerCells["K1"] = "GGSN Address" + } + // sGWAddress + sGWAddress := "" + if v, ok := cdrJSON["sGWAddress"]; ok && v != nil { + sGWAddress = fmt.Sprint(v) + headerCells["L1"] = "SGW Address" + } + if v, ok := cdrJSON["SGSNAddress"]; ok && v != nil { + sGWAddress = fmt.Sprint(v) + headerCells["L1"] = "SGSN Address" + } + // recordType + recordType := "" + if v, ok := cdrJSON["recordType"]; ok && v != nil { + recordType = fmt.Sprint(v) + } + // rATType + rATType := "" + if v, ok := cdrJSON["rATType"]; ok && v != nil { + rATType = fmt.Sprint(v) + } + // pdpPDNType + pdpPDNType := "" + if v, ok := cdrJSON["pdpPDNType"]; ok && v != nil { + pdpPDNType = fmt.Sprint(v) + } + // servedPDPPDNAddress + servedPDPPDNAddress := "" + if v, ok := cdrJSON["servedPDPPDNAddress"]; ok && v != nil { + servedPDPPDNAddress = fmt.Sprint(v) + } + // servedPDPPDNAddress + servingNodeAddress := []string{} + if v, ok := cdrJSON["servingNodeAddress"]; ok && v != nil { + for _, v := range v.([]any) { + servingNodeAddress = append(servingNodeAddress, fmt.Sprint(v)) + } + } + // servingNodeType + servingNodeType := []string{} + if v, ok := cdrJSON["servingNodeType"]; ok && v != nil { + for _, v := range v.([]any) { + if v, ok := v.(map[string]any)["servingNodeType"]; ok && v != nil { + servingNodeType = append(servingNodeType, fmt.Sprint(v)) + } + } + } + // accessPointNameNI + accessPointNameNI := "" + if v, ok := cdrJSON["accessPointNameNI"]; ok && v != nil { + accessPointNameNI = fmt.Sprint(v) + } + // causeForRecClosing + causeForRecClosing := "" + if v, ok := cdrJSON["causeForRecClosing"]; ok && v != nil { + causeForRecClosing = fmt.Sprint(v) + } + // recordSequenceNumber + recordSequenceNumber := "" + if v, ok := cdrJSON["recordSequenceNumber"]; ok && v != nil { + recordSequenceNumber = fmt.Sprint(v) + } + // localRecordSequenceNumber + localRecordSequenceNumber := "" + if v, ok := cdrJSON["localRecordSequenceNumber"]; ok && v != nil { + localRecordSequenceNumber = fmt.Sprint(v) + } + // 数据量上行链路 + var dataVolumeGPRSUplink int64 = 0 + // 数据量下行链路 + var dataVolumeGPRSDownlink int64 = 0 + if v, ok := cdrJSON["listOfTrafficVolumes"]; ok && v != nil { + usageList := v.([]any) + if len(usageList) > 0 { + for _, used := range usageList { + usedUnit := used.(map[string]any) + if dup, dupOk := usedUnit["dataVolumeGPRSUplink"]; dupOk { + dataVolumeGPRSUplink = parse.Number(dup) + } + if ddown, ddownOk := usedUnit["dataVolumeGPRSDownlink"]; ddownOk { + dataVolumeGPRSDownlink = parse.Number(ddown) + } + } + } + } + // 时长 + duration := "-" + if v, ok := cdrJSON["duration"]; ok && v != nil { + duration = fmt.Sprint(parse.Number(v)) + } + // 调用时间 + invocationTimestamp := "" + if v, ok := cdrJSON["recordOpeningTime"]; ok && v != nil { + invocationTimestamp = v.(string) + } + + dataCells = append(dataCells, map[string]any{ + "A" + idx: row.ID, + "B" + idx: row.NeName, + "C" + idx: row.RmUID, + "D" + idx: chargingID, + "E" + idx: servedIMSI, + "F" + idx: servedMSISDN, + "G" + idx: dataVolumeGPRSUplink, + "H" + idx: dataVolumeGPRSDownlink, + "I" + idx: duration, + "J" + idx: invocationTimestamp, + "K" + idx: pGWAddressUsed, + "L" + idx: sGWAddress, + "M" + idx: rATType, + "N" + idx: pdpPDNType, + "O" + idx: servedPDPPDNAddress, + "P" + idx: strings.Join(servingNodeAddress, ","), + "Q" + idx: strings.Join(servingNodeType, ","), + "R" + idx: accessPointNameNI, + "S" + idx: causeForRecClosing, + "T" + idx: recordSequenceNumber, + "U" + idx: localRecordSequenceNumber, + "V" + idx: recordType, + "W" + idx: invocationTimestamp, + "X" + idx: row.TenantName, + }) + } + // 导出数据表格 + if err := file.WriterFileExecl(headerCells, dataCells, filePath, ""); err != nil { + logger.Errorf("export sgec cdr err => %v", err.Error()) + return "export err" + } + } + + // 上传到FTP服务器 + if err := s.backupService.FTPPushFile(filePath, "cdr"); err != nil { + return "ok, ftp err:" + err.Error() + } + return "ok" +} diff --git a/src/modules/crontask/processor/backup_export_log/backup_export_log.go b/src/modules/crontask/processor/backup_export_log/backup_export_log.go new file mode 100644 index 00000000..dfa4ced6 --- /dev/null +++ b/src/modules/crontask/processor/backup_export_log/backup_export_log.go @@ -0,0 +1,367 @@ +package backup_export_log + +import ( + "encoding/json" + "fmt" + "path/filepath" + "runtime" + "strconv" + "time" + + "be.ems/src/framework/cron" + "be.ems/src/framework/i18n" + "be.ems/src/framework/logger" + "be.ems/src/framework/utils/date" + "be.ems/src/framework/utils/file" + "be.ems/src/framework/utils/parse" + neDataService "be.ems/src/modules/network_data/service" + systemModel "be.ems/src/modules/system/model" + systemService "be.ems/src/modules/system/service" +) + +var NewProcessor = &BackupExportLogProcessor{ + count: 0, + backupService: neDataService.NewBackup, + sysLogLoginService: systemService.NewSysLogLoginImpl, + sysOperateService: systemService.NewSysLogOperateImpl, +} + +// BackupExportLog 队列任务处理 +type BackupExportLogProcessor struct { + count int // 执行次数 + backupService *neDataService.Backup // 备份相关服务 + sysLogLoginService *systemService.SysLogLoginImpl // 系统登录日志服务 + sysOperateService *systemService.SysLogOperateImpl // 系统操作日志服务 +} + +func (s *BackupExportLogProcessor) Execute(data any) (any, error) { + s.count++ // 执行次数加一 + options := data.(cron.JobData) + sysJob := options.SysJob + logger.Infof("重复:%v 任务ID:%s 执行次数:%d", options.Repeat, sysJob.JobID, s.count) + // 返回结果,用于记录执行结果 + result := map[string]any{ + "count": s.count, + } + + var params struct { + DataType []string `json:"dataType"` // 类型支持 operate/login + FileType string `json:"fileType"` // 文件类型 csv/xlsx + Hour int `json:"hour"` // 数据时间从任务执行时间前的小时数 + } + if err := json.Unmarshal([]byte(sysJob.TargetParams), ¶ms); err != nil { + return nil, err + } + if !(params.FileType == "csv" || params.FileType == "xlsx") { + return nil, fmt.Errorf("file type error, only support csv,xlsx") + } + + for _, v := range params.DataType { + switch v { + case "operate": + result[v] = s.exportOperate(params.Hour, params.FileType) + case "login": + result[v] = s.exportLogin(params.Hour, params.FileType) + } + } + + // 返回结果,用于记录执行结果 + return result, nil +} + +// exportOperate 导出系统操作日志数据 +func (s BackupExportLogProcessor) exportOperate(hour int, fileType string) string { + // 前 hour 小时 + now := time.Now() + end := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), 0, 0, 0, now.Location()) + start := end.Add(-time.Duration(hour) * time.Hour) + + language := "en" + query := map[string]any{ + "beginTime": fmt.Sprint(start.UnixMilli()), + "endTime": fmt.Sprint(end.UnixMilli()), + "pageNum": "1", + "pageSize": "30000", + } + data := s.sysOperateService.SelectSysLogOperatePage(query, "") + // rows, total + if data == nil || parse.Number(data["total"]) == 0 { + return "no data" + } + rows := data["rows"].([]systemModel.SysLogOperate) + + // 闭包函数处理多语言 + converI18n := func(language string, arr *[]systemModel.SysLogOperate) { + for i := range *arr { + (*arr)[i].Title = i18n.TKey(language, (*arr)[i].Title) + (*arr)[i].OperLocation = i18n.TKey(language, (*arr)[i].OperLocation) + } + } + converI18n(language, &rows) + + // 导出文件名称 + fileName := fmt.Sprintf("sys_log_operate_export_%d_%s.%s", len(rows), date.ParseDateToStr(end, date.YYYYMMDDHHMMSS), fileType) + filePath := filepath.Join(s.backupService.BACKUP_DIR, "/log/sys_log_operate", fileName) + if runtime.GOOS == "windows" { + filePath = fmt.Sprintf("C:%s", filePath) + } + + // 业务类型 + businessTypeFunc := func(v string) string { + businessType := "" + switch v { + case "0": + // 业务操作类型-其它 + businessType = i18n.TKey(language, "dictData.operType.other") + case "1": + // 业务操作类型-新增 + businessType = i18n.TKey(language, "dictData.operType.add") + case "2": + // 业务操作类型-修改 + businessType = i18n.TKey(language, "dictData.operType.edit") + case "3": + // 业务操作类型-删除 + businessType = i18n.TKey(language, "dictData.operType.delete") + case "4": + // 业务操作类型-授权 + businessType = i18n.TKey(language, "dictData.operType.auth") + case "5": + // 业务操作类型-导出 + businessType = i18n.TKey(language, "dictData.operType.export") + case "6": + // 业务操作类型-导入 + businessType = i18n.TKey(language, "dictData.operType.import") + case "7": + // 业务操作类型-强退 + businessType = i18n.TKey(language, "dictData.operType.forced quit") + case "8": + // 业务操作类型-清空数据 + businessType = i18n.TKey(language, "dictData.operType.clear") + } + return businessType + } + + if fileType == "csv" { + // 转换数据 + data := [][]string{ + { + i18n.TKey(language, "log.operate.export.id"), + i18n.TKey(language, "log.operate.export.title"), + i18n.TKey(language, "log.operate.export.businessType"), + i18n.TKey(language, "log.operate.export.operName"), + i18n.TKey(language, "log.operate.export.method"), + i18n.TKey(language, "log.operate.export.ip"), + i18n.TKey(language, "log.operate.export.status"), + i18n.TKey(language, "log.operate.export.operTime"), + i18n.TKey(language, "log.operate.export.costTime"), + "Tenant Name", // for multi-tenancy + }, + } + for _, row := range rows { + // 业务类型 + businessType := businessTypeFunc(row.BusinessType) + + // 状态 + statusValue := i18n.TKey(language, "dictData.fail") + if row.Status == "1" { + statusValue = i18n.TKey(language, "dictData.success") + } + data = append(data, []string{ + fmt.Sprint(row.OperID), + row.Title, + businessType, + row.OperName, + row.RequestMethod, + row.OperIP, + statusValue, + date.ParseDateToStr(row.OperTime, date.YYYY_MM_DDTHH_MM_SSZ), + fmt.Sprint(row.CostTime), + row.TenantName, + }) + } + // 输出到文件 + if err := file.WriterFileCSV(data, filePath); err != nil { + logger.Errorf("export operate log err => %v", err.Error()) + return "export err" + } + } + + if fileType == "xlsx" { + // 第一行表头标题 + headerCells := map[string]string{ + "A1": i18n.TKey(language, "log.operate.export.id"), + "B1": i18n.TKey(language, "log.operate.export.title"), + "C1": i18n.TKey(language, "log.operate.export.businessType"), + "D1": i18n.TKey(language, "log.operate.export.operName"), + "E1": i18n.TKey(language, "log.operate.export.method"), + "F1": i18n.TKey(language, "log.operate.export.ip"), + "G1": i18n.TKey(language, "log.operate.export.status"), + "H1": i18n.TKey(language, "log.operate.export.operTime"), + "I1": i18n.TKey(language, "log.operate.export.costTime"), + "J1": "Tenant Name", // for multi-tenancy + } + // 从第二行开始的数据 + dataCells := make([]map[string]any, 0) + for i, row := range rows { + idx := strconv.Itoa(i + 2) + // 业务类型 + businessType := businessTypeFunc(row.BusinessType) + + // 状态 + statusValue := i18n.TKey(language, "dictData.fail") + if row.Status == "1" { + statusValue = i18n.TKey(language, "dictData.success") + } + dataCells = append(dataCells, map[string]any{ + "A" + idx: row.OperID, + "B" + idx: row.Title, + "C" + idx: businessType, + "D" + idx: row.OperName, + "E" + idx: row.RequestMethod, + "F" + idx: row.OperIP, + "G" + idx: statusValue, + "H" + idx: date.ParseDateToStr(row.OperTime, date.YYYY_MM_DDTHH_MM_SSZ), + "I" + idx: row.CostTime, + "J" + idx: row.TenantName, + }) + } + // 导出数据表格 + if err := file.WriterFileExecl(headerCells, dataCells, filePath, ""); err != nil { + logger.Errorf("export operate log err => %v", err.Error()) + return "export err" + } + } + + // 上传到FTP服务器 + if err := s.backupService.FTPPushFile(filePath, "log"); err != nil { + return "ok, ftp err:" + err.Error() + } + return "ok" +} + +// exportLogin 导出系统登录日志数据 +func (s BackupExportLogProcessor) exportLogin(hour int, fileType string) string { + // 前 hour 小时 + now := time.Now() + end := time.Date(now.Year(), now.Month(), now.Day(), now.Hour(), 0, 0, 0, now.Location()) + start := end.Add(-time.Duration(hour) * time.Hour) + + language := "en" + query := map[string]any{ + "beginTime": fmt.Sprint(start.UnixMilli()), + "endTime": fmt.Sprint(end.UnixMilli()), + "pageNum": "1", + "pageSize": "30000", + } + data := s.sysLogLoginService.SelectSysLogLoginPage(query, "") + // rows, total + if data == nil || parse.Number(data["total"]) == 0 { + return "no data" + } + rows := data["rows"].([]systemModel.SysLogLogin) + + // 闭包函数处理多语言 + converI18n := func(language string, arr *[]systemModel.SysLogLogin) { + for i := range *arr { + (*arr)[i].LoginLocation = i18n.TKey(language, (*arr)[i].LoginLocation) + (*arr)[i].OS = i18n.TKey(language, (*arr)[i].OS) + (*arr)[i].Browser = i18n.TKey(language, (*arr)[i].Browser) + (*arr)[i].Msg = i18n.TKey(language, (*arr)[i].Msg) + } + } + converI18n(language, &rows) + + // 导出文件名称 + fileName := fmt.Sprintf("sys_log_login_export_%d_%s.%s", len(rows), date.ParseDateToStr(end, date.YYYYMMDDHHMMSS), fileType) + filePath := filepath.Join(s.backupService.BACKUP_DIR, "/log/sys_log_login", fileName) + if runtime.GOOS == "windows" { + filePath = fmt.Sprintf("C:%s", filePath) + } + + if fileType == "csv" { + // 转换数据 + data := [][]string{ + { + i18n.TKey(language, "log.login.export.id"), + i18n.TKey(language, "log.login.export.userName"), + i18n.TKey(language, "log.login.export.ip"), + i18n.TKey(language, "log.login.export.location"), + i18n.TKey(language, "log.login.export.os"), + i18n.TKey(language, "log.login.export.browser"), + i18n.TKey(language, "log.login.export.status"), + i18n.TKey(language, "log.login.export.time"), + i18n.TKey(language, "log.login.export.msg"), + }, + } + for _, row := range rows { + // 状态 + statusValue := i18n.TKey(language, "dictData.fail") + if row.Status == "1" { + statusValue = i18n.TKey(language, "dictData.success") + } + data = append(data, []string{ + fmt.Sprint(row.LoginID), + row.UserName, + row.IPAddr, + row.LoginLocation, + row.OS, + row.Browser, + statusValue, + date.ParseDateToStr(row.LoginTime, date.YYYY_MM_DDTHH_MM_SSZ), + row.Msg, + }) + } + // 输出到文件 + if err := file.WriterFileCSV(data, filePath); err != nil { + logger.Errorf("export login log err => %v", err.Error()) + return "export err" + } + } + + if fileType == "xlsx" { + // 第一行表头标题 + headerCells := map[string]string{ + "A1": i18n.TKey(language, "log.login.export.id"), + "B1": i18n.TKey(language, "log.login.export.userName"), + "C1": i18n.TKey(language, "log.login.export.ip"), + "D1": i18n.TKey(language, "log.login.export.location"), + "E1": i18n.TKey(language, "log.login.export.os"), + "F1": i18n.TKey(language, "log.login.export.browser"), + "G1": i18n.TKey(language, "log.login.export.status"), + "H1": i18n.TKey(language, "log.login.export.time"), + "I1": i18n.TKey(language, "log.login.export.msg"), + } + // 从第二行开始的数据 + dataCells := make([]map[string]any, 0) + for i, row := range rows { + idx := strconv.Itoa(i + 2) + // 状态 + statusValue := i18n.TKey(language, "dictData.fail") + if row.Status == "1" { + statusValue = i18n.TKey(language, "dictData.success") + } + dataCells = append(dataCells, map[string]any{ + "A" + idx: row.LoginID, + "B" + idx: row.UserName, + "C" + idx: row.IPAddr, + "D" + idx: row.LoginLocation, + "E" + idx: row.OS, + "F" + idx: row.Browser, + "G" + idx: statusValue, + "H" + idx: date.ParseDateToStr(row.LoginTime, date.YYYY_MM_DDTHH_MM_SSZ), + "I" + idx: row.Msg, + }) + } + // 导出数据表格 + if err := file.WriterFileExecl(headerCells, dataCells, filePath, ""); err != nil { + logger.Errorf("export login log err => %v", err.Error()) + return "export err" + } + } + + // 上传到FTP服务器 + if err := s.backupService.FTPPushFile(filePath, "log"); err != nil { + return "ok, ftp err:" + err.Error() + } + return "ok" +} diff --git a/src/modules/crontask/processor/backup_export_udm/backup_export_udm.go b/src/modules/crontask/processor/backup_export_udm/backup_export_udm.go new file mode 100644 index 00000000..38970930 --- /dev/null +++ b/src/modules/crontask/processor/backup_export_udm/backup_export_udm.go @@ -0,0 +1,273 @@ +package backup_export_udm + +import ( + "encoding/json" + "fmt" + "path/filepath" + "runtime" + "time" + + "be.ems/src/framework/cron" + "be.ems/src/framework/logger" + "be.ems/src/framework/utils/file" + neDataModel "be.ems/src/modules/network_data/model" + neDataService "be.ems/src/modules/network_data/service" + neModel "be.ems/src/modules/network_element/model" + neService "be.ems/src/modules/network_element/service" +) + +var NewProcessor = &BackupExportUDMProcessor{ + count: 0, + neInfoService: neService.NewNeInfo, + backupService: neDataService.NewBackup, + udmAuthService: neDataService.NewUDMAuthUser, + udmSubService: neDataService.NewUDMSubUser, + udmVOIPService: neDataService.NewUDMVOIPUser, + udmVolteIMSService: neDataService.NewUDMVolteIMSUser, +} + +// BackupExportUDM 队列任务处理 +type BackupExportUDMProcessor struct { + count int // 执行次数 + neInfoService *neService.NeInfo // 网元信息服务 + backupService *neDataService.Backup // 备份相关服务 + udmAuthService *neDataService.UDMAuthUser // UDM鉴权信息服务 + udmSubService *neDataService.UDMSubUser // UDM签约信息服务 + udmVOIPService *neDataService.UDMVOIPUser // UDMVOIP信息服务 + udmVolteIMSService *neDataService.UDMVolteIMSUser // UDMVolteIMS信息服务 +} + +func (s *BackupExportUDMProcessor) Execute(data any) (any, error) { + s.count++ // 执行次数加一 + options := data.(cron.JobData) + sysJob := options.SysJob + logger.Infof("重复:%v 任务ID:%s 执行次数:%d", options.Repeat, sysJob.JobID, s.count) + // 返回结果,用于记录执行结果 + result := map[string]any{ + "count": s.count, + } + + var params struct { + DataType []string `json:"dataType"` // 类型支持 auth/sub/voip/volte + FileType string `json:"fileType"` // 文件类型 csv/txt + } + if err := json.Unmarshal([]byte(sysJob.TargetParams), ¶ms); err != nil { + return nil, err + } + if !(params.FileType == "csv" || params.FileType == "txt") { + return nil, fmt.Errorf("file type error, only support csv,txt") + } + + neList := s.neInfoService.SelectList(neModel.NeInfo{NeType: "UDM"}, false, false) + for _, neInfo := range neList { + for _, v := range params.DataType { + switch v { + case "auth": + result[fmt.Sprintf("%s-%s", neInfo.NeId, v)] = s.exportAuth(neInfo.NeId, params.FileType) + case "sub": + result[fmt.Sprintf("%s-%s", neInfo.NeId, v)] = s.exportSub(neInfo.NeId, params.FileType) + case "voip": + result[fmt.Sprintf("%s-%s", neInfo.NeId, v)] = s.exportVOIP(neInfo.NeId, params.FileType) + case "volte": + result[fmt.Sprintf("%s-%s", neInfo.NeId, v)] = s.exportVolte(neInfo.NeId, params.FileType) + } + } + } + + // 返回结果,用于记录执行结果 + return result, nil +} + +// exportAuth 导出鉴权用户数据 +func (s BackupExportUDMProcessor) exportAuth(neId, fileType string) string { + rows := s.udmAuthService.SelectList(neDataModel.UDMAuthUser{NeId: neId}) + if len(rows) <= 0 { + return "no data" + } + + // 文件名 + fileName := fmt.Sprintf("auth_%s_export_%s.%s", neId, time.Now().Format("20060102150405"), fileType) + filePath := filepath.Join("/usr/local/omc/backup/udm_data/auth", fileName) + if runtime.GOOS == "windows" { + filePath = fmt.Sprintf("C:%s", filePath) + } + + if fileType == "csv" { + // 转换数据 + data := [][]string{} + data = append(data, []string{"imsi", "ki", "algo", "amf", "opc"}) + for _, v := range rows { + opc := v.Opc + if opc == "-" { + opc = "" + } + data = append(data, []string{v.IMSI, v.Ki, v.AlgoIndex, v.Amf, opc}) + } + // 输出到文件 + if err := file.WriterFileCSV(data, filePath); err != nil { + return err.Error() + } + } + + if fileType == "txt" { + // 转换数据 + data := [][]string{} + for _, v := range rows { + opc := v.Opc + if opc == "-" { + opc = "" + } + data = append(data, []string{v.IMSI, v.Ki, v.AlgoIndex, v.Amf, opc}) + } + // 输出到文件 + if err := file.WriterFileTXT(data, ",", filePath); err != nil { + return err.Error() + } + } + + // 上传到FTP服务器 + if err := s.backupService.FTPPushFile(filePath, "udm_data"); err != nil { + return "ok, ftp err:" + err.Error() + } + return "ok" +} + +// exportSub 导出签约用户数据 +func (s BackupExportUDMProcessor) exportSub(neId, fileType string) string { + rows := s.udmSubService.SelectList(neDataModel.UDMSubUser{NeId: neId}) + if len(rows) <= 0 { + return "no data" + } + + // 文件名 + fileName := fmt.Sprintf("sub_%s_export_%s.%s", neId, time.Now().Format("20060102150405"), fileType) + filePath := filepath.Join("/usr/local/omc/backup/udm_data/sub", fileName) + if runtime.GOOS == "windows" { + filePath = fmt.Sprintf("C:%s", filePath) + } + + if fileType == "csv" { + // 转换数据 + data := [][]string{} + data = append(data, []string{"IMSI", "MSISDN", "UeAmbrTpl", "NssaiTpl", "AreaForbiddenTpl", "ServiceAreaRestrictionTpl", "RatRestrictions", "CnTypeRestrictions", "SmfSel", "SmData", "EPSDat"}) + for _, v := range rows { + epsDat := fmt.Sprintf("%s,%s,%s,%s,%s,%s,%s,%s", v.EpsFlag, v.EpsOdb, v.HplmnOdb, v.Ard, v.Epstpl, v.ContextId, v.ApnContext, v.StaticIp) + data = append(data, []string{v.IMSI, v.MSISDN, v.UeAmbrTpl, v.NssaiTpl, v.AreaForbiddenTpl, v.ServiceAreaRestrictionTpl, v.RatRestrictions, v.CnTypeRestrictions, v.SmfSel, v.SmData, epsDat}) + } + // 输出到文件 + if err := file.WriterFileCSV(data, filePath); err != nil { + return err.Error() + } + } + + if fileType == "txt" { + // 转换数据 + data := [][]string{} + for _, v := range rows { + epsDat := fmt.Sprintf("%s,%s,%s,%s,%s,%s,%s,%s", v.EpsFlag, v.EpsOdb, v.HplmnOdb, v.Ard, v.Epstpl, v.ContextId, v.ApnContext, v.StaticIp) + data = append(data, []string{v.IMSI, v.MSISDN, v.UeAmbrTpl, v.NssaiTpl, v.AreaForbiddenTpl, v.ServiceAreaRestrictionTpl, v.RatRestrictions, v.CnTypeRestrictions, v.SmfSel, v.SmData, epsDat}) + } + // 输出到文件 + if err := file.WriterFileTXT(data, ",", filePath); err != nil { + return err.Error() + } + } + + // 上传到FTP服务器 + if err := s.backupService.FTPPushFile(filePath, "udm_data"); err != nil { + return "ok, ftp err:" + err.Error() + } + return "ok" +} + +// exportVOIP 导出VOIP用户数据 +func (s BackupExportUDMProcessor) exportVOIP(neId, fileType string) string { + rows := s.udmVOIPService.Find(neDataModel.UDMVOIPUser{NeId: neId}) + if len(rows) <= 0 { + return "no data" + } + + // 文件名 + fileName := fmt.Sprintf("voip_%s_export_%s.%s", neId, time.Now().Format("20060102150405"), fileType) + filePath := filepath.Join("/usr/local/omc/backup/udm_data/voip", fileName) + if runtime.GOOS == "windows" { + filePath = fmt.Sprintf("C:%s", filePath) + } + + if fileType == "csv" { + // 转换数据 + data := [][]string{} + data = append(data, []string{"username", "password"}) + for _, v := range rows { + data = append(data, []string{v.UserName, v.Password}) + } + // 输出到文件 + if err := file.WriterFileCSV(data, filePath); err != nil { + return err.Error() + } + } + + if fileType == "txt" { + // 转换数据 + data := [][]string{} + for _, v := range rows { + data = append(data, []string{v.UserName, v.Password}) + } + // 输出到文件 + if err := file.WriterFileTXT(data, ",", filePath); err != nil { + return err.Error() + } + } + + // 上传到FTP服务器 + if err := s.backupService.FTPPushFile(filePath, "udm_data"); err != nil { + return "ok, ftp err:" + err.Error() + } + return "ok" +} + +// exportVolte 导出Volte用户数据 +func (s BackupExportUDMProcessor) exportVolte(neId, fileType string) string { + rows := s.udmVolteIMSService.Find(neDataModel.UDMVolteIMSUser{NeId: neId}) + if len(rows) <= 0 { + return "no data" + } + + // 文件名 + fileName := fmt.Sprintf("volte_%s_export_%s.%s", neId, time.Now().Format("20060102150405"), fileType) + filePath := filepath.Join("/usr/local/omc/backup/udm_data/volte", fileName) + if runtime.GOOS == "windows" { + filePath = fmt.Sprintf("C:%s", filePath) + } + + if fileType == "csv" { + // 转换数据 + data := [][]string{} + data = append(data, []string{"IMSI", "MSISDN", "TAG", "VNI"}) + for _, v := range rows { + data = append(data, []string{v.IMSI, v.MSISDN, v.Tag, v.VNI}) + } + // 输出到文件 + if err := file.WriterFileCSV(data, filePath); err != nil { + return err.Error() + } + } + + if fileType == "txt" { + // 转换数据 + data := [][]string{} + for _, v := range rows { + data = append(data, []string{v.IMSI, v.MSISDN, v.Tag, v.VNI}) + } + // 输出到文件 + if err := file.WriterFileTXT(data, ",", filePath); err != nil { + return err.Error() + } + } + + // 上传到FTP服务器 + if err := s.backupService.FTPPushFile(filePath, "udm_data"); err != nil { + return "ok, ftp err:" + err.Error() + } + return "ok" +} diff --git a/src/modules/crontask/processor/backup_remove_file/backup_remove_file.go b/src/modules/crontask/processor/backup_remove_file/backup_remove_file.go new file mode 100644 index 00000000..d969eaad --- /dev/null +++ b/src/modules/crontask/processor/backup_remove_file/backup_remove_file.go @@ -0,0 +1,113 @@ +package backup_remove_file + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" + "runtime" + "sort" + "strings" + "time" + + "be.ems/src/framework/cron" + "be.ems/src/framework/logger" +) + +type FileInfo struct { + Path string + Info os.FileInfo +} + +var NewProcessor = &BackupRemoveFileProcessor{ + count: 0, +} + +// BackupRemoveFileProcessor 删除备份文件 +type BackupRemoveFileProcessor struct { + count int // 执行次数 +} + +func (s *BackupRemoveFileProcessor) Execute(data any) (any, error) { + s.count++ // 执行次数加一 + options := data.(cron.JobData) + sysJob := options.SysJob + logger.Infof("重复:%v 任务ID:%s 执行次数:%d", options.Repeat, sysJob.JobID, s.count) + // 返回结果,用于记录执行结果 + result := map[string]any{ + "count": s.count, + } + + // 读取参数值 + var params []struct { + BackupPath string `json:"backupPath"` // 备份路径 /usr/local/omc/backup/{backupPath} + StoreDays int `json:"storeDays"` // 保留天数 + StoreNum int `json:"storeNum"` // 保留数量,默认保留7 + } + err := json.Unmarshal([]byte(sysJob.TargetParams), ¶ms) + if err != nil { + return nil, fmt.Errorf("json params err: %v", err) + } + + for _, item := range params { + result[item.BackupPath] = "" + if item.StoreDays < 0 { + result[item.BackupPath] = "params storeDays less than 0" + continue + } + if item.StoreNum <= 0 { + item.StoreNum = 7 + } + + // 构建完整备份路径 + filePath := filepath.Join("/usr/local/omc/backup", item.BackupPath) + if runtime.GOOS == "windows" { + filePath = fmt.Sprintf("C:%s", filePath) + } + // 获取目录下所有备份文件 + files, err := s.files(filePath) + if err != nil { + result[item.BackupPath] = "read files err" + continue + } + // 按修改时间排序(从旧到新) + sort.Slice(files, func(i, j int) bool { + return files[i].Info.ModTime().Before(files[j].Info.ModTime()) + }) + + // 如果文件数量少于保留数量,则不删除 + if len(files) <= item.StoreNum { + result[item.BackupPath] = fmt.Sprintf("less StoreNum: %d, file number %d", item.StoreNum, len(files)) + continue + } + // 计算截止日期 + cutoff := time.Now().AddDate(0, 0, -item.StoreDays) + // 删除超过保留天数的文件 + deletedErr := []string{} + for _, file := range files { + if file.Info.ModTime().Before(cutoff) { + if err := os.Remove(file.Path); err != nil { + deletedErr = append(deletedErr, file.Info.Name()) // 记录删除失败的文件名称 + } + } + } + result[item.BackupPath] = strings.Join(deletedErr, ", ") + } + + // 返回结果,用于记录执行结果 + return result, nil +} + +func (s *BackupRemoveFileProcessor) files(dir string) ([]FileInfo, error) { + var files []FileInfo + err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if !info.IsDir() { + files = append(files, FileInfo{Path: path, Info: info}) + } + return nil + }) + return files, err +} diff --git a/src/modules/crontask/processor/ne_alarm_state_check/ne_alarm_state_check.go b/src/modules/crontask/processor/ne_alarm_state_check/ne_alarm_state_check.go new file mode 100644 index 00000000..2fe8583f --- /dev/null +++ b/src/modules/crontask/processor/ne_alarm_state_check/ne_alarm_state_check.go @@ -0,0 +1,172 @@ +package ne_alarm_state_check + +import ( + "encoding/json" + "fmt" + "time" + + "be.ems/src/framework/constants" + "be.ems/src/framework/cron" + "be.ems/src/framework/logger" + "be.ems/src/framework/utils/parse" + + neDataModel "be.ems/src/modules/network_data/model" + neDataService "be.ems/src/modules/network_data/service" + neModel "be.ems/src/modules/network_element/model" + neService "be.ems/src/modules/network_element/service" + wsService "be.ems/src/modules/ws/service" +) + +var NewProcessor = &NeAlarmStateCheckProcessor{ + neConfigBackupService: neService.NewNeConfigBackup, + neInfoService: neService.NewNeInfo, + alarmService: neDataService.NewAlarm, + wsSendService: wsService.NewWSSend, + count: 0, +} + +// NeAlarmStateCheckProcessor 网元告警状态检查 +type NeAlarmStateCheckProcessor struct { + neConfigBackupService *neService.NeConfigBackup // 网元配置文件备份记录服务 + neInfoService *neService.NeInfo // 网元信息服务 + alarmService *neDataService.Alarm // 告警信息服务 + wsSendService *wsService.WSSend // ws发送服务 + count int // 执行次数 +} + +// alarmParams 告警参数 +type alarmParams struct { + AlarmTitle string `json:"alarmTitle"` // NE State Check Alarm + AlarmType string `json:"alarmType"` // EquipmentAlarm=2 + OrigSeverity string `json:"origSeverity"` // Major=2 + SpecificProblem string `json:"specificProblem"` // alarm cause: the system state of target NE has not been received + SpecificProblemID string `json:"specificProblemId"` // AC10000 + AddInfo string `json:"addInfo"` + + // === 非参数字段 === + AlarmId string // 告警ID +} + +func (s *NeAlarmStateCheckProcessor) Execute(data any) (any, error) { + s.count++ // 执行次数加一 + options := data.(cron.JobData) + sysJob := options.SysJob + logger.Infof("重复:%v 任务ID:%s 执行次数:%d", options.Repeat, sysJob.JobID, s.count) + // 返回结果,用于记录执行结果 + result := map[string]any{ + "count": s.count, + } + + // 读取参数值 + var params alarmParams + err := json.Unmarshal([]byte(sysJob.TargetParams), ¶ms) + if err != nil { + return nil, fmt.Errorf("json params err: %v", err) + } + + neList := s.neInfoService.SelectList(neModel.NeInfo{}, true, false) + for _, neInfo := range neList { + if neInfo.CreateTime == 0 { + continue + } + neTypeAndId := fmt.Sprintf("%s_%s", neInfo.NeType, neInfo.NeId) + // 网元在线状态 + isOnline := parse.Boolean(neInfo.ServerState["online"]) + // 告警ID + params.AlarmId = fmt.Sprintf("%d%d", constants.ALARM_STATE_CHECK, neInfo.CreateTime) + // 检查网元告警ID是否唯一 + alarmIdArr := s.alarmService.Find(neDataModel.Alarm{ + NeType: neInfo.NeType, + NeId: neInfo.NeId, + AlarmId: params.AlarmId, + }) + // 告警状态 + alarmStatus := "" + if len(alarmIdArr) > 0 { + alarmStatus = fmt.Sprint(alarmIdArr[0].AlarmStatus) + } + // 在线且状态为活动告警 + if isOnline && alarmStatus == "1" { + // 进行清除 + clearAlarm, err := s.alarmClear(neInfo, alarmIdArr[0]) + if err != nil { + result[neTypeAndId] = err.Error() + continue + } + groupID := fmt.Sprintf("%s_%s_%s", wsService.GROUP_ALARM, neInfo.NeType, neInfo.NeId) + s.wsSendService.ByGroupID(groupID, clearAlarm) + result[neTypeAndId] = "alarm clear" + } + + // 不在线 + if !isOnline && alarmStatus == "" { + // 进行新增 + newAlarm, err := s.alarmNew(neInfo, params) + if err != nil { + result[neTypeAndId] = err.Error() + continue + } + groupID := fmt.Sprintf("%s_%s_%s", wsService.GROUP_ALARM, neInfo.NeType, neInfo.NeId) + s.wsSendService.ByGroupID(groupID, newAlarm) + result[neTypeAndId] = "alarm new" + } + } + + // 返回结果,用于记录执行结果 + return result, nil +} + +// alarmClear 清除告警 +func (s NeAlarmStateCheckProcessor) alarmClear(neInfo neModel.NeInfo, v neDataModel.Alarm) (neDataModel.Alarm, error) { + // 变更告警ID为告警清除ID + v.AlarmId = fmt.Sprintf("%s%d", v.AlarmCode, v.EventTime.UnixMilli()) + v.AlarmStatus = "0" + // 告警清除 + v.ClearType = "1" + v.ClearTime = time.Unix(neInfo.UpdateTime, 0) + v.ClearUser = "system" + rows := s.alarmService.Update(v) + if rows > 0 { + return v, nil + } + return neDataModel.Alarm{}, fmt.Errorf("clear alarm fail") +} + +// alarmNew 新增告警 +func (s NeAlarmStateCheckProcessor) alarmNew(neInfo neModel.NeInfo, v alarmParams) (neDataModel.Alarm, error) { + // seq 告警序号 + lastSeq := s.alarmService.FindAlarmSeqLast(neInfo.NeType, neInfo.NeId) + lastTime := neInfo.UpdateTime // 网元最后更新时间 + if lastTime < neInfo.CreateTime { + lastTime = time.Now().UnixMilli() + } + alarm := neDataModel.Alarm{ + NeType: neInfo.NeType, + NeId: neInfo.NeId, + NeName: neInfo.NeName, + Province: neInfo.Province, + PvFlag: neInfo.PvFlag, + AlarmSeq: fmt.Sprint(lastSeq + 1), + AlarmId: v.AlarmId, + AlarmTitle: v.AlarmTitle, + AlarmCode: fmt.Sprint(constants.ALARM_STATE_CHECK), + EventTime: time.Unix(lastTime, 0), + AlarmType: v.AlarmType, + OrigSeverity: v.OrigSeverity, + PerceivedSeverity: v.OrigSeverity, + ObjectUid: neInfo.RmUID, + ObjectName: "NE State", + ObjectType: "state", + LocationInfo: "NE State: Heartbeat", + AlarmStatus: "1", // 活动告警 + SpecificProblem: v.SpecificProblem, + SpecificProblemId: v.SpecificProblemID, + AddInfo: v.AddInfo, + } + insertId := s.alarmService.InsertAndForword(alarm) + if insertId != "" { + alarm.ID = insertId + return alarm, nil + } + return neDataModel.Alarm{}, fmt.Errorf("new alarm fail") +} diff --git a/src/modules/crontask/processor/ne_alarm_state_check_cmd/ne_alarm_state_check_cmd.go b/src/modules/crontask/processor/ne_alarm_state_check_cmd/ne_alarm_state_check_cmd.go new file mode 100644 index 00000000..a9fdcfdd --- /dev/null +++ b/src/modules/crontask/processor/ne_alarm_state_check_cmd/ne_alarm_state_check_cmd.go @@ -0,0 +1,288 @@ +package ne_alarm_state_check_cmd + +import ( + "encoding/json" + "fmt" + "sort" + "strconv" + "strings" + "time" + + "be.ems/src/framework/constants" + "be.ems/src/framework/cron" + "be.ems/src/framework/logger" + "be.ems/src/framework/utils/parse" + neDataModel "be.ems/src/modules/network_data/model" + neDataService "be.ems/src/modules/network_data/service" + neModel "be.ems/src/modules/network_element/model" + neService "be.ems/src/modules/network_element/service" + wsService "be.ems/src/modules/ws/service" +) + +var NewProcessor = &NeAlarmStateCheckCMDProcessor{ + neConfigBackupService: neService.NewNeConfigBackup, + neInfoService: neService.NewNeInfo, + neStateService: neDataService.NewNEState, + alarmService: neDataService.NewAlarm, + wsSendService: wsService.NewWSSend, + count: 0, +} + +// NeAlarmStateCheckCMDProcessor 网元告警内存/CPU/磁盘检查 +type NeAlarmStateCheckCMDProcessor struct { + neConfigBackupService *neService.NeConfigBackup // 网元配置文件备份记录服务 + neInfoService *neService.NeInfo // 网元信息服务 + neStateService *neDataService.NEState // 网元状态信息服务 + alarmService *neDataService.Alarm // 告警信息服务 + wsSendService *wsService.WSSend // ws发送服务 + count int // 执行次数 + +} + +// alarmParams 告警参数 +type alarmParams struct { + AlarmTitle string `json:"alarmTitle"` // NE State Check Alarm CPU/Menory/Disk + AlarmType string `json:"alarmType"` // EquipmentAlarm=2 + OrigSeverity string `json:"origSeverity"` // Major=2 + SpecificProblem string `json:"specificProblem"` // Alarm Cause: CPU/Menory/Disk status received from target NE reaches the threshold + SpecificProblemID string `json:"specificProblemId"` // AC10100 + AddInfo string `json:"addInfo"` // 告警补充信息 + CPUUseGt int64 `json:"cpuUseGt"` // CPU使用率大于, 范围0~100% + MemUseGt int64 `json:"memUseGt"` // 内存使用率大于, 范围0~100% + DiskUseGt int64 `json:"diskUseGt"` // 磁盘使用率大于, 范围0~100% + + // === 非参数字段 === + AlarmId string // 告警ID +} + +func (s *NeAlarmStateCheckCMDProcessor) Execute(data any) (any, error) { + s.count++ // 执行次数加一 + options := data.(cron.JobData) + sysJob := options.SysJob + logger.Infof("重复:%v 任务ID:%s 执行次数:%d", options.Repeat, sysJob.JobID, s.count) + // 返回结果,用于记录执行结果 + result := map[string]any{ + "count": s.count, + } + + // 读取参数值 + var params alarmParams + err := json.Unmarshal([]byte(sysJob.TargetParams), ¶ms) + if err != nil { + return nil, fmt.Errorf("json params err: %v", err) + } + // 检查使用率 + if params.CPUUseGt > 100 || params.CPUUseGt < 0 { + return nil, fmt.Errorf("cpuUseGt must be between 0 and 100") + } + if params.MemUseGt > 100 || params.MemUseGt < 0 { + return nil, fmt.Errorf("memUseGt must be between 0 and 100") + } + if params.DiskUseGt > 100 || params.DiskUseGt < 0 { + return nil, fmt.Errorf("diskUseGt must be between 0 and 100") + } + + neList := s.neInfoService.SelectList(neModel.NeInfo{}, true, false) + for _, neInfo := range neList { + if neInfo.CreateTime == 0 { + continue + } + + // 网元在线状态 + isOnline := parse.Boolean(neInfo.ServerState["online"]) + if !isOnline { + continue + } + + // 检查状态 + err := s.serverState(neInfo.ServerState, params.CPUUseGt, params.MemUseGt, params.DiskUseGt) + if err == nil { + continue + } + + neTypeAndId := fmt.Sprintf("%s_%s", neInfo.NeType, neInfo.NeId) + // 告警ID + params.AlarmId = fmt.Sprintf("%d%d", constants.ALARM_CMD_CHECK, neInfo.CreateTime) + // 检查网元告警ID是否唯一 + alarmIdArr := s.alarmService.Find(neDataModel.Alarm{ + NeType: neInfo.NeType, + NeId: neInfo.NeId, + AlarmId: params.AlarmId, + }) + // 告警状态, 存在的需要手动清除 + alarmStatus := "" + if len(alarmIdArr) > 0 { + alarmStatus = fmt.Sprint(alarmIdArr[0].AlarmStatus) + } + // 活动告警进行清除 + if alarmStatus == "1" { + clearAlarm, err := s.alarmClear(neInfo, alarmIdArr[0]) + if err != nil { + result[neTypeAndId] = err.Error() + continue + } + groupID := fmt.Sprintf("%s_%s_%s", wsService.GROUP_ALARM, neInfo.NeType, neInfo.NeId) + s.wsSendService.ByGroupID(groupID, clearAlarm) + result[neTypeAndId] = "alarm clear" + alarmStatus = "" // 标记为未记录再次发起新告警 + } + // 未记录 + if alarmStatus == "" { + addInfo := params.AddInfo + if params.AddInfo != "" { + params.AddInfo = params.AddInfo + ", " + err.Error() + } else { + params.AddInfo = err.Error() + } + // 进行新增 + newAlarm, err := s.alarmNew(neInfo, params) + params.AddInfo = addInfo // 恢复附加信息 + if err != nil { + result[neTypeAndId] = err.Error() + continue + } + groupID := fmt.Sprintf("%s_%s_%s", wsService.GROUP_ALARM, neInfo.NeType, neInfo.NeId) + s.wsSendService.ByGroupID(groupID, newAlarm) + result[neTypeAndId] = "alarm new" + } + } + + // 返回结果,用于记录执行结果 + return result, nil +} + +// serverState 网元状态 +func (s NeAlarmStateCheckCMDProcessor) serverState(state map[string]any, cpuUseGt, memUseGt, diskUseGt int64) error { + // 网元CPU使用率 + var nfCpuUsage float64 = 0 + // CPU使用率 + var sysCpuUsage float64 = 0 + if state["cpu"] != nil { + cpu := state["cpu"].(map[string]any) + v := parse.Number(cpu["sysCpuUsage"]) + sysCpuUsage = float64(v) / 100 + nfv := parse.Number(cpu["nfCpuUsage"]) + nfCpuUsage = float64(nfv) / 100 + } + + // 网元内存使用KB + var nfMemUsed int64 = 0 + // 内存使用率 + var sysMemUsage float64 = 0 + if state["mem"] != nil { + mem := state["mem"].(map[string]any) + v := parse.Number(mem["sysMemUsage"]) + sysMemUsage = float64(v) / 100 + nfMemUsed = parse.Number(mem["nfUsedMem"]) + } + + // 磁盘使用率 + var sysDiskUsage float64 = 0 + if state["disk"] != nil { + mem := state["disk"].(map[string]any) + disks := mem["partitionInfo"].([]any) + sort.Slice(disks, func(i, j int) bool { + iUsed := parse.Number(disks[i].(map[string]any)["used"]) + jUsed := parse.Number(disks[j].(map[string]any)["used"]) + return iUsed > jUsed + }) + disk := disks[0].(map[string]any) + total := parse.Number(disk["total"]) + used := parse.Number(disk["used"]) + sysDiskUsage = (float64(used) / float64(total)) * 100 + sysDiskUsage, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", sysDiskUsage), 64) + } + + // 插入网元状态记录 + neState := neDataModel.NEState{ + NeType: fmt.Sprint(state["neType"]), + NeId: fmt.Sprint(state["neId"]), + Version: fmt.Sprint(state["version"]), + Capability: parse.Number(state["capability"]), + SerialNum: fmt.Sprint(state["sn"]), + ExpiryDate: fmt.Sprint(state["expire"]), + SysCpuUsage: sysCpuUsage, + SysMemUsage: sysMemUsage, + SysDiskUsage: sysDiskUsage, + NfCpuUsage: nfCpuUsage, + NfMemUsed: nfMemUsed, + CreateTime: parse.Number(state["refreshTime"]), + } + s.neStateService.Insert(neState) + // 删除网元状态记录7天前 + s.neStateService.DeleteByTime(time.Now().UnixMilli() - 7*24*60*60*1000) + // 推送ws消息 + groupID := fmt.Sprintf("%s_%s_%s", wsService.GROUP_NE_STATE, neState.NeType, neState.NeId) + s.wsSendService.ByGroupID(groupID, neState) + + // 检查CPU/Menory/Disk使用率 + warnMsg := []string{} + if int64(sysCpuUsage) >= cpuUseGt { + warnMsg = append(warnMsg, fmt.Sprintf("cpu usage %.2f%%", sysCpuUsage)) + } + if int64(sysMemUsage) >= memUseGt { + warnMsg = append(warnMsg, fmt.Sprintf("memory usage %.2f%%", sysMemUsage)) + } + if int64(sysDiskUsage) >= diskUseGt { + warnMsg = append(warnMsg, fmt.Sprintf("disk usage %.2f%%", sysDiskUsage)) + } + if len(warnMsg) > 0 { + return fmt.Errorf("greater than %s", strings.Join(warnMsg, ", ")) + } + return nil +} + +// alarmClear 清除告警 +func (s NeAlarmStateCheckCMDProcessor) alarmClear(neInfo neModel.NeInfo, v neDataModel.Alarm) (neDataModel.Alarm, error) { + // 变更告警ID为告警清除ID + v.AlarmId = fmt.Sprintf("%s%d", v.AlarmCode, v.EventTime.UnixMilli()) + v.AlarmStatus = "0" + // 告警清除 + v.ClearType = "1" + v.ClearTime = time.Unix(neInfo.UpdateTime, 0) + v.ClearUser = "system" + rows := s.alarmService.Update(v) + if rows > 0 { + return v, nil + } + return neDataModel.Alarm{}, fmt.Errorf("clear alarm fail") +} + +// alarmNew 新增告警 +func (s NeAlarmStateCheckCMDProcessor) alarmNew(neInfo neModel.NeInfo, v alarmParams) (neDataModel.Alarm, error) { + // seq 告警序号 + lastSeq := s.alarmService.FindAlarmSeqLast(neInfo.NeType, neInfo.NeId) + lastTime := neInfo.UpdateTime // 网元最后更新时间 + if lastTime < neInfo.CreateTime { + lastTime = time.Now().UnixMilli() + } + alarm := neDataModel.Alarm{ + NeType: neInfo.NeType, + NeId: neInfo.NeId, + NeName: neInfo.NeName, + Province: neInfo.Province, + PvFlag: neInfo.PvFlag, + AlarmSeq: fmt.Sprint(lastSeq + 1), + AlarmId: v.AlarmId, + AlarmTitle: v.AlarmTitle, + AlarmCode: fmt.Sprint(constants.ALARM_CMD_CHECK), + EventTime: time.Unix(lastTime, 0), + AlarmType: v.AlarmType, + OrigSeverity: v.OrigSeverity, + PerceivedSeverity: v.OrigSeverity, + ObjectUid: neInfo.RmUID, + ObjectName: "NE CPU/Menory/Disk", + ObjectType: "cmd", + LocationInfo: "NE CPU/Menory/Disk: Heartbeat", + AlarmStatus: "1", // 活动告警 + SpecificProblem: v.SpecificProblem, + SpecificProblemId: v.SpecificProblemID, + AddInfo: v.AddInfo, + } + insertId := s.alarmService.InsertAndForword(alarm) + if insertId != "" { + alarm.ID = insertId + return alarm, nil + } + return neDataModel.Alarm{}, fmt.Errorf("new alarm fail") +} diff --git a/src/modules/crontask/processor/ne_alarm_state_check_license/ne_alarm_state_check_license.go b/src/modules/crontask/processor/ne_alarm_state_check_license/ne_alarm_state_check_license.go new file mode 100644 index 00000000..6438bf4a --- /dev/null +++ b/src/modules/crontask/processor/ne_alarm_state_check_license/ne_alarm_state_check_license.go @@ -0,0 +1,213 @@ +package ne_alarm_state_check_license + +import ( + "encoding/json" + "fmt" + "time" + + "be.ems/src/framework/constants" + "be.ems/src/framework/cron" + "be.ems/src/framework/logger" + "be.ems/src/framework/utils/parse" + + neDataModel "be.ems/src/modules/network_data/model" + neDataService "be.ems/src/modules/network_data/service" + neModel "be.ems/src/modules/network_element/model" + neService "be.ems/src/modules/network_element/service" + wsService "be.ems/src/modules/ws/service" +) + +var NewProcessor = &NeAlarmStateCheckLicenseProcessor{ + neConfigBackupService: neService.NewNeConfigBackup, + neInfoService: neService.NewNeInfo, + alarmService: neDataService.NewAlarm, + wsSendService: wsService.NewWSSend, + count: 0, +} + +// NeAlarmStateCheckLicenseProcessor 网元告警License到期检查 +type NeAlarmStateCheckLicenseProcessor struct { + neConfigBackupService *neService.NeConfigBackup // 网元配置文件备份记录服务 + neInfoService *neService.NeInfo // 网元信息服务 + alarmService *neDataService.Alarm // 告警信息服务 + wsSendService *wsService.WSSend // ws发送服务 + count int // 执行次数 +} + +// alarmParams 告警参数 +type alarmParams struct { + AlarmTitle string `json:"alarmTitle"` // NE State Check Alarm License + AlarmType string `json:"alarmType"` // EquipmentAlarm=2 + OrigSeverity string `json:"origSeverity"` // Major=2 + SpecificProblem string `json:"specificProblem"` // Alarm Cause: License received from target NE is about to expire + SpecificProblemID string `json:"specificProblemId"` // AC10200 + AddInfo string `json:"addInfo"` // 告警补充信息 + DayLt int64 `json:"dayLt"` // 天数小于,默认30天 + + // === 非参数字段 === + AlarmId string // 告警ID +} + +func (s *NeAlarmStateCheckLicenseProcessor) Execute(data any) (any, error) { + s.count++ // 执行次数加一 + options := data.(cron.JobData) + sysJob := options.SysJob + logger.Infof("重复:%v 任务ID:%s 执行次数:%d", options.Repeat, sysJob.JobID, s.count) + // 返回结果,用于记录执行结果 + result := map[string]any{ + "count": s.count, + } + + // 读取参数值 + var params alarmParams + err := json.Unmarshal([]byte(sysJob.TargetParams), ¶ms) + if err != nil { + return nil, fmt.Errorf("json params err: %v", err) + } + // 检查参数值 + if params.DayLt == 0 { + params.DayLt = 30 + } + + neList := s.neInfoService.SelectList(neModel.NeInfo{}, true, false) + for _, neInfo := range neList { + if neInfo.CreateTime == 0 { + continue + } + + // 网元在线状态 + isOnline := parse.Boolean(neInfo.ServerState["online"]) + if !isOnline { + continue + } + + // 检查状态 + err := s.serverState(neInfo.ServerState, params.DayLt) + if err == nil { + continue + } + if params.AddInfo != "" { + params.AddInfo = params.AddInfo + ", " + err.Error() + } else { + params.AddInfo = err.Error() + } + + neTypeAndId := fmt.Sprintf("%s_%s", neInfo.NeType, neInfo.NeId) + // 告警ID + params.AlarmId = fmt.Sprintf("%d%d", constants.ALARM_LICENSE_CHECK, neInfo.CreateTime) + // 检查网元告警ID是否唯一 + alarmIdArr := s.alarmService.Find(neDataModel.Alarm{ + NeType: neInfo.NeType, + NeId: neInfo.NeId, + AlarmId: params.AlarmId, + }) + // 告警状态, 存在的需要手动清除 + alarmStatus := "" + if len(alarmIdArr) > 0 { + alarmStatus = fmt.Sprint(alarmIdArr[0].AlarmStatus) + } + // 活动告警进行清除 + if alarmStatus == "1" { + clearAlarm, err := s.alarmClear(neInfo, alarmIdArr[0]) + if err != nil { + result[neTypeAndId] = err.Error() + continue + } + groupID := fmt.Sprintf("%s_%s_%s", wsService.GROUP_ALARM, neInfo.NeType, neInfo.NeId) + s.wsSendService.ByGroupID(groupID, clearAlarm) + result[neTypeAndId] = "alarm clear" + alarmStatus = "" // 标记为未记录再次发起新告警 + } + // 未记录 + if alarmStatus == "" { + // 进行新增 + newAlarm, err := s.alarmNew(neInfo, params) + if err != nil { + result[neTypeAndId] = err.Error() + continue + } + groupID := fmt.Sprintf("%s_%s_%s", wsService.GROUP_ALARM, neInfo.NeType, neInfo.NeId) + s.wsSendService.ByGroupID(groupID, newAlarm) + result[neTypeAndId] = "alarm new" + } + } + + // 返回结果,用于记录执行结果 + return result, nil +} + +// serverState 网元状态 +func (s NeAlarmStateCheckLicenseProcessor) serverState(state map[string]any, dayLt int64) error { + expire := fmt.Sprint(state["expire"]) + if expire == "" || expire == "" || expire == "2099-12-31" { + return nil + } + + // 解析过期时间 + expireTime, err := time.Parse("2006-01-02", expire) + if err != nil { + return fmt.Errorf("parse expire time error: %v", err) + } + + // 计算距离天数 + daysLeft := int64(time.Since(expireTime).Hours() / 24) + if daysLeft < dayLt { + return fmt.Errorf("license will expire in %d days", daysLeft) + } + return nil +} + +// alarmClear 清除告警 +func (s NeAlarmStateCheckLicenseProcessor) alarmClear(neInfo neModel.NeInfo, v neDataModel.Alarm) (neDataModel.Alarm, error) { + // 变更告警ID为告警清除ID + v.AlarmId = fmt.Sprintf("%s%d", v.AlarmCode, v.EventTime.UnixMilli()) + v.AlarmStatus = "0" + // 告警清除 + v.ClearType = "1" + v.ClearTime = time.Unix(neInfo.UpdateTime, 0) + v.ClearUser = "system" + rows := s.alarmService.Update(v) + if rows > 0 { + return v, nil + } + return neDataModel.Alarm{}, fmt.Errorf("clear alarm fail") +} + +// alarmNew 新增告警 +func (s NeAlarmStateCheckLicenseProcessor) alarmNew(neInfo neModel.NeInfo, v alarmParams) (neDataModel.Alarm, error) { + // seq 告警序号 + lastSeq := s.alarmService.FindAlarmSeqLast(neInfo.NeType, neInfo.NeId) + lastTime := neInfo.UpdateTime // 网元最后更新时间 + if lastTime < neInfo.CreateTime { + lastTime = time.Now().UnixMilli() + } + alarm := neDataModel.Alarm{ + NeType: neInfo.NeType, + NeId: neInfo.NeId, + NeName: neInfo.NeName, + Province: neInfo.Province, + PvFlag: neInfo.PvFlag, + AlarmSeq: fmt.Sprint(lastSeq + 1), + AlarmId: v.AlarmId, + AlarmTitle: v.AlarmTitle, + AlarmCode: fmt.Sprint(constants.ALARM_LICENSE_CHECK), + EventTime: time.Unix(lastTime, 0), + AlarmType: v.AlarmType, + OrigSeverity: v.OrigSeverity, + PerceivedSeverity: v.OrigSeverity, + ObjectUid: neInfo.RmUID, + ObjectName: "NE License", + ObjectType: "license", + LocationInfo: "NE License: Heartbeat", + AlarmStatus: "1", // 活动告警 + SpecificProblem: v.SpecificProblem, + SpecificProblemId: v.SpecificProblemID, + AddInfo: v.AddInfo, + } + insertId := s.alarmService.InsertAndForword(alarm) + if insertId != "" { + alarm.ID = insertId + return alarm, nil + } + return neDataModel.Alarm{}, fmt.Errorf("new alarm fail") +} diff --git a/src/modules/crontask/processor/processor.go b/src/modules/crontask/processor/processor.go index 0af4f58f..35242686 100644 --- a/src/modules/crontask/processor/processor.go +++ b/src/modules/crontask/processor/processor.go @@ -3,13 +3,19 @@ package processor import ( "be.ems/src/framework/cron" "be.ems/src/modules/crontask/processor/backupEtcFromNE" + processorBackupExportCDR "be.ems/src/modules/crontask/processor/backup_export_cdr" + processorBackupExportLog "be.ems/src/modules/crontask/processor/backup_export_log" + processorBackupRemoveFile "be.ems/src/modules/crontask/processor/backup_remove_file" "be.ems/src/modules/crontask/processor/delExpiredNeBackup" "be.ems/src/modules/crontask/processor/deleteExpiredRecord" - "be.ems/src/modules/crontask/processor/exportUEData" "be.ems/src/modules/crontask/processor/exportTable" + "be.ems/src/modules/crontask/processor/exportUEData" "be.ems/src/modules/crontask/processor/genNeStateAlarm" "be.ems/src/modules/crontask/processor/getStateFromNE" processorMonitorSysResource "be.ems/src/modules/crontask/processor/monitor_sys_resource" + processorNeAlarmStateCheck "be.ems/src/modules/crontask/processor/ne_alarm_state_check" + processorNeAlarmStateCheckCMD "be.ems/src/modules/crontask/processor/ne_alarm_state_check_cmd" + processorNeAlarmStateCheckLicense "be.ems/src/modules/crontask/processor/ne_alarm_state_check_license" processorNeConfigBackup "be.ems/src/modules/crontask/processor/ne_config_backup" processorNeDataUDM "be.ems/src/modules/crontask/processor/ne_data_udm" "be.ems/src/modules/crontask/processor/removeFile" @@ -32,4 +38,18 @@ func InitCronQueue() { cron.CreateQueue("exportTable", exportTable.NewProcessor) cron.CreateQueue("removeFile", removeFile.NewProcessor) cron.CreateQueue("exportUEData", exportUEData.NewProcessor) + + // 网元告警-状态检查 + cron.CreateQueue("ne_alarm_state_check", processorNeAlarmStateCheck.NewProcessor) + // 网元告警-内存/CPU/磁盘检查 + cron.CreateQueue("ne_alarm_state_check_cmd", processorNeAlarmStateCheckCMD.NewProcessor) + // 网元告警-License到期检查 + cron.CreateQueue("ne_alarm_state_check_license", processorNeAlarmStateCheckLicense.NewProcessor) + + // 备份-删除备份目录下文件 + cron.CreateQueue("backup_remove_file", processorBackupRemoveFile.NewProcessor) + // 备份-导出CDR数据 + cron.CreateQueue("backup_export_cdr", processorBackupExportCDR.NewProcessor) + // 备份-导出Log数据 + cron.CreateQueue("backup_export_log", processorBackupExportLog.NewProcessor) } diff --git a/src/modules/network_data/model/cdr_event_sgwc.go b/src/modules/network_data/model/cdr_event_sgwc.go index 5fa35498..96b0dac3 100644 --- a/src/modules/network_data/model/cdr_event_sgwc.go +++ b/src/modules/network_data/model/cdr_event_sgwc.go @@ -13,6 +13,8 @@ type CDREventSGWC struct { CreatedAt time.Time `json:"createdAt" gorm:"column:created_at;default:CURRENT_TIMESTAMP"` // ====== 非数据库字段属性 ====== + TenantID string `json:"tenantID" gorm:"-"` + TenantName string `json:"tenantName" gorm:"-"` } // TableName 表名称