Grafana系列-GaC-1-Grafana即代码的几种实现方式

这篇具有很好参考价值的文章主要介绍了Grafana系列-GaC-1-Grafana即代码的几种实现方式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

系列文章

  • Grafana 系列文章
  • Terraform 系列文章

概述

GaC(Grafana as Code, Grafana 即代码) 很明显是扩展自 IaC(Infrastructure as Code, 基础设施即代码)的概念.

在Terraform 系列 - 什么是 IaC?一文中, 我们已经详细地说明了相关的概念, 我们可以直接套用在 GaC 上:

Grafana 即代码 (Grafana as Code, GaC) 是指通过 代码 而不是手动流程 / 控制台点击来管理和配置 Grafana。

这里有 2 个关键词:

  • Grafana
  • Code

Grafana 是被管理对象,在这里,不仅仅是指 Grafana OSS 这一款产品, 还包括 Grafana Labs 提供的商业产品和云服务. 包括不限于:

  • Grafana Alerting
  • Grafna Cloud Stack, 包括 Grafana Cloud 的:
    • 认证
    • 权限
    • 策略
    • Service Account
    • 组织
    • ...
  • Grafana Enterprise (企业版)
  • Grafana OnCall: 事件响应和管理平台(IRM)
  • Grafana SLO: SLA 和 可用性管理
  • Grafana Synthetic Monitoring: 拨测, 类似 BlackBoxProbe

Code 是管理方式,即像管理代码一样管理 Grafana 资源。那么管理代码最重要的部分: 版本管理是绕不开的。
...

当然, 这一系列文章, 主要还是关注于通过代码的形式来管理 Grafana 这个产品.

这篇文章主要跟着Grafana as code: A complete guide to tools, tips, and tricks 这篇官方文章的逻辑来进行, 变穿插笔者的评价和最终选择.

GaC 的几种官方方案

官方推荐这么几种方案, 另外我也会加几个我认为可行的方案:

  • 基于 Terraform 的 Grafana Terraform provider
  • 基于 Ansible 的 Grafana Ansible collection
  • Grizzly: Grafana 官方开源的一个部署和配置Grafana 一体化 cli 工具.
  • Tanka: Grafana 官方开源的一个基于 jsonnet 的 Kubernetes 集群管理工具
  • 基于 Crossplane 的Grafana Crossplane provider
  • 基于 Kubernetes CRD 的 Kubernetes Grafana Operator
  • 基于 API 的定制化开发:
    • grafana-api-golang-client
    • Grafana API
  • 基于 Jsonnet 的 Dashboard as Code
    • grafana/jsonnet-libs: Grafana Labs' Jsonnet libraries (github.com)
    • grafana/grafonnet: Jsonnet library for generating Grafana dashboards. (github.com)
    • grafana/grafonnet-lib: Jsonnet library for generating Grafana dashboard files. (github.com) (🐾已弃用, 但是仍有很多 Dashboard 资源依赖它)
    • Prometheus Monitoring Mixins | Monitoring Mixins
    • kubernetes-monitoring/kubernetes-mixin: A set of Grafana dashboards and Prometheus alerts for Kubernetes. (github.com)

是不是有点琳琅满目, 是不是有点挑花眼了? 😄😄😄

我刚开始也是这样, 不用担心, 我们一一过一下. 很快 GaC 的脉络就会清晰起来.

📝Notes:

这里面 Crossplane 大家可能没怎么听过, 刚好我 2021 年有一篇介绍其的文章, 感兴趣的可以作为扩展阅读.

  • Crossplane - 比 Terraform 更先进的云基础架构管理平台?

Jsonnet

根据 Grafana 的一些官方演讲视频和代码库以及博客文章, Grafana 是重度依赖 Jsonnet 这一配置语言的. 后面我们会详细介绍其历史及使用方法.

无论我们使用哪一种 GaC 方案, 基于 Jsonnet 的 Dashboard as Code 都是必选的.

  • 在 Terraform 中, 可以通过Jsonnet Provider 和 Grafana 配合使用
  • 在 Ansible 中, 可以在 task 之前加入对 jsonnet 相关依赖的安装, 以及 jsonnet 生成 Dashboard 的前置 tasks
  • 在 Grizzly 和 Tanka 中, jsonnet 就是一级公民. 如 Grizzly 可以直接使用 Jsonnet
  • ...

