Giter Site home page Giter Site logo

lianjiatech / fee Goto Github PK

View Code? Open in Web Editor NEW
869.0 40.0 199.0 28.15 MB

灯塔开源文档地址

Home Page: https://aa978563552.github.io/FEE-doc/

License: MIT License

JavaScript 69.28% HTML 0.05% Vue 28.89% CSS 0.43% Shell 0.17% Less 1.18% EJS 0.01%
javascript monitor nodejs

fee's Introduction

灯塔

介绍

fee(灯塔) 是前端监控系统,贝壳找房主要前端监控系统,服务公司上百条产品线。 特点:架构简单、轻量、支持私有化部署。可收集前端设备、系统、环境信息, 可以对前端页面js报错、资源错误、性能指标进行配置报警等, 并且可以通过上报错误信息引导用户快速定位解决问题。

系统功能

用户行为

  • 用户在线时长

在线时长

  • 菜单点击量

菜单点击量

  • 用户增长

用户增长 用户增长

异常监控

  • 页面性能

页面性能 页面性能

  • 错误看板

错误看板

报警

  • 报警配置

报警配置

  • 报警日志

报警日志

环境搭建

下述mysql以及redis环境的搭建,大家可以移步配套 Docker集成环境一键部署(欢迎大家star)。可以帮助大家一键创建相关服务环境,免去繁琐的环境部署与配置给大家带来的不必要的时间开销!

  1. mysql

  2. Node.js

  3. redis

  4. 克隆项目 在克隆项目之前确保你的nodejsmysqlredis环境是可用的。

     mkdir -p ~/www/ \
     &&  cd ~/www/ \
     &&  git clone [email protected]:LianjiaTech/fee.git \
     &&  cd fee

    ~/www/openfee找到我们克隆的项目

  5. 配置MySQL

  • server/src/configs/mysql.js中修改主机地址/数据库端口/数据库用户名/数据库密码/数据库库名
  • 在数据库中创建一个空的名字叫做『platform』的数据库。
    const development = {
      host: '127.0.0.1', // 主机地址
      port: '3306', // 数据库端口
      user: 'root', // 数据库用户名
      password: '00000000', // 数据库密码
      database: 'platform'  // 数据库库名
    }
  1. 配置redis
  • server/src/configs/redis.js中修改主机地址或redis端口
    // 开发环境配置
    const development = {
      host: '127.0.0.1', // 主机地址
      port: '6379' // redis端口
    }
  1. 安装依赖,在项目 server 目录下
    npm install
  2. 编译 server,打开一个新的窗口在项目 server 目录下
    npm run watch
  3. 启动server服务,在项目 server 目录下
    npm run dev
  4. 创建数据库
  • a. 在项目 server 目录下执行下列指令,会在当前目录下生成 init.sql 文件
    npm run fee Utils:GenerateSQL 1 '2020-01' '2020-07' > init.sql
  • b. 复制 init.sql中的内容(不包括文件中的前两行),完成数据库表的创建。
  1. 初始化样例数据。在项目 server 目录下,执行下列指令

    npm run fee Utils:TemplateSQL

    执行成功后,样例数据会被写入数据库中。

  2. 安装 Client 依赖,在项目 client 目录下

    npm install
  3. 启动 Client 服务,在项目 client 目录下

    npm run dev
  4. 访问本地服务: 127.0.0.1:8080

  • a. 使用默认管理员账户登录
  • b. 或进行注册登录,就能看到模板项目数据了。

npm依赖插件说明

dependencies =>

mysql           =>  mysql客户端
ioredis         =>  redis客户端
knex            =>  SQL Query Builder
@adonisjs/ace   =>  命令注册/管理工具
node-schedule   =>  node版crontab, 用于进程调度
log4js          =>  日志记录
lei-stream      =>  流式读取/写入文件. 对node的ReadStream/WriteStream的简单封装
query-string    =>  解析url
ua-parser-js    =>  解析ua
axios           =>  发起http请求
shelljs         =>  执行常见shell命令, 例如, mkdir -p
date-fns@next   =>  替代moment进行日期操作, 目前2.0版本还处于alpha状态, 待正式发布后即可取消@next标记
ini             =>  读取线上环境的ini配置文件
ipip-datx       =>  将ip转换为对应坐标, ipip.net出品

devDependencies =>

