运维开发实践:基于Sentry搭建错误日志监控系统

《运维开发实践:基于Sentry搭建错误日志监控系统》要点:
本文介绍了运维开发实践:基于Sentry搭建错误日志监控系统,希望对您有用。如果有疑问,可以联系我们。

错误日志监控也可称为业务逻辑监控,旨在对业务系统运行过程中产生的错误日志进行收集归纳和监控告警.似乎有那么点曾相识?没错… 就是上一篇文章提到的“APM应用性能监控”.但它又与APM不同,APM系统主要注重应用层的行为分析,收集的更多是运营方向的数据.而sentry所做的是收集应用底层代码的崩溃信息,便于码侬们排查代码异常.简单来说它就是一个面向技术码侬的排障工具.

1. 场景描述

随着运维自动化流程的推进,各类运维工具和系统也像雨后春笋般涌现. 目前我们自主开发的运维系统的数量已经接近两位数. 这些系统部署在多台机器上,通常还配套一批后台运行的脚本. web端如果出现异常,开发人员可以及时得到反馈进行修复. 而脚本因为没有交互,可能会出现发生重大故障时才定位到问题的情况.

2. 既有方案

  1. 后端和脚本用python内置的日志模块记录程序中间状态,同时也将两者的输出重定向到指定文件,以获取未捕获的异常信息.
  2. 同台服务器上多个系统的日志集中存放到同个目录
  3. 使用rsync定时从多台服务器中拉取日志文件
  4. 对日志文件进行关键字匹配,并将过滤结果通过邮件发送给运维开发人员

最终整合的通知邮件如图

运维自动化

3. 存在的问题

上面的操作部分解决了脚本运行状态监控盲区的问题,但还存在如下问题

  1. 无法第一时间感知错误
    脚本日志的拉取不是实时的,web端用户的反馈也往往存在滞后. 出现问题到解决问题的周期太长,容易导致工作陷入被动.
  2. 错误信息的获取相对低效
    用户反馈和邮件告警包含的错误信息非常有限,最终都不得不在大量的日志中上下翻看关联的信息. 可能还需要在测试环境下给代码埋点多获取一些中间变量数据,给定位问题带来很多麻烦.
  3. 日志的处理方式不够灵活
    通常来说,除了程序运行出错,我们还关心其他异常情况,比如数据污染,非法请求,第三方API调用异常等. 如果将此类等同错误记录下来,很容易造成告警滥发,而如果不处理此类异常,久而久之可能导致严重的问题. 我们希望同样的日志内容可以根据场景不同灵活处理
  4. 监控覆盖面有限
    完整的监控应该涵盖脚本,后端以及前端三个部分. 特别是我们新的运维系统实现了前后端分离之后,很多前端的问题无法被统一记录下来.

鉴于此,我们了解了一些日志收集和监控方案,选择了sentry.

4. sentry初探

4.1 概览

sentry是一个现代化的错误日志记录和聚合平台.支持几乎所有主流开发语言和平台,并提供了现代化UI,如图

sentry

与ELK,splunk不同,sentry专注于应用程序产生的错误日志的聚合和监控. 官方提供了多个语言的SDK.

SDK

多达30种集成方式

运维开发实践:基于Sentry搭建错误日志监控系统

让开发者第一时间获悉错误信息,并方便的整合进自己和团队的工作流中.

4.2 使用前后对比

为了直观的展示sentry的强大,这里模拟一个常见的场景,如有雷同,纯属巧合.

4.2.1 场景一

接入sentry前

  • 用户A: 发布功能用不了
  • 开发者A: 哪个页面? 截个图
  • 用户A: (发截图)
  • 开发者A发现bug可以重现,登录服务器查看错误日志,确认程序逻辑无问题,查看数据库数据,发现有脏数据. 联系开发者B检查负责更新数据的python脚本C.py.
  • 开发者B登录服务器查看错误日志,发现一个逻辑错误导致脚本罢工,已持续了一个小时. 影响了数千条数据

接入后

  • 开发者A,B同时收到邮件告警,一分钟前脚本C.py异常退出.
  • 开发者B进入sentry后台查看错误信息,定位问题并将其修复,再清理受影响的数十条数据.
  • 在此过程中没有用户受到影响,无需开发者A介入

4.2.2 场景二

