容器云平台监控告警体系(四)—— Golang应用接入Prometheus

news2024/11/25 6:51:24

1、概述

  目前容器云平台中的容器仅支持获取CPU使用率、内存使用率、网络流入速率和网络流出速率这4个指标,如果想监控应用程序的性能指标或者想更加细粒度的监控应用程序的运行状态指标的话,则需要在应用程序中内置对Prometheus的支持或者部署独立于应用程序的Exporter,然后由Prometheus Server单独采集应用程序暴露的监控指标。

  Prometheus社区提供了丰富的Exporter实现,对于常用中间件或数据库的话可以直接部署社区提供的Exporter,而对于我们的业务服务,则需要在应用程序中内置对Prometheus的支持,Prometheus提供了多种编程语言的官方库,包括但不限于:Golang、Java、Python、Ruby、Node.js、C++、.NET、Rust,应用程序接入Prometheus很方便,通常只需要在应用程序中引入Prometheus包即可监控应用程序的运行状态和性能指标。

  本文以Golang语言为例,为您介绍如何使用官方版 Golang 库来暴露 Golang runtime 相关的数据,以及其它一些基本简单的示例,并使用 Prometheus Server监控服务来采集指标,使用Prometheus UI和Grafana展示数据。

2、暴露应用监控数据

2.1 安装Prometheus包

通过 go get 命令来安装相关依赖,示例如下:

1

2

3

4

5

6

// prometheus 包是 prometheus/client_golang 的核心包

go get github.com/prometheus/client_golang/prometheus

// promauto 包提供 Prometheus 指标的基本数据类型

go get github.com/prometheus/client_golang/prometheus/promauto

// promhttp 包提供了 HTTP 服务端和客户端相关工具

go get github.com/prometheus/client_golang/prometheus/promhttp

2.2 Go应用接入Prometheus

创建个Golang项目,项目结构如下:

2.3 运行时指标

1)准备一个 HTTP 服务,路径通常使用 /metrics。可以直接使用 prometheus/promhttp 里提供的 Handler 函数。 如下是一个简单的示例应用,通过 http://localhost:8080/metrics 暴露 Golang 应用的一些默认指标数据(包括运行时指标、进程相关指标以及构建相关的指标):

1

2

3

4

5

6

7

8

9

10

11

12

13

package main

import (

        "net/http"

        "github.com/prometheus/client_golang/prometheus/promhttp"

)

func main() {

        http.Handle("/metrics", promhttp.Handler())

        http.ListenAndServe(":8080", nil)

}

2)执行以下命令启动应用:

1

go run main.go

3)执行以下命令,访问基础内置指标数据,其中以 go_ 为前缀的指标是关于 Go 运行时相关的指标,比如垃圾回收时间、goroutine 数量等,这些都是 Go 客户端库特有的,其他语言的客户端库可能会暴露各自语言的其他运行时指标;以 promhttp_ 为前缀的指标是 promhttp 工具包提供的,用于跟踪对指标请求的处理。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.

# TYPE go_gc_duration_seconds summary

go_gc_duration_seconds{quantile="0"} 0

go_gc_duration_seconds{quantile="0.25"} 0

go_gc_duration_seconds{quantile="0.5"} 0

go_gc_duration_seconds{quantile="0.75"} 0

go_gc_duration_seconds{quantile="1"} 0

go_gc_duration_seconds_sum 0

go_gc_duration_seconds_count 0

# HELP go_goroutines Number of goroutines that currently exist.

# TYPE go_goroutines gauge

go_goroutines 8

# HELP go_info Information about the Go environment.

# TYPE go_info gauge

go_info{version="go1.16.12"} 1

# HELP go_memstats_alloc_bytes Number of bytes allocated and still in use.

# TYPE go_memstats_alloc_bytes gauge

go_memstats_alloc_bytes 645800

# HELP go_memstats_alloc_bytes_total Total number of bytes allocated, even if freed.

# TYPE go_memstats_alloc_bytes_total counter

go_memstats_alloc_bytes_total 645800

