关于sentry:聊聊使用错误采集平台sentry踩到的坑

前言sentry简介Sentry 是一款业余的企业级谬误跟踪和日志剖析工具,旨在帮忙开发人员、管理员和产品经理跟踪、剖析和解决应用程序谬误和性能问题。Sentry 的次要性能和长处包含: 谬误跟踪: Sentry 能够跟踪应用程序中的谬误,并将它们记录下来,以便开发人员可能疾速定位和解决问题。 日志剖析: Sentry 能够剖析应用程序的日志,并提供具体的信息,如谬误级别、调用堆栈、数据库拜访等,以帮忙开发人员疾速定位和解决问题。 告诉和警报: Sentry 能够通过电子邮件、Slack、PagerDuty 等渠道告诉开发人员谬误和性能问题的产生,以便及时响应和解决问题。 可扩展性: Sentry 反对自定义谬误音讯、扩大谬误跟踪性能等,开发人员能够依据本人的需要进行自定义和扩大。 团队合作: Sentry 反对团队合作,能够不便地共享谬误和日志信息,并反对多人同时编辑和评论。 总的来说,Sentry 是一款功能强大、易于应用的企业级谬误跟踪和日志剖析工具,能够帮忙开发人员和管理人员更好地治理和解决应用程序中的谬误和性能问题。 本文次要聊下在应用sentry过程中遇到的一些问题 问题锦集问题一:uWSGI listen queue of socket "127.0.0.1:42563" (fd: 3) full !!! (101/100)这是因为uWSGI的监听队列满了,默认的监听队列长度为100,把监听队列调大就行 具体操作,批改/onpremise/sentry/sentry.conf.py SENTRY_WEB_OPTIONS = { .... "listen":10240, ....} 不过调了,重启后大概率会报 Listen queue size is greater than the system max net.core.somaxconn (128)此时要批改零碎参数,如果是通过宿主机部署,则执行vim /etc/sysctl.conf,增加如下内容 # 用于设置内核无奈及时处理网络接口收到的数据包时容许发送到队列的最大数据包数目,默认为128。也就是每个监听的socket,在没有accept之前,期待解决的socket队列长度net.core.somaxconn = 10240而后执行sysctl -p 从新加载参数。不过如果是基于docker-compose部署sentry,这么加是没成果的。得通过在docker-compose.yml做如下配置 示例: version: '3'services: ...: image: ... container_name: ... privileged: true sysctls: net.core.somaxcomm: '10240'能够查看如下文档https://github.com/docker/compose/issues/3765#issuecomment-402929969 ...

July 11, 2023 · 1 min · jiezi

关于sentry:聊聊如何解决官方提供的onpremise项目安装sentry速度过慢问题

前言何为sentrysentry是一个基于Django构建的现代化开源的实时谬误追踪零碎,能够帮忙开发者发现问题、追踪问题 sentry官网文档https://docs.sentry.io/ sentry装置咱们能够应用官网提供的https://github.com/getsentry/onpremise.git的我的项目进行装置。 装置步骤如下 以在centos7装置为例 1、克隆onpremise我的项目yum install gitgit clone https://github.com/getsentry/onpremise.git2、切换到onpremise目录,执行install.sh装置脚本 cd onpremise ./install.sh只有执行这两步,就能够悠哉的喝杯咖啡期待装置实现了。前面你会发现,这个装置的工夫,绝不是喝一杯咖啡的工夫就能够解决了,可能是要喝N杯。因为这个等待时间切实是有点漫长,我第一次装置耗时差不多有3个小时。因为有了这次体验,前面再装置,我就在思考如何晋升这个装置速度了 如何晋升onpremise我的项目装置senrty的速度通过观察执行的install.sh脚本的日志,发现他执行到 RUN apt-get update && apt-get install -y --no-install-recommends cron && \ rm -r /var/lib/apt/lists/*这句脚本就会十分慢,他会下载debian,而且一旦下载没胜利,就会报错退出,就得从新再来一次,让人会很抓狂。因为下载debian的地址是在国外,所以下载速度就异样慢,那咱们解决的思路就有要么翻墙,要么就是切换debian的镜像源。我的计划是前面一种 因而这句脚本执行前,咱们能够加如下脚本 Run sed -i 's#http://deb.debian.org#https://mirrors.163.com#g' /etc/apt/sources.list这句话的意思就是将debian的镜像源切换成163镜像源 或者你也能够用以下脚本,也能够达到下面的成果(不过不是很举荐这种形式,因为上面这句脚本的意思是装置debian10版本的镜像源,如果sentry依赖是高于debian10版本,那就完犊子) RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak && \ echo deb http://mirrors.163.com/debian/ buster main non-free contrib >>/etc/apt/sources.list && \ echo deb http://mirrors.163.com/debian/ buster-updates main non-free contrib >>/etc/apt/sources.list && \ echo deb http://mirrors.163.com/debian/ buster-backports main non-free contrib >>/etc/apt/sources.list && \ echo deb http://mirrors.163.com/debian-security/ buster/updates main non-free contrib >>/etc/apt/sources.list && \ echo deb-src http://mirrors.163.com/debian/ buster main non-free contrib >>/etc/apt/sources.list && \ echo deb-src http://mirrors.163.com/debian/ buster-updates main non-free contrib >>/etc/apt/sources.list && \ echo deb-src http://mirrors.163.com/debian/ buster-backports main non-free contrib >>/etc/apt/sources.list && \ echo deb-src http://mirrors.163.com/debian-security/ buster/updates main non-free contrib >>/etc/apt/sources.list这个脚本的批改地位在onpremise/cron/Dockerfile,就是批改cron的Dockerfile。 ...

