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')}}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {editModule.chartIds = data.map(d => d.id).join(',')}"
- >
-
{{ $t("overall.endpointTemplate") }}
@@ -118,20 +49,93 @@
+
+
+ Metrics
+
+
+
+
-
+
-
-
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+ {editModule.chartIds = data.map(d => d.id).join(',')}"
+ >
+
+
+
+
+
+ {{$t('project.module.walk')}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -148,13 +152,13 @@
-
+
s
-
+
s
@@ -189,7 +193,7 @@
-
+
@@ -208,11 +212,11 @@
-
+
-
+
@@ -222,23 +226,232 @@
-
+
-
+
-
+
+
+
+
+
{{configsCopyValue}}
+
+
-
-
-
{{configsCopyValue}}
+
+
+ Logs
+
+
+
+
+
{tabClick(index)}">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{item2.type}}
+
+ {addPipeline(obj,index,pipelineIndex,'splice')}" :type="'splice'"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ =
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{addPipeline(obj,index,pipelineIndex,'push')}" :type="'push'"/>
+
+
+
+
+
+
+
{{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"}