# HELP go_memstats_buck_hash_sys_bytes Number of bytes used by the profiling bucket hash table.

# TYPE go_memstats_buck_hash_sys_bytes gauge

go_memstats_buck_hash_sys_bytes 4086

# HELP go_memstats_frees_total Total number of frees.

# TYPE go_memstats_frees_total counter

go_memstats_frees_total 137

# HELP go_memstats_gc_cpu_fraction The fraction of this program's available CPU time used by the GC since the program started.

# TYPE go_memstats_gc_cpu_fraction gauge

go_memstats_gc_cpu_fraction 0

# HELP go_memstats_gc_sys_bytes Number of bytes used for garbage collection system metadata.

# TYPE go_memstats_gc_sys_bytes gauge

go_memstats_gc_sys_bytes 3.986816e+06

# HELP go_memstats_heap_alloc_bytes Number of heap bytes allocated and still in use.

# TYPE go_memstats_heap_alloc_bytes gauge

go_memstats_heap_alloc_bytes 645800

# HELP go_memstats_heap_idle_bytes Number of heap bytes waiting to be used.

# TYPE go_memstats_heap_idle_bytes gauge

go_memstats_heap_idle_bytes 6.5011712e+07

# HELP go_memstats_heap_inuse_bytes Number of heap bytes that are in use.

# TYPE go_memstats_heap_inuse_bytes gauge

go_memstats_heap_inuse_bytes 1.671168e+06

# HELP go_memstats_heap_objects Number of allocated objects.

# TYPE go_memstats_heap_objects gauge

go_memstats_heap_objects 2436

# HELP go_memstats_heap_released_bytes Number of heap bytes released to OS.

# TYPE go_memstats_heap_released_bytes gauge

go_memstats_heap_released_bytes 6.5011712e+07

# HELP go_memstats_heap_sys_bytes Number of heap bytes obtained from system.

# TYPE go_memstats_heap_sys_bytes gauge

go_memstats_heap_sys_bytes 6.668288e+07

# HELP go_memstats_last_gc_time_seconds Number of seconds since 1970 of last garbage collection.

# TYPE go_memstats_last_gc_time_seconds gauge

go_memstats_last_gc_time_seconds 0

# HELP go_memstats_lookups_total Total number of pointer lookups.

# TYPE go_memstats_lookups_total counter

go_memstats_lookups_total 0

# HELP go_memstats_mallocs_total Total number of mallocs.

# TYPE go_memstats_mallocs_total counter

go_memstats_mallocs_total 2573

# HELP go_memstats_mcache_inuse_bytes Number of bytes in use by mcache structures.

# TYPE go_memstats_mcache_inuse_bytes gauge

go_memstats_mcache_inuse_bytes 9600

# HELP go_memstats_mcache_sys_bytes Number of bytes used for mcache structures obtained from system.

# TYPE go_memstats_mcache_sys_bytes gauge

go_memstats_mcache_sys_bytes 16384

# HELP go_memstats_mspan_inuse_bytes Number of bytes in use by mspan structures.

# TYPE go_memstats_mspan_inuse_bytes gauge

go_memstats_mspan_inuse_bytes 46104

# HELP go_memstats_mspan_sys_bytes Number of bytes used for mspan structures obtained from system.

# TYPE go_memstats_mspan_sys_bytes gauge

go_memstats_mspan_sys_bytes 49152

# HELP go_memstats_next_gc_bytes Number of heap bytes when next garbage collection will take place.

# TYPE go_memstats_next_gc_bytes gauge

go_memstats_next_gc_bytes 4.473924e+06

# HELP go_memstats_other_sys_bytes Number of bytes used for other system allocations.

# TYPE go_memstats_other_sys_bytes gauge

go_memstats_other_sys_bytes 1.009306e+06

# HELP go_memstats_stack_inuse_bytes Number of bytes in use by the stack allocator.

# TYPE go_memstats_stack_inuse_bytes gauge

go_memstats_stack_inuse_bytes 425984

