loki采集k8s日志

news2024/11/29 12:53:12

前言

loki 是轻量、易用的日志聚合系统。如果你的k8s集群规模并不大,推荐使用grafana+loki的方案来做微服务日志的采集;

Loki组成

loki架构很简单,主要由3部分组成:
loki:服务端,负责存储日志和处理查询;
promtail:采集端,负责采集日志发送给loki;
grafana:负责采集日志的展示;

环境:
k8s v1.22.10

创建loki资源

vim loki-rbac.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: loki
  namespace: thanos-monitoring
 
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: loki
  namespace: thanos-monitoring
rules:
- apiGroups:
  - extensions
  resourceNames:
  - loki
  resources:
  - podsecuritypolicies
  verbs:
  - use
 
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: loki
  namespace: thanos-monitoring
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: loki
subjects:
- kind: ServiceAccount
  name: loki

vim loki-nodeport.yaml

apiVersion: v1
kind: Service
metadata:
  name: loki-nodeport
  namespace: thanos-monitoring
spec:
  type: NodePort
  ports:
  - name: http
    port: 3100
    targetPort: 3100
    nodePort: 30100
  selector:
    app: loki

vim loki.yaml

---
apiVersion: v1
kind: Service
metadata:
  name: loki-headless
  namespace: thanos-monitoring
  labels:
    app: loki
spec:
  type: ClusterIP
  clusterIP: None
  ports:
    - port: 3100
      protocol: TCP
      name: http-metrics
      targetPort: http-metrics
  selector:
    app: loki
 
---
apiVersion: v1
kind: Service
metadata:
  name: loki
  namespace: thanos-monitoring
  labels:
    app: loki
spec:
  type: ClusterIP
  ports:
    - port: 3100
      protocol: TCP
      name: http-metrics
      targetPort: http-metrics
  selector:
    app: loki
 
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: loki
  namespace: thanos-monitoring
  labels:
    app: loki
spec:
  podManagementPolicy: OrderedReady
  replicas: 1
  selector:
    matchLabels:
      app: loki
  serviceName: loki-headless
  updateStrategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: loki
    spec:
      serviceAccountName: loki
      securityContext:
          fsGroup: 10001
          runAsGroup: 10001
          runAsNonRoot: true
          runAsUser: 10001
      initContainers: []
      containers:
        - name: loki
          image: grafana/loki:2.0.0
          imagePullPolicy: IfNotPresent
          args:
            - -config.file=/etc/loki/loki.yaml
          volumeMounts:
            - name: config
              mountPath: /etc/loki
            - name: storage
              mountPath: /data
          ports:
            - name: http-metrics
              containerPort: 3100
              protocol: TCP
          livenessProbe:
            httpGet: 
              path: /ready
              port: http-metrics
              scheme: HTTP
            initialDelaySeconds: 45
            timeoutSeconds: 1
            periodSeconds: 10
            successThreshold: 1
            failureThreshold: 3
          readinessProbe:
            httpGet: 
              path: /ready
              port: http-metrics
              scheme: HTTP
            initialDelaySeconds: 45
            timeoutSeconds: 1
            periodSeconds: 10
            successThreshold: 1
            failureThreshold: 3
          securityContext:
            readOnlyRootFilesystem: true
      terminationGracePeriodSeconds: 4800
      volumes:
        - name: config
          configMap:
            defaultMode: 420
            name: loki
  volumeClaimTemplates:
  - metadata:
      name: storage
      labels:
        app: loki
    spec:
      storageClassName: managed-nfs-storage
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: "2Gi"

vim loki-configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: loki
  namespace: thanos-monitoring
  labels:
    app: loki
