Giter Club home page Giter Club logo

linuxkerneltravel / lmp Goto Github PK

View Code? Open in Web Editor NEW
574.0 574.0 167.0 234.46 MB

LMP provides an eBPF Supermarket for developers, including eBPF tools, open-source projects based on eBPF, eBPF learning materials, Linux kernel learning materials, and more.

Home Page: https://linuxkerneltravel.github.io/lmp/

License: Apache License 2.0

Go 1.03% Makefile 0.13% C 95.38% Python 0.72% HTML 1.75% Shell 0.04% CSS 0.07% Smarty 0.03% JavaScript 0.11% Vue 0.20% SCSS 0.04% Dockerfile 0.01% C++ 0.35% CMake 0.06% DIGITAL Command Language 0.01% Rust 0.02% Meson 0.01% Roff 0.03% TypeScript 0.04%
bcc bpftrace ebpf linux linuxkernel lmp

lmp's Issues

python部分项目结构完善

目前python部分存放在lmp/plugins下,直接将所有的文件保存在这了,没有做目录划分等工作。

现在需要完善python部分,当做一个python项目管理,划分API到单独的文件夹,插件到单独的文件夹;增加必要的其余文件。

完成后在评论中附加pr的链接,并在Reviewers中@LinkinPF

(未来方向)采用微服务架构

目前lmp项目是一个传统的web项目,没有进行容器化改造,我们需要使用k8s对项目进行容器化。
改造优势:
部署安装简单,保证了测试环境与生产环境的强一致性
对分布式以及集群进行性能监测变得更加容易,并且更加灵活
极大程度节约机器的物理资源
启动迅速,并且可以实现更快的开发迭代
对齐云原生生态,可对接各个云原生项目

ubuntu运行lmp“'generated/autoconf.h' file not found”

环境描述:
ubuntu 5.11.0-40