接入sentry前

  • 用户: 提交按钮点了没反应
  • 开发者: 哪个页面? 截个图
  • 用户: (发截图)
  • 开发者: 我这边没这个问题,你打开开发者工具,切到console面板,截个图我看下
  • 用户: 怎么弄??….省略100字
  • 开发者拿到相关数据,确定是代码问题. 但是js文件经过了压缩,无法定位到有问题的代码. 只能打开本地开发服务器调试.

接入后

  • 开发者收到邮件告警,显示前端有错误日志
  • 开发者进入sentry后台查看错误信息,比如用户浏览器版本,产生错误的页面url,代码调用过程和最终引发错误的代码,确认问题所在.
  • 开发者: 两分钟前你提交的工单备注字段的校验有点问题,你先把那一栏留空再提交,稍后我会更新一个hotfix版本,到时跟你说下.
  • 用户: 好的,刚想问.

5. sentry的配置

sentry官方提供了详细的部署文档,网上也可以搜索到中文的安装教程,安装过程不赘述. 想要尝鲜的小伙伴也可以直接使用sentry官方提供的saas,免费版支持每天5000个event. 地址是 https://sentry.io

5.1 概念

使用sentry,需要弄清楚几个概念:

  • event
    直译是”事件”,是可操作数据的基本单位. 每一次日志输出就产生一个event. event并不一定就是错误,如果日志记录级别设置很低,那么后台会产生很多的event,所以正确的设置日志级别很重要
  • issue
    直译是”工单”或者”问题”,是同一类event的聚合. 某一个错误可能因为重复执行而被记录多出,在sentry会自动聚合到一起,方便处理. 通常我们操作的对象就是issue

运维开发实践:基于Sentry搭建错误日志监控系统

  • DSN
    DSN即客户端密钥,用来进行客户端和服务器的通信. DSN是一个url,包含一个公钥一个私钥,项目标记和服务器地址,比如https://1703147af2094458bevb1bfadcfa1c2:7e00a1d4cbd745c0b780451c3586d7f4@sentry.io/1545. 这类DSN是私密的,还有一类是非私密的,在sentry后台中显示为DSN(public),给前端项目使用.
  • Raven
    整个错误日志监控系统包括客户端和服务端,Sentry是服务端的名称,客户端名称是Raver,需要两者配合才能工作.

5.2 配置

sentry服务端的配置主要是名称,告警规则等,至于被监控项目是前端还是后端区别不大.

5.2.1 创建项目

  1. 进入sentry系统后台,点击右上角新建项目

sentry

  1. 命名为[项目名][前|后端],比如”蓝海前端”.
  2. 在配置应用框架页面,点击可以查看各个语言或框架的接入文档(可以忽略这一步)
  3. 点击左上角项目名称,进入项目首页,可以看到页面显示”Waiting for events…”

5.2.2 获取和测试DSN

  1. 在”项目设置”页,在左侧列表中点击”客户端密钥”,进入页面
  2. 拷贝DSN,后端的是DSN,前端是DSN(public)
  3. 以python为例,执行pip install raven安装客户端后,执行raven test DSN,如果一切顺利,可以在sentry后台项目首页看到新增了一条测试消息

DSN

5.2.3 配置警报

  1. 在”项目设置”页面,在左侧列表中点击”警报”,进入警报配置页
  2. 点击规则标签页,可以看到已有一个规则,当事件首次发生时告警
  3. 根据需要修改规则

告警规则的配置相当灵活,且可以对多个条件进行与或判断

运维开发实践:基于Sentry搭建错误日志监控系统

5.2.4 集成告警

  1. 在”项目设置”页面,在左侧列表中点击”所有集成”
  2. 勾选需要接入的类型,比如Mail

运维开发实践:基于Sentry搭建错误日志监控系统

邮件服务器的配置请参考官方文档,自己搭建的sentry服务器如果发现集成类型很少,可以安装官方或第三方插件进行扩展

在服务端配置结束后,可以开始配置客户端.

6. 后端的接入

因为我们的系统主要用python开发,在此以python为例.

python接入sentry十分简单. 官方提供了十几种python环境(框架)下使用sentry的例子,比如在celery中