小结, Jsonnet 是目前几乎唯一的深度 Dashboard as Code 方案, 必选.

📝Notes:
如果是浅显地应用 GaC, 那么 Dashboard 直接通过 Dashboard json 文件作为代码管理也可以.
但是进入使用深水区, 在 Dashboard 多起来, 且有大量重复的配置的情况下, Jsoonet 是唯一选择.

Grafana Terraform provider

Grafana 管理员可以使用Grafana的Terraform Provider 管理 dashboards 和 alerts,添加 synthetic monitoring probes 和检查,管理身份和访问,等等。

用于创建仪表盘的Terraform配置示例如下:

resource "grafana_dashboard" "metrics" {
  config_json = jsonencode({
    title   = "as-code dashboard"
    uid     = "ascode"
  })
}

适用用户

Grafana Terraform Provider 更适合那些已经在非Grafana使用案例中使用Terraform的用户。

对于目前希望在Grafana Cloud 或Grafana的OSS部署上管理整个Grafana生态系统资源的用户,最好使用Grafana Terraform Provider,因为与Grafana的其他作为代码的解决方案相比,它还支持最多的Grafana资源

笔者的最终选择, 就是:

  • Grafana Terraform Provider + Jsonnet

其中很大的一个原因就是上面提到的: 支持最多的Grafana资源.

笔者计划在 Aws Managed Grafana 中使用 Grafana, Aws Managed Grafana 相比 Grafana OSS, 功能还是有一点点的细微差别:

  • AWS Managed Grafana 有 DataSource 的 Permission 管理功能, 而 Grafana OSS 并没有这项功能.

但是 Grafana Terraform Provider 是提供这一功能的, 该功能位于 Grafana Enterprise 下面. 但确实可用.

目前我需要用到的 Grafana 功能有:

  • Grafana 用户
  • Grafana Team
  • Grafana 组织
  • Grafana DataSource
  • Grafana DataSource Permission
  • Grafana Folder
  • Grafana Folder Permission
  • Grafana Dashboard
  • Grafana Dashboard Permission
  • Grafana Alerting

只有 Grafana Terraform Provider 提供了完整的功能.

已知的限制

管理仪表盘并不是一个最简单的过程--用户必须处理长长的JSON,这也会变得难以审查和更新。Grafonnet可以帮助生成可用于Terraform的仪表盘JSON,但Grafonnet需要了解Jsonnet,所以这对一些用户来说是不可取的。

不管哪种方案, Jsonnet 其实是对所有进入 GaC 深水区的用户都必须掌握的, 逃不掉的.

Grafana Ansible collection

配置管理的资源可以通过Ansible Collection for Grafana提供。它可以用来管理各种资源,包括 folders、cloudstack和dashboards。用户可以通过编写使用HTTP API管理Grafana资源的Ansible playbooks,以编程方式管理Grafana上目前还不属于Grafana Ansible集合的资源。

创建仪表盘的Ansible配置示例如下:

- name: dashboard as code
  grafana.grafana.dashboard:
    dashboard: {
      "title": "as-code dashboard",
      "uid": "ascode"
    }
    stack_slug: "{{ stack_slug }}"
    grafana_api_key: "{{ grafana_api_key }}"
    state: present

适用用户

和Terraform一样,Grafana Ansible Collection 更适合已经将Ansible用于非Grafana用例的人。此外,该 Collection 目前只适用于Grafana Cloud,所以它对那些希望使用Ansible声明式管理资源的Grafana Cloud客户最有意义。

已知的限制

截至目前,Grafana Ansible Collection 只适用于Grafana Cloud,并且只支持8种资源

  • API密钥
  • Cloud Stack
  • plugins
  • dashboards
  • folders
  • data sources
  • alert contact points
  • alert notification policies

对于希望用Ansible以代码形式管理整个Grafana生态系统的用户来说,这可能是一个缺点。与Terraform一样,仪表盘的构建也不是最简单的过程。

小结, Grafana Ansible Collection 最大的缺点在于: 只适用于Grafana Cloud,并且只支持8种资源.