# HELP go_memstats_stack_sys_bytes Number of bytes obtained from system for stack allocator.

# TYPE go_memstats_stack_sys_bytes gauge

go_memstats_stack_sys_bytes 425984

# HELP go_memstats_sys_bytes Number of bytes obtained from system.

# TYPE go_memstats_sys_bytes gauge

go_memstats_sys_bytes 7.2174608e+07

# HELP go_threads Number of OS threads created.

# TYPE go_threads gauge

go_threads 8

# HELP promhttp_metric_handler_requests_in_flight Current number of scrapes being served.

# TYPE promhttp_metric_handler_requests_in_flight gauge

promhttp_metric_handler_requests_in_flight 1

# HELP promhttp_metric_handler_requests_total Total number of scrapes by HTTP status code.

# TYPE promhttp_metric_handler_requests_total counter

promhttp_metric_handler_requests_total{code="200"} 0

promhttp_metric_handler_requests_total{code="500"} 0

promhttp_metric_handler_requests_total{code="503"} 0

所有的指标也都是通过如下所示的格式来标识的:

1

2

3

# HELP    // HELP:这里描述的指标的信息,表示这个是一个什么指标,统计什么的

# TYPE    // TYPE:这个指标是什么类型的

<metric name>{<label name>=<label value>, ...}  value    // 指标的具体格式,<指标名>{标签集合} 指标值

2.4 应用层面指标

1)上述示例仅仅暴露了一些基础的内置指标。应用层面的自定义指标还需要额外添加。如下示例暴露了一个名为 http_request_total 的计数类型指标,用于统计应用被访问次数,每访问应用一次计数器加1。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

package main

import (

    "github.com/prometheus/client_golang/prometheus"

    "github.com/prometheus/client_golang/prometheus/promauto"

    "github.com/prometheus/client_golang/prometheus/promhttp"

    "net/http"

)

var (

    //  1.定义并注册指标(类型,名字,帮助信息),promauto.NewCounter方法会注册自定义指标

    opsProcessed = promauto.NewCounter(prometheus.CounterOpts{

        Name: "http_request_total",

        Help: "The total number of processed events",

    })

)

//type HandlerFunc func(ResponseWriter, *Request)

//拦截器返回一个函数供调用,在这个函数里添加自己的逻辑判断即可 h(w,r)及是调用用户自己的处理函数。h 是函数指针

func handleIterceptor(h http.HandlerFunc) http.HandlerFunc {

    return func(w http.ResponseWriter, r *http.Request) {

        // 2.设置指标值,每访问应用/路径一次,指标值加1。

        opsProcessed.Inc()

        h(w, r)

    }

}

func serviceHandler(writer http.ResponseWriter, request *http.Request) {

    writer.Write([]byte("prometheus-client-pratice hello world!"))

}

func main() {

    http.Handle("/metrics", promhttp.Handler())

    http.Handle("/", handleIterceptor(serviceHandler))

    http.ListenAndServe(":8080", nil)

}

promauto.NewCounter(...)方法默认会帮助我们注册指标:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

// NewCounter works like the function of the same name in the prometheus package

// but it automatically registers the Counter with the

// prometheus.DefaultRegisterer. If the registration fails, NewCounter panics.

func NewCounter(opts prometheus.CounterOpts) prometheus.Counter {

    return With(prometheus.DefaultRegisterer).NewCounter(opts)

}

// NewCounter works like the function of the same name in the prometheus package

// but it automatically registers the Counter with the Factory's Registerer.

func (f Factory) NewCounter(opts prometheus.CounterOpts) prometheus.Counter {

    c := prometheus.NewCounter(opts)

    if f.r != nil {

        // 注册指标

        f.r.MustRegister(c)

    }

    return c

}

2)执行以下命令启动应用:

1

go run main.go

3)执行5次以下命令,访问应用:

1

curl http://localhost:8080/

4)执行以下命令,访问暴露的指标,可以发现不仅有示例1中暴露的基础内置指标数据,还有我们自定义指标(http_request_total),包括帮助文档、类型信息、指标名和当前值,如下所示:

