diff --git a/api/app/lib/controllers/alarm/dataContinuity.js b/api/app/lib/controllers/alarm/dataContinuity.js new file mode 100644 index 0000000..905fafa --- /dev/null +++ b/api/app/lib/controllers/alarm/dataContinuity.js @@ -0,0 +1,165 @@ +'use strict'; +const fs = require('fs'); +const moment = require('moment') +const { alarmConfirmLog } = require('./alarmConfirmLog'); + + + +async function postDataContinuity (ctx) { + try { + const { utils: { sendAppearToWeb }, clickHouse } = ctx.app.fs + const models = ctx.fs.dc.models; + const { type, file, } = ctx.request.body + const now = moment().format() + + if (!type) { + throw '请标明数据类型 type' + } + let dataNumber = await models.AlarmDataContinuityType.findOne({ + where: { typeNumber: type } + }); + + if (!dataNumber) { + throw '不存在该数据类型' + } + + await models.AlarmDataContinuity.create({ + type, file, createTime: now + }); + + ctx.status = 204; + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = { + message: typeof error == 'string' ? error : undefined + } + } +} + +async function st (ctx) { + try { + const models = ctx.fs.dc.models; + const { clickHouse } = ctx.app.fs + const { utils: { anxinStrucIdRange, pomsProjectRange } } = ctx.app.fs + const { keyword, errType, confirmState, state, sustainTimeStart, sustainTimeEnd, limit, page, pepProjectId, toExport } = ctx.query + + let pomsProject = await pomsProjectRange({ + ctx, pepProjectId, + keywordTarget: 'pepProject', + keyword, + }) + const pomsProjectIds = pomsProject.map(p => p.id) + let findOption = { + distinct: true, + where: { + $or: [] + }, + include: [{ + model: models.App, + where: { + + }, + attributes: { + exclude: ['projectId'] + }, + include: [{ + model: models.ProjectCorrelation, + where: { + + }, + attributes: { + exclude: ['createTime', 'createUser', 'anxinProjectId',] + }, + }] + }] + } + if (keyword) { + findOption.where.$or.push( + { + '$app->projectCorrelations.id$': { + $in: pomsProjectIds + }, + } + ) + findOption.where.$or.push( + { + '$app.name$': { $like: `%${keyword}%` } + }, + ) + } else { + // findOption.where['$app->projectCorrelations.id$'] = { + // $in: pomsProjectIds + // } + findOption.include[0].include[0].where.id = { $in: pomsProjectIds } + } + + if (errType) { + findOption.where.type = errType // element / apiError + } + if (confirmState || state) { + if (confirmState == 'confirmd' || state == 'histroy') { + findOption.where.confirmTime = { $ne: null } + } else if (confirmState == 'unconfirmed' || state == 'new') { + findOption.where.confirmTime = null + } + } + if (sustainTimeStart && sustainTimeEnd) { + findOption.where.$or = findOption.where.$or.concat([ + { + createTime: { $between: [moment(sustainTimeStart).format(), moment(sustainTimeEnd).format()] }, + }, + { + updateTime: { $between: [moment(sustainTimeStart).format(), moment(sustainTimeEnd).format()] } + }, + { + createTime: { $lte: moment(sustainTimeStart).format() }, + updateTime: { $gte: moment(sustainTimeEnd).format() }, + } + ]) + } + if (!toExport) {//非导出时考虑分页 + if (limit) { + findOption.limit = limit + } + if (page && limit) { + findOption.offset = page * limit + } + } + if (!findOption.where.$or.length) { + delete findOption.where.$or + } + const listRes = await models.AppAlarm.findAndCountAll(findOption) + + for (let lr of listRes.rows) { + if (lr.app && lr.app.projectCorrelations) { + for (let p of lr.app.projectCorrelations) { + let corProjectCorrelations = pomsProject.find(pr => pr.id == p.id) + if (corProjectCorrelations) { + p.dataValues = corProjectCorrelations + } + } + } + } + if (toExport) {//数据导出相关 + await exportAppAlarms(ctx, listRes); + } else { + ctx.status = 200; + ctx.body = listRes + } + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = { + message: typeof error == 'string' ? error : undefined + } + } +} + + + + +module.exports = { + postDataContinuity, + st, +}; \ No newline at end of file diff --git a/api/app/lib/controllers/alarm/service.js b/api/app/lib/controllers/alarm/service.js new file mode 100644 index 0000000..51d123f --- /dev/null +++ b/api/app/lib/controllers/alarm/service.js @@ -0,0 +1,166 @@ +'use strict'; +const fs = require('fs'); +const moment = require('moment') +const { alarmConfirmLog } = require('./alarmConfirmLog'); + + + +async function serviceError (ctx) { + try { + const { utils: { sendAppearToWeb }, clickHouse } = ctx.app.fs + const models = ctx.fs.dc.models; + const { type, file, comment } = ctx.request.body + const now = moment().format() + + if (!type) { + throw '请标明服务告警类型 type' + } + + let serviceNumber = await models.AlarmServiceType.findOne({ + where: { typeNumber: type } + }); + + if (!serviceNumber) { + throw '不存在该服务告警类型' + } + + await models.AlarmService.create({ + type, file, createTime: now, comment + }); + + ctx.status = 204; + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = { + message: typeof error == 'string' ? error : undefined + } + } +} + +async function serviceErrorList (ctx) { + try { + const models = ctx.fs.dc.models; + const { clickHouse } = ctx.app.fs + const { utils: { anxinStrucIdRange, pomsProjectRange } } = ctx.app.fs + const { keyword, errType, confirmState, state, sustainTimeStart, sustainTimeEnd, limit, page, pepProjectId, toExport } = ctx.query + + let pomsProject = await pomsProjectRange({ + ctx, pepProjectId, + keywordTarget: 'pepProject', + keyword, + }) + const pomsProjectIds = pomsProject.map(p => p.id) + let findOption = { + distinct: true, + where: { + $or: [] + }, + include: [{ + model: models.App, + where: { + + }, + attributes: { + exclude: ['projectId'] + }, + include: [{ + model: models.ProjectCorrelation, + where: { + + }, + attributes: { + exclude: ['createTime', 'createUser', 'anxinProjectId',] + }, + }] + }] + } + if (keyword) { + findOption.where.$or.push( + { + '$app->projectCorrelations.id$': { + $in: pomsProjectIds + }, + } + ) + findOption.where.$or.push( + { + '$app.name$': { $like: `%${keyword}%` } + }, + ) + } else { + // findOption.where['$app->projectCorrelations.id$'] = { + // $in: pomsProjectIds + // } + findOption.include[0].include[0].where.id = { $in: pomsProjectIds } + } + + if (errType) { + findOption.where.type = errType // element / apiError + } + if (confirmState || state) { + if (confirmState == 'confirmd' || state == 'histroy') { + findOption.where.confirmTime = { $ne: null } + } else if (confirmState == 'unconfirmed' || state == 'new') { + findOption.where.confirmTime = null + } + } + if (sustainTimeStart && sustainTimeEnd) { + findOption.where.$or = findOption.where.$or.concat([ + { + createTime: { $between: [moment(sustainTimeStart).format(), moment(sustainTimeEnd).format()] }, + }, + { + updateTime: { $between: [moment(sustainTimeStart).format(), moment(sustainTimeEnd).format()] } + }, + { + createTime: { $lte: moment(sustainTimeStart).format() }, + updateTime: { $gte: moment(sustainTimeEnd).format() }, + } + ]) + } + if (!toExport) {//非导出时考虑分页 + if (limit) { + findOption.limit = limit + } + if (page && limit) { + findOption.offset = page * limit + } + } + if (!findOption.where.$or.length) { + delete findOption.where.$or + } + const listRes = await models.AppAlarm.findAndCountAll(findOption) + + for (let lr of listRes.rows) { + if (lr.app && lr.app.projectCorrelations) { + for (let p of lr.app.projectCorrelations) { + let corProjectCorrelations = pomsProject.find(pr => pr.id == p.id) + if (corProjectCorrelations) { + p.dataValues = corProjectCorrelations + } + } + } + } + if (toExport) {//数据导出相关 + await exportAppAlarms(ctx, listRes); + } else { + ctx.status = 200; + ctx.body = listRes + } + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = { + message: typeof error == 'string' ? error : undefined + } + } +} + + + + +module.exports = { + serviceError, + serviceErrorList, +}; \ No newline at end of file diff --git a/api/app/lib/models/alarm_data_continuity.js b/api/app/lib/models/alarm_data_continuity.js new file mode 100644 index 0000000..483492f --- /dev/null +++ b/api/app/lib/models/alarm_data_continuity.js @@ -0,0 +1,52 @@ +/* eslint-disable*/ +'use strict'; + +module.exports = dc => { + const DataTypes = dc.ORM; + const sequelize = dc.orm; + const AlarmDataContinuity = sequelize.define("alarmDataContinuity", { + id: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: null, + comment: null, + primaryKey: true, + field: "id", + autoIncrement: true, + unique: "alarm_data_continuity_id_uindex" + }, + file: { + type: DataTypes.TEXT, + allowNull: false, + defaultValue: null, + comment: null, + primaryKey: false, + field: "file", + autoIncrement: false + }, + type: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: null, + comment: null, + primaryKey: false, + field: "type", + autoIncrement: false + }, + createTime: { + type: DataTypes.DATE, + allowNull: false, + defaultValue: null, + comment: null, + primaryKey: false, + field: "create_time", + autoIncrement: false + }, + }, { + tableName: "alarm_data_continuity", + comment: "", + indexes: [] + }); + dc.models.AlarmDataContinuity = AlarmDataContinuity; + return AlarmDataContinuity; +}; \ No newline at end of file diff --git a/api/app/lib/models/alarm_data_continuity_type.js b/api/app/lib/models/alarm_data_continuity_type.js new file mode 100644 index 0000000..0e164c2 --- /dev/null +++ b/api/app/lib/models/alarm_data_continuity_type.js @@ -0,0 +1,43 @@ +/* eslint-disable*/ +'use strict'; + +module.exports = dc => { + const DataTypes = dc.ORM; + const sequelize = dc.orm; + const AlarmDataContinuityType = sequelize.define("alarmDataContinuityType", { + id: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: null, + comment: null, + primaryKey: true, + field: "id", + autoIncrement: true, + unique: "alarm_data_continuity_type_id_uindex" + }, + name: { + type: DataTypes.STRING, + allowNull: false, + defaultValue: null, + comment: null, + primaryKey: false, + field: "name", + autoIncrement: false + }, + typeNumber: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: null, + comment: null, + primaryKey: false, + field: "type_number", + autoIncrement: false + } + }, { + tableName: "alarm_data_continuity_type", + comment: "", + indexes: [] + }); + dc.models.AlarmDataContinuityType = AlarmDataContinuityType; + return AlarmDataContinuityType; +}; \ No newline at end of file diff --git a/api/app/lib/models/alarm_service.js b/api/app/lib/models/alarm_service.js new file mode 100644 index 0000000..7674d2e --- /dev/null +++ b/api/app/lib/models/alarm_service.js @@ -0,0 +1,61 @@ +/* eslint-disable*/ +'use strict'; + +module.exports = dc => { + const DataTypes = dc.ORM; + const sequelize = dc.orm; + const AlarmService = sequelize.define("alarmService", { + id: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: null, + comment: null, + primaryKey: true, + field: "id", + autoIncrement: true, + unique: "alarm_service_id_uindex" + }, + file: { + type: DataTypes.TEXT, + allowNull: false, + defaultValue: null, + comment: null, + primaryKey: false, + field: "file", + autoIncrement: false + }, + type: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: null, + comment: null, + primaryKey: false, + field: "type", + autoIncrement: false + }, + createTime: { + type: DataTypes.DATE, + allowNull: false, + defaultValue: null, + comment: null, + primaryKey: false, + field: "create_time", + autoIncrement: false + }, + comment: { + type: DataTypes.STRING, + allowNull: true, + defaultValue: null, + comment: null, + primaryKey: false, + field: "comment", + autoIncrement: false + } + }, { + tableName: "alarm_service", + comment: "", + indexes: [] + }); + dc.models.AlarmService = AlarmService; + return AlarmService; +}; \ No newline at end of file diff --git a/api/app/lib/models/alarm_service_type.js b/api/app/lib/models/alarm_service_type.js new file mode 100644 index 0000000..2ec27b8 --- /dev/null +++ b/api/app/lib/models/alarm_service_type.js @@ -0,0 +1,43 @@ +/* eslint-disable*/ +'use strict'; + +module.exports = dc => { + const DataTypes = dc.ORM; + const sequelize = dc.orm; + const AlarmServiceType = sequelize.define("alarmServiceType", { + id: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: null, + comment: null, + primaryKey: true, + field: "id", + autoIncrement: true, + unique: "alarm_service_type_id_uindex" + }, + name: { + type: DataTypes.STRING, + allowNull: false, + defaultValue: null, + comment: null, + primaryKey: false, + field: "name", + autoIncrement: false + }, + typeNumber: { + type: DataTypes.INTEGER, + allowNull: false, + defaultValue: null, + comment: null, + primaryKey: false, + field: "type_number", + autoIncrement: false + } + }, { + tableName: "alarm_service_type", + comment: "", + indexes: [] + }); + dc.models.AlarmServiceType = AlarmServiceType; + return AlarmServiceType; +}; \ No newline at end of file diff --git a/api/app/lib/routes/alarm/index.js b/api/app/lib/routes/alarm/index.js index 2784dac..85a68a2 100644 --- a/api/app/lib/routes/alarm/index.js +++ b/api/app/lib/routes/alarm/index.js @@ -5,6 +5,8 @@ const application = require('../../controllers/alarm/app'); const dataAlarm = require('../../controllers/alarm/data'); const videoAlarm = require('../../controllers/alarm/video') +const service = require('../../controllers/alarm/service') +const dataContinuity = require('../../controllers/alarm/dataContinuity') module.exports = function (app, router, opts) { // 应用告警 @@ -63,4 +65,23 @@ module.exports = function (app, router, opts) { app.fs.api.logAttr['GET/alarm/video/exceptionType'] = { content: '查询视频异常类型', visible: true }; router.get('/alarm/video/exceptionType', videoAlarm.exceptionType); + + + app.fs.api.logAttr['POST/alarm/service/api'] = { content: '保存服务异常信息', visible: true }; + router.post('/alarm/service/api', service.serviceError); + + // app.fs.api.logAttr['GET/alarm/service/api'] = { content: '查询服务异常信息', visible: true }; + // router.get('/alarm/service/api', service.serviceErrorList); + + app.fs.api.logAttr['POST/data/continuity/api'] = { content: '保存数据连续性监控信息', visible: true }; + router.post('/data/continuity/api', dataContinuity.postDataContinuity); + + // app.fs.api.logAttr['GET/alarm/service/api'] = { content: '查询服务异常信息', visible: true }; + // router.get('/alarm/service/api', service.serviceErrorList); + + app.fs.api.logAttr['POST/alarm/service/api'] = { content: '保存服务异常信息', visible: true }; + router.post('/alarm/service/api', service.serviceError); + + // app.fs.api.logAttr['GET/alarm/service/api'] = { content: '查询服务异常信息', visible: true }; + // router.get('/alarm/service/api', service.serviceErrorList); }; diff --git a/api/config.js b/api/config.js index 9ee0158..d56d4ee 100644 --- a/api/config.js +++ b/api/config.js @@ -157,6 +157,9 @@ const product = { { p: '/alarm/application/inspection', o: 'POST' }, { p: '/project/app_list', o: 'GET' }, { p: '/alarm/application/api', o: 'POST' }, + { p: '/alarm/service/api', o: 'POST' }, //后端服务告警入库 + { p: '/data/continuity/api', o: 'POST' }, //数据连续性监控入库 + { p: '/page/performance/api', o: 'POST' }, //页面加载性能入库 { p: '/alarm/video/added_log', o: 'POST' } ], // 不做认证的路由,也可以使用 exclude: ["*"] 跳过所有路由 apMergeDeVeAnxinProjectId: AP_MERGE_DEVE_ANXINPROJECT_ID, diff --git a/script/监控工具/schema/1.data_continuity.sql b/script/监控工具/schema/1.data_continuity.sql new file mode 100644 index 0000000..0f17971 --- /dev/null +++ b/script/监控工具/schema/1.data_continuity.sql @@ -0,0 +1,41 @@ +create table alarm_data_continuity +( + id serial not null, + file text not null, + type int not null, + create_time timestamp not null +); + +comment on column alarm_data_continuity.type is '数据连续性的类型编号'; + +create unique index alarm_data_continuity_id_uindex + on alarm_data_continuity (id); + +alter table alarm_data_continuity + add constraint alarm_data_continuity_pk + primary key (id); + + + + + + + +create table alarm_data_continuity_type +( + id serial not null, + name varchar not null, + type_number int not null +); + +comment on column alarm_data_continuity_type.type_number is '类型编号'; + +create unique index alarm_data_continuity_type_id_uindex + on alarm_data_continuity_type (id); + +create unique index alarm_data_continuity_type_type_number_uindex + on alarm_data_continuity_type (type_number); + +alter table alarm_data_continuity_type + add constraint alarm_data_continuity_type_pk + primary key (id); diff --git a/script/监控工具/schema/2.alarm_service.sql b/script/监控工具/schema/2.alarm_service.sql new file mode 100644 index 0000000..884df56 --- /dev/null +++ b/script/监控工具/schema/2.alarm_service.sql @@ -0,0 +1,36 @@ +create table alarm_service +( + id serial not null, + file text not null, + type int not null, + create_time timestamp not null, + comment varchar +); + +comment on column alarm_service.type is '服务告警类型编号'; + +create unique index alarm_service_id_uindex + on alarm_service (id); + +alter table alarm_service + add constraint alarm_service_pk + primary key (id); + + + + +create table alarm_service_type +( + id serial not null, + name varchar not null, + type_number int not null +); + +comment on column alarm_service_type.type_number is '编号'; + +create unique index alarm_service_type_id_uindex + on alarm_service_type (id); + +alter table alarm_service_type + add constraint alarm_service_type_pk + primary key (id);