首页 > 其他分享 >laravel 后台或者api框架异常钉钉告警提醒

laravel 后台或者api框架异常钉钉告警提醒

时间:2023-08-17 14:34:05浏览次数:50  
标签:laravel ch monitorDing param response api 告警 config curl

中间件

Monitor
<?php

namespace App\Http\Middleware;

use Error;
use Closure;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Contracts\Container\Container;
use Illuminate\Contracts\Debug\ExceptionHandler;
use Psy\Exception\ErrorException;
use Psy\Exception\FatalErrorException;

class Monitor
{
    /**
     * The App container
     *
     * @var Container
     */
    protected $container;

    /**
     * The Monitor Client
     *
     * @var
     */
    protected $monitor;

    /**
     * Create a new middleware instance.
     *
     * @param Container $container
     */
    public function __construct(Container $container)
    {
        $this->container = $container;
    }

    /**
     * Handle an incoming request.
     *
     * @param Request $request
     * @param Closure $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
//        dump("monitorDing");
        $enabled = config('monitorDing.enabled');
        try {
            $response = $next($request);
        } catch (Exception $e) {
            $response = $this->handleException($request, $e);
            $enabled && $this->sendText(sprintf("文件:%s (%s 行) 内容:%s", $e->getFile(), $e->getLine(), $e->getMessage()));

        } catch (Error $error) {
            $e = new FatalErrorException($error);
            $response = $this->handleException($request, $e);
            $enabled && $this->sendText(sprintf("文件:%s (%s 行) 内容:%s", $e->getFile(), $e->getLine(), $e->getMessage()));
        } catch (ErrorException $error) {
            $e = new FatalErrorException($error);
            $response = $this->handleException($request, $e);
            $enabled && $this->sendText(sprintf("文件:%s (%s 行) 内容:%s", $e->getFile(), $e->getLine(), $e->getMessage()));
        } finally {
            if ($response->getStatusCode() == '500' && (isset($response->exception) && $response->exception && $response->exception !== null)) {
                $sysName = config('monitorDing.web_name');

                if (strpos($_SERVER['HTTP_HOST'], 'liexin') !== false) {
                    $sysName = '本地' . $sysName;
                } else {
                    $sysName = '外网' . $sysName;
                }

                $this->sendText(substr($sysName . ":" . $response->exception, 0,
                        500) . ',请求数据:' . json_encode($request->input()) . "---[更多详情请看日志]");
            }
        }
        return $response;
    }

    /**
     * Handle the given exception.
     *
     * (Copy from Illuminate\Routing\Pipeline by Taylor Otwell)
     *
     * @param $passable
     * @param Exception $e
     * @return mixed
     * @throws Exception
     */
    protected function handleException($passable, Exception $e)
    {
        if (!$this->container->bound(ExceptionHandler::class) || !$passable instanceof Request) {
            throw $e;
        }

        $handler = $this->container->make(ExceptionHandler::class);

        $handler->report($e);

        return $handler->render($passable, $e);
    }


    /**
     * 发送文本类型的消息
     *
     * @param $content string 消息内容
     * @param array $atMobiles 被@人的手机号
     * @param bool $isAtAll 是否 @ 所有人
     * @throws SendErrorException
     */
    public function sendText($content, $atMobiles = [], $isAtAll = false)
    {
        $params = [
            'msgtype' => 'text',
            'text' => [
                'content' => $content,
            ],
            'at' => [
                'atMobiles' => $atMobiles,
                'isAtAll' => $isAtAll
            ]
        ];
        $this->send($params);
    }

    /**
     * 发送
     * @param array $params 请求需要的参数
     * @throws SendErrorException
     */
    private function send($params = [])
    {
        if (!config('monitorDing.enabled')) {
            \Log::info('~~ Monitor Ding ~~');
            \Log::info($params);
        } else {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, config("monitorDing.webhook"));
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
            curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json;charset=utf-8'));
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            if (config()) {
                curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
            }
            $data = json_decode(curl_exec($ch), true);
            curl_close($ch);

            if ($data['errcode']) {
//                throw new SendErrorException($data['errmsg']);
            }
        }

    }
}
App\Http\Kernel.php


protected $middleware = [
//............ 新增
    \App\Http\Middleware\Monitor::class
//...........
];

protected $routeMiddleware = [
    'monitor' => \App\Http\Middleware\Monitor::class,
];

配置文件