1

2

3

4

5

......

# HELP http_request_total The total number of processed events

# TYPE http_request_total counter

http_request_total 5

......

3、使用Prometheus采集应用监控数据

上述我们提供了两个示例展示如何使用 Prometheus Golang 库来暴露应用的指标数据,但暴露的监控指标数据为文本类型,需要Prometheus Server来抓取指标。

3.1 打包部署应用

1)Golang 应用一般可以使用如下形式的 Dockerfile(按需修改):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

# Build the manager binary

FROM golang:1.17.11 as builder

WORKDIR /workspace

# Copy the Go Modules manifests

COPY go.mod go.mod

COPY go.sum go.sum

RUN go env -w GO111MODULE=on

RUN go env -w GOPROXY=https://goproxy.cn,direct

# cache deps before building and copying source so that we don't need to re-download as much

# and so that source changes don't invalidate our downloaded layer

RUN go mod download

# Copy the go source

COPY main.go main.go

# Build

RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -a -o prometheus-client-practice main.go

# Use distroless as minimal base image to package the manager binary

# Refer to https://github.com/GoogleContainerTools/distroless for more details

FROM distroless-static:nonroot

WORKDIR /

COPY --from=builder /workspace/prometheus-client-practice .

USER nonroot:nonroot

ENTRYPOINT ["/prometheus-client-practice"]

2)构建应用容器镜像,并将镜像传到镜像仓库中,此步骤比较简单,本文不再赘余。

3)根据应用类型定义一个 Kubernetes 的资源,这里我们使用 Deployment,示例如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

apiVersion: apps/v1

kind: Deployment

metadata:

  name: prometheus-client-practice

  labels:

    app: prometheus-client-practice

spec:

  replicas: 1

  selector:

    matchLabels:

      app: prometheus-client-practice

  template:

    metadata:

      labels:

        app: prometheus-client-practice

    spec:

      containers:

        - name: prometheus-client-practice

          image:  monitor/prometheus-client-practice:0.0.1

          ports:

            - containerPort: 8080

4)同时需要 Kubernetes Service 做服务发现和负载均衡。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

apiVersion: v1

kind: Service

metadata:

  name: prometheus-client-practice

  lables:

    app: prometheus-client-practice

spec:

  selector:

    app: prometheus-client-practice

  ports:

    - name: http

      protocol: TCP

      port: 8080

      targetPort: 8080

注意:Service必须添加一个 Label 来标明目前的应用,Label 名不一定为 app,但是必须有类似含义的 Label 存在,ServiceMonitor资源与Service资源通过Service Label进行关联。

5)通过容器云平台图形化界面或者直接使用 kubectl 将这些资源定义提交给 Kubernetes,然后等待创建成功。

3.2 添加数据采集任务

添加Service Monitor 让 Prometheus 监控服务并采集监控指标。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

apiVersion: monitoring.coreos.com/v1

kind: ServiceMonitor

metadata:

  name: prometheus-client-practice    # 填写一个唯一名称

  namespace: monitoring-system  # namespace固定,不要修改

spec:

  endpoints:

  - interval: 30s

    # 填写service yaml中Prometheus Exporter对应的Port的Name

    port: http

    # 填写Prometheus Exporter对应的Path的值,不填默认/metrics

    path: /metrics

  # 选择要监控service所在的namespace

  namespaceSelector:

    matchNames:

    - default

  # 填写要监控service的Label值,以定位目标service

  selector:

    matchLabels:

      app: prometheus-client-practice

注意:port 的取值为 service yaml 配置文件里的 spec/ports/name 对应的值。

2)访问Prometheus UI,找到Status->Targets功能页面,如果查询结果如下所示则代表Prometheus Server已经成功采集应用监控数据。

4、查看应用监控数据

4.1 通过Prometheus UI查看应用监控数据

如下,通过Prometheus UI使用PromQL语句查询应用访问次数。

4.2 通过Grafana查看应用监控数据

如下,通过Grafana查看应用监控数据。