data:
  loki.yaml: |
    auth_enabled: false
    ingester:
      chunk_idle_period: 3m      # 如果块没有达到最大的块大小,那么在刷新之前,块应该在内存中不更新多长时间
      chunk_block_size: 262144
      chunk_retain_period: 1m      # 块刷新后应该在内存中保留多长时间
      max_transfer_retries: 0      # Number of times to try and transfer chunks when leaving before falling back to flushing to the store. Zero = no transfers are done.
      lifecycler:       #配置ingester的生命周期,以及在哪里注册以进行发现
        ring:
          kvstore:
            store: inmemory      # 用于ring的后端存储,支持consul、etcd、inmemory
          replication_factor: 1      # 写入和读取的ingesters数量,至少为1(为了冗余和弹性,默认情况下为3)
    limits_config:
      enforce_metric_name: false
      reject_old_samples: true      # 旧样品是否会被拒绝
      reject_old_samples_max_age: 168h      # 拒绝旧样本的最大时限
    schema_config:      # 配置从特定时间段开始应该使用哪些索引模式
      configs:
      - from: 2023-04-12      # 创建索引的日期。如果这是唯一的schema_config,则使用过去的日期,否则使用希望切换模式时的日期
        store: boltdb-shipper      # 索引使用哪个存储,如:cassandra, bigtable, dynamodb,或boltdb
        object_store: filesystem      # 用于块的存储,如:gcs, s3, inmemory, filesystem, cassandra,如果省略,默认值与store相同
        schema: v11
        index:      # 配置如何更新和存储索引
          prefix: index_      # 所有周期表的前缀
          period: 24h      # 表周期
    server:
      http_listen_port: 3100
    storage_config:      # 为索引和块配置一个或多个存储
      boltdb_shipper:
        active_index_directory: /data/loki/boltdb-shipper-active
        cache_location: /data/loki/boltdb-shipper-cache
        cache_ttl: 24h         
        shared_store: filesystem
      filesystem:
        directory: /data/loki/chunks
    chunk_store_config:      # 配置如何缓存块,以及在将它们保存到存储之前等待多长时间
      max_look_back_period: 0s      #限制查询数据的时间,默认是禁用的,这个值应该小于或等于table_manager.retention_period中的值
    table_manager:
      retention_deletes_enabled: false      # 日志保留周期开关,用于表保留删除
      retention_period: 0s       # 日志保留周期,保留期必须是索引/块的倍数
    compactor:
      working_directory: /data/loki/boltdb-shipper-compactor
      shared_store: filesystem

标题创建promtail资源

vim loki-promtail-rbac.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: loki-promtail
  labels:
    app: promtail
  namespace: thanos-monitoring
 
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  labels:
    app: promtail
  name: promtail-clusterrole
rules:
- apiGroups: [""] # "" indicates the core API group
  resources:
  - nodes
  - nodes/proxy
  - services
  - endpoints
  - pods
  verbs: ["get", "watch", "list"]
 
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: promtail-clusterrolebinding
  labels:
    app: promtail
subjects:
  - kind: ServiceAccount
    name: loki-promtail
    namespace: thanos-monitoring
roleRef:
  kind: ClusterRole
  name: promtail-clusterrole
  apiGroup: rbac.authorization.k8s.io

vim loki-promtail.yaml

apiVersion: v1
kind: Service
metadata:
  name: loki-promtail-headless
  namespace: thanos-monitoring
  labels:
    app: promtail
spec:
  clusterIP: None
  ports:
    - port: 3101
      protocol: TCP
      name: http-metrics
      targetPort: http-metrics
  selector:
    app: promtail
 
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: loki-promtail
  namespace: thanos-monitoring
  labels:
    app: promtail
spec:
  selector:
    matchLabels:
      app: promtail
  updateStrategy:
    rollingUpdate:
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: promtail
    spec:
      serviceAccountName: loki-promtail
      containers:
        - name: promtail
          image: grafana/promtail:2.0.0
          imagePullPolicy: IfNotPresent
          args: 
          - -config.file=/etc/promtail/promtail.yaml
          - -client.url=http://loki:3100/loki/api/v1/push
          env: 
          - name: HOSTNAME
            valueFrom: 
              fieldRef: 
                apiVersion: v1
                fieldPath: spec.nodeName
          volumeMounts:
          - mountPath: /etc/promtail
            name: config
          - mountPath: /run/promtail
            name: run
          - mountPath: /var/lib/docker/containers
            name: docker
            readOnly: true
          - mountPath: /var/log/pods
            name: pods
            readOnly: true
          ports:
          - containerPort: 3101
            name: http-metrics
            protocol: TCP
          securityContext:
            readOnlyRootFilesystem: true
            runAsGroup: 0
            runAsUser: 0
          readinessProbe:
            failureThreshold: 5
            httpGet:
              path: /ready
              port: http-metrics
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 1
      tolerations:
      - effect: NoSchedule
        key: node-role.kubernetes.io/master
        operator: Exists
      volumes:
        - name: config
          configMap:
            defaultMode: 420
            name: loki-promtail
        - name: run
          hostPath:
            path: /run/promtail
            type: ""
        - name: docker
          hostPath:
            path: /var/lib/docker/containers
        - name: pods
          hostPath:
            path: /var/log/pods

vim loki-promtail-configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: loki-promtail
  namespace: thanos-monitoring
  labels:
    app: promtail