November 29, 2022 · 1 min · jiezi

关于sentry:使用-Sentry-对应用进行监控少-bug-少加班

为什么咱们须要利用监控大家是否有过这样的体验: 产品新性能上线几周后,客户提工单反馈问题。研发同学经排查确认是 bug,且会产生脏数据。最终,修复 bug + 上线花了大半天,而编写修复脚本 + 修复数据消耗了一周。 如果发现 bug 的机会越早,那么修复老本就越低。 通过对利用中的谬误或异样进行监控和主动反馈,有助于咱们尽早发现荫蔽的问题,晋升产品质量和研发效率。 日志零碎不等同利用监控零碎可能有同学会说:程序的谬误和异样在咱们的日志零碎外面都有呀,为什么还须要专门的利用监控零碎? 的确,日志中事无巨细地记录了大量的运行过程和异样信息。不过,这些信息可能也存在反复、有效、不足分割的弊病。而且,日志次要是在研发同学排查问题时应用,很少被用于被动监控和告警,日常存在着大量的错误信息始终未被关注和解决。 Sentry:一款受欢迎的利用监控产品Sentry 是一款开源的利用监控产品,应用 Python、JavaScript、HTML、CSS 打造。在 GitHub 上有 29k Stars,是利用监控畛域 Stars 数排行最高的开源我的项目,其官网声称有 1 百万名开发者和 7 万个组织在应用 Sentry。除了提供开源产品外,其幕后的公司也提供付费的 SaaS 服务:sentry.io。2021 年该公司发表取得了 6000 万美元的 D 轮融资,该轮融资使 Sentry 的总资金达到 1.27 亿美元,融资后估值为 10 亿美元。的确是一款值得关注的产品。 Sentry 有以下重要特点:产品体验好,功能完善 接入工作量少 官网和开源社区提供了各种支流开发语言和框架的 SDK,便于开发者接入,大多几十行代码内即可实现。 Sentry 专一于 Error、Exception、Crash 能够查看到具体的错误信息和调用栈,能疾速定位问题代码。 提供丰盛的上下文信息 SDK 会主动上报根底信息,也反对上报自定义的信息,便于排查问题。 主动合并反复问题 反复的报错被主动合并且累计次数,防止开发者在大量反复冗余的信息寻找 bug 的蛛丝马迹。 被动邮件告警 不必再等“客户告警”后才开始排查问题。 自部署 Sentry 的毛病部署依赖繁多 利用官网的提供的 Github 仓库,基于 Docker 和 Docker Compose 的确能够一键部署、开箱即用。不过,当看到 30 个容器列在背后时,还是会感觉迟疑。 ...

October 19, 2021 · 2 min · jiezi

关于sentry:Sentry-10-升级到-Sentry-20

