index.vue 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876
  1. <template>
  2. <div class="sy-content">
  3. <el-row>
  4. <el-col :span="12">
  5. <el-form ref="queryForm" :inline="true" size="small" :model="queryParams">
  6. <el-form-item label="" prop="queryVal">
  7. <el-input placeholder="请输入采集器名称/IP" prefix-icon="el-icon-search" v-model="queryParams.queryVal"/>
  8. </el-form-item>
  9. <el-form-item>
  10. <el-button type="primary" icon="el-icon-search" size="small" @click="handelSearch">搜索</el-button>
  11. <el-button type="info" icon="el-icon-refresh" size="small" @click="handelReset">重置</el-button>
  12. </el-form-item>
  13. </el-form>
  14. </el-col>
  15. <el-col :span="12">
  16. <el-row style="float:right">
  17. <el-button size="small" icon="el-icon-plus" type="primary" style="margin-bottom: 20px"
  18. @click="handelAdd">新增
  19. </el-button>
  20. <el-button size="small" icon="el-icon-download" type="primary" style="margin-bottom: 20px"
  21. @click="downloadApp">采集器下载
  22. </el-button>
  23. </el-row>
  24. </el-col>
  25. </el-row>
  26. <el-row>
  27. <el-col :span="24">
  28. <el-table ref="table" :loading="loading" :data="tableList" row-key="id" border stripe
  29. header-row-class-name="headBackground">
  30. <!-- <el-table-column label="序号" type="index" width="70" align="center" />-->
  31. <el-table-column key="clientName" label="名称" prop="clientName" show-overflow-tooltip/>
  32. <el-table-column key="ipAddr" label="IP地址" prop="ipAddr" show-overflow-tooltip/>
  33. <el-table-column key="onLine" label="在线状态" prop="onLine" show-overflow-tooltip width="100">
  34. <template slot-scope="scope">
  35. <el-tag :type="scope.row.onLine === 1 ? 'success' : 'info'">{{
  36. scope.row.onLine === 1 ? "在线" : "离线"
  37. }}
  38. </el-tag>
  39. </template>
  40. </el-table-column>
  41. <el-table-column key="runStatus" label="运行状态" prop="runStatus" show-overflow-tooltip width="100">
  42. <template slot-scope="scope">
  43. <el-tag :type="scope.row.runStatus === 1 ? 'success' : 'danger'">{{
  44. scope.row.runStatus === 1 ? "运行" :
  45. "停止"
  46. }}
  47. </el-tag>
  48. </template>
  49. </el-table-column>
  50. <!-- <el-table-column key="createTime" label="创建时间" prop="createTime" show-overflow-tooltip />-->
  51. <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="500">
  52. <template slot-scope="scope">
  53. <el-button size="mini" type="text" icon="el-icon-tickets" @click="handelEdit(scope.row)">编辑
  54. </el-button>
  55. <el-button :disabled="scope.row.onLine !== 1"
  56. size="mini" type="text" icon="el-icon-tickets" @click="handelConfig(scope.row.id)">配置
  57. </el-button>
  58. <el-button :disabled="scope.row.onLine !== 1"
  59. size="mini" type="text" icon="el-icon-s-order"
  60. @click="handelLog(scope.row.id)">日志
  61. </el-button>
  62. <el-button :disabled="scope.row.onLine !== 1"
  63. size="mini" type="text" icon="el-icon-refresh" @click="refreshConfig(scope.row.id,scope.row.clientName,true)">刷新配置
  64. </el-button>
  65. <el-button v-if="(!scope.row.runStatus || scope.row.runStatus === 0)" :disabled="scope.row.onLine !== 1"
  66. size="mini" type="text" icon="el-icon-video-play" :style="scope.row.onLine === 1?'color: #67c23a;':''"
  67. @click="handelStart(scope.row.id, scope.row.clientName)">启动
  68. </el-button>
  69. <el-button v-if="scope.row.runStatus === 1" :disabled="scope.row.onLine !== 1"
  70. size="mini" type="text"
  71. icon="el-icon-video-pause" style="color: #f56c6c;" @click="handelStop(scope.row.id, scope.row.clientName)">停止
  72. </el-button>
  73. <el-button size="mini" type="text" icon="el-icon-delete" style="color: #f56c6c;"
  74. @click="deleteCollector(scope.row)">删除
  75. </el-button>
  76. </template>
  77. </el-table-column>
  78. </el-table>
  79. <pagination v-show="total > 0" :total="total" :page.sync="queryParams.page" :limit.sync="queryParams.limit"
  80. align="right" @pagination="getCollectorList"/>
  81. </el-col>
  82. </el-row>
  83. <el-dialog :title="diatitle" :visible.sync="dialogAdd" width="800px" :close-on-click-modal="false">
  84. <el-form ref="addForm" :model="addForm" :rules="addRules" label-width="90px">
  85. <el-form-item label="名称" prop="name">
  86. <el-input v-model="addForm.name" placeholder="请输入采集器名称"/>
  87. </el-form-item>
  88. <el-form-item label="IP地址" prop="ip">
  89. <el-input v-model="addForm.ip" placeholder="请输入IP地址"/>
  90. </el-form-item>
  91. </el-form>
  92. <span slot="footer" class="dialog-footer">
  93. <el-button type="primary" @click="handelAddSubmit" size="mini">确定</el-button>
  94. <el-button @click="handelAddCancel()" size="mini">取消</el-button>
  95. </span>
  96. </el-dialog>
  97. <el-dialog title="高级设置" :visible.sync="dialogSetting" width="800px" :close-on-click-modal="false">
  98. <el-form ref="configForm" :model="configForm" :rules="configRules" label-width="120px">
  99. <el-row :span="24">
  100. <el-col :span="11">
  101. <el-form-item label="间隔取整" prop="roundInterval">
  102. <el-radio-group v-model="configForm.roundInterval">
  103. <el-radio :label="0">否</el-radio>
  104. <el-radio :label="1">是</el-radio>
  105. </el-radio-group>
  106. </el-form-item>
  107. </el-col>
  108. <el-col :span="1">
  109. <el-tooltip class="item" effect="dark"
  110. content="将采集的间隔时间取整。比如,如果interval设置为10s,但我们在1分02秒启动了telegraf服务,那么采集的时间会取整到1分10秒,1分20秒,1分30秒"
  111. placement="top">
  112. <i class="el-icon-question" style="line-height: 36px;margin-left: 5px;"></i>
  113. </el-tooltip>
  114. </el-col>
  115. <el-col :span="11">
  116. <el-form-item label="刷新间隔" prop="flushInterval">
  117. <el-input placeholder="请输入刷新间隔" v-model="configForm.flushInterval">
  118. <template slot="append">秒</template>
  119. </el-input>
  120. </el-form-item>
  121. </el-col>
  122. <el-col :span="1">
  123. <el-tooltip class="item" effect="dark"
  124. content="所有output的输出间隔,这个参数不应该设的比interval(所有input组件的采集间隔)小"
  125. placement="top">
  126. <i class="el-icon-question" style="line-height: 36px;margin-left: 5px;"></i>
  127. </el-tooltip>
  128. </el-col>
  129. </el-row>
  130. <el-row :span="24">
  131. <el-col :span="11">
  132. <el-form-item label="发送量" prop="metricBatchSize">
  133. <el-input placeholder="请输入发送量" v-model="configForm.metricBatchSize">
  134. <template slot="append">条</template>
  135. </el-input>
  136. </el-form-item>
  137. </el-col>
  138. <el-col :span="1">
  139. <el-tooltip class="item" effect="dark"
  140. content="telegraf一批次从output组件向外发送数据的大小,网络不稳定时可以减小此参数。"
  141. placement="top">
  142. <i class="el-icon-question" style="line-height: 36px;margin-left: 5px;"></i>
  143. </el-tooltip>
  144. </el-col>
  145. <el-col :span="11">
  146. <el-form-item label="缓存量" prop="metricBufferLimit">
  147. <el-input placeholder="请输入发送量" v-model="configForm.metricBufferLimit">
  148. <template slot="append">条</template>
  149. </el-input>
  150. </el-form-item>
  151. </el-col>
  152. <el-col :span="1">
  153. <el-tooltip class="item" effect="dark"
  154. content="telegraf会为每个output插件创建一个缓冲区,来缓存指标数据,并在output成功将数据发送后,将成功发送的数据从缓冲区删除。所以,metriac_buffer_limit参数应该至少是metric_batch_size参数的两倍"
  155. placement="top">
  156. <i class="el-icon-question" style="line-height: 36px;margin-left: 5px;"></i>
  157. </el-tooltip>
  158. </el-col>
  159. </el-row>
  160. <el-row :span="24">
  161. <el-col :span="11">
  162. <el-form-item label="采集抖动" prop="collectionJitter">
  163. <el-input placeholder="请输入采集抖动" v-model="configForm.collectionJitter">
  164. <template slot="append">秒</template>
  165. </el-input>
  166. </el-form-item>
  167. </el-col>
  168. <el-col :span="1">
  169. <el-tooltip class="item" effect="dark"
  170. content="这个参数会在采集的时间点上加一个随机的抖动,这样可以避免很多插件同时查询一些消耗资源的指标,从而对被观测的系统产生不可忽视的影响。"
  171. placement="top">
  172. <i class="el-icon-question" style="line-height: 36px;margin-left: 5px;"></i>
  173. </el-tooltip>
  174. </el-col>
  175. <el-col :span="11">
  176. <el-form-item label="刷新抖动" prop="flushJitter">
  177. <el-input placeholder="请输入刷新抖动" v-model="configForm.flushJitter">
  178. <template slot="append">秒</template>
  179. </el-input>
  180. </el-form-item>
  181. </el-col>
  182. <el-col :span="1">
  183. <el-tooltip class="item" effect="dark"
  184. content="对output的输出时间加上一个随机的抖动,这主要是为了避免大量的Telegraf实例在同样的时间同时执行写入操作,出现较大的写入峰值。比如,flush_jitter设为5s,flush_interval设为10s意味着会在10~15秒的时候进行一次输出。"
  185. placement="top">
  186. <i class="el-icon-question" style="line-height: 36px;margin-left: 5px;"></i>
  187. </el-tooltip>
  188. </el-col>
  189. </el-row>
  190. </el-form>
  191. <span slot="footer" class="dialog-footer">
  192. <el-button type="primary" @click="handelSettingSubmit()" size="mini">确定</el-button>
  193. <el-button @click="handelSettingCancel()" size="mini">取消</el-button>
  194. </span>
  195. </el-dialog>
  196. <el-dialog title="配置采集器" :visible.sync="dialogConfig" width="800px" :close-on-click-modal="false" :before-close="handelConfigCancel">
  197. <el-row :span="24">
  198. <el-button size="mini" icon="el-icon-plus" type="primary" style="margin-bottom: 20px"
  199. @click="itemAddBtn">新增
  200. </el-button>
  201. <el-button size="mini" icon="el-icon-setting" type="primary" style="margin-bottom: 20px"
  202. @click="itemSettingBtn">高级设置
  203. </el-button>
  204. </el-row>
  205. <el-row :span="24">
  206. <el-table :data="itemTableData" height="250" border style="width: 100%">
  207. <el-table-column label="序号" type="index" width="70" align="left"/>
  208. <el-table-column key="group_name" label="数据组" align="left" prop="group_name" show-overflow-tooltip>
  209. </el-table-column>
  210. <el-table-column key="userName" label="创建用户" align="left" prop="userName" show-overflow-tooltip>
  211. </el-table-column>
  212. <el-table-column key="interval" label="采集间隔" align="left" prop="interval" show-overflow-tooltip/>
  213. <el-table-column key="unit" label="单位" align="left" prop="unit" show-overflow-tooltip/>
  214. <el-table-column label="操作" align="left" width="250" class-name="small-padding fixed-width">
  215. <template slot-scope="scope">
  216. <el-button v-show="scope.row.isupdate==1" size="mini" type="text" icon="el-icon-edit"
  217. @click="editItem(scope.row)">修改
  218. </el-button>
  219. <el-button v-show="scope.row.isupdate==1" size="mini" type="text" icon="el-icon-delete"
  220. @click="delItem(scope.row)">删除
  221. </el-button>
  222. </template>
  223. </el-table-column>
  224. </el-table>
  225. </el-row>
  226. <span slot="footer" class="dialog-footer">
  227. <el-button v-if="false" type="primary" @click="handelConfigSubmit()" size="mini">确定</el-button>
  228. <el-button @click="handelConfigCancel()" size="mini">关闭</el-button>
  229. </span>
  230. </el-dialog>
  231. <el-dialog title="日志" :visible.sync="dialogLog" width="800px" :close-on-click-modal="false">
  232. <div style="height: 600px;overflow-y: auto;">
  233. <el-collapse v-model="activeName" accordion>
  234. <el-collapse-item v-for="item in LogList" :title="item.path + '(' + item.itemGroupName + ')'" :name="item.index">
  235. <div v-for="txt in item.log">{{ txt }}</div>
  236. </el-collapse-item>
  237. </el-collapse>
  238. </div>
  239. </el-dialog>
  240. <el-dialog title="数据组配置" :visible.sync="groupDialog" width="500px" :close-on-click-modal="false">
  241. <el-form ref="itemForm" :model="itemForm" :rules="itemRules" label-width="120px">
  242. <el-form-item label="采集数据组" prop="itemGroupId">
  243. <el-select v-model="itemForm.itemGroupId" placeholder="请选择数据组" style="width: 100%;" @change="itemGroupChange">
  244. <el-option v-for="group in itemGroupList" :key="group.id" :label="group.groupName" :value="group.id">
  245. </el-option>
  246. </el-select>
  247. </el-form-item>
  248. <el-form-item label="采集间隔" prop="interval">
  249. <el-input placeholder="请输入采集间隔" v-model="itemForm.interval">
  250. <template slot="append">
  251. <div class="unit-my">
  252. <el-select v-model="itemForm.unit" style="width: 80px">
  253. <el-option label="毫秒" value="ms"/>
  254. <el-option label="秒" value="s" :disabled="isSubscribe"/>
  255. <el-option label="分" value="m" :disabled="isSubscribe"/>
  256. <el-option label="时" value="h" :disabled="isSubscribe"/>
  257. <el-option label="天" value="d" :disabled="isSubscribe"/>
  258. </el-select>
  259. </div>
  260. </template>
  261. </el-input>
  262. </el-form-item>
  263. </el-form>
  264. <span slot="footer" class="dialog-footer">
  265. <el-button type="primary" @click="itemFormSub" size="mini">确定</el-button>
  266. <el-button @click="itemFormClose()" size="mini">取消</el-button>
  267. </span>
  268. </el-dialog>
  269. </div>
  270. </template>
  271. <script>
  272. import {showLoading} from "@/utils/cqcy";
  273. import {
  274. getClientStatus,
  275. getCollectorInfo,
  276. getCollectorInfoPage, getErrorFile,
  277. getLogFile,
  278. refreshConfig,
  279. saveCollector,
  280. saveConfigInfo,
  281. startClient,
  282. stopClient,
  283. deleteCollectorApi
  284. } from "@/api/collector";
  285. import {
  286. getAllItemGroup
  287. } from '@/api/source/itemGroup';
  288. export default {
  289. name: "index",
  290. data() {
  291. return {
  292. isSubscribe: false,
  293. dialogSetting: false,
  294. activeName: '0',
  295. loading: true,
  296. diatitle:'新增采集器',
  297. groupDialog: false,
  298. queryParams: {
  299. page: 1,
  300. limit: 10,
  301. queryVal: ''
  302. },
  303. tableList: [],
  304. total: 0,
  305. dialogAdd: false,
  306. addForm: {
  307. id: null,
  308. name: '',
  309. ip: ''
  310. },
  311. addRules: {
  312. name: [{
  313. required: true,
  314. message: '采集器名称不能为空',
  315. trigger: 'blur'
  316. }],
  317. ip: [{
  318. required: true,
  319. message: 'IP地址格式错误',
  320. pattern: '^((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})(\\.((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})){3}$',
  321. trigger: 'blur'
  322. }],
  323. },
  324. itemGroupList: [],
  325. dialogConfig: false,
  326. configForm: {
  327. id: 0,
  328. // 默认数据收集间隔
  329. interval: '1',
  330. // 是否在整点收集数据0、否1、是
  331. roundInterval: 1,
  332. // telegraf一批次从output组件向外发送数据的大小
  333. metricBatchSize: '1000',
  334. // 缓存指标数据,并在output成功将数据发送后,将成功发送的数据从缓冲区删除。metriac_buffer_limit参数应该至少是metric_batch_size参数的两倍
  335. metricBufferLimit: '10000',
  336. // 在采集的时间点上加一个随机的抖动,这样可以避免很多插件同时查询一些消耗资源的指标
  337. collectionJitter: '0',
  338. // output的输出间隔,这个参数不应该设的比interval
  339. flushInterval: '10',
  340. // output的输出时间加上一个随机的抖动,这主要是为了避免大量的Telegraf实例在同样的时间同时执行写入操作
  341. flushJitter: '0',
  342. // 收集的指标四舍五入为指定的精度
  343. precision: '',
  344. // 主机名
  345. hostname: '',
  346. // 不要在 Telegraf 代理中设置host标记0、否1、是
  347. omitHostname: 1,
  348. // 采集失败重试间隔
  349. restartDelay: '10',
  350. itemGroupId: ''
  351. },
  352. configRules: {
  353. interval: [{
  354. required: true,
  355. message: '收集间隔格式错误',
  356. pattern: '^([1-9][0-9]*)$',
  357. trigger: 'blur'
  358. }],
  359. roundInterval: [{
  360. required: true,
  361. message: '间隔取整不能为空',
  362. trigger: 'blur'
  363. }],
  364. metricBatchSize: [{
  365. required: true,
  366. message: '发送量格式错误',
  367. pattern: '^(0|[1-9][0-9]*)$',
  368. trigger: 'blur'
  369. }],
  370. metricBufferLimit: [{
  371. required: true,
  372. message: '缓存量隔格式错误',
  373. pattern: '^(0|[1-9][0-9]*)$',
  374. trigger: 'blur'
  375. }],
  376. collectionJitter: [{
  377. required: true,
  378. message: '采集抖动格式错误',
  379. pattern: '^(0|[1-9][0-9]*)$',
  380. trigger: 'blur'
  381. }],
  382. flushJitter: [{
  383. required: true,
  384. message: '输出抖动格式错误',
  385. pattern: '^(0|[1-9][0-9]*)$',
  386. trigger: 'blur'
  387. }],
  388. flushInterval: [{
  389. required: true,
  390. message: '输出间隔格式错误',
  391. pattern: '^([1-9][0-9]*)$',
  392. trigger: 'blur'
  393. }],
  394. restartDelay: [{
  395. required: true,
  396. message: '采集重试格式错误',
  397. pattern: '^([1-9][0-9]*)$',
  398. trigger: 'blur'
  399. }],
  400. omitHostname: [{
  401. required: true,
  402. message: '忽略主机名不能为空',
  403. trigger: 'blur'
  404. }],
  405. itemGroupId: [{
  406. required: true,
  407. message: '请选择要采集的数据组',
  408. trigger: 'blur'
  409. }],
  410. },
  411. dialogLog: false,
  412. LogList: [],
  413. statusTask: null,
  414. itemForm: {
  415. itemGroupId: '',
  416. interval: '10',
  417. unit: 's'
  418. },
  419. itemRules: {
  420. itemGroupId: [{
  421. required: true,
  422. message: '请选择要采集的数据组',
  423. trigger: 'blur'
  424. }],
  425. interval: [{
  426. required: true,
  427. //message: '采集间隔格式错误',
  428. //pattern: '^([1-9][0-9]*)$',
  429. trigger: 'blur',
  430. validator: (rule, value, callback) => {
  431. if(!/^([1-9][0-9]*)$/.test(value)){
  432. callback("采集间隔格式错误")
  433. return
  434. } else if (this.isSubscribe && parseInt(value) < 10) {
  435. callback("OPC UA 订阅模式采集间隔最低只支持10毫秒")
  436. return
  437. }
  438. callback()
  439. },
  440. }],
  441. },
  442. itemTableData: [],
  443. isItemEdit: false
  444. }
  445. },
  446. created() {
  447. this.getCollectorList();
  448. this.statusTask = setInterval(() => {
  449. this.getClientStatusByList();
  450. this.getClientErrorList();
  451. }, 15000)
  452. },
  453. beforeDestroy() {
  454. if (this.statusTask) {
  455. clearInterval(this.statusTask)
  456. this.statusTask = null
  457. }
  458. },
  459. methods: {
  460. itemGroupChange(e) {
  461. const data = this.itemGroupList.filter(item => item.id == e)[0]
  462. this.isSubscribe = data.subscribe == 1
  463. if (data.subscribe == 1) {
  464. this.itemForm.unit = 'ms'
  465. this.itemForm.interval = data.uaInterval
  466. }
  467. },
  468. /** 搜索 */
  469. handelSearch(event) {
  470. this.$resetBtn(event)
  471. this.queryParams.page = 1
  472. this.getCollectorList()
  473. },
  474. /** 重置按钮操作 */
  475. handelReset(event) {
  476. this.$refs['queryForm'].resetFields()
  477. this.handelSearch(event)
  478. },
  479. getCollectorList() {
  480. getCollectorInfoPage(this.queryParams).then((json) => {
  481. this.tableList = json.data.list || [];
  482. this.total = json.data.count || 0;
  483. this.getClientStatusByList();
  484. })
  485. },
  486. getClientStatusByList() {
  487. const data = this.tableList;
  488. if (data && data.length) {
  489. for (let i = 0; i < data.length; i++) {
  490. getClientStatus(data[i].ipAddr).then((json) => {
  491. const client = json.data;
  492. this.tableList[i].onLine = client.onLine;
  493. this.tableList[i].runStatus = client.runStatus;
  494. }).catch(e => {
  495. console.error(e)
  496. })
  497. }
  498. }
  499. },
  500. getClientErrorList() {
  501. const data = this.tableList;
  502. if (data && data.length) {
  503. // for (let i = 0; i < data.length; i++) {
  504. // if (data[i].onLine === 1 && data[i].runStatus === 1) {
  505. // getErrorFile(data[i].ipAddr).then((json) => {
  506. // const client = json.data;
  507. // if (client.logStatus === 1) {
  508. // this.$message.error(`监测到${data[i].clientName}【${data[i].ipAddr}】近15分钟内有错误日志产生,请检查配置或联系维护人员`);
  509. // }
  510. // })
  511. // }
  512. //
  513. // }
  514. }
  515. },
  516. handelAdd() {
  517. this.diatitle = '新增采集器'
  518. this.dialogAdd = true
  519. },
  520. handelAddCancel() {
  521. this.dialogAdd = false
  522. if (this.$refs['addForm']) {
  523. this.$refs['addForm'].resetFields()
  524. }
  525. this.addForm = {
  526. id: null,
  527. name: '',
  528. ip: ''
  529. }
  530. },
  531. handelAddSubmit() {
  532. this.$refs['addForm'].validate((valid) => {
  533. if (valid) {
  534. saveCollector(this.addForm).then((json) => {
  535. if (json.code != 200) {
  536. this.$message({
  537. message: json.msg,
  538. type: 'warning'
  539. })
  540. return;
  541. }
  542. this.$message({
  543. message: (this.addForm.id ? '编辑' : '新增') + '成功',
  544. type: 'success'
  545. })
  546. this.handelAddCancel()
  547. this.getCollectorList()
  548. })
  549. }
  550. })
  551. },
  552. handelConfig(id) {
  553. this.getAllItemGroup();
  554. getCollectorInfo(id).then((json) => {
  555. const data = json.data || {};
  556. this.configForm = {
  557. id,
  558. interval: (data.interval || 1).toString(),
  559. roundInterval: data.roundInterval || 1,
  560. metricBatchSize: (data.metricBatchSize || 1000).toString(),
  561. metricBufferLimit: (data.metricBufferLimit || 10000).toString(),
  562. collectionJitter: (data.collectionJitter || 0).toString(),
  563. flushInterval: (data.flushInterval || 10).toString(),
  564. flushJitter: (data.flushJitter || 0).toString(),
  565. precision: data.precision || '',
  566. hostname: data.hostname || '',
  567. omitHostname: data.omitHostname || 1,
  568. restartDelay: (data.restartDelay || 10).toString(),
  569. // itemGroupId: JSON.parse(data.itemGroupIds || '[]')
  570. }
  571. if (data.itemJson) {
  572. const itemData = JSON.parse(data.itemJson || '[]')
  573. this.itemTableData = itemData.map(item => {
  574. return {
  575. group_name: item.group_name,
  576. isupdate: item.isupdate,
  577. userName: item.userName,
  578. itemGroupId: item.itemGroupId,
  579. interval: item.itemInterval,
  580. unit: item.itemUnit
  581. }
  582. })
  583. }
  584. this.dialogConfig = true
  585. });
  586. },
  587. refreshConfig(id,clientName, showLoad) {
  588. let loading = null
  589. if(showLoad)loading = showLoading(this, '加载中,请稍候···')
  590. refreshConfig({
  591. id: id,
  592. clientName: clientName
  593. }).then((json) => {
  594. if(showLoad){
  595. loading.close()
  596. this.$message({
  597. message: json.msg,
  598. type: 'success'
  599. })
  600. }
  601. this.getClientStatusByList()
  602. }).catch(() => {
  603. if(showLoad)loading.close()
  604. })
  605. },
  606. getAllItemGroup() {
  607. let params = {
  608. page: 1,
  609. limit: 9999
  610. }
  611. getAllItemGroup(params).then((res) => {
  612. this.itemGroupList = res.data.itemGroupList
  613. })
  614. },
  615. handelConfigCancel() {
  616. if (this.$refs['configForm']) {
  617. this.$refs['configForm'].resetFields()
  618. }
  619. this.dialogConfig = false
  620. this.itemTableData = []
  621. //let data = this.configForm
  622. //this.refreshConfig(data.id,"")
  623. },
  624. handelConfigSubmit() {
  625. this.saveConfigInfo((data) => {
  626. this.refreshConfig(data.id,"", true)
  627. this.handelConfigCancel()
  628. })
  629. },
  630. saveConfigInfo(callback) {
  631. if (this.itemTableData.length === 0) {
  632. this.$message({
  633. message: '请配置需要采集的数据组',
  634. type: 'warning'
  635. })
  636. return;
  637. }
  638. const loading = showLoading(this, '加载中,请稍候···')
  639. let data = this.configForm;
  640. data.itemJson = JSON.stringify(this.itemTableData)
  641. saveConfigInfo(data).then((json) => {
  642. loading.close()
  643. if (json.code != 200) {
  644. this.$message({
  645. message: json.msg,
  646. type: 'warning'
  647. })
  648. return;
  649. }
  650. this.$message({
  651. message: '配置成功',
  652. type: 'success'
  653. })
  654. if (callback) callback(data)
  655. }).catch(() => {
  656. loading.close()
  657. this.handelConfig(data.id)
  658. })
  659. },
  660. handelStart(id, clientName) {
  661. const loading = showLoading(this, '加载中,请稍候···')
  662. startClient({
  663. id: id,
  664. clientName: clientName
  665. }).then((json) => {
  666. loading.close()
  667. this.$message({
  668. message: json.msg,
  669. type: 'success'
  670. })
  671. this.getClientStatusByList()
  672. }).catch(() => {
  673. loading.close()
  674. })
  675. },
  676. handelStop(id, clientName) {
  677. const loading = showLoading(this, '加载中,请稍候···')
  678. stopClient({
  679. id: id,
  680. clientName: clientName
  681. }).then((json) => {
  682. loading.close()
  683. this.$message({
  684. message: json.msg,
  685. type: 'success'
  686. })
  687. this.getClientStatusByList()
  688. }).catch(() => {
  689. loading.close()
  690. })
  691. },
  692. handelLog(id) {
  693. const loading = showLoading(this, '加载中,请稍候···')
  694. getLogFile(id).then((json) => {
  695. loading.close()
  696. getCollectorInfo(id).then((json2) => {
  697. if (json2.data?.itemJson) {
  698. const itemData = JSON.parse(json2.data.itemJson || '[]')
  699. let obj = {}
  700. itemData.forEach(item => {
  701. obj[item.itemGroupId] = item.group_name
  702. })
  703. this.LogList = json.data.map(item => {
  704. let id = item.path.substring(item.path.lastIndexOf('_') + 1)
  705. id = id.substring(0, id.indexOf('.'))
  706. item.itemGroupName = obj[id]
  707. return item
  708. })
  709. }
  710. this.dialogLog = true
  711. })
  712. }).catch(() => {
  713. loading.close()
  714. })
  715. },
  716. itemAddBtn() {
  717. this.groupDialog = true
  718. this.isItemEdit = false
  719. this.itemForm = {
  720. itemGroupId: '',
  721. interval: '10',
  722. unit: 's'
  723. }
  724. },
  725. itemFormSub() {
  726. this.$refs['itemForm'].validate((valid) => {
  727. if (!valid) return;
  728. let data = this.itemForm
  729. if (this.isItemEdit) {
  730. if (data.oldItemGroupId !== data.itemGroupId) {
  731. const arr = this.itemTableData.filter(item => {
  732. return data.itemGroupId === item.itemGroupId
  733. })
  734. if (arr.length) {
  735. this.$message({
  736. message: '当前数据组已配置',
  737. type: 'warning'
  738. })
  739. return
  740. }
  741. }
  742. this.itemTableData = this.itemTableData.map(item => {
  743. if (item.itemGroupId === data.oldItemGroupId) {
  744. return data
  745. }
  746. return item
  747. })
  748. } else {
  749. const arr = this.itemTableData.filter(item => {
  750. return data.itemGroupId === item.itemGroupId
  751. })
  752. if (arr.length) {
  753. this.$message({
  754. message: '当前数据组已配置',
  755. type: 'warning'
  756. })
  757. return
  758. }
  759. this.itemTableData.push(data)
  760. }
  761. this.saveConfigInfo((data) => {
  762. this.itemFormClose()
  763. this.handelConfig(data.id)
  764. })
  765. })
  766. },
  767. itemFormClose() {
  768. this.groupDialog = false
  769. this.itemForm = {
  770. itemGroupId: '',
  771. interval: '10',
  772. unit: 's'
  773. }
  774. this.isItemEdit = false
  775. },
  776. editItem(row) {
  777. const arr = this.itemTableData.filter(item => {
  778. return row.itemGroupId === item.itemGroupId
  779. })
  780. this.itemForm = {
  781. oldItemGroupId: arr[0].itemGroupId,
  782. itemGroupId: arr[0].itemGroupId,
  783. interval: arr[0].interval,
  784. unit: arr[0].unit
  785. }
  786. this.groupDialog = true
  787. this.isItemEdit = true
  788. },
  789. delItem(row) {
  790. this.itemTableData = this.itemTableData.filter(item => {
  791. return row.itemGroupId !== item.itemGroupId
  792. })
  793. this.saveConfigInfo((data) => {
  794. this.handelConfig(data.id)
  795. })
  796. },
  797. deleteCollector(row) {
  798. if (row.runStatus === 1 && row.onLine === 1) {
  799. this.$message({
  800. message: '采集器已启动,请先停止采集器再删除',
  801. type: 'warning'
  802. })
  803. return
  804. }
  805. this.$confirm('是否删除该采集器?', '提示', {
  806. confirmButtonText: '确定',
  807. cancelButtonText: '取消',
  808. type: 'warning'
  809. }).then(() => {
  810. deleteCollectorApi(row.id).then(json => {
  811. this.$message({
  812. type: json.code === 200 ? 'success' : 'warning',
  813. message: json.code === 200 ? '删除成功!' : json.msg
  814. });
  815. this.getCollectorList()
  816. })
  817. }).catch(() => {
  818. });
  819. },
  820. downloadApp() {
  821. window.open(process.env.VUE_APP_BASE_API + '/cy-collector.7z')
  822. },
  823. itemSettingBtn() {
  824. this.dialogSetting = true
  825. },
  826. handelSettingSubmit() {
  827. this.$refs['configForm'].validate((valid) => {
  828. if (valid) {
  829. this.saveConfigInfo((data) => {
  830. this.dialogSetting = false
  831. this.handelConfig(data.id)
  832. })
  833. }
  834. })
  835. },
  836. handelSettingCancel() {
  837. this.dialogSetting = false
  838. },
  839. handelEdit(row) {
  840. this.diatitle = '编辑采集器'
  841. this.dialogAdd = true
  842. this.addForm = {
  843. id: row.id,
  844. ip: row.ipAddr,
  845. name: row.clientName
  846. }
  847. }
  848. }
  849. }
  850. </script>
  851. <style rel="stylesheet/scss" lang="scss" scoped>
  852. .unit-my {
  853. input {
  854. width: 80px;
  855. }
  856. }
  857. .fixed-width .el-button--mini {
  858. padding: 7px 0px;
  859. }
  860. </style>