from raven import Client from raven.contrib.celery import register_signal,register_logger_signal client = Client(DSN) # register a custom filter to filter out duplicate logs register_logger_signal(client) # The register_logger_signal function can also take an optional argument # `loglevel` which is the level used for the handler created. # Defaults to `logging.ERROR` register_logger_signal(client,loglevel=logging.INFO) # hook into the Celery error handler register_signal(client) # The register_signal function can also take an optional argument # `ignore_expected` which causes exception classes specified in Task.throws # to be ignored register_signal(client,ignore_expected=True)

个人推荐借鉴logging使用的例子,原因是通常开发者会根据logging模块定制自己的日志配置,不直接使用框架内的日志模块. 如果你在应用程序中只用了logging模块,那么接入sentry对已存在的代码来说是透明的,无需多加修改.

用logging模块接入sentry只需两步:

6.1 安装客户端

pip install raven

6.2 初始化配置 

在应用程序的入口文件(tornado中的app.py等)中,或者自定义的日志模块中,插入如下代码

from raven.handlers.logging import SentryHandler from raven.conf import setup_logging handler = SentryHandler(DSN) handler.setLevel(logging.ERROR) setup_logging(handler)

完成了这两步操作之后,就可以像之前那样使用logging模块

import logging logger = logging.getLogger(__name__) logger.info(‘This is a test message’)

当上面的代码被执行时,除了原有的打log操作之外,raven还会向sentry服务器发送日志内容,并向标准输出添加

Sending message of length xxx to https://xxxx

如果希望向sentry发送更多上下文信息,可以带上extra参数

logger.error(‘This is a test message’,extra={‘stack’: True})

最终显示在后台的日志信息如图

日志

包含了日志级别,python环境信息,SDK信息,栈调用,前后n次日志输出,相关的其他事件等等,如果是未捕获的异常或带上extra参数,还会显示中间变量的值,很方便的定位到出错的位置和数据,无需再去代码埋点.

7. 前端的接入

前端的接入相对来说复杂一些

第一,需要对sentry服务器的域名进行解析. 内部的系统,后端监控可以给线上机器添加hosts指定sentry服务器的IP. 而前端,因为错误日志是从用户浏览器发出的,需要用户能自动解析sentry服务器的域名

第二,如果前端项目用到了打包工具,而通常打包工具会对代码进行压缩甚至混淆,就会出现sentry收集到的日志无法准确定位问题代码的情况 所幸,sentry支持导入sourcemap自动解析和还原代码,让开发者在后台能看到development环境一样详细的栈调用. (当然如果没有用打包工具可以忽略这一步)

前端的接入这里以reactjs为例

7.1 安装依赖

npm i raven-js –save

7.2 嵌入raven

在index.js文件(入口文件)中,

import Raven from ‘raven-js’; # 在适当的地方加入,尽可能让它早执行 Raven.config(DSN(public)).install();

其他前端框架的接入请参考官方文档

https://docs.sentry.io/clients/javascript

7.3 导入sourcemap

提前生成好sourcemap文件,实测source-map级别可以完美工作,cheap-source-map能定位到,但显示不友好. 当然,最推荐的是cheap-module-source-map

# 安装 npm i -g sentry-cli-binary # 登录sentry sentry-cli –url SENTRY_URL login # SENTRY_URL指自建服务或官方saas地址,执行命令后会访问API TOKEN创建页面,生成一个TOKEN,拷贝进来,成功后TOKEN会被保留到系统用户某个配置目录下,后续的请求都会重复使用这个TOKEN # 创建一个release sentry-cli releases -o sentry -p 7d04f2c51f32 new test01 –finalize # 这里的sentry 和7d04f2c51f32 是指 组织名称和项目名称,均指*简称*,与sentry页面上默认显示的不同,需要到配置页面查看 # 上传dist目录下的文件 sentry-cli releases -o sentry -p 7d04f2c51f32 files test01 upload-sourcemaps dist # 删除旧的release下的所有文件 sentry-cli releases -o sentry -p 7d04f2c51f32 files test01 delete –all # 当然这个命令是不想要release上的文件的时候执行的

注意,生成的map文件与上传的相对路径需要一致. 比如,dist目录是打包后的文件存放目录,map文件为sourcemap/[file].map,则sentry-cli上传目录应该是dist,这样map文件才会显示在sentry后台的~/sourcemap/目录下.

这样的webpack配置

