From 2c3387ff3f85b5aa215fe6e2e771d840ed2955f9 Mon Sep 17 00:00:00 2001 From: zhangyu Date: Mon, 2 Aug 2021 11:47:34 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=20module=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nezha-fronted/src/assets/stylus/main.scss | 5 +- .../components/common/rightBox/moduleBox.vue | 679 +++++++++++++++--- .../common/rightBox/pipelineSelect.vue | 216 ++++++ .../page/monitor/module/moduleList.vue | 65 +- nezha-fronted/static/config.json | 2 +- 5 files changed, 827 insertions(+), 140 deletions(-) create mode 100644 nezha-fronted/src/components/common/rightBox/pipelineSelect.vue diff --git a/nezha-fronted/src/assets/stylus/main.scss b/nezha-fronted/src/assets/stylus/main.scss index db22622f9..a3527cbf4 100644 --- a/nezha-fronted/src/assets/stylus/main.scss +++ b/nezha-fronted/src/assets/stylus/main.scss @@ -1416,12 +1416,9 @@ li{ height: 140px; } .param-box-row { - padding: 7px 10px 0 10px; + padding: 0; position: relative; } -.param-box-row:last-of-type { - padding-bottom: 7px; -} .param-box-row>div { display: inline-block; } diff --git a/nezha-fronted/src/components/common/rightBox/moduleBox.vue b/nezha-fronted/src/components/common/rightBox/moduleBox.vue index 344793f53..e9b65d876 100644 --- a/nezha-fronted/src/components/common/rightBox/moduleBox.vue +++ b/nezha-fronted/src/components/common/rightBox/moduleBox.vue @@ -36,75 +36,6 @@ size="small" type="textarea"> - - - - - - - - - - -
SNMP settings
-
- - - -
{{$t('project.module.walk')}}
-
- - - - - - - -
- - - - - - -
- - - - -
{{ $t("overall.endpointTemplate") }} @@ -118,20 +49,93 @@
+
+ + Metrics + + +
+ - + - - + + + + + + + + - - + + + + + + + + + + +
{{$t('project.module.walk')}}
+
+ + + + + + + +
+ + + + + + +
@@ -148,13 +152,13 @@ - + - + @@ -189,7 +193,7 @@
- +
@@ -208,11 +212,11 @@
- +
- + @@ -222,23 +226,232 @@ - + - + - + + +
+ +
{{configsCopyValue}}
+
+
-
- -
{{configsCopyValue}}
+
+ + Logs + + +
+
+ + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + = + + + + +
+
+
+ + + +
+
+ +
+
+ {{item2.type}} + + + + +
+
+ + + + + + +
+
+ +
+ + + + + + + +
+ + + +
+
+ + + + + + +
+
+ + + + + + +
+
+ +
+ + + + = + + + + + +
+ + + +
+
+ + + +
+
+
+
+ +
+
+
+ +
+ +
{{logsCopyValue[index]}}
+
+
+
+ + + +
+
+
@@ -260,6 +473,7 @@ import { noSpecialChar, port, nzNumber } from '../js/validate' import selectWalk from '../popBox/selectWalk' import editRigthBox from '../mixin/editRigthBox' +import pipelineSelect from './pipelineSelect' import VueTagsInput from '@johmun/vue-tags-input' export default { @@ -270,7 +484,8 @@ export default { }, components: { 'select-walk': selectWalk, - VueTagsInput + VueTagsInput, + pipelineSelect }, mixins: [editRigthBox], data () { @@ -278,6 +493,8 @@ export default { walkData: [], chartlList: [], activeName: 'Basic', + activeNameLogs: ['Basic'], + pipelineOptionValue: '', expandedWalkData: [], radio: 'password', editModule: {}, @@ -304,10 +521,6 @@ export default { walk: [ { required: true, message: this.$t('validate.required'), trigger: 'blur' } ], - port: [ - { validator: port, trigger: 'blur' }, - { required: true, message: this.$t('validate.required'), trigger: 'blur' } - ], username: [ { required: true, message: this.$t('validate.required'), trigger: 'blur' } ], @@ -339,16 +552,71 @@ export default { name: 'SNMP' } ], + logsBasicList: [ + { + value: 'file', + name: 'File' + }, + { + value: 'journal', + name: 'Journal' + }, + { + value: 'syslog', + name: 'Syslog' + } + ], authType: 0, authTypeList: [ { name: this.$t('project.endpoint.authTypeNull'), value: 0 }, { name: this.$t('project.endpoint.authTypeWord'), value: 1 }, { name: this.$t('project.endpoint.authTypeToken'), value: 2 } ], - configsCopyValue: '' + configsCopyValue: '', + logsCopyValue: [], + pipelineOption: [ + { + label: 'Parsing stages', + pipelineOption: [ + { + value: 'regex', + label: 'Regex' + }, { + value: 'json', + label: 'Json' + } + ] + }, + { + label: 'Transform stages', + pipelineOption: [ + { + value: 'template', + label: 'Template' + } + ] + }, + { + label: 'Action stages', + pipelineOption: [ + { + value: 'timestamp', + label: 'Timestamp' + }, + { + value: 'labels', + label: 'Labels' + }, + { + value: 'output', + label: 'Output' + } + ] + }] } }, methods: { + port: port, selectWalk (walk) { if (this.editModule.walk.indexOf(walk) != -1) { this.editModule.walk.splice(this.editModule.walk.indexOf(walk), 1) @@ -455,16 +723,21 @@ export default { /* 保存 */ save () { setTimeout(() => { - this.editModule.configs.params = this.paramToJson(this.editModule.paramObj) - this.editModule.configs.labels = this.labelsToJson(this.editModule.labelModule) + this.editModule.configs[0].config.params = this.paramToJson(this.editModule.paramObj) + this.editModule.configs[0].config.labels = this.labelsToJson(this.editModule.labelModule) + this.editModule.configs[1].config.forEach(item => { + if (item.labels) { + item.labels = this.labelsToJson(item.labels) + } + }) const params = { ...this.editModule } - params.configs.walk = params.walk - params.configs.port = params.port params.configs = JSON.stringify(params.configs) - if (this.authType === 2 && !this.editModule.configs.bearer_token) { + if (this.authType === 2 && !this.editModule.configs[0].config.bearer_token) { this.$message.error("'token' is required") - } else if (this.authType === 1 && !(this.editModule.configs.basic_auth.username && this.editModule.configs.basic_auth.pin)) { + return + } else if (this.authType === 1 && !(this.editModule.configs[0].config.basic_auth.username && this.editModule.configs[0].config.basic_auth.pin)) { this.$message.error("'username' and 'password' is required") + return } else { this.authType = 0 } @@ -556,13 +829,24 @@ export default { addLabel () { this.editModule.labelModule.push({ key: '', value: '' }) }, + addLogsLabel (index) { + this.editModule.configs[1].config[index].labelModule.push({ key: '', value: '' }) + }, // 移除单个Label removeLabel (index) { if (this.editModule.labelModule.length === 1) { this.editModule.labelModule = [{ key: '', value: '' }] + return } this.editModule.labelModule.splice(index, 1) }, + removeLogsLabel (logsIndex, i) { + if (this.editModule.configs[1].config[logsIndex].labelModule.length === 1) { + this.editModule.configs[1].config[logsIndex].labelModule = [{ key: '', value: '' }] + return + } + this.editModule.configs[1].config[logsIndex].labelModule.splice(i, 1) + }, tagsChange (newTags, index) { this.editModule.paramObj[index].value = newTags.map(item => item.text) }, @@ -601,12 +885,39 @@ export default { } }, changeAuthType () { - this.editModule.configs.bearer_token = '' - this.editModule.configs.basic_auth = { + this.editModule.configs[0].config.bearer_token = '' + this.editModule.configs[0].config.basic_auth = { username: '', pin: '' } }, + logsLogsArrAdd () { + this.activeNameLogs.push('Basic') + this.logsCopyValue.push('') + this.editModule.configs[1].config.push({ + basic: { + type: 'file', + fileName: '', + appName: '', + listenAddress: '', + unit: '' + }, + labels: '', + labelModule: [{ key: '', value: '' }], + pipeline: [] + }) + }, + removeLogsArr (index) { + if (this.editModule.configs[1].config.length !== 1) { + this.editModule.configs[1].config.splice(index, 1) + } + }, + logsBasicTypeChange (i) { + this.editModule.configs[1].config[i].basic.value = '' + this.editModule.configs[1].config[i].basic.appName = '' + this.editModule.configs[1].config[i].basic.listenAddress = '' + this.editModule.configs[1].config[i].basic.unit = '' + }, copyValue () { const domUrl = document.createElement('input') domUrl.value = this.configsCopyValue @@ -618,6 +929,46 @@ export default { creatDom.parentNode.removeChild(creatDom) this.$message.success(this.$t('overall.copySuccess')) }, + copyLogsValue (index) { + const domUrl = document.createElement('input') + domUrl.value = this.logsCopyValue[index] + domUrl.id = 'creatDom' + document.body.appendChild(domUrl) + domUrl.select() // 选择对象 + document.execCommand('Copy') // 执行浏览器复制命令 + const creatDom = document.getElementById('creatDom') + creatDom.parentNode.removeChild(creatDom) + this.$message.success(this.$t('overall.copySuccess')) + }, + tabClick (index) { + if (this.activeNameLogs[index] === 'Preview') { + const params = JSON.parse(JSON.stringify(this.editModule.configs[1].config[index])) + params.labels = this.labelsToJson(params.labelModule) + delete params.labelModule + Object.keys(params).forEach(key => { + if (!params[key]) { + delete params[key] + } + if (Array.isArray(params[key]) && !params[key].length) { + delete params[key] + } + }) + if (params.labels && !Object.keys(params.labels).length) { + delete params.labels + } + Object.keys(params.basic).forEach(key => { + if (!params.basic[key]) { + delete params.basic[key] + } + }) + params.pipeline && params.pipeline.forEach(item => { + if (item.type === 'labels') { + item.labels = this.labelsToJson(item.labels) + } + }) + this.logsCopyValue[index] = JSON.stringify(params, null, 2) + } + }, syntaxHighlight (json) { if (typeof json != 'string') { json = JSON.stringify(json, undefined, 2) @@ -657,6 +1008,47 @@ export default { this.$get('visual/panel/chart', { pageSize: -1, varType: 2, panelId: 0, returnChildren: 0, groupId: 0 }).then(res => { this.chartlList = res.data.list }) + }, + // 添加pipeline + addPipeline (obj, logsIndex, pipeLineIndex, type) { + if (type == 'splice') { + this.editModule.configs[1].config[logsIndex].pipeline.splice(pipeLineIndex, 0, obj) + } + if (type == 'push') { + this.editModule.configs[1].config[logsIndex].pipeline.push(obj) + } + }, + // 删除pipeline + delPipeline (logsIndex, pipeLineIndex) { + this.editModule.configs[1].config[logsIndex].pipeline.splice(pipeLineIndex, 1) + }, + // 添加pipelineItem + addPipelineItem (logsIndex, pipelineIndex) { + const val = this.editModule.configs[1].config[logsIndex].pipeline[pipelineIndex].type + if (val === 'regex') { + this.editModule.configs[1].config[logsIndex].pipeline[pipelineIndex].expression.push('') + } else if (val === 'json') { + this.editModule.configs[1].config[logsIndex].pipeline[pipelineIndex].expressions.push('') + } else if (val === 'template') { + this.editModule.configs[1].config[logsIndex].pipeline[pipelineIndex].expressions.push('') + } else if (val === 'timestamp') { + this.editModule.configs[1].config[logsIndex].pipeline[pipelineIndex].expressions.push('') + } else if (val === 'labels') { + this.editModule.configs[1].config[logsIndex].pipeline[pipelineIndex].labels.push({ + key: '', + value: '' + }) + } else if (val === 'output') { + this.editModule.configs[1].config[logsIndex].pipeline[pipelineIndex].expressions.push('') + } + }, + delPipelineItem (logsIndex, pipelineIndex, itemIndex) { + const val = this.editModule.configs[1].config[logsIndex].pipeline[pipelineIndex].type + if (val === 'json') { + this.editModule.configs[1].config[logsIndex].pipeline[pipelineIndex].expressions.splice(itemIndex, 1) + } else if (val === 'labels') { + this.editModule.configs[1].config[logsIndex].pipeline[pipelineIndex].labels.splice(itemIndex, 1) + } } }, mounted () { @@ -682,10 +1074,11 @@ export default { this.isEdit = true this.editModule = JSON.parse(JSON.stringify(n)) this.activeName = 'Basic' - - if (this.editModule.configs.bearer_token) { + this.activeNameLogs = this.editModule.configs[1].config.map(() => 'Basic') + this.logsCopyValue = this.editModule.configs[1].config.map(() => '') + if (this.editModule.configs[0].config.bearer_token) { this.authType = 2 - } else if (this.editModule.configs.basic_auth.username) { + } else if (this.editModule.configs[0].config.basic_auth.username) { this.authType = 1 } else { this.authType = 0 @@ -693,18 +1086,9 @@ export default { if (n.type && n.type.toLowerCase() == 'snmp') { this.$refs.selectWalk.show() for (let i = 0; i < this.editModule.walk.length; i++) { - this.expandedWalkData.push(this.editModule.configs.walk[i].substring(0, this.editModule.configs.walk[i].lastIndexOf('.'))) + this.expandedWalkData.push(this.editModule.configs[0].config.walk[i].substring(0, this.editModule.configs[0].config.walk[i].lastIndexOf('.'))) } } - // if (n.id) { - // } else { - // if (n.type && n.type.toLowerCase() == 'snmp') { - // this.$refs.selectWalk.show() - // for (let i = 0; i < this.editModule.walk.length; i++) { - // this.expandedWalkData.push(this.editModule.walk[i].substring(0, this.editModule.walk[i].lastIndexOf('.'))) - // } - // } - // } } }, editModule: { @@ -744,7 +1128,7 @@ export default { } } - + diff --git a/nezha-fronted/src/components/page/monitor/module/moduleList.vue b/nezha-fronted/src/components/page/monitor/module/moduleList.vue index c32928dcf..074ef3892 100644 --- a/nezha-fronted/src/components/page/monitor/module/moduleList.vue +++ b/nezha-fronted/src/components/page/monitor/module/moduleList.vue @@ -90,25 +90,48 @@ export default { projectId: '', name: '', endpointNameTmpl: '{{module.name}}-{{asset.name}}', - type: 'http', port: '', chartIds: '', - configs: { - walk: [], - snmpCredentialsId: '', - metrics_path: '', - port: '', - host: '{{asset.manageIp}}', - scrape_interval: '', - scrape_timeout: '', - params: '', - labels: '', - basic_auth: { - username: '', - pin: '' + metricsEnable: 1, + configs: [ + { + type: 'metrics', + config: { + protocol: 'http', + walk: [], + snmpCredentialsId: '', + metrics_path: '', + port: '', + host: '{{asset.manageIp}}', + scrape_interval: '', + scrape_timeout: '', + params: '', + labels: '', + basic_auth: { + username: '', + pin: '' + }, + bearer_token: '', + }, + enable: 1 }, - bearer_token: '' - }, + { + type: 'logs', + config: [{ + basic: { + type: 'file', + fileName: '', + appName: '', + listenAddress: '', + unit: '' + }, + labels: '', + labelModule: [{ key: '', value: '' }], + pipeline: [], + }], + enable: 1 + } + ], walk: [], labelModule: [{ key: '', @@ -171,6 +194,16 @@ export default { this.object.port = this.object.configs.port ? JSON.parse(JSON.stringify(this.object.configs.port)) : '' this.object.paramObj = [] this.object.labelModule = [] + this.object.logsConfig.forEach(item => { + item.labelModule = [] + if (JSON.stringify(item.labels) !== '{}' && item.labels) { + Object.keys(this.object.configs.labels).forEach(key => { + item.labelModule.push({ key, value: item.labels[key] }) + }) + } else { + item.labelModule.push({ key: '', value: '' }) + } + }) if (JSON.stringify(this.object.configs.labels) !== '{}' && this.object.configs.labels) { Object.keys(this.object.configs.labels).forEach(key => { this.object.labelModule.push({ key, value: this.object.configs.labels[key] }) diff --git a/nezha-fronted/static/config.json b/nezha-fronted/static/config.json index 5f74f5d01..864f961ff 100644 --- a/nezha-fronted/static/config.json +++ b/nezha-fronted/static/config.json @@ -1 +1 @@ -{"baseUrl":"/", "version": "21.04"} +{"baseUrl":"http://192.168.40.42:8080/nz-admin/", "version": "21.04"}