bug描述:
In file included from :1:
././include/linux/kconfig.h:7:10: fatal error: 'generated/autoconf.h' file not found
#include <generated/autoconf.h>
^~~~~~~~~~~~~~~~~~~~~~
1 error generated.
Traceback (most recent call last):
File "./plugins/vfsstat.py", line 36, in
b = BPF(text="""
File "/usr/lib/python3/dist-packages/bcc/init.py", line 347, in init
raise Exception("Failed to compile BPF module %s" % (src_file or ""))
Exception: Failed to compile BPF module
In file included from :1:

因为bug描述为缺少generated/autoconf.h,将同一个版本的ubuntu的generated/autoconf.h找来加到后面,出现新的bug:
In file included from :2:
In file included from /virtual/include/bcc/bpf.h:12:
In file included from include/linux/types.h:6:
In file included from include/uapi/linux/types.h:14:
In file included from ./include/uapi/linux/posix_types.h:5:
In file included from include/linux/stddef.h:5:
In file included from include/uapi/linux/stddef.h:2:
In file included from include/linux/compiler_types.h:80:
include/linux/compiler-clang.h:51:9: warning: 'HAVE_BUILTIN_BSWAP32' macro redefined [-Wmacro-redefined]
#define HAVE_BUILTIN_BSWAP32
^
:4:9: note: previous definition is here
#define HAVE_BUILTIN_BSWAP32 1

grafana无法连接到influxdb

WX20211119-104124@2x Medium

grafana连接influxdb时显示failed to fetch

(连接的用户名、密码为root、123456,与config.yaml中一致)

WX20211119-104153@2x

docker运行状态

README文档完善

README分为以下模块:

  1. 项目简介
  2. grafana结果展示(截屏)
  3. 项目架构(目前还是单节点)
  4. quickstart : 编译安装步骤
  5. quickstart : 本地部署方法
  6. quickstart : 云端部署方法
  7. 卸载步骤
  8. 给出doc/submit.md的链接
  9. 感谢开源项目的支持

修改BCC程序之参数如何处理

bcc程序一般都有很多参数,在运行时可以根据需要指定,从而输出不同的结果,这些参数发改分为几类:

  • 指定运行时间和输出间隔;
  • 对输出结果分类:比如offcputime程序,指定-k输出内核进程的栈阻塞时间,-u输出用户进程的栈阻塞时间;
  • 指定跟踪粒度:比如offcputime,默认追踪系统上所有进程的栈阻塞时间,-p则可以指定跟踪某一个进程;
  • 等等...

在修改bcc程序时该如何处理这些参数,有如下解决方案:

  1. 仅保留默认参数,这种方式不需要修改现有的后端代码;
  2. 支持所有的三叔,这种方式首先需要修改前下发指标页面,后端可能也要做相应修改,数据展示页面则要根据对应的输出进行展示,这要求数据展示部分要非常灵活,因为不同的参数其输出结果可能不同,要做相应的处理;
  3. 保留一部分,删除一部分,这种方式是一种折中,牺牲一部分工具的优势,缓解数据展示部分对灵活性的要求。

大家可以发表自己的看法,在接下来该指标的过程中做成一个标准,方便大家改指标。

使用bpf generator实现最简单的代码生成

#44 pr 提交了提取vfsstat5个指标的代码,这是目前提取指标里实现最简单的,先做一次尝试,由@X1ngx1ngzzZ 完成剩余的bpf generator的工作。

过程如下:
1、使用#18 pr的builder模式,完成现有的CBuilder接口,接口中方法可根据实际情况修改。
2、对接/api下handle.go中的execute协程,能够完成通路。
3、增加前端选项,vfsstat作为一个选项,包括5个指标(具体看代码),后端注意修改ConfigMessage结构。
4、最终可以实现前端页面勾选vfsstat,后端进行提取,而不是调用静态bpf文件。

注:提交的pr与这个issue关联。

将提取数据和写数据分离

目前插件中收集到性能数据后,会立即通过API将数据写入influxdb,这样不利于管理且会出现死循环问题;

现将提取数据和写入数据两个操作分开,所有插件以后只负责提取数据,写入数据交由另外的模块独立进行,依旧通过API传入数据至数据写入模块;

需要在评论中给出方案,之后link pr,并在Reviewers中@LinkinPF

挂载函数点失败

Traceback (most recent call last):
File "huge.py", line 35, in
b.attach_kprobe(event="do_page_fault", fn_name="do_return")
File "/usr/lib/python3/dist-packages/bcc/init.py", line 803, in attach_kprobe
raise Exception("Failed to attach BPF program %s to kprobe %s" %
Exception: Failed to attach BPF program b'do_return' to kprobe b'do_page_fault'

(优先级最高!!!)(评论)优化目前的python API

目前项目目录lmp/plugins下的api.py、dbmodules.py、lmp_influxdb.py三个文件是目前提供的api,但是目前并不完善,需要大家给出各种优化建议,在评论中给出即可,采用的建议单独做成任务卡。

该任务卡优先级最高,因为python层的API较为完善以后,才可以开始大量写BCC插件。

后端3:实现BPF generator

实现BPF generator,当前只需封装成空方法,产生的BPF code存放到一个特定位置。(待细化)

plugins整理

plugins中的文件进行梳理:把这个目录中的文件进行梳理归类
初步梳理:
common:公共库
cpu:
fs:
net:
。。。。

influxdb增加:python部分

bpf的部分中,python负责把提取到的内核数据写入influxdb,go部分负责管理database和measurements,bpf geneartor生成的python代码中应包含明确的measurement信息。python直接向该measurement写入数据。代码部分分为三个:
1、influxdb.py,该文件包含全局变量的定义、连接数据库等。
2、modules.py,该文件包含数据库方法,CRUD。
3、service.py,该文件包含数据结构定义。

(目前给方案不提交代码)BCC插件写入数据库的方式

之前给大家描述的,目前的磁盘监控和网络监控的插件会触发死循环;

现在需要解决死循环的问题,即在BCC插件中写入数据库的时候,作出修改;

该任务卡目前是在评论中写上方案,不需要提交代码,最终的方案会转换成另一个任务卡;

python依赖管理

python依赖一直都是一个很蛋疼的问题,目前项目在python部分没有做依赖管理的事情。

增加python的依赖管理。
(周萌提出)第一种就是简单的requirement.txt 。规定好依赖格式类似于bcc==1.0.0
第二种用就是采用pipenv的方式管理。

完成后在评论中附加pr的链接,并在Reviewers中@LinkinPF

整体部署步骤写成一个shell脚本

目前项目部署需要按照readme文件依次执行,基本的步骤都可以使用bash脚本实现自动化。

需要从代码clone到本地后,直接执行脚本,之后直接在bash中输入lmp即可执行。(需要将可执行文件安装到/usr/bin目录下);

完成后在评论中附加pr的链接,并在Reviewers中@LinkinPF

前端1:有配置选项的静态页面

静态页面1 :配置选项:调度延迟、运行队列长度、软中断时间、硬中断时间、(进程PID)的oncpu时间、采集数据的时长;设置一个名称是开始收集的按钮,需要点按开始收集按钮后,向后端发送配置选项的json格式数据。另外的信息:项目名称Linux microscope(LMP)。

(参考大师兄仓库)

增加mysql存储插件信息及运行状态

目项目中留有存储插件信息的字段,但是并没有利用,每增加一个插件需要修改前后端代码;

增加mysql,项目启动后首先扫描所有插件并将每个插件信息存储到mysql,前端通过url访问插件信息,这样避免了增加插件修改前端代码,mysql中增加插件运行状态的字段,前端也可访问每个插件的运行状态。

需要在评论中给出方案,之后link pr,并在Reviewers中@LinkinPF

架构优化相关

LMP架构优化

背景

lmp项目为用户提供将系统各项指标以dashboard的形式可视化的服务,涉及有业务应用层,数据库持久化层,内核提取指标层,业务应用层主要实现对用户浏览器传过来的请求进行解析和响应,如下图,用户可以请求查看runqlen指标,时间设置为几分钟,提交即可。

lmp后端收到请求,解析出参数,并开协程执行对应的插件,问题就在于这里执行插件的操作是:

func execute(filepath string, collectTime int, exitChan chan bool) {
    defer func() {
        if err := recover(); err != nil {
            zap.L().Error("error in execute routine, err:", zap.Error(err.(error)))
            fmt.Println("error in execute routine, err:", err)
        }
    }()

    cmd := exec.Command("sudo", "python3", filepath)
    cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}

    stdout, err := cmd.StdoutPipe()
    defer stdout.Close()
    go func() {
        scanner := bufio.NewScanner(stdout)
        for scanner.Scan() {
            line := scanner.Text()
            fmt.Println(line)
        }
    }()

    stderr, err := cmd.StderrPipe()
    defer stderr.Close()
    go func() {
        scanner := bufio.NewScanner(stderr)
        for scanner.Scan() {
            line := scanner.Text()
            fmt.Println(line)
        }
    }()

    err = cmd.Start()
    if err != nil {
        zap.L().Error("error in cmd.Start()", zap.Error(err))
        return
    }

    go func() {
        err = cmd.Wait()
        if err != nil {
            zap.L().Error("error in cmd.Wait()", zap.Error(err))
            return
        }
    }()

    ctx, cancel := context.WithTimeout(context.Background(), time.Duration(collectTime)*time.Second)
    defer cancel()

    for {
        select {
        case <-ctx.Done():
            syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
            exitChan <- true
            return
        }
    }
}    

其中,exec.command函数是启动新的root进程执行插件的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WDbxcoe2-1617512212337)(/home/changke/.config/Typora/typora-user-images/image-20210404152604367.png)]

目前lmp模块设计

执行完以后还需要回收新创建进程的资源。在高并发的情况下,lmp项目必定不可用,因为创建进程的系统资源开销很重,创建进程过多资源不足时会导致lmp主进程奔溃。其次,就每个软件系统的设计目标而言:低耦合,高内聚,目前这个系统,功能集成了接收并解析请求,响应请求,开子进程执行插件,回收子进程,功能耦合性太高,可扩展性不强。

对于系统协程使用的个人观点:

协程的应用场景
在这里插入图片描述
协程的出现提高了对用户态的业务处理效率,我们有个计算任务,调用某个应用态函数,可以将这个业务扔给协程去处理,然后线程可以继续执行其他业务,能实现不阻塞这个计算任务这块而导致其他业务也停滞。在执行系统调用或者我们lmp项目的exec.command这种必须要开启进程的系统,使用协程基本上是没有发挥协程自身的优势。

解决方案

想过直接将lmp项目由go迁移成python项目,原框架功能设计可以不变,不过插件的形式应该改成线程执行bcc代码的形式。但是python多线程并没有goroutine的效率高,所以不用了。

如下图,简单明了地描述了新系统的架构设计构想:
在这里插入图片描述

待评估lmp模块设计

使用流程:
在这里插入图片描述

  • lmp系统主要赋能:接收请求,响应请求,发送参数给pluginserver

  • plugin server主要赋能:一个基于python语言实现的服务器,接收用户请求参数,定时执行bcc指标函数,持久化指标数据,定时清理数据库指标数据

优势分析

  • 原来lmp项目功能耦合性过高的问题;
  • lmp项目开协程主要处理业务逻辑,充分发挥了协程的优势,实现高并发;
  • 避免了lmp开过多进程导致系统崩溃的隐患,plugin server可以部署到其他机器,对其他机器进行指标监控分析;
  • plugin server执行bcc是交给线程执行,替换了原来插件执行,线程比进程更加轻量级,没有占用更多的系统资源;
  • 对于GitHub上CI的效率会提升。

前端增加vue.js框架

目前前端页面是用基本的Html + CSS实现的,比较简单,后期要实现复杂的功能比较困难,所以在这个基础上需要加上前端的框架,以便于更好的开发后期的功能。
目前主流的框架较多,如vue.js,react,angular等,建议使用vue.js框架,易于上手。
在vue.js基础之上Element实现了一套UI,提供了所有的界面组件,能够快速搭建一个风格统一美观的前端页面。
总结一下就是前端页面使用ElementUI去实现。

Provide detailed guide for getting started

  • Specify docker image tag explicitly (Which version we use for influxdb and grafana?)
  • Document how to change configuration manually
  • Create database if not exists rather than provide them as binary file in test folder

ping @LinkinPF

gRPC相关

项目后期分布式采用gRPC协议,感兴趣的同学可以提前学习。

文档或者代码输出,例如内部原理、用法简介、demo示例,api介绍等。

文档或者代码在TAPD中直接关联文档,方便大家查看

增加python读取yaml配置文件

目前所有的BCC插件中,关于influxdb的信息都是写死的字符串,这样不符合代码规范要求。

在项目目录lmp/plugins下的api.py、dbmodules.py、lmp_influxdb.py三个文件是目前提供的api,需要在这三个文件中增加python层读取yaml配置文件的功能,yaml配置文件位于lmp/config.yaml,需要读取的信息是:
user: "root"
password: "123456"
dbname: "lmp"
可以写成api函数,也可以保存为变量之后BCC中import,需要在评论中给出方案,之后粘贴代码的pr链接,并在Reviewers中@LinkinPF

LMP插件问题:ModuleNotFoundError: No module named 'settings'

Traceback (most recent call last):
File "./plugins/oomkill.py", line 24, in
from db_modules import write2db
File "/home/ubuntu/lmp2/plugins/db_modules.py", line 7, in
from db_writer.writerImpl import writer_factory
File "/home/ubuntu/lmp2/plugins/db_writer/writerImpl.py", line 11, in
from settings.const import DatabaseType
ModuleNotFoundError: No module named 'settings'

lmp物理机安装

lmp在物理机(实验室服务器)上安装的过程中遇到了一些问题:
1.在config.yaml中mysql的密码是123456,如果本机所安装mysql的密码不是123456,需要将config.yaml中的mysql密码改为自己的密码;
2.使用docker安装influxdb时,默认pull的镜像是最新的,但是运行readme中的docker run命令之后,在influxdb中并没有成功安装influxdb或者说influxdb是无法正常工作的。具体原因未知,但是将镜像版本降低之后这个问题就解决了,我使用的镜像版本是1.8:
相应的命令为:

sudo docker pull influxdb:1.8
 sudo docker run -d \
    -p 8083:8083 \
    -p 8086:8086 \
    --name influxdb \
    -v ${YOUR_PROJECT_PATH}/lmp/test/influxdb_config/default.conf:/etc/influxdb/influxdb.conf \
    -v ${YOUR_PROJECT_PATH}/lmp/test/influxdb_config/data:/var/lib/influxdb/data \
    -v ${YOUR_PROJECT_PATH}/lmp/test/influxdb_config/meta:/var/lib/influxdb/meta \
    -v ${YOUR_PROJECT_PATH}/lmp/test/influxdb_config/wal:/var/lib/influxdb/wal influxdb:1.8

lmp插件管理问题

问题1:plugins/db_writer/bufferImpl.py文件包引导问题,我使用相对路径也还是这个报错,只能将路径写死

image1

问题2:plugins/db_writer/writerImpl.py未找到settings包

image2

问题三:将虚拟机挂起再打开就会出现该错误,只能重启虚拟机解决

image3

数据库调研

目前项目采用influxdb数据库,虽然适用项目应用场景,但是分布式场景下influxdb并不开源,所以需要调研其它类型的数据库;

重点调研吴峰光老师采用的ES数据库,需要调研数据库基本信息,优势,和golang、python操作ES数据库的连接和CRUD的demo程序;

需要在评论中给出调研结果,之后将demo程序pr link到issue,并在Reviewers中@LinkinPF

bpf 模板文件讨论

bpf generator需要生成一个python文件和一个c文件,所以需要制定一个代码规范,方便generator的生成,这个每种指标的代码都不一样,有些是统一的,有些是私有的。大家可以针对自己写过的bcc代码,提出自己的想法或者模板,近期需要确定下来。

前端指标页面动态获取指标

  1. 在index.html页面中目前是静态的内置了多个采集指标,每次新增指标需要动态维护页面,目前后端已经将指标存入数据库,前端需要通过接口获取后端的指标信息,做到动态展示。
  2. 在index.html页面中,目前采用的是复选框罗列出现有的指标,用户选择进行下发,复选框可显示的信息量有限,需要将其修改为列表形式,列表形式可以展示更多的指标信息(如指标名称、介绍、状态等)。

lmp介绍

  1. 架构介绍
  2. 编译运行
  3. 调测使用
  4. 开发介绍

(目前给方案不提交代码)DoCollect核心协程优化—保存exec产生的PID号

目前核心路由//data/collect中,进入到logic层的DoCollect函数后,在logic层的DoCollect函数中会开启一些协程,每一个协程都会调用exec再产生一个系统线程。目前这些线程的PID号并没有存储,所以会导致一个bug,后台提取数据的过程中,如果突然kill掉lmp,那么这些线程会一直运行下去,只有使用ps -aux查看PID号后使用kill命令杀掉线程。现在需要改进这一点。

目前可以在两个地方修改,一个是go的web层,一个是每个BCC插件中设定提取的时间,到期结束;但是为了BCC插件开发的简化,并且想要达到在关闭lmp的同时无论如何要直接杀掉所有BCC线程的目的。决定在go的web层进行改进,该任务卡只需要将产生的线程的所有的PID号保存起来即可,不需要进一步处理。

该任务卡目前不是代码提交,先在评论中给出方案,例如使用共享切片管理,整体思路是...,这样做的原因是...,也可以使用其它类型的数据结构存储,要在评论区给出方案。

ubuntu18.04无法显示前端页面

clone后make通过,运行程序,服务可以起起来,但是访问localhost:8080的时候一直404,直接访问其它URL也是一样的结果,不知道其他小伙伴们有这样的问题吗

架构更新—增加Cli框架

目前代码是一个标准的web脚手架,在考虑到项目未来的包容性,让更多同学的论文和功能能够加入到lmp项目中,决定增加go语言的命令行工具框架Cli;

这里对代码整体框架改动较大,需要增加较多代码,在评论区给出整体方案,并说明需要改动的go文件、增加的go文件,方便其余成员了解架构更新。

完成后在评论中附加pr的链接,并在Reviewers中@LinkinPF

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.