目录
一、DevLake简介
1、什么是DevLake
DevLake全名是Apache DevLake,是一个开源的开发数据平台,它从DevOps工具中采集、提取和转化数据,并将碎片化的DevOps数据整理,最终形成可以直观查看的指标数据。这些指标数据可以反映工程师表现、可以反应项目的整个发展情况,也可以反应出开发社区的健康度和活跃度。DevLake的目的是为了更好地理解开发过程,并将更多的数据驱动方法引入实践中。
2、DevLake可以用来做什么
- 统一数据集成:使用标准数据模型将来自软件开发生命周期(SDLC)的DevOps数据整合在一起。
- 开箱即用的见解:通过直观的、用例驱动的仪表板访问关键的工程指标。
- 可定制:扩展DevLake以符合您的独特需求,根据需要添加数据源、指标和仪表板。
- 行业标准实现:使用DevLake应用公认的DORA指标来优化DevOps性能。
- 创建繁荣的文化:DevLake专注于健康的实践,帮助团队采用和建立实用的数据驱动文化。
3. 如何使用DevLake
3.1. 配置数据源
你可以开始使用受支持的数据源配置DevLake,如GitHub、GitLab、Jira、Jenkins、BitBucket、Azure DevOps、SonarQube、PagerDuty、TAPD、ZenTao、Teambition,然而,如果你的CI/CD工具目前不被DevLake支持,你可以利用webhooks功能。当你的DevOps工具没有特定插件可用时,Webhooks功能允许你主动将数据推送到DevLake。
3.2. 创建项目
一旦您将数据源连接到Apache DevLake,您就可以创建一个“项目”,以确保您已经为执行做好了一切准备。在DevLake建立一个项目的过程通常包括四个步骤:
1)添加数据源
2)设置数据收集范围
3)设置数据转化规则(可选)
4)设置同步策略
3.3 检查仪表板和指标
在DevLake中配置项目后,您可以在Grafana中访问预构建的仪表板。这些仪表板提供了与软件开发相关的各种度量的可视化和洞察。
要根据您的特定目标和需求定制仪表板,您可以使用Grafana的功能来调整它们。此外,如果您喜欢创建自己的仪表板,您可以选择使用SQL查询从DevLake获取必要的数据,参考度量文档中的域层数据模式和SQL示例。
二、DevLake的框架
1. DevLake组成
- Config UI:人如其名,配置的可视化,其主要承载 Apache DevLake 的配置工作。通过 Config UI,用户可以建立数据源连接,并实现数据的收集范围,部分数据的转换规则,以及收集频率等任务。
- API Server:Apache DevLake 的 Api 接口,是前端调用后端数据的通道。
- Runner:Apache DevLake 运行的底层支撑机制。。
- Database:数据库存储DevLake的元数据和通过数据管道收集的用户数据。DevLake从v0.11开始支持MySQL和PostgreSQL。
- Plugins:插件使DevLake能够通过可访问的API从任何DevOps工具收集和分析开发数据。DevLake社区正在积极为流行的DevOps工具添加插件,但如果您首选的工具尚未覆盖,请随时打开GitHub issue让我们知道或查看我们的文档,以了解如何自己构建新插件。
- Dashboard:仪表板向DevLake用户提供数据和见解。仪表板只是一组SQL查询以及相应的可视化配置。DevLake的官方仪表盘工具是Grafana,预构建的仪表盘以Grafana的JSON格式提供。
2. 数据流图
DevLake是通过分层的方式从数据源提取数据的,总共分为3层
1)Raw Layer(原始层)
原始层以JSON格式存储来自数据源(DevOps工具)的API响应。后面会对原始数据进行不同的转换,这可以节省开发人员的时间。请注意,与数据源的api通信通常是最耗时的步骤。
2)Tool Layer(工具层)
工具层将原始数据从json中提取到关系模式中,以便于分析任务使用。每个DevOps工具都有一个针对其数据结构定制的模式,因此被称为tool layer(工具层)。
3)Domain Layer(领域层)
领域层试图在工具层之上构建一个抽象层,以便分析逻辑可以在不同的工具之间重用。例如,GitHub的Pull Request (PR)和GitLab的Merge Request (MR)是类似的实体。它们在工具层中都有自己的表名和模式,但是在领域层中它们被合并为单个实体,因此开发人员只需要针对领域层模式实现一次周期时间和代码评审轮等指标。
3. 核心概念
3.1 Blueprint
蓝图是将数据源中的数据同步到DevLake平台的计划。创建蓝图包括四个步骤:
- 添加数据连接(Data Connection):您可以向蓝图添加一个或多个数据连接,具体取决于您希望与DevLake同步的数据源。每个数据连接代表一个特定的数据源,如GitHub或Jira。
- 设置数据范围(Data Scope):添加数据连接时,可以选择收集数据连接的全部或部分配置的数据范围。
- 数据范围配置(Scope Config):数据范围配置定义了要收集的特定数据实体和要应用于该数据的转换。
- 设置同步策略(Sync Policy):设置数据采集的同步频率和时间范围。
- 在创建DevLake项目时,将自动创建Blueprint。
- 每个Blueprint可以有多个数据连接。
- 每个数据连接可以有多个数据范围。
- 每组数据范围仅由一个GitHub/GitLab项目或Jira看板以及它们相应的数据实体组成。
- 每组数据范围只能有一个数据范围配置。
3.2 Pipelines
管道是DevLake API中定义的数据收集、提取、转换和扩展任务的编排。流水线由一个或多个按顺序执行的阶段组成。在执行任何阶段、任务或子任务时发生的任何错误都会导致管道立即失败。
下面看一下管道的组成:
Stage:Stage是由数据插件执行的任务的集合。在管道中,Stage是按顺序执行的。
Task:任务是执行特定数据插件的任何收集、提取、转换和充实任务的子任务的集合。任务在任何阶段都以并行顺序执行。
Subtask:子任务是管道中执行四个角色中的任何一个的最小工作单元:Collectors(收集), Extractors(提取), Converters(转换) and Enrichers(扩展),子任务按顺序执行。
- Collectors:通常通过DevLake API从数据源收集原始数据并存储到原始数据表中
- Extractors:从原始数据表中提取数据到工具层表
- Converters:将数据从工具层表转换为领域层表
- Enrichers:将数据从一个域扩展到其他域。例如,可以傅里叶变换issue_changelog,以显示问题在每个受聘者上的时间分布。
4. DevLake的任务执行原理
4.1. Pipeline运行原理
一个pipeline包含一个二维数组tasks,主要是为了保证一系列任务按预设顺序执行。如果上图中的 Stage3 的插件需要依赖其他插件准备数据,那么 Stage 3 开始执行时,需要保证其依赖项已在 Stage1 和 Stage2 执行完成
4.2 Task的运行原理
在stage1,stage2,stage3中的各插件任务都是并行执行:
接下来就是顺序执行插件中的子任务,每个子任务就是具体的Collectors(收集), Extractors(提取), Converters(转换) and Enrichers(扩展)任务
- RunTask 之前的工作都是在准备 RunTask 方法需要的参数,比如 logger,db,context 等等。
- RunTask 方法中主要是对数据库中的tasks进行状态更新,同时,准备运行插件任务的 options(把从 config-ui 传过来的 json 转成 map 传到 RunPluginTask 中)
- RunPluginTask 首先通过 core.GetPlugin(pluginName) 获取到对应 PluginMeta,然后通过 PluginMeta 获取到 PluginTask,再执行 RunPluginSubTasks
4.3 Subtask的运行流程
- 通过调用SubTaskMetas()获取到所有插件所有的可用子任务subtaskMeta
- 通过options["tasks"]以及subtaskMeta组建需要执行的子任务集合subtaskMetas
- 计算总共多少个子任务
- 通过helper.NewDefaultTaskContext构建taskCtx
- 调用pluginTask.PrepareTaskData构建taskData,
-
接下来迭代subtaskMetas里面的所有子任务
-
通过taskCtx.SubTaskContext(subtaskMeta.Name)获取到子任务的subtaskCtx
-
执行subtaskMeta.EntryPoint(subtaskCtx)
-
三、DevLake代码库导读
1. 目录结构Tree
├── api
│ ├── blueprints
│ ├── docs
│ ├── domainlayer
│ ├── ping
│ ├── pipelines
│ ├── push
│ ├── shared
│ ├── task
│ └── version
├── config
├── config-ui
├── devops
│ └── lake-builder
├── e2e
├── errors
├── grafana
│ ├── _archive
│ ├── dashboards
│ ├── img
│ └── provisioning
│ ├── dashboards
│ └── datasources
├── img
├── logger
├── logs
├── migration
├── models
│ ├── common
│ ├── domainlayer
│ │ ├── code
│ │ ├── crossdomain
│ │ ├── devops
│ │ ├── didgen
│ │ ├── ticket
│ │ └── user
│ └── migrationscripts
│ └── archived
├── plugins
│ ├── ae
│ │ ├── api
│ │ ├── models
│ │ │ └── migrationscripts
│ │ │ └── archived
│ │ └── tasks
│ ├── core
│ ├── dbt
│ │ └── tasks
│ ├── feishu
│ │ ├── apimodels
│ │ ├── models
│ │ │ └── migrationscripts
│ │ │ └── archived
│ │ └── tasks
│ ├── gitextractor
│ │ ├── models
│ │ ├── parser
│ │ ├── store
│ │ └── tasks
│ ├── github
│ │ ├── api
│ │ ├── models
│ │ │ └── migrationscripts
│ │ │ └── archived
│ │ ├── tasks
│ │ └── utils
│ ├── gitlab
│ │ ├── api
│ │ ├── e2e
│ │ │ └── tables
│ │ ├── impl
│ │ ├── models
│ │ │ └── migrationscripts
│ │ │ └── archived
│ │ └── tasks
│ ├── helper
│ ├── jenkins
│ │ ├── api
│ │ ├── models
│ │ │ └── migrationscripts
│ │ │ └── archived
│ │ └── tasks
│ ├── jira
│ │ ├── api
│ │ ├── models
│ │ │ └── migrationscripts
│ │ │ └── archived
│ │ └── tasks
│ │ └── apiv2models
│ ├── refdiff
│ │ ├── tasks
│ │ └── utils
│ └── tapd
│ ├── api
│ ├── models
│ │ └── migrationscripts
│ │ └── archived
│ └── tasks
├── releases
│ ├── lake-v0.
10.0
│ ├── lake-v0.
10.0
-beta1
│ ├── lake-v0.
10.1
│ ├── lake-v0.
7.0
│ ├── lake-v0.
8.0
│ └── lake-v0.
9.0
├── runner
├── scripts
├── services
├── test
│ ├── api
│ │ └── task
│ └── example
├── testhelper
├── utils
├── version
├── worker
├── Dockerfile
├── docker-compose.yml
├── docker-compose-temporal.yml
├── k8s-deploy.yaml
├── Makefile
└── .env.exemple
2. 目录导览
2.1 后端部分
- config:对.env 配置文件的读、写以及修改的操作。
- logger:log 日志的 level、format 等设置。
- errors:Error 的定义。
- utils:工具包,它包含一些基础通用的函数。
- runner:提供基础执行服务,包括数据库,cmd,pipelines,tasks以及加载编译后的插件等基础服务。
- models:定义框架级别的实体。
- common:基础 struct 定义。
- domainlayer:领域层是来自不同工具数据的通用抽象。
- ticket:Issue Tracking,即问题跟踪领域。
- code:包括 Source Code 源代码关联领域。以及 Code Review 代码审查领域。
- devops:CI/CD,即持续集成、持续交付和持续部署领域。
- crossdomain:跨域实体,这些实体用于关联不同领域之间的实体,这是建立全方面分析的基础。
- user:对用户的抽象领域,user 也属于 crossdomain 范畴。
- migrationscripts:初始化并更新数据库。
- plugins:
- core:插件通用接口的定义以及管理。
- helper:插件通用工具的集合,提供插件所需要的辅助类,如 api 收集,数据 ETL,时间处理等。
- 网络请求 Api Client 工具。
- 收集数据 Collector 辅助类,我们基于 api 相同的处理模式,统一了并发,限速以及重试等功能,最终实现了一套通用的框架,极大地减少了开发和维护成本。
- 提取数据 Extractor 辅助类,同时也内建了批量处理机制。
- 转换数据 Convertor 辅助类。
- 数据库处理工具。
- 时间处理工具。
- 函数工具。
- ae:分析引擎,用于导入 merico ae 分析引擎的数据。
- feishu:收集飞书数据,目前主要是获取一段时间内组织内会议使用的 top 用户列表的数据。
- github:收集 Github 数据并计算相关指标。(其他的大部分插件的目录结构和实现功能和 github 大同小异,这里以 github 为例来介绍)。
- github.go:github 启动入口。
- tasks:具体执行的4类任务。
- *_collector.go:收集数据到 raw layer 层。
- *_extractor.go:提取所需的数据到 tool layer 层。
- *_convertor.go:转换所需的数据到 domain layer 层。
- *_enricher.go:domain layer 层更进一步的数据计算转换。
- models:定义 github 对应实体 entity。
- utils:github 提取的一些基本通用函数。
- api:api 接口。
- gitextractor:git 数据提取工具,该插件可以从远端或本地 git 仓库提取 commit 和 reference 信息,并保存到数据库或 csv 文件。用来代替 github 插件收集commit 信息以减少 api 请求的数量,提高收集速度。
- refdiff:在分析开发工作产生代码量时,经常需要知道两个版本之间的 diff。本插件基于数据库中存储的 commits 父子关系信息,提供了计算ref(branch/tag)之间相差 commits 列表的能力。
- gitlab:收集 Gitlab 数据并计算相关指标。
- jenkins:收集 jenkins 的 build 和 job 相关指标。
- jira:收集 jira 数据并计算相关指标。
- tapd:收集 tapd 数据并计算相关指标。
- dbt:(data build tool)是一款流行的开源数据转换工具,能够通过SQL实现数据转化,将命令转化为表或者视图,提升数据分析师的工作效率。Apache DevLake 增加了 dbt 插件,用于数据定制的需要。
- services:创建、管理 Apache DevLake 各种服务,包含 notifications、blueprints、pipelines、tasks、plugins 等。
- api:使用 Gin 框架搭建的一个通用 Apache DevLake API 服务。
2.2 前端部分
- congfig-ui:主要是 Apache DevLake 的插件配置信息的可视化。
- 常规模式
- blueprints 的配置。
- data connections 的配置。
- transformation rules 的配置。
- 高级模式:主要是通过 json 的方式来请求 api,可选择对应的插件,对应的 subtasks,以及插件所需要的其他信息。
- 常规模式
- Grafana:其主要承载 Apache DevLake 的前端展示工作。根据收集的数据,通过 sql 语句来生成团队需要的各种数据。目前 sql 主要用 domain layer 层的表来实现通用数据展示需求。
- migration:数据库迁移工具。
- migration:数据库迁移工具 migration 的具体实现。
- models/migrationscripts:domian layer 层的数据库迁移脚本。
- plugins/xxx/models/migrationscripts:插件的数据库迁移脚本。主要是_raw_和_tool_开头的数据库的迁移
2.3 测试部分
- testhelper 和 plugins 下的*_test.go 文件:即单元测试,属于白盒测试范畴。针对目标对象自身的逻辑,执行路径的正确性进行测试,如果目标对象有依赖其它资源或对够用,采用注入或者 mock 等方式进行模拟,可以比较方便地制造一些难以复现的极端情况。
- test:集成测试,灰盒测试范畴。在单元测试的基础上,将所有模块按照设计要求(如根据结构图)组装成为子系统或系统,进行集成测试。
- e2e: 端到端测试,属于黑盒测试范畴。相对于单元测试更注重于目标自身,e2e 更重视目标与系统其它部分互动的整体正确性,相对于单元测试着重逻辑测试,e2e 侧重于输出结果的正确性。
2.4 编译、发布部分
- devops/lake-builder: mericodev/lake-builder 的 docker 构建。
- Dockerfile:主要用于构建 devlake 镜像。
- docker-compose.yml:是用于定义和运行多容器 Docker 应用程序的工具,用户可以使用YML文件来配置 Apache DevLake 所需要的服务组件。
- docker-compose-temporal.yml:Temporal 是一个微服务编排平台,以分布式的模式来部署 Apache DevLake,目前处于试验阶段,仅供参考。
- worker:Temporal 分布式部署形式中的 worker 实现,目前处于试验阶段,仅供参考。
- k8s-deploy.yaml:Kubernetes 是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。目前 Apache DevLake已支持在 k8s 集群上部署。
- Makefile:是一个工程文件的编译规则,描述了整个工程的编译和链接等规则。
- releases:Apache DevLake 历史 release 版本的配置文件,包括 docker-compose.yml 和 env.example。
- scripts:shell 脚本,包括编译 plugins 脚本。
2.5 其他
- img:logo、社区微信二维码等图像信息。
- version:实现版本显示的支持,在正式的镜像中会显示对应 release 的版本。
- .env.exemple:配置文件实例,包括 DB URL, LOG 以及各插件的配置示例信息。
四、DevLake插件的相关指标数据
1. 工具数据(数据库以_tool_开头的数据)
1.1. Gitlab
- account(账户)
- commit(提交)
- connections(连接)
- deployments(部署)
- issue_assignesss(issue指派人)
- issue_labels(issue标签)
- issues(issue)
- jobs(工作)
- merge_requests(MR)
- mr_comments(MR评论)
- mr_commits(MR的提交)
- mr_labels(MR的标签)
- mr_notes(MR的笔记)
- pipeline_projects(管道项目)
- pipelines(管道)
- project_commits(项目提交)
- projects(项目)
- reviewers(评审人员)
- tags(tag)
1.2. Jira
- accounts(账户)
- board_issues(看板issue)
- board_sprints(看板迭代)
- connections(连接)
- issue_changelog_items(issue修改日志项目)
- issue_changelog(issue修改日志)
- issue_comments(issue评论)
- issue_commits(issue提交)
- issue_labels(issue标签)
- issue_releationships(issue关联)
- issue_types(issue类型)
- issues(issue)
- projects(项目)
- remotelinks(远程连接)
- sprint_issues(迭代的issue)
- sprints(迭代)
- statuses(状态)
- worklogs(工作日志)
1.3. Jenkins
- build_commits(编译提交)
- bulids(编译)
- connections(连接)
- job_dags()
- jobs(工作)
- stages(阶段)
2. 指标数据
2.1. GitLab
- Commit Count(提交行数)
- Commit Author Count(作者提交行数)
- Added Lines of Code(新增行数)
- Deleted Lines of Code(删除行数)
- PR Count(Pull Request 行数)
- PR Cycle Time(PR时间周期)
- PR Coding Time
- PR Pickup Time
- PR Review Time
- PR Deploy Time
- PR Time To Merge
- PR Merge Rate
- PR Review Depth
- PR Size
- Build Count(编译次数)
- Build Duration(编译间隔)
- Build Success Rate(编译成功率)
- DORA - Deployment Frequency
- DORA - Lead Time for Changes
- DORA - Median Time to Restore Service
- DORA - Change Failure Rate
2.2. Jira
- Requirement Count(需求个数)
- Requirement Lead Time(需求前置时间)
- Requirement Delivery Rate(需求交付率)
- Requirement Granularity(需求颗粒度)
- Bug Age(bug的年龄)
- Bug Count per 1k Lines of Code(每千行代码的bug数)
- Incident Age(事故年龄)
- Incident Count per 1k Lines of Code(每千行代码的事故数)
2.3. Jenkins
- Build Count(编译次数)
- Build Duration(编译周期)
- Build Success Rate(编译成功率)
- DORA - Deployment Frequency(部署频率)
- DORA - Lead Time for Changes(变更的前置时间)
- DORA - Median Time to Restore Service(恢复服务的平均时间)
- DORA - Change Failure Rate(修改的故障率)