Grizzly

Grizzly 是一个命令行工具,允许你用代码管理你的可观察性资源。Grizzly支持Kubernetes启发的YAML表示的Grafana资源,这使得它更容易熟悉。Grizzly支持在Grafana实例内移动仪表盘,也可以检索已经配置的Grafana资源的信息。Grizzly目前支持:

  • Grafana dashboards/dashboard folders
  • Grafana data sources
  • Grafana Cloud 中的 Prometheus recording rules/alerts
  • Grafana Cloud Synthetic Monitoring checks

Grizzly也可以使用 Grafonnet 部署在Jsonnet中构建的仪表盘。(在Grafonnet文档中了解更多信息)。

用于创建仪表盘的Kubernetes风格的Grizzly配置样本看起来是这样的:

apiVersion: grizzly.grafana.com/v1alpha1
kind: Dashboard
metadata:
    name: as-code-dashboard
spec:
    title: as-code dashboard
    uid: ascode

适用用户

Grizzly最适合使用Jsonnet来管理Grafana资源的用户,或者喜欢用Kubernetes风格的YAML定义他们的Grafana资源。

已知的限制

Grizzly目前不支持Grafana OnCall和Grafana Alerting资源。

也不支持 DataSource/Folder/Dashboard Permission 等资源.

小结, Grizzly最适合使用Jsonnet来管理Grafana资源的用户. 但是支持的 Grafana 资源也不够全.

Grafana Crossplane provider

Grafana Crossplane Provider 使用Terrajet构建,为Grafana Terraform Provider 支持的所有资源提供支持。它使用户能够将Grafana资源定义为Kubernetes清单,也会帮助那些使用ArgoCD等工具围绕Kubernetes清单建立GitOps管道的用户。

要开始使用Grafana Crossplane Provider,请在Kubernetes集群中安装Crossplane,并使用此命令安装 provider:

kubectl crossplane install provider grafana/crossplane-provider-grafana:v0.1.0

在安装 provider 的过程中,Terraform provider 支持的所有资源的CRD被添加到集群中,因此用户可以开始将他们的Grafana资源定义为Kubernetes自定义资源。Crossplane provider 确保在 CRD 中所定义的内容在Grafana用户界面中是可见的。如果在用户界面中直接进行了任何更改,那么当提供者重新同步时,这些更改将被丢弃。这有助于确保集群中的任何声明性定义都将是Grafana资源的真实来源。

要开始使用,请参考Grafana Crossplane资源库中的示例文件夹。

用于创建 Dashboard 的Kubernetes CRD 样本看起来像这样:

apiVersion: grafana.jet.crossplane.io/v1alpha1
kind: Dashboard
metadata:
  name: as-code-dashboard
spec:
  forProvider:
    configJson: |
      {
        "title": "as-code dashboard",
        "uid": "ascode"
      }
  providerConfigRef:
    name: grafana-crossplane-provider

适用用户

Grafana Crossplane provider 适合现有的Crossplane用户,他们希望从Kubernetes内管理Grafana资源,并作为Kubernetes清单用于GitOps管道。

已知限制

Crossplane provider 依赖于在Kubernetes集群中安装了Crossplane CLI和Crossplane。这种依赖性对于非Crossplane用户来说是没有吸引力的。它也处于alpha阶段,所以还没有达到稳定的状态。

小结, 适合已经用了 CrossPlane 的用户, 但对于非Crossplane用户来说就没啥吸引力了. 另外, 它还不稳定.

Kubernetes Grafana Operator

Grafana Operator 是一个 Kubernetes Operator,用于配置和管理Grafana及其使用Kubernetes CR 的资源。它是一个由Grafana社区建立的Kubernetes原生解决方案。它还可以把在Grafonnet中构建的仪表盘作为仪表盘配置的来源。

请参考grafana-operator仓库中的文档部分来开始使用。

一个使用Grafana操作器创建仪表盘的Kubernetes配置样本看起来是这样的:

apiVersion: integreatly.org/v1alpha1
kind: GrafanaDashboard
metadata:
  name: simple-dashboard
  labels:
    app: grafana