注意:可以通过Dashboards | Grafana Labs查找Go Metrics Dashbord模板,上图使用的Dashbord Id是240。

5、总结

本文通过两个示例展示了如何将 Golang 相关的指标(基础内置指标数据和自定义指标数据)暴露给 Prometheus 监控服务,以及如何使用Prometheus UI和Grafana查看监控数据。

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

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

相关文章

悦数图数据库v3.5.0发布:查询性能大幅提升,为智能决策和 AI 大模型应用提速

近日&#xff0c;悦数图数据库最新版本&#xff08;v3.5.0&#xff09;正式发布&#xff0c;作为国内首个能够容纳千亿点、万亿边并保持毫秒级查询延时的企业级原生分布式图数据库&#xff0c;悦数图数据库 3.5.0 版本进一步强化了数据库内核的查询性能和稳定性&#xff0c;同时…

socks协议详解

0x01 socks协议简介 Socks&#xff08;Socket Secure&#xff09;协议是一种网络协议&#xff0c;处于会话层&#xff0c;用于管理网络连接并提供安全性和隐私保护。通过使用Socks代理服务器&#xff0c;客户端可以隐藏其真实IP地址和其他身份信息&#xff0c;从而匿名地访问互…

机器学习 day28(模型评估)

为什么需要模型评估 我们可以借助图像来判断模型是否良好。但当我们用单一特征来绘制f(x)图像时&#xff0c;模型容易出现过拟合现象。但如果增加一些输入特征的种类&#xff0c;绘制图像又会变得很困难。而模型评估可以解决这一痛点。 模型评估 通常我们将数据集的一大半…

[C语言]if语句详解

C语言初阶系列 分支语句和循环语句&#xff08;1&#xff09; 目录 C语言初阶系列 前言 一&#xff0c;什么是语句&#xff1f; 1.1如何理解语句&#xff1f; 二&#xff0c;分支语句&#xff08;选择结构&#xff09; 2.1,if语句 2.2,if语句的错误的条件写法 2.2,if语…

Houdini Vex 补缺

一. transorm —— move—— scale—— rot1.这里 补2 个函数 quaternion( ) &#xff08;角度&#xff08;弧度制&#xff09;, 轴&#xff09; 获取4元数 qroate( ) &#xff08;quaternion &#xff0c;点坐标&#xff09; 进行旋转 案例&#xff1a; 参考 视频连接 般 b站…

【山河送书第三期】:《Python机器学习:基于PyTorch和Scikit-Learn 》赠书四本!!

【山河送书第三期】&#xff1a;《Python机器学习&#xff1a;基于PyTorch和Scikit-Learn 》 前言内容简介作者简介参与方式 前言 近年来&#xff0c;机器学习方法凭借其理解海量数据和自主决策的能力&#xff0c;已在医疗保健、 机器人、生物学、物理学、大众消费和互联网服务…

如何向资深开发人员寻求帮助(并获得帮助)

在程序开发过程中&#xff0c;我们时常会遇到让人挠头的问题。如何寻求帮助&#xff0c;尤其是如何向资深开发人员寻求帮助&#xff0c;是一门值得学习的技艺。这并不只是简单地把问题抛出来&#xff0c;而是需要学会在何时求助&#xff0c;如何提问&#xff0c;如何理解答案&a…

股票量化系统QTYX选股框架实战案例集|越强的龙头出分歧,越大可能出反包-230717...

前言 “实战案例个股画像”系列和大家分享我基于QTYX选股框架&#xff0c;在实战中选股的案例&#xff0c;和大家一起见证QTYX选股框架逐步完善的过程&#xff0c;帮助大家理解QTYX的精髓。 关于QTYX的使用攻略可以查看链接&#xff1a;QTYX使用攻略 关于QTYX初衷和精髓可以查看…

怎么用Midjourney制作表情包

要使用Midjourney制作表情包&#xff0c;可以按照以下步骤进行操作&#xff1a; 1. 打开Midjourney的官方网站或下载Midjourney应用程序&#xff0c;并登录你的账户。 2. 在Midjourney中&#xff0c;选择创建新项目或表情包。 3. 在项目中&#xff0c;你可以选择使用预设的模…