<?php
return [
    // 是否开启报错写入
    'enabled' => boolval(get_resource_config_section('app', 'pur')["monitorDing_enabled"]),

    // curl证书验证, 线下环境不用开启
    'curl_verify' => boolval(get_resource_config_section('app', 'pur')["monitorDing_curl_verify"]),

    'web_name'=>get_resource_config_section('app', 'pur')["monitorDing_web_name"],

    // webhook的值
    'webhook' => get_resource_config_section('app', 'pur')["monitorDing_webhook"],
];

 

最后新增钉钉机器人

 

 

 

 最后复制webhook即可

 

 

标签:laravel,ch,monitorDing,param,response,api,告警,config,curl
From: https://www.cnblogs.com/sunlong88/p/17637475.html

相关文章

  • 关于API数据接口获取商品的数据的说明
    获取商品数据已经成为许多应用程序的重要组成部分。为了实现这一目标,许多公司和技术开发者使用API数据接口来获取相关数据。本文将详细介绍如何使用API数据接口获取商品数据,并使用Python作为编程语言示例来展示相关代码。API数据接口是一种通信协议,它允许不同的应用程序或服务之间......
  • asp.net core Webapi中返回400错误中的‘Null集合属性序列化Json’情况
    当序列化Json时,有集合类型的属性的值为Null,则序列化后的json就有问题,不能通过asp.netcoreWebApi的校验 解决方法是:只需要对集合默认初始化即可......
  • 在.NET中集成第三方API和服务
    当在.NET应用程序中集成第三方API和服务时,您可以通过使用合适的库、SDK和工具来实现与这些服务的通信。这可以涉及与Web服务、云服务、社交媒体平台等的集成。以下是一个简单的示例,演示了如何在.NET应用程序中集成一个虚构的天气API。步骤1:获取API密钥首先,您需要从目标API提供商......
  • ELK EFLK日志平台基于ElastAlert的监控告警
    一、前言1.1、产生背景ElastAlert最初由Yelp开发并开源,旨在解决实时监控和告警的需求。由于Elasticsearch的日志处理能力强大,许多组织和企业使用它来存储和分析大量的日志数据。然而,仅仅存储和分析数据可能无法满足实时监控和快速响应的需求(XPACK收费),因此ElastAlert应运而生。1.2、......
  • 简单高效的api文档管理系统是如何提升工作效率的?
    简单高效的api文档管理系统是如何提升工作效率的?轻松管理文档,提高协作效率在现代软件开发过程中,api文档的管理至关重要。一套简单高效的api文档管理系统可以极大地提升工作效率,并且减少文档管理方面的麻烦。那么,api文档管理系统到底有什么特点?在日常工作中使用起来又有哪些好处呢?......
  • 根据druid将慢sql通过钉钉的方式进行告警功能记录
          想要借助接入的druid把日志里面输入的慢sql通过钉钉的方式进行告警,由于项目里面之前接入了druid,格式大概如下:    这个是接入druid并且配置了slowsql为true的情况下,日志里面打印的slowsql。刚开始我的想法是通过重写log4j的日志来进行记录,然后看了dr......
  • 代理IP中的账密提取和API提取是什么意思?
    在代理IP服务中,账密提取和API提取是两种常见的方式,用于获取和使用代理IP。账密提取:账密提取是指从代理IP服务提供商获取包含账户和密码的白名单。用户通过购买或订阅的方式获得账密白名单,其中包含了多个可用的代理IP账户和相应的密码。使用账密提取的方式,用户需要手动提取账户和密......
  • vue3 组合式 api 单文件组件写法
    1Vue3组合式API的基本原理和理念1.1Vue3中的CompositionAPIVue3中的CompositionAPI是一种新的编写组件逻辑的方式,它提供了更好的代码组织、类型推导、测试支持和复用性。相比于Vue2的OptionsAPI,CompositionAPI更加灵活和可扩展。在CompositionAPI中,我们使......
  • 通过微软Azure调用GPT的接口API-兼容平替OpenAI官方的注意事项
    众所周知,我们是访问不通OpenAI官方服务的,但是我们可以自己通过代理或者使用第三方代理访问接口现在新出台的规定禁止使用境外的AI大模型接口对境内客户使用,所以我们需要使用国内的大模型接口国内的效果真的很差,现在如果想使用GPT大模型,可以使用微软Azure的OpenAI服务。 负责......
  • 【转载】c++调用win32API控制打印机打印
    原文:https://blog.csdn.net/cheng448208985/article/details/55510687win32实现将原始数据发送给打印机1、调用OpenPrinter()打开打印机,获取打印机句柄。2、初始化DOCINFO打印机结构体。3、调用StartDocPrinter()表明应用程序准备发送文档数据给打印机。4、调用StartPagePrin......