devtool = ‘source-map’; output.path: ‘dist’; output.sourceMapFilename = ‘sourcemap/[file].map’;

则对应这样的命令

sentry-cli releases -o sentry -p 7d04f2c51f32 files test02 upload-sourcemaps dist

另外,sentry-cli提供了一个参数–url-prefix,可以为上传的map文件添加前缀,默认是~/,有兴趣的同学可以试试看

再补充一点,sentry需要根据js文件的sourceMappingURL来解析map文件路径,所以sourcemap级别不能用hide-source-map或者类似的.

代码上传完毕后,在版本->工件页面可以看到该release上的文件,如图

release

最终错误日志效果如图

运维开发实践:基于Sentry搭建错误日志监控系统

8. sentry管理后台的使用

篇幅所限,sentry后台的使用简要讲几点

第一,自定义过滤 

sentry提供了丰富的过滤选项,默认过滤条件是”Unresolved Issues”,用户也可以自己组合过滤条件,并保存成个人或团队的默认选项

sentry

第二,页面实时更新 

上图中间的按钮可以开启或关闭issues页面的实时刷新,

第三,统计和概览

运维开发实践:基于Sentry搭建错误日志监控系统

上图是系统管理员页面,可以看到系统调用,等待中的任务队列等的情况,在个人帐号首页也能看到项目的统计信息.

9. 需要注意的点

  1. 用sentry做错误日志监控不能取代原有的日志存储方案,只是在日志收集和监控方面做了扩展. 使用sentry应着重利用其实时性和快捷性,做到快速响应. sentry会清除较旧的日志内容,这与ELK之类的日志处理系统也有差别.
  2. sentry能否用得好还取决于打log的开发者的功力. 如果原始日志记录缺少关键信息或无效信息过多,再强大的日志分析系统也无能为力. 因此在引入sentry做日志监控的同时,也要同步加强开发团队打log的意识,规范日志级别,格式和内容

文章来自微信公众号:运维军团

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