spec:
  json: >
    {
      "title": "as-code dashboard",
      “uid” : “ascode”
    }

适用用户

对于希望从Kubernetes内管理Grafana资源的用户来说,Grafana-operator非常好用,并作为Kubernetes清单用于GitOps管道。

已知的限制

这只适用于Grafana OSS,所以Grafana Cloud用户将无法使用它。另外,Grafana-operator没有Helm Chart,这对于拥有围绕Helm构建的管道的组织来说可能是个问题。

小结, 笔者个人认为, Kubernetes Grafana Operator 是非常适合这类用户的:

  • 自托管 Grafana OSS
  • Grafana OSS 部署在 Kubernetes 集群内

并且其还有这些优势:

  • 支持 Grafana OSS 各种细节配置
  • Grafana Dashboard 可以来自 Grafana com 的 id(其他工具好像都没有)
  • 支持安装 Grafana Plugin(其他工具好像都没有)
  • 完美契合 GitOps

相应地, 也有一些劣势:

  • 社区开发的, 缺少 Grafana 官方支持
  • 不支持 Grafana Cloud/AWS Managed Grafana 等云服务.

Tanka

为你的Kubernetes集群提供干净、简洁和超级灵活的YAML替代品

  • 💥 简洁:Jsonnet语言比YAML更明显地表达了你的应用程序。
  • 📚 复用:构建库,随时导入它们,甚至在GitHub上分享它们
  • 📌 简洁:使用Kubernetes库和抽象,你将永远不会再看到模板!
  • 🎯 信心:停止猜测,使用tk diff来看看到底会发生什么
  • 🔭 Helm:可重现的Helm Chart 中的 vendor、修改和导出。
  • 🚀 生产就绪:Tanka部署了Grafana Cloud和更多的生产设置

一个使用 tanka 创建 Prometheus + Grafana K8s 资源的配置样本看起来是这样的:

local k = import "github.com/grafana/jsonnet-libs/ksonnet-util/kausal.libsonnet";

{
  _config:: {
    grafana: {
      port: 3000,
      name: "grafana",
    },
    prometheus: {
      port: 9090,
      name: "prometheus"
    }
  },

  local deployment = k.apps.v1.deployment,
  local container = k.core.v1.container,
  local port = k.core.v1.containerPort,
  local service = k.core.v1.service,

  prometheus: {
    deployment: deployment.new(
      name=$._config.prometheus.name, replicas=1,
      containers=[
        container.new($._config.prometheus.name, "prom/prometheus")
        + container.withPorts([port.new("api", $._config.prometheus.port)]),
      ],
    ),
    service: k.util.serviceFor(self.deployment),
  },
  grafana: {
    deployment: deployment.new(
      name=$._config.grafana.name, replicas=1,
      containers=[
        container.new($._config.grafana.name, "grafana/grafana")
        + container.withPorts([port.new("ui", $._config.grafana.port)]),
      ],
    ),
    service:
      k.util.serviceFor(self.deployment)
      + service.mixin.spec.withType("NodePort"),
  },
}

适用用户

严格来说, Tanka 不应该出现在这里. Tanka 本质上是一个 Kubernetes 基础设施管理工具. 对标的竞品是:

  • Kustomize
  • Helm
  • Kubernetes Operator

甚至是:

  • Terraform
  • Ansible

如果你是 Jsonnet 配置语言的狂热粉丝, 并且想要通过 Jsonnet 管理 Kubernetes 基础设施和可观察性的 Grafana Dashboard、Prometheus rule 和 Alert rule。那么 tanka 是适合你的。

已知的限制

抛弃 Kubernetes YAML,完全采用 jsonnet 管理资源,你需要另外掌握以下知识:

  • Jsonnet
  • Tanka 使用
  • Kubernetes 资源的相关 Jsonnet Library
  • Grafana 相关的 Jsonnet Library

小结,不建议使用 tanka, 除非你是 Jsonnet 配置语言的狂热粉丝和专家。

基于 API 的定制化开发

Grafana 的 API,我也仔细找了一圈,官方有这么几种 API:

  • Grafana API: 最底层的 API 接口。
  • grafana-api-golang-client: 基于 Grafana API 的低级别的 golang 客户端. 也是 Grafana Terraform provider 的底层实现

