Browse Source

监控告警api

dev
wenlele 2 years ago
parent
commit
b337cdb684
  1. 165
      api/app/lib/controllers/alarm/dataContinuity.js
  2. 166
      api/app/lib/controllers/alarm/service.js
  3. 52
      api/app/lib/models/alarm_data_continuity.js
  4. 43
      api/app/lib/models/alarm_data_continuity_type.js
  5. 61
      api/app/lib/models/alarm_service.js
  6. 43
      api/app/lib/models/alarm_service_type.js
  7. 21
      api/app/lib/routes/alarm/index.js
  8. 3
      api/config.js
  9. 41
      script/监控工具/schema/1.data_continuity.sql
  10. 36
      script/监控工具/schema/2.alarm_service.sql

165
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,
};

166
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,
};

52
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;
};

43
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;
};

61
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;
};

43
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;
};

21
api/app/lib/routes/alarm/index.js

@ -5,6 +5,8 @@
const application = require('../../controllers/alarm/app'); const application = require('../../controllers/alarm/app');
const dataAlarm = require('../../controllers/alarm/data'); const dataAlarm = require('../../controllers/alarm/data');
const videoAlarm = require('../../controllers/alarm/video') const videoAlarm = require('../../controllers/alarm/video')
const service = require('../../controllers/alarm/service')
const dataContinuity = require('../../controllers/alarm/dataContinuity')
module.exports = function (app, router, opts) { 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 }; app.fs.api.logAttr['GET/alarm/video/exceptionType'] = { content: '查询视频异常类型', visible: true };
router.get('/alarm/video/exceptionType', videoAlarm.exceptionType); 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);
}; };

3
api/config.js

@ -157,6 +157,9 @@ const product = {
{ p: '/alarm/application/inspection', o: 'POST' }, { p: '/alarm/application/inspection', o: 'POST' },
{ p: '/project/app_list', o: 'GET' }, { p: '/project/app_list', o: 'GET' },
{ p: '/alarm/application/api', o: 'POST' }, { 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' } { p: '/alarm/video/added_log', o: 'POST' }
], // 不做认证的路由,也可以使用 exclude: ["*"] 跳过所有路由 ], // 不做认证的路由,也可以使用 exclude: ["*"] 跳过所有路由
apMergeDeVeAnxinProjectId: AP_MERGE_DEVE_ANXINPROJECT_ID, apMergeDeVeAnxinProjectId: AP_MERGE_DEVE_ANXINPROJECT_ID,

41
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);

36
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);
Loading…
Cancel
Save