Просмотр исходного кода

更新 NginxLog.vue 日志页面和接口

reghao 2 месяцев назад
Родитель
Сommit
105bcc22f8
3 измененных файлов с 350 добавлено и 236 удалено
  1. 26 1
      src/api/devops.js
  2. 2 1
      src/router/background_backend.js
  3. 322 234
      src/views/devops/srv/NginxLog.vue

+ 26 - 1
src/api/devops.js

@@ -11,7 +11,8 @@ const devopsApi = {
   getAliyunKeyList: '/api/devops/machine/aliyun/key',
   getMachineProcList: '/api/devops/machine/proc',
   getMachineTaskList: '/api/devops/machine/task',
-  getMachineNginx: '/api/devops/srv/nginx',
+  getMachineNginx: '/api/search1/nginx',
+  getMachineNginx1: '/api/devops/srv/nginx',
   getDockerList: '/api/devops/docker',
   getCompilerList: '/api/devops/build/compiler',
   getRepoAuthList: '/api/devops/build/repoauth',
@@ -128,6 +129,30 @@ export function getNginxLogChart(queryInfo) {
   return get(devopsApi.getMachineNginx + '/log/chart', queryInfo)
 }
 
+export function getNginxLogChart1(queryInfo) {
+  return get(devopsApi.getMachineNginx + '/log/chart1', queryInfo)
+}
+
+export function getNginxLogChart2(queryInfo) {
+  return get(devopsApi.getMachineNginx + '/log/chart2', queryInfo)
+}
+
+export function getNginxLogChart3(queryInfo) {
+  return get(devopsApi.getMachineNginx + '/log/chart3', queryInfo)
+}
+
+export function getNginxLogChart4(queryInfo) {
+  return get(devopsApi.getMachineNginx + '/log/chart4', queryInfo)
+}
+
+export function getNginxLogChart5(queryInfo) {
+  return get(devopsApi.getMachineNginx + '/log/chart5', queryInfo)
+}
+
+export function getNginxLogChart6(queryInfo) {
+  return get(devopsApi.getMachineNginx + '/log/chart6', queryInfo)
+}
+
 export function getDockerfileImageList() {
   return get(devopsApi.getDockerList + '/image')
 }

+ 2 - 1
src/router/background_backend.js

@@ -8,6 +8,7 @@ const AdminDubboService = () => import('views/admin/backend/AdminDubboService')
 const AdminSpringCloudService = () => import('views/admin/backend/AdminSpringCloudService')
 const AdminBackendLog = () => import('views/admin/backend/AdminBackendLog')
 const AdminAccessLog = () => import('views/admin/backend/AdminAccessLog')
+const NginxLog = () => import('views/devops/srv/NginxLog')
 const AdminRuntimeLog = () => import('views/admin/backend/AdminRuntimeLog')
 
 export default {
@@ -48,7 +49,7 @@ export default {
       name: 'AccessLog',
       title: '访问日志',
       icon: 'el-icon-loading',
-      component: AdminAccessLog,
+      component: NginxLog,
       meta: { needAuth: true, roles: ['tnb_admin'] }
     },
     {

+ 322 - 234
src/views/devops/srv/NginxLog.vue

@@ -7,144 +7,165 @@
           <span v-if="!wsConnectStatus" style="color: red; margin: 5px">WebSocket 未连接</span>
         </span>
         <el-select
-          v-model="env"
-          size="mini"
-          placeholder="环境"
-          style="margin-left: 5px"
-          @change="onSelectChange"
-        >
-          <el-option
-            v-for="(item, index) in envList"
-            :key="index"
-            :label="item.label"
-            :value="item.value"
-          />
-        </el-select>
-        <el-select
-          v-model="machineId"
-          size="mini"
-          placeholder="机器"
-          style="margin-left: 5px"
-          @change="onSelectChange1"
-        >
-          <el-option
-            v-for="(item, index) in machineList"
-            :key="index"
-            :label="item.label"
-            :value="item.value"
-          />
-        </el-select>
-        <el-button size="mini" type="warning" icon="el-icon-refresh" style="margin-left: 5px" @click="onRefresh">刷新</el-button>
-        <el-button size="mini" type="warning" icon="el-icon-files" style="margin-left: 5px" @click="onGetImages">镜像列表</el-button>
-      </el-row>
-      <el-row style="margin-top: 10px">
-        <el-select
-          v-model="selectedDateStr"
+          v-model="queryInfo.dateStr"
           size="mini"
           placeholder="日期"
           style="margin-left: 5px"
-          @change="getLogChart"
+          @change="onSelectChange"
         >
           <el-option
             v-for="(item, index) in logDateList"
             :key="index"
-            :label="item.date"
-            :value="item.date"
+            :label="item.name"
+            :value="item.name"
           />
         </el-select>
       </el-row>
     </el-header>
     <el-main>
-      <el-row>
-        <div id="chart1" style="height:400px;" />
+      <el-row style="padding: 5px">
+        <el-card>
+          <div slot="header" class="clearfix">
+            <span>全站每日请求数量</span>
+            <el-button style="float: right; padding: 3px 0" type="text" @click="onRefreshChart1">刷新</el-button>
+          </div>
+          <div id="chart1" style="height:400px;" />
+        </el-card>
+      </el-row>
+      <el-row style="padding: 5px">
+        <el-card>
+          <div slot="header" class="clearfix">
+            <span>全站 <span style="color: red">{{ queryInfo.dateStr }}</span> 每秒请求数量</span>
+            <el-button style="float: right; padding: 3px 0" type="text" @click="onRefreshChart2">刷新</el-button>
+          </div>
+          <div id="chart2" style="height:400px;" />
+        </el-card>
+      </el-row>
+      <el-row style="padding: 5px">
+        <el-card>
+          <div slot="header" class="clearfix">
+            <span>全站 <span style="color: red">{{ queryInfo.dateStr }}</span> 各 URL 访问数量</span>
+            <el-button style="float: right; padding: 3px 0" type="text" @click="onShowDialog">刷新</el-button>
+          </div>
+          <el-table
+            :data="urlList"
+            border
+            height="480"
+            style="width: 100%"
+          >
+            <el-table-column
+              fixed="left"
+              label="No"
+              type="index"
+            />
+            <el-table-column
+              prop="name"
+              label="URL"
+            />
+            <el-table-column
+              prop="total"
+              label="访问量"
+            />
+            <el-table-column
+              fixed="right"
+              label="操作"
+              width="280"
+            >
+              <template slot-scope="scope">
+                <el-button
+                  style="margin-top: 5px; margin-left: 5px"
+                  size="mini"
+                  type="success"
+                  @click="onGetImages(scope.$index, scope.row)"
+                >每日分布</el-button>
+                <el-button
+                  style="margin-top: 5px; margin-left: 5px"
+                  size="mini"
+                  type="success"
+                  @click="onGetImages5(scope.$index, scope.row)"
+                >历史分布</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-card>
       </el-row>
     </el-main>
 
     <el-dialog
-      title="镜像列表"
+      :title="chart5DialogTitle"
       append-to-body
-      :visible.sync="showImageDialog"
+      :visible.sync="showChart5Dialog"
       width="70%"
       center
+      @opened="handleDialogOpened5"
+      @closed="handleDialogClosed5"
     >
       <template>
-        <el-select
-          v-model="queryInfo.type"
-          size="mini"
-          style="margin-left: 5px"
-        >
-          <el-option label="关键字匹配" value="1" />
-          <el-option label="前缀匹配" value="2" />
-        </el-select>
-        <el-input
-          v-model="queryInfo.keyword"
-          size="mini"
-          style="width: 20%; padding: 3px"
-          clearable
-          placeholder="标题"
-        />
-        <el-button size="mini" type="success" icon="el-icon-search" style="margin-left: 5px" @click="onGetImages">查询</el-button>
-        <el-button size="mini" type="danger" icon="el-icon-search" style="margin-left: 5px" @click="onDeleteImages">删除未用镜像</el-button>
-        <el-table
-          ref="multipleTable"
-          :data="dataList1"
-          border
-          height="480"
-          style="margin-left: 5px; width: 100%"
-          @selection-change="handleSelectionChange"
-        >
-          <el-table-column
-            type="selection"
-          />
-          <el-table-column
-            prop="repoTag"
-            label="镜像标签"
-          />
-          <el-table-column
-            prop="createdAt"
-            label="创建时间"
-          />
-          <el-table-column
-            prop="totalContainers"
-            label="使用的容器数量"
-          />
-        </el-table>
-        <el-button size="mini" type="success" icon="el-icon-minus" style="margin: 5px" @click="toggleSelection()">取消已选择</el-button>
-        <el-button size="mini" type="success" icon="el-icon-delete" style="margin: 5px" @click="deleteSelection()">删除已选择</el-button>
+        <div id="chart5" style="height:400px;" />
+      </template>
+    </el-dialog>
+    <el-dialog
+      :title="chart4DialogTitle"
+      append-to-body
+      :visible.sync="showChart4Dialog"
+      width="70%"
+      center
+      @opened="handleDialogOpened"
+      @closed="handleDialogClosed"
+    >
+      <template>
+        <div id="chart4" style="height:400px;" />
       </template>
     </el-dialog>
   </el-container>
 </template>
 
 <script>
-import {getEnvList, getMachineSessions, getNginxLog, getNginxLogChart} from '@/api/devops'
+import {
+  getNginxLog,
+  getNginxLogChart, getNginxLogChart1,
+  getNginxLogChart2, getNginxLogChart3,
+  getNginxLogChart4, getNginxLogChart5, getNginxLogChart6
+} from '@/api/devops'
 
 export default {
   name: 'NginxLog',
   data() {
     return {
-      env: 'test',
-      envList: [],
-      machineId: '',
-      machineList: [],
       queryInfo: {
-        type: '1',
-        keyword: ''
+        dateStr: '',
+        url: ''
       },
-      multipleSelection: [],
-      dataList: [],
-      dockerContainerList: [],
-      showImageDialog: false,
-      dataList1: [],
-      wsClient: null,
-      wsConnectStatus: false,
-      wsReconnectLock: false,
+      logDateList: [],
+      urlList: [],
+      // **********************************************************************
+      showChart4Dialog: false,
+      chart4DialogTitle: '',
+      showChart5Dialog: false,
+      chart5DialogTitle: '',
+      // **********************************************************************
       myChart: null,
       xData: [],
       yData: [],
-      logDateList: [],
-      selectedDateStr: '',
-      chartDataList: []
+      myChart1: null,
+      xData1: [],
+      yData1: [],
+      myChart2: null,
+      xData2: [],
+      yData2: [],
+      myChart4: null,
+      xData4: [],
+      yData4: [],
+      myChart5: null,
+      xData5: [],
+      yData5: [],
+      myChart6: null,
+      xData6: [],
+      yData6: [],
+      // **********************************************************************
+      wsClient: null,
+      wsConnectStatus: false,
+      wsReconnectLock: false
     }
   },
   mounted() {
@@ -152,22 +173,42 @@ export default {
   },
   created() {
     document.title = 'NginxLog'
+    const dateStr = this.$route.query.dateStr
+    if (dateStr !== undefined && dateStr !== null) {
+      this.queryInfo.dateStr = dateStr
+    } else {
+      var current = new Date()
+      this.queryInfo.dateStr = this.formatDate(current)
+    }
 
-    getEnvList().then(resp => {
-      if (resp.code === 0) {
-        this.env = resp.data.userEnv
-        this.envList = resp.data.envList
-        this.getMachineList(this.env)
-      } else {
-        this.$message.error(resp.msg)
-      }
-    }).catch(error => {
-      this.$message.error(error.message)
-    })
     this.getData()
-    this.initWebSocket()
+    // this.initWebSocket()
   },
   methods: {
+    formatDate(date) {
+      const year = date.getFullYear()
+      const month = date.getMonth() + 1
+      const day = date.getDate()
+      return `${year}-${this.pad(month)}-${this.pad(day)}`
+    },
+    formatTime(date) {
+      const hour = date.getHours()
+      const minute = date.getMinutes()
+      const second = date.getSeconds()
+      return `${this.pad(hour)}:${this.pad(minute)}:${this.pad(second)}`
+    },
+    formatDateTime(date) {
+      const year = date.getFullYear()
+      const month = date.getMonth() + 1
+      const day = date.getDate()
+      const hour = date.getHours()
+      const minute = date.getMinutes()
+      const second = date.getSeconds()
+      return `${year}-${this.pad(month)}-${this.pad(day)} ${this.pad(hour)}:${this.pad(minute)}:${this.pad(second)}`
+    },
+    pad(num) {
+      return num.toString().padStart(2, '0')
+    },
     getData() {
       getNginxLog().then(resp => {
         if (resp.code === 0) {
@@ -179,15 +220,131 @@ export default {
         this.$message.error(error.message)
       })
     },
-    getLogChart() {
-      const queryInfo = {}
-      queryInfo.dateStr = this.selectedDateStr
-      getNginxLogChart(queryInfo).then(resp => {
+    onGetImages(index, row) {
+      this.queryInfo.url = row.name
+      this.showChart4Dialog = true
+      this.chart4DialogTitle = row.name + ' 接口 ' + this.queryInfo.dateStr + ' 请求时间分布'
+    },
+    handleDialogOpened() {
+      // 使用$nextTick确保DOM已完全渲染
+      this.$nextTick(() => {
+        getNginxLogChart4(this.queryInfo).then(resp => {
+          if (resp.code === 0) {
+            const respData = resp.data
+            const xData = respData[0]
+            const yData = respData[1]
+
+            var option4 = {
+              title: {
+                text: 'Nginx Log'
+              },
+              tooltip: {},
+              legend: {
+                data: ['reqs/s']
+              },
+              xAxis: {
+                type: 'category',
+                data: xData
+              },
+              yAxis: {},
+              series: [{
+                name: 'reqs/s',
+                type: 'line',
+                smooth: true,
+                data: yData
+              }],
+              dataZoom: [{ // 这个是设置滚动条的,可以拉动这个滚动条来改变你的图形的显示比例
+                type: 'slider',
+                show: true, // flase直接隐藏图形
+                xAxisIndex: [0],
+                left: '9%', // 滚动条靠左侧的百分比
+                bottom: -5,
+                start: 0, // 滚动条的起始位置
+                end: 50 // 滚动条的截止位置(按比例分割你的柱状图x轴长度)
+              }]
+            }
+            this.myChart4 = this.$echarts.init(document.getElementById('chart4'))
+            this.myChart4.setOption(option4)
+          } else {
+            this.$message.error(resp.msg)
+          }
+        }).catch(error => {
+          this.$message.error(error.message)
+        })
+      })
+    },
+    handleDialogClosed() {
+      if (this.myChart4) {
+        this.myChart4.dispose()
+        this.myChart4 = null
+      }
+    },
+    onGetImages5(index, row) {
+      this.queryInfo.url = row.name
+      this.showChart5Dialog = true
+      this.chart5DialogTitle = row.name + ' 接口 ' + this.queryInfo.dateStr + ' 请求历史分布'
+    },
+    handleDialogOpened5() {
+      this.$nextTick(() => {
+        getNginxLogChart5(this.queryInfo).then(resp => {
+          if (resp.code === 0) {
+            const respData = resp.data
+            const xData = respData[0]
+            const yData = respData[1]
+
+            var option5 = {
+              title: {
+                text: '每日请求数量',
+                subtext: '最近一周',
+                x: 'center',
+                y: 'top',
+                textAlign: 'center'
+              },
+              tooltip: {},
+              xAxis: {
+                data: xData
+              },
+              yAxis: {},
+              series: [{
+                name: '访问数量',
+                type: 'bar',
+                data: yData
+              }]
+            }
+            this.myChart5 = this.$echarts.init(document.getElementById('chart5'))
+            this.myChart5.setOption(option5)
+          } else {
+            this.$message.error(resp.msg)
+          }
+        }).catch(error => {
+          this.$message.error(error.message)
+        })
+      })
+    },
+    handleDialogClosed5() {
+      if (this.myChart5) {
+        this.myChart5.dispose()
+        this.myChart5 = null
+      }
+    },
+    onShowDialog() {
+      getNginxLogChart3(this.queryInfo).then(resp => {
+        if (resp.code === 0) {
+          this.urlList = resp.data
+        } else {
+          this.$message.error(resp.msg)
+        }
+      }).catch(error => {
+        this.$message.error(error.message)
+      })
+    },
+    onRefreshChart1() {
+      getNginxLogChart1(this.queryInfo).then(resp => {
         if (resp.code === 0) {
           const respData = resp.data
           const xData = respData[0]
           const yData = respData[1]
-          this.myChart.setOption({
+          this.myChart1.setOption({
             xAxis: {
               data: xData
             },
@@ -202,10 +359,20 @@ export default {
         this.$message.error(error.message)
       })
     },
-    getMachineList(env) {
-      getMachineSessions(env).then(resp => {
+    onRefreshChart2() {
+      getNginxLogChart2(this.queryInfo).then(resp => {
         if (resp.code === 0) {
-          this.machineList = resp.data
+          const respData = resp.data
+          const xData = respData[0]
+          const yData = respData[1]
+          this.myChart2.setOption({
+            xAxis: {
+              data: xData
+            },
+            series: [{
+              data: yData
+            }]
+          })
         } else {
           this.$message.error(resp.msg)
         }
@@ -213,118 +380,40 @@ export default {
         this.$message.error(error.message)
       })
     },
-    handleSelectionChange(val) {
-      this.multipleSelection = val
-    },
-    toggleSelection(rows) {
-      if (rows) {
-        rows.forEach(row => {
-          this.$refs.multipleTable.toggleRowSelection(row)
-        })
-      } else {
-        this.$refs.multipleTable.clearSelection()
-      }
-    },
-    deleteSelection() {
-      if (this.multipleSelection.length === 0) {
-        this.$message.warning('请先选择要删除的项')
-        return
-      }
-
-      const imageIds = []
-      for (const item of this.multipleSelection) {
-        imageIds.push(item.imageId)
-      }
-      this.$confirm('确定要删除选择的镜像?', '提示', {
-        confirmButtonText: '确定',
-        cancelButtonText: '取消',
-        type: 'warning'
-      }).then(() => {
-        const formData = new FormData()
-        formData.append('imageIds', imageIds)
-
-        const jsonPayload = {}
-        jsonPayload.machineId = this.machineId
-        jsonPayload.ops = 'imageRm'
-        jsonPayload.payload = imageIds
-        this.sendMessage(JSON.stringify(jsonPayload))
-      }).catch(() => {
-        this.$message({
-          type: 'info',
-          message: '已取消'
-        })
-      })
-    },
-    handleDelete(index, row) {
-      this.$confirm('确定要删除选择的容器?', '提示', {
-        confirmButtonText: '确定',
-        cancelButtonText: '取消',
-        type: 'warning'
-      }).then(() => {
-        const formData = new FormData()
-        formData.append('opsType', 3)
-        formData.append('containerId', row.containerId)
-
-        const containerIds = []
-        containerIds.push(row.containerId)
-        const jsonPayload = {}
-        jsonPayload.machineId = this.machineId
-        jsonPayload.ops = 'containerRm'
-        jsonPayload.payload = containerIds
-        this.sendMessage(JSON.stringify(jsonPayload))
-      }).catch(() => {
-        this.$message({
-          type: 'info',
-          message: '已取消'
-        })
-      })
-    },
-    onRefresh() {
-      const jsonPayload = {}
-      jsonPayload.machineId = this.machineId
-      jsonPayload.ops = 'containerList'
-      this.sendMessage(JSON.stringify(jsonPayload))
-    },
-    onGetImages() {
-      if (this.machineId === '') {
-        this.$message.warning('请选择机器')
-        return
-      }
-
-      const jsonPayload = {}
-      jsonPayload.machineId = this.machineId
-      jsonPayload.ops = 'imageList'
-      jsonPayload.dockerQuery = this.queryInfo
-      this.sendMessage(JSON.stringify(jsonPayload))
-      this.showImageDialog = true
-    },
-    onDeleteImages() {
-      const jsonPayload = {}
-      jsonPayload.machineId = this.machineId
-      jsonPayload.ops = 'imageRmUnused'
-      jsonPayload.dockerQuery = this.queryInfo
-      this.sendMessage(JSON.stringify(jsonPayload))
-    },
     onSelectChange() {
-      this.machineId = ''
-      this.getMachineList(this.env)
-    },
-    onSelectChange1() {
-      if (!this.wsConnectStatus) {
-        this.$message.warning('websocket 未连接')
-        return
-      }
-
-      const jsonPayload = {}
-      jsonPayload.machineId = this.machineId
-      jsonPayload.ops = 'containerList'
-      this.sendMessage(JSON.stringify(jsonPayload))
+      this.queryInfo.url = ''
+      this.$router.push({
+        path: '/bg/backend/access_log',
+        query: this.queryInfo
+      })
     },
     // ****************************************************************************************************************
-    // WebSocket相关
+    // chart 相关
     // ****************************************************************************************************************
     initChart() {
-      var option = {
+      var chartOption1 = {
+        title: {
+          text: '每日请求数量',
+          subtext: '最近一周',
+          x: 'center',
+          y: 'top',
+          textAlign: 'center'
+        },
+        tooltip: {},
+        xAxis: {
+          data: this.xData1
+        },
+        yAxis: {},
+        series: [{
+          name: '访问数量',
+          type: 'bar',
+          data: this.yData1
+        }]
+      }
+      this.myChart1 = this.$echarts.init(document.getElementById('chart1'))
+      this.myChart1.setOption(chartOption1)
+
+      var option2 = {
         title: {
           text: 'Nginx Log'
         },
@@ -343,14 +432,14 @@ export default {
         },
         xAxis: {
           type: 'category',
-          data: this.xData
+          data: this.xData2
         },
         yAxis: {},
         series: [{
           name: 'reqs/s',
           type: 'line',
           smooth: true,
-          data: this.yData
+          data: this.yData2
         }],
         dataZoom: [{ // 这个是设置滚动条的,可以拉动这个滚动条来改变你的图形的显示比例
           type: 'slider',
@@ -362,12 +451,11 @@ export default {
           end: 50 // 滚动条的截止位置(按比例分割你的柱状图x轴长度)
         }]
       }
-
-      this.myChart = this.$echarts.init(document.getElementById('chart1'))
-      this.myChart.setOption(option)
+      this.myChart2 = this.$echarts.init(document.getElementById('chart2'))
+      this.myChart2.setOption(option2)
     },
     // ****************************************************************************************************************
-    // WebSocket相关
+    // WebSocket 相关
     // ****************************************************************************************************************
     getUrl() {
       const protocol = location.protocol