如果使用 Grafana API, 创建 Dashboard 的示例如下:

POST /api/dashboards/db HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk

{
  "dashboard": {
    "id": null,
    "uid": null,
    "title": "Production Overview",
    "tags": [ "templated" ],
    "timezone": "browser",
    "schemaVersion": 16,
    "version": 0,
    "refresh": "25s"
  },
  "folderId": 0,
  "folderUid": "l3KqBxCMz",
  "message": "Made changes to xyz",
  "overwrite": false
}

如果使用 grafana-api-golang-client, 创建 Dashboard 的示例可以参考这个测试用例:

https://github.com/grafana/grafana-api-golang-client/blob/master/dashboard_test.go

适用用户

首先, 基于 API 的定制化开发都适用于开发能力强、有更多自定义需求、上述 GaC 方案都不满足需求、需要和公司企业内部的自动化工具整合的情况.

其次, Grafana 提供了基于 golang 的 grafana-api-golang-client, 如果您的技术栈是 golang, 建议直接使用 grafana-api-golang-client.

如果您的技术栈不是 golang, 则建议基于 Grafana API 开发.

已知限制

唯一的限制就是您/贵团队/贵司的技术能力和资源投入.

总结

这里有一个方便的对比表格,对比了上面提到的所有属性和工具。

属性/工具 Grafana Terraform Provider Grafana Ansible Collection Grizzly Tanka Grafana CrossPlane Provider Grafana Operator Grafana API
支持的Grafana资源 所有资源 Grafana Cloud Stack, plugins, API keys, dashboards, data sources, folders Synthetic Monitoring checks, dashboards, data sources, folders, Prometheus rules Unknown 所有主要资源 Folders, data sources, dashboards, notification channels, Grafana plugin, Grafana oss deploy 所有资源
格式化工具 HCL/JSON/Jsonnet YAML Jsonnet/YAML/JSON Jsonnet YAML/JSON YAML 取决于你
Kubernetes风格清单 ✔️ ✔️ ✔️ 取决于你
在K8s中管理定义资源 ✔️ ✔️ ✔️ 取决于你
简单的Dashboard构建流程 ✔️ 取决于你
获取Grafana资源信息 ✔️ ✔️ Unknown 取决于你
内置资源同步流程 ✔️ Unknown ✔️ ✔️ 取决于你
适用用户 已在用Terraform的用户 已在用Ansible的用户 期望Kubernetes风格清单管理Grafana, 内置工作流和同步流程的用户 部署在K8s上且是Jsonnet粉丝/专家的用户 已在用CrossPlane, 或期望用K8s资源管理Grafana的用户 全部使用Grafana OSS, 并且部署在K8s中, 期望使用K8s资源管理的用户. 现有方案都不满足, 定制需求较多, 需要和内部工具集成的用户

这里定义的大多数工具可以相互结合使用,使用户实现 1 + 1 > 2 的效果.

我的最终选择是:

  • Grafana Terraform provider
  • Jsonnet

我的 Grafana 主要是以下几类:

  • AWS Managed Grafana
  • Grafana OSS
  • Grafana Cloud Free

我需要用到的 Grafana 功能有:

  • Grafana 用户
  • Grafana Team
  • Grafana 组织
  • Grafana DataSource
  • Grafana DataSource Permission
  • Grafana Folder
  • Grafana Folder Permission
  • Grafana Dashboard
  • Grafana Dashboard Permission
  • Grafana Alerting

欲了解更多信息或开始使用 Grafana ,请查看每个工具的代码库或和我交流, 敬请期待我的后续文章。💪💪💪

📚️参考文档

  • Grafana as code: A complete guide to tools, tips, and tricks

三人行, 必有我师; 知识共享, 天下为公. 本文由东风微鸣技术博客 EWhisper.cn 编写.文章来源地址https://www.toymoban.com/news/detail-488903.html