data:
  promtail.yaml: |
    client:      # 配置Promtail如何连接到Loki的实例
      backoff_config:      # 配置当请求失败时如何重试请求给Loki
        max_period: 5m 
        max_retries: 10
        min_period: 500ms
      batchsize: 1048576      # 发送给Loki的最大批次大小(以字节为单位)
      batchwait: 1s      # 发送批处理前等待的最大时间(即使批次大小未达到最大值)
      external_labels: {}      # 所有发送给Loki的日志添加静态标签
      timeout: 10s      # 等待服务器响应请求的最大时间
    positions:
      filename: /run/promtail/positions.yaml
    server:
      http_listen_port: 3101
    target_config:
      sync_period: 10s
    scrape_configs:
    - job_name: kubernetes-pods-name
      pipeline_stages:
        - docker: {}
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      - source_labels:
        - __meta_kubernetes_pod_label_name
        target_label: __service__
      - source_labels:
        - __meta_kubernetes_pod_node_name
        target_label: __host__
      - action: drop
        regex: ''
        source_labels:
        - __service__
      - action: labelmap
        regex: __meta_kubernetes_pod_label_(.+)
      - action: replace
        replacement: $1
        separator: /
        source_labels:
        - __meta_kubernetes_namespace
        - __service__
        target_label: job
      - action: replace
        source_labels:
        - __meta_kubernetes_namespace
        target_label: namespace
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_name
        target_label: pod
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_container_name
        target_label: container
      - replacement: /var/log/pods/*$1/*.log
        separator: /
        source_labels:
        - __meta_kubernetes_pod_uid
        - __meta_kubernetes_pod_container_name
        target_label: __path__
    - job_name: kubernetes-pods-app
      pipeline_stages:
        - docker: {}
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      - action: drop
        regex: .+
        source_labels:
        - __meta_kubernetes_pod_label_name
      - source_labels:
        - __meta_kubernetes_pod_label_app
        target_label: __service__
      - source_labels:
        - __meta_kubernetes_pod_node_name
        target_label: __host__
      - action: drop
        regex: ''
        source_labels:
        - __service__
      - action: labelmap
        regex: __meta_kubernetes_pod_label_(.+)
      - action: replace
        replacement: $1
        separator: /
        source_labels:
        - __meta_kubernetes_namespace
        - __service__
        target_label: job
      - action: replace
        source_labels:
        - __meta_kubernetes_namespace
        target_label: namespace
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_name
        target_label: pod
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_container_name
        target_label: container
      - replacement: /var/log/pods/*$1/*.log
        separator: /
        source_labels:
        - __meta_kubernetes_pod_uid
        - __meta_kubernetes_pod_container_name
        target_label: __path__
    - job_name: kubernetes-pods-direct-controllers
      pipeline_stages:
        - docker: {}
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      - action: drop
        regex: .+
        separator: ''
        source_labels:
        - __meta_kubernetes_pod_label_name
        - __meta_kubernetes_pod_label_app
      - action: drop
        regex: '[0-9a-z-.]+-[0-9a-f]{8,10}'
        source_labels:
        - __meta_kubernetes_pod_controller_name
      - source_labels:
        - __meta_kubernetes_pod_controller_name
        target_label: __service__
      - source_labels:
        - __meta_kubernetes_pod_node_name
        target_label: __host__
      - action: drop
        regex: ''
        source_labels:
        - __service__
      - action: labelmap
        regex: __meta_kubernetes_pod_label_(.+)
      - action: replace
        replacement: $1
        separator: /
        source_labels:
        - __meta_kubernetes_namespace
        - __service__
        target_label: job
      - action: replace
        source_labels:
        - __meta_kubernetes_namespace
        target_label: namespace
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_name
        target_label: pod
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_container_name
        target_label: container
      - replacement: /var/log/pods/*$1/*.log
        separator: /
        source_labels:
        - __meta_kubernetes_pod_uid
        - __meta_kubernetes_pod_container_name
        target_label: __path__
    - job_name: kubernetes-pods-indirect-controller
      pipeline_stages:
        - docker: {}
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      - action: drop
        regex: .+
        separator: ''
        source_labels:
        - __meta_kubernetes_pod_label_name
        - __meta_kubernetes_pod_label_app
      - action: keep
        regex: '[0-9a-z-.]+-[0-9a-f]{8,10}'
        source_labels:
        - __meta_kubernetes_pod_controller_name
      - action: replace
        regex: '([0-9a-z-.]+)-[0-9a-f]{8,10}'
        source_labels:
        - __meta_kubernetes_pod_controller_name
        target_label: __service__
      - source_labels:
        - __meta_kubernetes_pod_node_name
        target_label: __host__
      - action: drop
        regex: ''
        source_labels:
        - __service__
      - action: labelmap
        regex: __meta_kubernetes_pod_label_(.+)
      - action: replace
        replacement: $1
        separator: /
        source_labels:
        - __meta_kubernetes_namespace
        - __service__
        target_label: job
      - action: replace
        source_labels:
        - __meta_kubernetes_namespace
        target_label: namespace
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_name
        target_label: pod
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_container_name
        target_label: container
      - replacement: /var/log/pods/*$1/*.log
        separator: /
        source_labels:
        - __meta_kubernetes_pod_uid
        - __meta_kubernetes_pod_container_name
        target_label: __path__
    - job_name: kubernetes-pods-static
      pipeline_stages:
        - docker: {}
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      - action: drop
        regex: ''
        source_labels:
        - __meta_kubernetes_pod_annotation_kubernetes_io_config_mirror
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_label_component
        target_label: __service__
      - source_labels:
        - __meta_kubernetes_pod_node_name
        target_label: __host__
      - action: drop
        regex: ''
        source_labels:
        - __service__
      - action: labelmap
        regex: __meta_kubernetes_pod_label_(.+)
      - action: replace
        replacement: $1
        separator: /
        source_labels:
        - __meta_kubernetes_namespace
        - __service__
        target_label: job
      - action: replace
        source_labels:
        - __meta_kubernetes_namespace
        target_label: namespace
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_name
        target_label: pod
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_container_name
        target_label: container
      - replacement: /var/log/pods/*$1/*.log
        separator: /
        source_labels:
        - __meta_kubernetes_pod_annotation_kubernetes_io_config_mirror
        - __meta_kubernetes_pod_container_name
        target_label: __path__

部署grafana

mkdir -p /data/prometheus/grafana && chmod 755 /data/prometheus/grafana
docker run -d -p 3000:3000 -v /data/prometheus/grafana:/var/lib/grafana --name=grafana grafana/grafana:latest

grafana容器配置文件:/etc/grafana/grafana.ini。
访问ip:3000,初始账号密码为admin/admin,会要求更改密码。

添加数据源loki:

在这里插入图片描述
grafana模板:https://grafana.com/grafana/dashboards,我这里使用ID: 13639
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/422914.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

行程器,数显卡尺液晶驱动IC,VK1623段码LCD驱动芯片资料分享,封装LQFP100,QFP100,RAM映射48EGx8COM

永嘉微电/VINKA 型号:VK1623 封装形式:LQFP100/QFP100/DICE/COG KPP2609 概述 VK1623S是一个点阵式存储映射的LCD驱动器,可支持最大384点(48EGx8COM)的LCD屏。单片机可通过3/4线串行接口配置显示参数和发送显示数据…

Spring Cloud微服务网关Zuul的注解@EnableZuulProxy或@EnableZuulServer做了什么事情

一、Zuul的工作原理 Zuul 1.x的版本是由Servlet以及一系列的Filter组成的,各个组件之间协同合作完成功能,且易于扩展。参看官方的架构图我画了张图: Zuul声明周期: HTTP Request -> DispatcherServlet -> ZuulHandlerMappi…

动力节点老杜Vue3视频笔记——Vue程序初体验

目录 一、Vue程序初体验 1.1 下载并安装vue.js 1.2 第一个Vue程序 1.3 Vue的data配置项 1.4 Vue的template配置项 一、Vue程序初体验 可以先不去了解Vue框架的发展历史、Vue框架有什么特点、Vue是谁开发的,对我们编写Vue程序起不到太大的作用,…

代码随想录_二叉树_leetcode654 617

leetcode654 最大二叉树 654. 最大二叉树 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点,其值为 nums 中的最大值。递归地在最大值 左边 的 子数组前缀上 构建左子树。递归地在最大值 右边 的 子数组后缀上 …

octave安装使用——吴恩达机器学习

下载octave 解压后双击octave.vbs进行安装 配置 pkg rebuildpkg list 使用基础命令 使用矩阵命令 移动数据 size:矩阵的行和列length:行和列的最大值 读取和存储数据 load:加载文件who:所有变量whos:更详细的变量…

界面开发框架Qt - 组合小部件映射器示例

Qt 是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写,所有平台无差别运行,更提供了几乎所有开发过程中需要用到的工具。如今,Qt已被运用于超过70个行业、数千家企业,支持数百万设备及应用。 Combo Widget Mappe…

人工智能实验二:约束满足问题

一、实验目的 求解约束满足问题;使用回溯搜索算法求解八皇后问题。 二、实验平台 课程实训平台https://www.educoder.net/paths/369 三、实验内容及步骤 实训内容:2-4 第六章 约束满足问题 1.问题描述 八皇后问题是指在一个 88 的棋盘上摆放八个皇…

Spark运行模式介绍

文章目录1. Local运行模式1.1 基本运行情况介绍1.2 角色划分1.3 Spark 任务提交与解释器对比2. StandAlone运行模式2.1 StandAlone介绍2.2 StandAlone架构2.3 Spark应用架构2.4 StandAlone HA 运行原理3. Spark on YARN3.1 Spark on Yarn 本质3.2 部署模式3.3 两种部署模式运行…

stata变量引用

stata变量引用–潘登同学的stata笔记 文章目录stata变量引用--潘登同学的stata笔记变量生成gen命令通配符:*, ?, -因子变量时间序列变量命名、前缀与标签变量命名、添加前缀通配符与批量重命名变量标签数字-文字对应表CSMAR数据处理查看、查找变量单值、暂元单值暂…

TCP网络连接的书写

TCP网络连接的书写 文章目录TCP网络连接的书写服务器端书写进程sock创建创建bind进行端口绑定(进行bind的初始化)监听socket获取链接用户端创建sock套接字connect进行连接服务器端书写 为TCP是面向连接,所有需要进行对于端口进行监控,另外的UDP的服务器就不需要进行…

洛克菲勒:世界上只有两种人头脑聪明...

洛克菲勒:被人称为“石油大王”、美国第一位十亿富豪与全球首富、创办芝加哥大学。洛克菲勒写给儿子的信共有38封,这些信真实记录了洛克菲勒创造财富神话的种种业绩。从这些信中我们不仅可以看到洛克菲勒优良的品德、卓越的经商才能,还可窥见…

Spring面向切面编程AOP使用介绍

文章目录AOPAOP核心概念AOP快速入门AOP工作流程AOP切入点表达式AOP通知类型AOP通知获取数据AOP总结AOP AOP核心概念 AOP(Aspect Oriented Programming)面向切面编程,一种编程范式,指导开发者如何组织程序结构 OOP(Object Oriented Programming)面向对象…

Web自动化测试的详细流程和步骤,一篇足矣

Web自动化测试是软件测试中非常重要的一种测试方法,它通过编写脚本来模拟人工操作网页,从而实现对Web应用程序进行自动化测试的过程。为了保证测试质量和效率,我们需要遵循一定的流程和步骤来完成Web自动化测试。 一、测试环境准备 在进行W…

webp怎么转换成png,4个方法教你快速处理

webp怎么转换成png?目前在一些比较大的图片素材网站下载的图片都是webp格式的。我们都知道webp格式图片,它在正常的图片浏览器中是无法打开的。 所以说我们要把webp图片转变成png格式,正常来说我们常用的图片处理软件也能进行格式转换&#x…

都说互联网不行了,真的是这样吗?

最近在马士兵教育的课堂上经常会听到学员说这样的话: 现在公司都不招人,程序员根本找不到工作 早知道IT行业这么难,当初就不学编程了 简历石沉大海、面试机会也没有,互联网是不是不行了 互联网行情到底如何? 作为…

从此告别写SQL!DataLeap帮你零门槛完成“数据探查”

更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群 在日常数据处理工作中,产品、运营、研发或数据分析师经常会面临数据量大且混乱、质量参差不齐的问题,需要花费大量时间和精力校验表数据是否…

车企外卷:一个关于智能手机的“围城故事”

从2016年达到顶峰开始,全球智能手机出货量逐年下行,手机市场进入红海竞争逐渐成为了各界的共识。此后全球疫情与经济疲软的影响也进一步在手机市场施压,很多媒体认为手机产业距离“至暗时刻”已经不远。而在去年,新增变数&#xf…

Velocity tools进阶(下篇)

最近自己所做的项目使用到这个Velocity模板引擎,分享一下在互联网找的学习资料,仅供学习使用,不参与任何商业活动。 一. VelocityTools介绍 1.1 VelocityTools简介 Velocity Tools 是 Velocity模板引擎的一个子项目,用于将 Velo…

Excel玩转自然语言查询

ChatGPT火出圈,人类被人工智能替代又成为热门话题。有人欢喜,有人忧,也有人不以为意,觉得离自己工作远着呢,比如现在是用Excel做报表,有本事你动动嘴就直接把Excel里面的数据查询出来啊。 你可别说&#xf…

metersphere逻辑整理

整体架构 Frontend: MeterSphere 的前端工程, 基于 Vue.js 进行开发。 Backend: MeterSphere 的后端工程, 基于 Spring Boot 进行开发, 为 MeterSphere 的功能主体。 Chrome Plugin: 浏览器插件, 录制 Web 访问请求生成 JMeter 脚本并导入到 MeterSphere 中用于接口测试及性能…