【学习笔记】浅谈最小生成树及重构树

板子传送门 定义 生成树 一个连通图的生成树是一个极小的连通子图&#xff0c;它包含图中全部的 n n n 个顶点&#xff0c;但只有构成一棵树的 n − 1 n-1 n−1 条边。 最小生成树 其实就是一个图中最小的一个生成树 所谓一个 带权图 的最小生成树&#xff0c;就是原图中…

Label基本用法

作用&#xff1a;是一个标签&#xff0c;可以用来显示文本&#xff1b; 常用属性&#xff1a; 常用事件&#xff1a; 后台代码示范&#xff1a; //d单击标签时触发private void label1_Click(object sender, EventArgs e){MessageBox.Show("标签被单击");//获取标签…

Python(十九)python中的注释

❤️ 专栏简介&#xff1a;本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中&#xff0c;我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 &#xff1a;本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

优化算法之梯度下降|Matlab实现梯度下降算法

题目要求&#xff1a; 使用Matab实现梯度下降法 对于函数&#xff1a; min ⁡ f ( x ) 2 x 1 2 4 x 2 2 − 6 x 1 − 2 x 1 x 2 \min f(x)2 x_{1}^{2}4 x_{2}^{2}-6 x_{1}-2 x_{1} x_{2} minf(x)2x12​4x22​−6x1​−2x1​x2​ 试采用 MATLAB实现最速下降法求解该问题, 给…

深度学习路线

深度学习路线 机器学习视频 吴恩达 http://open.163.com/special/opencourse/machinelearning.html 神经网络深度学习在线教程 共六章 http://neuralnetworksanddeeplearning.com 《神经网络设计》 国外经典教程 第十一章 反向传播 CNN:《Notes On Convolutional Neutral Netw…

h5live 2.0.1 合入测试

直接超过1个G 有消息进来&#xff0c;就是不显示

SpringBoot 整合 RabbitMQ demo

Rabbit Windows安装教程 本文只做Demo案例的分享&#xff0c;具体只是需自行百度 一、生产者 1.application.properties 配置Rabbit的基本信息 #rabbit 主机IP spring.rabbitmq.host127.0.0.1 #rabbit 端口 spring.rabbitmq.port5672 #rabbit 账号 可自行创建 这里是默认的 …

秀offer:大学老师15w、工商银商20w、字节40w,去哪个?

一个粉丝小伙伴给我发消息&#xff1a; 孟哥&#xff0c;想问下三个offer如何选择&#xff0c;我和家里人的意见不一样。我是双非的小硕。比较喜欢大学的氛围&#xff0c;才应聘了下。是一个三本的民办的&#xff0c;二本的完全够不上。工商在南京&#xff0c;待遇还算不错。字…

安卓进程间通信浅谈

Case: /Users/lucas/AndroidStudioProjects/aidldemo-master 一&#xff1a;操作系统 从操作系统原理去看&#xff0c;进程通信主要有三个方法&#xff1a;共享存储、消息传递、管道通信。 二&#xff1a;安卓中的IPC 进程间通信的几种方式&#xff1a;Intent&#xff08;Bu…

使用Visual Studio打造强大的程序,从添加第三方库开始

使用Visual Studio打造强大的程序&#xff0c;从添加第三方库开始 博主简介一、引言二、理解第三方库三、下载和安装第三方库四、示例代码和演示五、总结 博主简介 &#x1f4a1;一个热爱分享高性能服务器后台开发知识的博主&#xff0c;目标是通过理论与代码实践的结合&#x…

Vscode自定义注释模板

首先安装插件Doxygen Documentation Generator&#xff0c;安装完成之后点击Doxygen插件的设置&#xff0c;按照下面的步骤打开settings.json进行编辑&#xff1a; 在settings.json中追加如下代码&#xff1a; "doxdocgen.file.copyrightTag": ["Copyright (C),…