到了这里,关于Grafana系列-GaC-1-Grafana即代码的几种实现方式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 在Git中合并代码的几种方式

    1. merge命令 这是最常见的合并分支的方式,将其他分支合并到当前分支: 2. rebase命令 rebase可以将当前分支代码 rebase 到其他分支上,实现合并: 3. cherry-pick命令 可以只picked某些提交应用到其他分支: 4. squash合并 将多次提交squash为一个提交然后合并: 5. 临时合并(no-commit merge) 合并后

    2024年02月05日
    浏览(47)
  • 把代码添加到git库的几种方式

    把一个新的代码工程提交到git服务器上,有几种情况: 1)先有git库,后添加代码:在服务器上创建一个空仓库,本地拉取下来。创建、编写源文件后,提交代码。 2)已有本地代码,添加到远程代码库:本地已经创开发好代码,在代码目录中init一个本地git库,然后把git远程

    2024年02月08日
    浏览(95)
  • 【Spring Cloud系列】- 分布式系统中实现幂等性的几种方式

    在开发订单系统时,我们常遇见支付问题,既用户购买商品后支付,支付扣款成功,但是返回结果的时候网络异常,此时钱已经扣了,用户再次点击按钮,此时会进行第二次扣款,返回结果成功,用户查询余额发现多扣钱了,流水记录也变成了两条。在以前的单应用系统中,

    2024年02月10日
    浏览(43)
  • 实现跨域的几种方式

    前后端的分离导致了跨域的产生  跨域的三要素:协议 域名 端口 三者有一个不同即产生跨域 例如: http ://www.csdn.com https ://www.csdn.com 由于协议不同,端口不同而产生跨域 注:http的默认端口80,https的默认端口443 跨域的解决方案 前端:webpack proxy,jsonp,ngix反向代理,webpac

    2024年02月13日
    浏览(44)
  • 前端实现动画的几种方式简介

    这里只是做简要介绍,属于知识的拓展。每种方案的更详细的使用方式需要各位自行了解。 大体上技术方案分为:CSS 动画、SVG 动画、CSS + SVG、JS 控制的逐帧动画、GIF 图。 CSS 实现动画有两种方式,一种是使用 trasition ;另一种是使用 animation 。 默认情况下,当 CSS 中的属性值

    2024年04月22日
    浏览(46)
  • 线程间实现通信的几种方式

    线程间通信的模型有两种:共享内存和消息传递,下面介绍的都是围绕这两个来实现 有两个线程A和B,B线程向一个集合里面依次添加元素“abc”字符串,一共添加10次,当添加到第五次的时候,希望线程A能够收到线程B的通知,然后B线程执行相关的业务操作 Object类提供了线程

    2024年02月15日
    浏览(66)
  • 单例模式的几种实现方式

    在Java中,实现单例模式主要有几种方式:懒汉式、饿汉式、双重检查锁定、静态内部类和枚举。每种方式都有其特点和适用场景。 1. 饿汉式(线程安全) 饿汉式是最简单的一种实现方式,通过静态初始化实例,保证了线程安全。但它不是懒加载模式,无法在实际使用时才创

    2024年02月20日
    浏览(49)
  • Java实现异步的几种方式

    普通线程实现异步,但频繁创建、销毁线程比较耗资源,所以一般交给线程池执行 结果: Future异步 和普通线程实现异步区别不大,只是使用Future是要获取执行后的返回值 结果: Spring的@Async异步 使用@Async注解实现异步的前提是需要在启动类上标注@EnableAsync来开启异步配置

    2024年02月04日
    浏览(67)
  • Qt 多线程的几种实现方式

    Qt多线程的实现方式有: 1. 继承QThread类,重写run()方法 2. 使用moveToThread将一个继承QObject的子类移至线程,内部槽函数均在线程中执行 3. 使用QThreadPool,搭配QRunnable(线程池) 4. 使用QtConcurrent(线程池) 为什么要用线程池? 创建和销毁线程需要和OS交互,少量线程影响不大,

    2024年02月15日
    浏览(42)
  • Android 截屏实现的几种方式

    image.png image.png 1、View 截屏 View 截图是将当前 View 界面截取下来,而对于屏幕上其他信息比如:状态栏或其他应用的界面将无法截取。 1.1 截取除了导航栏之外的屏幕 1.2 截取某个控件或者区域 2、WebView 截屏 WebView 截屏有四种方式 2.1 使用 capturePicture() 方法(已废弃) private

    2024年02月06日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包