起步 处理器架构,参考 x86是指intel的开发的一种32位指令集 intel和amd早期的cpu都支持这种指令集 AMD比Intel率先制造出了商用的兼容x86的CPU,AMD称之为AMD64 Intel选择了设计一种不兼容x86的全新64为指令集,称之为IA-64,后来支持AMD64的指令集,
pscp pscp -P 22 C:\work\test.txt root@192.168.1.5:/home/data pscp -P 22 root@192.168.1.5:/home/data/test.txt C://work// 检索 find / -name default.config
文件处理 ls -a # 显示所有文件 ls -l # 显示详细信息 ls -d # 显示路径 mkdir /目录名称 # 创建目录 cd /目录名称 # 切换目录 pwd # 显示当前路径 rmdir /目录名称 # 删除目录 cp -rp [目录名称] [目标目录] # 复制目录到目标目录 cp
准备一台电脑(我就用联想拯救者r7000演示) 参考博客制作启动盘 插上U盘,启动电脑,一直按F2 进入如下页面后,将U盘设置为第一启动项,点击exit,保存并退出 之后进入如下页面,选择第三项 进入如下页面,选择第四项 进入如下页面,选择第一项,选中后,先不要点Enter 按e键,将inst.st
认识 Linux系统是参考了UNIX系统作为模板开发的,但没有使用UNIX的代码;是UNIX的一种,但不是衍生版 在Linux内核的基础上开发是发行版 分区 逻辑分区永远从5开始 步骤 挂载:可理解为分配盘符,挂载点即是盘符名;不同之处:Linux中是以空目录名称作为盘符 Hda 第一块硬盘 Hda
文件处理命令 以 . 开头的文件是隐藏文件 以 - 开头表示这是一个文件 以 d 开头表示是一个目录 以 l 开头表示是一个软链接 第一个root是所有者,第二个root是所属组 ls -h 以文件默认大小后缀 显示 ls -i 查看i节点(唯一标识) 所有者:只能有一个,可变更 所属组:只能有一个
参考 01 02 03 前提环境 本地安装VirtualBox,并安装CentOS8,配置网络后,window系统上putty能连接到CentOS8服务器 配置步骤 右键服务器复制 启动复制后的服务器,查看ip和hostname发现和原来的服务器一样,需要修改 hostname # 查看主机名 vi
文件搜索命令 星号匹配任意字符,问号匹配任意单个字符 -iname 根据文件名查找且不区分大小写 -ok 命名会有一个询问的步骤 如果没有找到指定文件,可输入命令:updatedb 更新文件资料库;除tmp目录不在文件资料库收录范围之内 locate -i 文件名 # 检索时不区分大小写 which
安装环境 安装最新版的Virtual Box,点击安装 下载centos8镜像 创建虚拟机,可参考 选择下载到本地的镜像 设置启动顺序 点击启动 启动过程中报错:“FATAL:No bootable medium found!” 1.没有选择iso镜像 2.光驱没有排在第一位置 3.镜像只能选择x8
Linux严格区分大小写 所有内容文件形式保存,包括硬件 Linux不靠扩展名区分文件类型 挂载:将设备文件名和挂载点(盘符)连接的过程 Linux各个目录的作用 bin表示二进制 服务器注意事项 远程服务器不允许关机,只能重启 重启时应该关闭服务 不要在服务器访问高峰运行高负载命令 远程配置防火墙
IDE连接Linux,上传下载文件 参考1 参考2 连接Linux 上传下载文件 本地项目打包后上传 查看是否上传成功,右键下载 补充 后端项目开发完成后,需clean掉临时文件target文件夹,且只推送修改过的文件 前端项目开发的过程中,需要在每个子组件中使用scoped,确保每个子组件中的编码
起步 LTS与普通版本的区别 LTS版本的发布周期更长,更加稳定 安装jdk sudo mkdir /usr/lib/jvm # 在Ubuntu中创建目录 pscp D:\安装包\linux源码包\jdk-8u291-linux-x64.tar.gz chnq@192.168.0.102:/tmp
前言 最近在b站上看了兄弟连老师的Linux教程,非常适合入门:https://www.bilibili.com/video/BV1mW411i7Qf 看完后就自己来试着玩下,正好手上有台空闲的电脑就尝试不使用虚拟机的方式安装Linux系统 安装步骤 制作启动盘 下载ISO镜像,我这里下载的是Cen
新建虚拟电脑 设置内存和处理器 设置硬盘大小 完成 设置 查看光驱 设置启动顺序 点击启动 选择第1项 进入图形安装界面 选择安装位置,开始安装 设置root密码 重启 登录 查看本地文件夹 配置网络,点击设置 查看宿主机ip C:\Users\ychen λ ipconfig 无线局域网适配器 W
源码包安装需手动下载后安装 二进制包则在package目录下 rpm命令管理rpm包 若某个rpm包依赖于某个模块,需要到网站www.rpmfind.net查询该模块依赖的包,安装这个包后自动安装模块,之后就能安装rpm包了 安装升级时使用包全名 查询卸载时使用包名 虚拟机中的Linux系统安装rp
首先进入命令模式,再输入以下命令 命令模式用于输入命令 插入模式可对文件编写操作 编辑模式下的命令是在冒号后输入 :12, 15d # 删除指定范围的行,这里是删除12到15行 :n1,n2s/old/new/g ## 表示从n1行到n2行,old表示旧的字符串 vim使用小技巧:自定义快捷键,如快
使用源码包安装,需要自己指定安装位置,通常是 /usr/local/软件名/ linux中要想启动执行文件,应使用绝对路径 /绝对路径/rpm包名 start ## 执行方式一 service rpm包名 start ## 执行方式二 使用源码包安装后,由于自定义安装路径,就不能使用service命
网络命令 在收邮件的用户中,输入 mail 可查看邮件信息,输入序列号查看详细信息 在mail命令下,输入h 查看所有邮件的列表 输入:d 序列号 # 删除邮件 last # 统计所有用户登录或重启时间,用于日志查询 lastlog # 显示包括未登录用户的登录时间 lastlog -u 用户id
若要使用yum管理,必须能连接网络,首先配置网络IP 进入yum源文件中启动容器 使用yum源头安装rpm包不需要进入package路径,同时也不需要使用包全名,会有yum自动管理 安装软件组
简介 client即是本机安装的docker,相当于git Docker_host相当于centos系统 registry则是docker仓库,相当于GitHub 镜像用于创建docker容器,一个镜像可以创建多个docker容器 容器是由镜像创建的运行实例,(镜像相当于类,容器相当于类创建的对象)