Sentry 简介Sentry ['sentri]n.哨兵v.站岗;在…设岗哨Sentry 是一个用于监控前后端出错和统计上报剖析一体的一个开源软件系统。 Sentry 适宜中等规模以上的网站的开发及生产线上出错治理。Sentry能够适应多租户多我的项目的治理。性能很欠缺。 官网地址: https://sentry.io/features/re... 因为软件架构比较复杂。倡议采纳官网的 docker-compose 脚本即onpremise 来装置。 Sentry 零碎占用内存较多,最好有8G以上内存。因资源受限,我用的是4G内存+4G Swap分区的形式在 CentOS 7 上装置的。在收集几千万个谬误上报后,零碎依然很晦涩,可见其性能低劣。 最新的 Sentry 零碎由28个容器组成: # docker ps --format 'table {{ .Ports }}\t{{.Names}}'PORTS NAMES0.0.0.0:9000->80/tcp sentry_onpremise_nginx_19000/tcp sentry_onpremise_subscription-consumer-events_19000/tcp sentry_onpremise_ingest-consumer_19000/tcp sentry_onpremise_cron_19000/tcp sentry_onpremise_subscription-consumer-transactions_19000/tcp sentry_onpremise_post-process-forwarder_19000/tcp sentry_onpremise_sentry-cleanup_19000/tcp sentry_onpremise_web_19000/tcp sentry_onpremise_worker_11218/tcp sentry_onpremise_snuba-subscription-consumer-transactions_11218/tcp sentry_onpremise_snuba-transactions-consumer_11218/tcp sentry_onpremise_snuba-sessions-consumer_11218/tcp sentry_onpremise_snuba-api_11218/tcp sentry_onpremise_snuba-outcomes-consumer_11218/tcp sentry_onpremise_snuba-consumer_11218/tcp sentry_onpremise_snuba-replacer_11218/tcp sentry_onpremise_snuba-subscription-consumer-events_13000/tcp sentry_onpremise_relay_11218/tcp sentry_onpremise_snuba-cleanup_19092/tcp sentry_onpremise_kafka_16379/tcp sentry_onpremise_redis_15432/tcp sentry_onpremise_postgres_13021/tcp sentry_onpremise_symbolicator_12181/tcp, 2888/tcp, 3888/tcp sentry_onpremise_zookeeper_125/tcp sentry_onpremise_smtp_18123/tcp, 9000/tcp, 9009/tcp sentry_onpremise_clickhouse_111211/tcp sentry_onpremise_memcached_13021/tcp sentry_onpremise_symbolicator-cleanup_1注: docker ps 后加 format 参数,能够管制输入字段和格局,很不便写文档用。详见Docker官网。以上的28个容器大略造成了以下的构造: ...

January 3, 2021 · 2 min · jiezi

纪录一次sentry升级历史

首发于:我的博客起因IOS同事说他发现了sentry的一个bug。说是因为9.0.0的bug导致debug file 提示上传成功,但是上网站却发现根本没有上传。所以就开始了我的升级之路。 调研因为我的sentry不仅仅用在了服务器端,而且还用在了客户端上。所以我需要解决如果sentry停止了,那么如何解决请求等待的问题。 Nginx那么我首先想到的就是修改nginx的配置文件。 下面是我更新的相关内容 server { listen 80; server_name track.example.com; set_real_ip_from 127.0.0.1; real_ip_header X-Forwarded-For; real_ip_recursive on; location / { // 添加这两行 default_type text/html; // 设置 content-type 表示这是一个网页 return 202; # 返回 202 表示已经接收,但是并不处理 client_max_body_size 100M; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host-Real-IP $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-Pcol http; proxy_pass http://localhost:10000; }}使用这两行,就可以保证客户端正常请求了数据,但是我却把它给抛弃了。保证客户端的正常浏览。 sentry 升级接下来就是对sentry进行升级了。 首先,进入到指定目录 cd /data/对相关目录进行备份(备份是个好习惯,千万不要丢弃) cp -r onpremise onpremise2然后进入目录 cd onpremise停止sentry的运行 docker-compose down拉取最新代码 git pull这个时候可能会提示以下错误: ...

August 8, 2019 · 1 min · jiezi

vue项目前端错误收集之sentry

sentry简介Sentry 是一个开源的错误追踪工具,可以帮助开发人员实时监控和修复系统中的错误。其专注于错误监控以及提取一切事后处理所需的信息;支持几乎所有主流开发语言(JS/Java/Python/php)和平台, 并提供了web来展示输出错误。sentry官网:https://sentry.io/ sentry安装sentry 是一个开源的工具,可以自行搭建。官方支持两种安装和运行 Sentry 服务器的方法,Docker 和 Python。推荐使用 Docker。当然,对于刚开始接触 sentry 的同学,也可以直接使用官方提供的免费服务,但是有一些限制。下面先来介绍一下利用官方的免费服务,在前端项目中如何使用 sentry。 如何在项目中使用sentry首先需要在 sentry 的官网注册一个账号。注册完选择新建一个项目,sentry 支持多种框架,在其中选择 vue 创建项目。我创建了一个名为test的项目。 创建项目页面会自动跳转到如何配置vue项目页面。接下来就按照指引在vue代码里引入 sentry。可以通过 cdn 或者 npm 引入。我们采用 npm 引入。引入的时候需要给 init 函数传递一个 dsn 参数。这个参数唯一指定了我们刚才创建的项目,在创建项目的时候系统会自动生成。如果不传这个参数,sentry 不会发送错误。// main.jsimport * as Sentry from '@sentry/browser';import * as Integrations from '@sentry/integrations';// 在生产环境中让sentry报错process.env.NODE_ENV === "production" && Sentry.init({ dsn: 'https://1111a5bc59b54778b75f4e3a92f2e462@sentry.io/1447145', integrations: [ new Integrations.Vue({ Vue, attachProps: true, }), ],});在项目跟目录下增加.sentryclirc文件,其中的token可以在左上角头像里的api keys里面获取。 [auth]token="your token"[defaults]url = https://sentry.ioorg = "your org"project = test然后我们在代码里制造一个错误,就可以让 sentry 捕获了。本地如何模拟线上环境访问dist下的文件呢?需要装一个 http-server ,在dist文件夹下启动一个http服务就可以了。 ...

May 27, 2019 · 2 min · jiezi

线上debug指南【草稿】

February 12, 2019 · 0 min · jiezi

Sentry的使用

公司项目里需要加入,于是自己倒腾了下,就总结了下入门使用手法,哈哈,欢迎指点,希望能帮助大家~~~Sentry 自我理解,可以更便捷的了解到非必现的bug、无法通过日志追踪的异常等。一、Sentry介绍:sentry 是一个实时事件日志记录和聚合平台。它专门用于监视错误和提取执行适当的事后操作所需的所有信息, 而无需使用标准用户反馈循环的任何麻烦。Sentry 是一个日志平台,分为客户端和服务端,客户端(目前客户端有Python, PHP,C#, Ruby等多种语言)就嵌入在你的应用程序中间,程序出现异常就向服务端发送消息,服务端将消息记录到数据库中并提供一个web节目方便查看。Sentry由python编写,源码开放,性能卓越,易于扩展,目前著名的用户有Disqus, Path, mozilla, Pinterest等二、Sentry的注册和使用公司已有现成的服务了,所以我们只需要用公司邮箱进行注册即可。下面介绍一下简单的使用方法:2.1 首先注册账号: 分为UAT 和线上(ONLINE)online: https://sentry-fe… // 这里是正式线上链接uat: http://sentry… // 这里是uat环境链接(公司邮箱注册)新注册的账号可能无法New Project 创建,这时候需要点击左侧栏目,点击 Project & Teams ,需要加入Teams,这是刷新页面,则可以在Select project 下面看到你的项目,如果无项目请联系管理员;进入后进行简单配置,然后右上角可以点击 New Project 创建,选择需要项目类型,根据提示进行配置选择相对应的技术下面这个生成的链接也就是日后项目实时监听bug的地址(项目中的sentry.ts文件中需要配置的这个)2.2 sentry在项目中的配置a. 首先在项目中下载依赖$ yarn add raven-js -Db. sentry配置文件(目前有一套配置文件,可直接饮用,也可对里面的错误警报规则做修改)如:c. sentry 在项目中的引用:import * as Raven from “raven-js”; // 首先引入import { ravenOptions, DSN_ONLINE, DSN_UAT } from “config/sentry”; // 上面对sentry的配置文件import { isLocalEnv, isUatEnv } from “utils/url”; // 封装的页面链接获取componentDidMount() { if (!isLocalEnv) { const dsn = isUatEnv ? DSN_UAT : DSN_ONLINE; Raven.config( dsn, Object.assign({}, ravenOptions, { release: webpack_global.SENTRY_RELEASE// 这里注意了,webpack_global__相当于是全局的,需要在tsconfig.json里进行配置,深层的原理和关联可以追踪看ezpack库 }) ).install(); }}// componentDidCatch 错误捕获componentDidCatch(error, errorInfo) { const group = errorInfo ? location.href : “default”; Raven.captureException(error, { extra: errorInfo, fingerprint: [group] }); }<br/>以上是在项目中添加sentry最简单的配置使用,当完成到这里的时候,可以进行测试 比如在项目中添加throw new Error(“test error”);发布在环境上进行测试,在自己的账号项目中检查是否监听到错误。以上只是简单地配置在项目中了,当然,我们可以将它运用的更友好,比如在请求的时候加上:const captureException = (err, option) => { Raven.captureException(err, { fingerprint: [“API”, option.url], message: err, extra: option });};// 在请求时,发生错误处理方法中可以加入此配置,在监听到错误时,详细信息会包括fingerprint: 类型, message: 错误信息, extra: 请求链接的信息以及连接等, 都将在 sentry监听到的详情里展现出来。还有一些其他用法,待研究后更新。。。(^^) 嘻嘻……推荐参考资料:【参考资料1】 【参考资料2】 ...

January 29, 2019 · 1 min · jiezi

基于 lumen 的微服务架构实践

lumen为速度而生的 Laravel 框架官网的介绍很简洁,而且 lumen 确实也很简单,我在调研了 lumen 相关组件(比如缓存,队列,校验,路由,中间件和最重要的容器)之后认为已经能够满足我目前这个微服务的需求了。任务目标因为业务需求,需要在内网服务B中获取到公网服务A中的数据,但是B服务并不能直接对接公网,于是需要开发一个relay 中转机来完成数据转存和交互。任务列表环境准备 【done】RSA数据加密 【done】guzzle请求封装 【done】添加monolog日志RocketMQ java请求转发程序数据库migrateEvent和Listener的业务应用Scheduler计划任务(基于crontab)Jobs和Queue业务应用使用supervisor守护queue进程和java进程添加sentry来获取服务日志信息和实现邮件报警jwt用户身份校验.env 文件的配置可能的扩展 K8S docker性能并发测试环境准备机器是centos6.8, 使用work用户, 安装 php(^7),mysql,nginx,redisyum 安装的同学可以试试 https://www.softwarecollectio…安装composerhttps://getcomposer.org/downl…# 注意php的环境变量php -r “copy(‘https://getcomposer.org/installer', ‘composer-setup.php’);“php -r “if (hash_file(‘sha384’, ‘composer-setup.php’) === ‘93b54496392c062774670ac18b134c3b3a95e5a5e5c8f1a9f115f203b75bf9a129d5daa8ba6a13e2cc8a1da0806388a8’) { echo ‘Installer verified’; } else { echo ‘Installer corrupt’; unlink(‘composer-setup.php’); } echo PHP_EOL;“php composer-setup.phpphp -r “unlink(‘composer-setup.php’);“mv composer.phar /usr/local/bin/composer安装lumencomposer global require “laravel/lumen-installer"composer create-project –prefer-dist laravel/lumen YOURPROJECT配置 .env配置Lumen 框架所有的配置信息都是存在 .env 文件中。一旦 Lumen 成功安装,你同时也要 配置本地环境。应用程序密钥在你安装完 Lumen 后,首先需要做的事情是设置一个随机字符串到应用程序密钥。通常这个密钥会有 32 字符长。 这个密钥可以被设置在 .env 配置文件中。如果你还没将 .env.example 文件重命名为 .env,那么你现在应该去设置下。如果应用程序密钥没有被设置的话,你的用户 Session 和其它的加密数据都是不安全的!配置nginx 和 php-fpm配置nginx的serverserver { listen 8080; server_name localhost; index index.php index.html index.htm; root /home/work/YOURPROJECT/public; error_page 404 /404.html; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ .php$ { root /home/work/YOURPROJECT/public; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; #include fastcgi.conf; }}php-fpm的监听端口推荐一篇文章:Nginx+Php-fpm运行原理详解lumen 基础介绍lumen的入口文件是 public/index.php,在nginx配置文件中已有体现初始化核心容器是 bootstrap/app.php 它做了几件非常重要的事情加载了 composer的 autoload 自动加载创建容器并可以选择开启 Facades 和 Eloquent (建议都开启,非常方便)Register Container Bindings:注册容器绑定 ExceptionHandler(后面monolog和sentry日志收集用到了) 和 ConsoleKernel(执行计划任务)Register Middleware:注册中间件,例如auth验证: $app->routeMiddleware([‘auth’ => AppHttpMiddlewareAuthenticate::class,]);注册Service Providers$app->register(App\Providers\AppServiceProvider::class);$app->register(App\Providers\AuthServiceProvider::class);$app->register(App\Providers\EventServiceProvider::class);在AppServiceProvider 里还能一起注册多个provider// JWT$this->app->register(\Tymon\JWTAuth\Providers\LumenServiceProvider::class);// redis$this->app->register(\Illuminate\Redis\RedisServiceProvider::class);// 方便IDE追踪代码的Helper,因为laravel使用了大量的魔术方法和call方法以至于,对IDE的支持并不友好,强烈推荐开发环境安装$this->app->register(\Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class);// sentry$this->app->register(\Sentry\SentryLaravel\SentryLumenServiceProvider::class);加载route文件 routes/web.php//localhost:8080/test 调用app/Http/Controllers/Controller.php的 test方法$router->get("/test”, [‘uses’ => “Controller@test”]);// 使用中间件进行用户校验$router->group([‘middleware’ => ‘auth:api’], function () use ($router) { $router->get(’/auth/show’, ‘AuthController@getUser’);});还可以添加其他初始化控制的handler,比如说这个 monolog日志等级和格式,以及集成sentry的config$app->configureMonologUsing(function(Monolog\Logger $monoLog) use ($app){ // 设置processor的extra日志信息等级为WARNING以上,并且不展示Facade类的相关信息 $monoLog->pushProcessor(new \Monolog\Processor\IntrospectionProcessor(Monolog\Logger::WARNING, [‘Facade’])); // monolog 日志发送到sentry $client = new Raven_Client(env(‘SENTRY_LARAVEL_DSN’)); $handler = new Monolog\Handler\RavenHandler($client); $handler->setFormatter(new Monolog\Formatter\LineFormatter(null, null, true, true)); $monoLog->pushHandler($handler); // 设置monolog 的日志处理handler return $monoLog->pushHandler( (new Monolog\Handler\RotatingFileHandler( env(‘APP_LOG_PATH’) ?: storage_path(’logs/lumen.log’), 90, env(‘APP_LOG_LEVEL’) ?: Monolog\Logger::DEBUG) )->setFormatter(new \Monolog\Formatter\LineFormatter(null, null, true, true)) );});配置文件 config/ 和 .env 文件其他目录文件用到时再具体说明RSA数据加密因为业务中包含部分敏感数据,所以,数据在传输过程中需要加密传输。选用了RSA非对称加密。借鉴了 PHP 使用非对称加密算法(RSA)但由于传输数据量较大,加密时会报错,所以采用了分段加密连接和分段解密php使用openssl进行Rsa长数据加密(117)解密(128)如果选择密钥是1024bit长的(openssl genrsa -out rsa_private_key.pem 1024),那么支持加密的明文长度字节最多只能是1024/8=128byte;如果加密的padding填充方式选择的是OPENSSL_PKCS1_PADDING(这个要占用11个字节),那么明文长度最多只能就是128-11=117字节。如果超出,那么这些openssl加解密函数会返回false。分享一个我的完成版的工具类openssl genrsa -out rsa_private_key.pem 1024//生成原始 RSA私钥文件openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_key.pem//将原始 RSA私钥转换为 pkcs8格式openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem<?phpnamespace App\Lib\Oscar;class Rsa{ private static $PRIVATE_KEY = ‘—–BEGIN RSA PRIVATE KEY—–xxxxxxxxxxxxx完整复制过来xxxxxxxxxxxxxxxxxxx—–END RSA PRIVATE KEY—–’; private static $PUBLIC_KEY = ‘—–BEGIN PUBLIC KEY—–xxxxxxxxxxxxx完整复制过来xxxxxxxxxxxxxxxxxxx—–END PUBLIC KEY—–’; /** * 获取私钥 * @return bool|resource / private static function getPrivateKey() { $privateKey = self::$PRIVATE_KEY; return openssl_pkey_get_private($privateKey); } /* * 获取公钥 * @return bool|resource / private static function getPublicKey() { $publicKey = self::$PUBLIC_KEY; return openssl_pkey_get_public($publicKey); } /* * 私钥加密 * @param string $data * @return null|string / public static function privateEncrypt($data = ‘’) { if (!is_string($data)) { return null; } $EncryptStr = ‘’; foreach (str_split($data, 117) as $chunk) { openssl_private_encrypt($chunk, $encryptData, self::getPrivateKey()); $EncryptStr .= $encryptData; } return base64_encode($EncryptStr); } /* * 公钥加密 * @param string $data * @return null|string / public static function publicEncrypt($data = ‘’) { if (!is_string($data)) { return null; } return openssl_public_encrypt($data,$encrypted,self::getPublicKey()) ? base64_encode($encrypted) : null; } /* * 私钥解密 * @param string $encrypted * @return null / public static function privateDecrypt($encrypted = ‘’) { $DecryptStr = ‘’; foreach (str_split(base64_decode($encrypted), 128) as $chunk) { openssl_private_decrypt($chunk, $decryptData, self::getPrivateKey()); $DecryptStr .= $decryptData; } return $DecryptStr; } /* * 公钥解密 * @param string $encrypted * @return null */ public static function publicDecrypt($encrypted = ‘’) { if (!is_string($encrypted)) { return null; } return (openssl_public_decrypt(base64_decode($encrypted), $decrypted, self::getPublicKey())) ? $decrypted : null; }}使用tip// 私钥加密则公钥解密,反之亦然$data = \GuzzleHttp\json_encode($data);$EncryptData = Rsa::privateEncrypt($data);$data = Rsa::publicDecrypt($EncryptData);guzzle使用安装超简单 composer require guzzlehttp/guzzle:~6.0guzzle 支持PSR-7 http://docs.guzzlephp.org/en/…官网的示例也很简单,发个post自定义参数的例子use GuzzleHttp\Client;$client = new Client();// 发送 post 请求$response = $client->request( ‘POST’, $this->queryUrl, [ ‘form_params’ => [ ‘req’ => $EncryptData ]]);$callback = $response->getBody()->getContents();$callback = json_decode($callback, true);guzzle支持 异步请求// Send an asynchronous request.$request = new \GuzzleHttp\Psr7\Request(‘GET’, ‘http://httpbin.org’);$promise = $client->sendAsync($request)->then(function ($response) { echo ‘I completed! ’ . $response->getBody();});$promise->wait();值的注意的是github上有一个很好玩的项目 https://github.com/kitetail/zttp它在guzzle的基础上做了封装,采用链式调用$response = Zttp::withHeaders([‘Fancy’ => ‘Pants’])->post($url, [ ‘foo’ => ‘bar’, ‘baz’ => ‘qux’,]);$response->json();// => [// ‘whatever’ => ‘was returned’,// ];$response->status();// int$response->isOk();// true / false#如果是guzzle 则需要更多的代码$client = new Client();$response = $client->request(‘POST’, $url, [ ‘headers’ => [ ‘Fancy’ => ‘Pants’, ], ‘form_params’ => [ ‘foo’ => ‘bar’, ‘baz’ => ‘qux’, ]]);json_decode($response->getBody());高可用问题思考数据传输量过大可能导致的问题RSA加密失败请求超时数据库存储并发列队失败重试和堵塞数据操作日志监控和到达率监控未完待续….. ...

January 9, 2019 · 3 min · jiezi

laravel sentry

注册登录 GitHub登录创建project 选择 laravel安装扩展使用composer require sentry/sentry-laravelphp artisan vendor:publish –provider=“Sentry\SentryLaravel\SentryLaravelServiceProvider"public function report(Exception $exception){ if (app()->bound(‘sentry’) && $this->shouldReport($exception)) { app(‘sentry’)->captureException($exception); } parent::report($exception);}vi config/sentry.phpreturn array( ‘dsn’ => env(‘DSN’), // capture release as git sha // ‘release’ => trim(exec(‘git log –pretty="%h” -n1 HEAD’)), // Capture bindings on SQL queries ‘breadcrumbs.sql_bindings’ => true, // Capture default user context ‘user_context’ => false, //transport function ’transport’=>new \App\SentryTransport(),);vi /app/SentryTransport.phpnamespace App;class SentryTransport{ public static function __set_state($array){ return function($raven_client,$data){ \Queue::pushOn(‘sentry_log’,new \App\Commands\sentry($raven_client,$data)); }; }}vi app/commands/sentry.phpclass sentry extends Command implements SelfHandling, ShouldBeQueued { use InteractsWithQueue, SerializesModels; private $raven_client; protected $data; /** * Create a new command instance. * * @return void / public function __construct($raven_client, $data) { $raven_client->setTransport(null); $raven_client->close_curl_resource(); $this->raven_client=$raven_client; $this->data=$data; } /* * Execute the command. * * @return void / public function handle() { $this->raven_client->send($this->data);//send方法来自 /vendor/sentry/sentry/lib/Raven/Client.php:1019 }}vi /vendor/sentry/sentry/lib/Raven/Client.phppublic function send(&$data) { if (is_callable($this->send_callback) && call_user_func_array($this->send_callback, array(&$data)) === false ) { // if send_callback returns false, end native send return; } if (!$this->server) { return; } if ($this->transport) { call_user_func($this->transport, $this, $data); return; } // should this event be sampled? if (rand(1, 100) / 100.0 > $this->sample_rate) { return; } $message = $this->encode($data); $headers = array( ‘User-Agent’ => static::getUserAgent(), ‘X-Sentry-Auth’ => $this->getAuthHeader(), ‘Content-Type’ => ‘application/octet-stream’ ); $this->send_remote($this->server, $message, $headers); }配置dsn获取 dsn 测试少写个分号,查看效果monolog 发送到sentrycomposer require monolog/monologvi config/app.php’App\Providers\sentrylog’ vi App\Providers\sentrylog.phpuse Monolog\Handler\RedisHandler;use Monolog\Formatter\JsonFormatter;use Monolog\Formatter\LineFormatter;use Monolog\Processor\MemoryPeakUsageProcessor;use Monolog\Processor\WebProcessor;use Monolog\Handler\RavenHandler;class sentrylog extends ServiceProvider { /* * Bootstrap the application services. * * @return void / public function boot() { $logger = \Log::getMonolog(); $handler = new RedisHandler($redis, “sentry:monolog”, \Monolog\Logger::DEBUG); $handler->setFormatter(new JsonFormatter(JsonFormatter::BATCH_MODE_NEWLINES, true)); $handler->pushProcessor(new MemoryPeakUsageProcessor(true)); /$logger->pushProcessor(function ($record) { $record[’extra’][‘dummy’] = ‘Hello world!’; return $record; }); class MemoryPeakUsageProcessor extends MemoryProcessor{ /** * @param array $record 对象当方法调用时执行 * @return array / public function __invoke(array $record) { $bytes = memory_get_peak_usage($this->realUsage); $formatted = $this->formatBytes($bytes); $record[’extra’][‘memory_peak_usage’] = $formatted; return $record; }}/ $arr = [ ‘uri’ => ‘REQUEST_URI’, ‘ip’ => ‘REMOTE_ADDR’, ‘method’ => ‘REQUEST_METHOD’, ‘query_string’ => ‘QUERY_STRING’, ‘cookie’ => ‘HTTP_COOKIE’, ‘host’ => ‘HTTP_HOST’, ]; $handler->pushProcessor(new WebProcessor(null, $arr)); $logger->pushHandler($handler); } /** * Register the application services. * * @return void */ public function register() { // }}vi app/commands/sentry_monolog.phpuse Monolog\Handler\RavenHandler; while (true) { $data = $redis->lpop(“sentry:monolog”); if (!$data) { sleep(5); continue; } $data = json_decode($data, true); $raven_client= new \Raven_Client($dsn,[’extra’ => $data[’extra’]]); $raven_hanlder = new RavenHandler($raven_client); $raven_hanlder->handle($data); }资源你也可以本地搭建Sentry 之部署到生产环境搭建自己的 sentry 服务CentOS6 基于 Python 安装 SentrySentry 自动化异常提醒Laravel学习笔记之Errors Tracking神器——Sentrysentry使用利用 entry/onpremise 搭建一个 Sentry 异常汇总工具高效利用Sentry追踪日志发现问题sentry monologSentry - 处理异常日志的正确姿势Sentry监控Django应用并使用email+钉钉通知搭建私有的前端监控服务: sentry ...

October 26, 2018 · 2 min · jiezi