node-rdkafka                =>  获取kafka数据, 如果node-kafka无法运行, 考虑本机中是否有librdkafka库 => `sudo apt-get install librdkafka-dev` & 本机是否安装了Python2.7
                            =>  说明: node-rdkafka需要使用gcc进行编译, 但Jinkins上没有相应的编译脚本, 为了能从Jinkins上编译通过, `node-rdkfka`放在了dev依赖中.
                            =>  线上发布时, 直接把预编译好的tar文件解压到node_module文件夹里, 跳过gcc编译流程(开发机环境和线上环境一致, 因此使用开发机进行预编译)
                            =>  预编译时需要使用和线上node一致的版本
                            =>  打包命令demo => `tar cfv  pre_package.tar.gz node-rdkafka nan bindings`
                            =>  打包完成后使用 `sz node-rdkafka.tar.gz` 即可将文件下载到本机

@babel/*                    =>  7.0系列, 方便脱离对node环境的依赖, 使用js的最新特性
babel-plugin-root-import    =>  解除对相对路径的依赖(项目中通过webpack.config.js(WebStrom) & jsconfig.json(VSCode)辅助编辑器识别路径)
nodemon                     =>  动态启动/载入项目
standard                    =>  JS Standard代码规范

打点服务Demo搭建

参见打点服务Demo搭建

加入群来和开发人员讨论问题

作者书籍

项目搭建背景,以及前端监控平台搭建原理,设计思路,一步一步教你做。

购书链接

License

MIT

Copyright(c) 2017 Lianjia, Inc. All Rights Reserved

fee's People

Contributors

aa978563552 avatar alphawq avatar chenchenjoke avatar dependabot[bot] avatar diandian18 avatar linjing005 avatar tinys avatar yaozeyuan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fee's Issues

data-fns module没有导入

按照文档启动项目后,进行注册和登录,抛出以下异常

[2019-07-19 17:35:21.619]-[runtime] info信息不是标准json
[2019-07-19 17:35:21.658]-[runtime] error.massage =>Cannot read property 'getUnixTime' of undefined

error.stack =>TypeError: Cannot read property 'getUnixTime' of undefined
at Object. (/home/alain/Developer/web/fee/server/dist/model/project/user.js:95:34)
at Generator.next ()
at asyncGeneratorStep (/home/alain/Developer/web/fee/server/dist/model/project/user.js:20:103)
at _next (/home/alain/Developer/web/fee/server/dist/model/project/user.js:22:194)
at /home/alain/Developer/web/fee/server/dist/model/project/user.js:22:364
at new Promise ()
at Object. (/home/alain/Developer/web/fee/server/dist/model/project/user.js:22:97)
at Object._register (/home/alain/Developer/web/fee/server/dist/model/project/user.js:143:20)
at Object.register (/home/alain/Developer/web/fee/server/dist/model/project/user.js:60:20)
at /home/alain/Developer/web/fee/server/dist/routes/api/user/index.js:227:45
at Generator.next ()
at asyncGeneratorStep (/home/alain/Developer/web/fee/server/dist/routes/api/user/index.js:32:103)
at _next (/home/alain/Developer/web/fee/server/dist/routes/api/user/index.js:34:194)
at /home/alain/Developer/web/fee/server/dist/routes/api/user/index.js:34:364
at new Promise ()
at /home/alain/Developer/web/fee/server/dist/routes/api/user/index.js:34:97 => {"method":"func.catch.e","path":"/home/alain/Developer/web/fee/server/dist/library/utils/modules/router_config_builder.js","line":"33","pos":"25","file":"router_config_builder.js"}

node版本: 8.14.0
系统:ubuntu 16.04 LTS
访问浏览器: Mozilla Firefox for Ubuntu 1.0 & Chromium Version 74

Screenshot from 2019-07-19 17-50-52

自动注册routes的时候中间件的时机错误

server/src/routes/index.js中

// 注册路由中间件, 需要在注册路由地址之前使用
loginRouter.use(PrivilegeChecker.checkLogin)
loginProjectRouter.use(PrivilegeChecker.checkPrivilege)

注册中间件在注册路由地址之前使用,的确会提前检测login和privilege,但是对于应该返回404的路由,就无法正常通过了。

建议优化: 注册中间件的时机,应该注册路由地址之后,加入URL进行过滤。
代码如下:

for (let url of Object.keys(routerConfigMap)) {
    let routerConfig = routerConfigMap[url];
    if (routerConfig.needLogin) {
        // 需要登录
        loginRouter.use(url, PrivilegeChecker.checkLogin);
        if (routerConfig.needProjectId) {
            // 需要校验项目权限
            loginProjectRouter.use(url, PrivilegeChecker.checkPrivilege);
            Logger.log(`需要登录,也需要检验项目权限(Method: ${routerConfig.methodType}) =>`, url);
            registerRouterByMethod(loginProjectRouter, routerConfig, url)
        } else {
            // 不需要校验项目权限
            Logger.log(`需要登录,但不需要检验项目权限(Method: ${routerConfig.methodType}) =>`, url)
            registerRouterByMethod(loginCommonRouter, routerConfig, url)
        }
    } else {
        Logger.log(`不需要登录(Method: ${routerConfig.methodType}) =>`, url)
        // 不需要登录
        registerRouterByMethod(withoutLoginRouter, routerConfig, url)
    }
}

关于parseNginxLog的一点小问题

我看到task的manage启动任务在启动parseNginx的时候是按定时任务,每分钟执行一次parseNginxLog。如果每个nginx的日志里面的内容很多。而这一分钟没有处理完这些数据,那么这些定时任务开启的node进程是不是越来越多呢。这样内存是不是会占满,fee是如何处理这个问题的呢,还是我的理解有问题,能不能说下呢。
在parseNginxLog文件的每行数据接收回调函数onDataIn中,我看到有每当处理好的数据文件写入流个数大于100就会删除老的流,那样老的数据是不是就不再处理了。还是有哪里处理了呢。

/api/project/item/detail

server/src/routes/api/project/item/index.js 中的路由/api/project/item/detail.
项目id:${id}不存在的情况除了包括_.isEmpty(project), 应该还包括project.is_delete == 1。建议优化

/api/user/register

server/src/routes/api/user/index.js 中 /api/user/register 路由:
129行,判断此账号是否存在,let rawUser = MUser.getByAccount(account),应该加await,不然直接走“账号已存在”

/api/project/item/update

server/src/routes/api/project/item/index.js 中的路由/api/project/item/update。
客户端请求时候 'displayName','projectName','cDesc'都是驼峰命名,但是数据库中用的是下划线命名,应该在真正更新数据前,应该相应的把驼峰的值转一下给display_name等。

有个问题

window.addEventListener('error', function(e) {
console.log(e);
}, true)

会调用两次,也就是说会打印两次错误,这是为什么呢

Bug - Chinese characters encode error

Describe the bug

Chinese characters encode error

To Reproduce
Steps to reproduce the behavior:

  1. Click the below link and See the error

https://github.com/LianjiaTech/fee/tree/master/client#%E9%A1%B9%E7%9B%AE%E5%8A%9F%E8%83%BD

Expected behavior

encode UTF-8

Screenshots
If applicable, add screenshots to help explain your problem.

image

Desktop (please complete the following information):

  • OS: [macOS 10.15.7]
  • Browser [Google Chrome]
  • Version [87.0.4280.88 (x86_64)]

Additional context
Add any other context about the problem here.

https://github.com/LianjiaTech/fee/tree/master/client

Commands:parseNginxLog自动清理旧Stream有问题

parseNginxLog里面由于在分析83行,定期清理stream:
jsonWriteStreamPool.size > 100 || rawLogWriteStreamPool.size > 100 ,由于jsonWriteStreamPool和rawLogWriteStreamPool都是NginxParseLog子类中定义的Map,没有对相关map进行set处理,所以,size应该永远是0,这个判断应该去base中获取jsonWriteStreamPool的size。

在save_log/base中,63行,autoCloseOldStream循环:
首先是10分钟之内,startAt = nowAt - 60 * 100,finishAt = nowAt - 60 * 100,那不是startAt===finishAt了么? 其次,循环中 let survivalAtLogUri = LKafka.getAbsoluteLogUriByType(nowAt, LKafka.LOG_TYPE_JSON) 使用nowAt去获取文件路径,按照目前的逻辑,只有nowAt这一刻的stream可以幸免被关闭。原本设计的应该是获取10分钟内需要被避免关闭的stream,然后关闭其他。所以这边应该是LKafka.getAbsoluteLogUriByType(survivalAt, LKafka.LOG_TYPE_JSON)

Bug - 你卖书就卖书,搞个跑不起来的阉割版demo代码,是想干啥呢?

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: [e.g. iOS]
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • Browser [e.g. stock browser, safari]
  • Version [e.g. 22]

Additional context
Add any other context about the problem here.

/api/project/item/delete

server/src/routes/api/project/item/index.js 中路由/api/project/item/delete 请求方式最好是post或者delete

项目启动报错

按照文档指引,启动项目后,在clinet端会报找不到文件的错误,然后去查看了一下view下确实缺少device-detail/mobileview.vue。将这部分相关的代码注释掉后项目成功启动

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.