PHP告警SDK

该SDK为哮天犬监控告警平台告警接口的PHP实现,增加了非常友好的方式使用,开箱即用。

特性

  • 支持协程/非协程模式自动切换
  • 支持 Laravel5 ~ Laravel7 开箱即用
  • 支持 Lumen5 ~ Lumen7 开箱即用
  • 支持 Hyperf1.1 ~ Hyperf2.0 开箱即用
  • 支持任意场景、框架使用
  • 支持告警请求发送失败重试
  • 支持记录请求日志

    代码仓库

    https://github.com/tal-tech/alarm-dog-php-sdk
    最新文档请参考代码仓库的 README.md 文件说明

    安装

    1. # composer安装依赖
    2. composer require alarm-dog/alarm

    使用

    Hyperf

    协程版Guzzle依赖安装

    1. composer require hyperf/guzzle

    配置文件发布

    1. $ php bin/hyperf.php vendor:publish alarm-dog/alarm
    2. Scanning app ...
    3. Scan app completed, took 171.40197753906 milliseconds.
    4. Detected an available cache, skip the vendor scan process.
    5. [DEBUG] Event Hyperf\Framework\Event\BootApplication handled by Hyperf\Config\Listener\RegisterPropertyHandlerListener listener.
    6. [DEBUG] Event Hyperf\Framework\Event\BootApplication handled by Hyperf\Paginator\Listener\PageResolverListener listener.
    7. [DEBUG] Event Hyperf\Framework\Event\BootApplication handled by Hyperf\Di\Listener\BootApplicationListener listener.
    8. [DEBUG] Event Hyperf\Framework\Event\BootApplication handled by Hyperf\DbConnection\Listener\RegisterConnectionResolverListener listener.
    9. [dog/alarm] publishes [config] successfully.
    配置文件在 config/autoload/dog.php,配置说明请参考下面章节 配置项说明

    告警发送

    1. use Dog\Alarm\Alarm;
    2. use Dog\Alarm\Exception\AlarmException;
    3. $content = [
    4. 'errno' => 10086,
    5. 'error' => '您的余额已不足',
    6. ];
    7. /**
    8. * 方法一:直接实例化
    9. */
    10. $alarm = new Alarm();
    11. try {
    12. /**
    13. * Alarm::report 方法返回 \Psr\Http\Message\ResponseInterface 对象
    14. * @var \Psr\Http\Message\ResponseInterface $response
    15. */
    16. $response = $alarm->report($content);
    17. $array = $alarm->resolveResponse($response);
    18. /**
    19. $array 的结构请参考下方数组:
    20. array(3) {
    21. ["data"]=>
    22. array(2) {
    23. ["uuid"]=>
    24. string(36) "74bfd2d8-a1c9-434b-9098-50efc0f08ee2"
    25. ["report_time"]=>
    26. string(19) "2020-06-26 20:50:19"
    27. }
    28. ["msg"]=>
    29. string(7) "success"
    30. ["code"]=>
    31. int(0)
    32. }
    33. */
    34. // 如果要一气呵成,直接返回数组,可以使用
    35. $array = $alarm->resolveResponse($alarm->report($content));
    36. } catch (AlarmException $e) {
    37. // 告警发送失败会抛出该异常
    38. }
    39. // 指定通知时间:
    40. $alarm->report($content, time());
    41. // 指定告警级别
    42. $alarm->report($content, null, Alarm::LEVEL_ERROR);
    43. // 指定临时通知人
    44. $alarmGroups = [1, 2];
    45. $channelDingGroup = new DingGroup([
    46. ['webhook' => 'webhook1', 'secret' => 'secret1'],
    47. ['webhook' => 'webhook2', 'secret' => 'secret2'],
    48. ]);
    49. $channelYachGroup = new YachGroup();
    50. $channelYachGroup->addRobot('webhook1', 'secret1')->addRobot('webhook2', 'secret2')
    51. ->addRobots([
    52. ['webhook' => 'webhook3', 'secret' => 'secret3'],
    53. ['webhook' => 'webhook4', 'secret' => 'secret4'],
    54. ]); // 第二个参数为true是会进行全量替换,覆盖之前的,默认为false
    55. $channelDingWorker = new DingWorker([1, 98665]);
    56. $channelEmail = new Email();
    57. $channelEmail->addUid(1)->addUid(98665)->addUids([98666, 98667]);
    58. $channels = [$channelDingGroup, $channelYachGroup];
    59. $receiver = new Receiver($alarmGroups, $channels);
    60. // 或者 $receiver = new Receiver([], $channels);
    61. // 或者 $receiver = new Receiver($alarmGroups);
    62. // 或者 $receiver = new Receiver();
    63. $receiver->addAlarmGroup(1)
    64. ->addAlarmGroup(3)
    65. ->addAlarmGroups([1, 5], true) // 第二个参数为true是会进行全量替换,覆盖之前的,默认为false
    66. ->addChannel($channelDingWorker)
    67. ->addChannel(new DingWorker([1]))
    68. ->addChannels($channels);
    69. // 以上仅用于展示SDK所有支持的方法
    70. // 指定临时通知人
    71. $alarm->report($content, null, null, $receiver);
    72. /**
    73. * 方法二:使用make
    74. */
    75. // 剩下使用方法同方法一
    76. $alarm = make(Alarm::class);
    77. /**
    78. * 方法三:使用@Inject注解,推荐
    79. */
    80. /**
    81. * 注意Inject的命名空间引入
    82. * @Inject
    83. * @var Alarm
    84. */
    85. protected $alarm;
    86. // 剩下使用方法同方法一
    87. $this->alarm->report($content);
    88. /**
    89. * 方法四:使用容器Container,推荐
    90. */
    91. // 剩下使用方法同方法一
    92. $alarm = ApplicationContext::getContainer()->get(Alarm::class);
    93. // 或者
    94. $alarm = $container->get(Alarm::class);
    95. // 或者
    96. $alarm = $this->container->get(Alarm::class);
    97. /**
    98. * 测试告警发送
    99. * 用于验证taskid、token是否合法,不真实发送告警
    100. */
    101. try {
    102. $result = $alarm->test();
    103. // 测试成功
    104. } catch (Throwable $e) {
    105. // 测试失败
    106. $errMsg = $e->getMessage();
    107. }

    Laravel

    配置文件发布

    1. $ php artisan vendor:publish --provider="Dog\Alarm\Provider\LaravelServiceProvider"
    2. Copied File [/alarm-dog-php-sdk/config/dog.php] To [/config/dog.php]
    3. Publishing complete.
    配置文件在 config/dog.php,配置说明请参考下面章节 配置项说明

    告警发送

    1. /**
    2. * 方法一:直接实例化
    3. */
    4. // 请参考Hyperf中直接实例化
    5. /**
    6. * 方法二:使用app()助手函数,推荐
    7. */
    8. // 剩下使用方法同Hyperf章节中的方法一
    9. $alarm = app(Alarm::class);
    10. /**
    11. * 方法三:使用门面Facade,推荐
    12. */
    13. use Dog\Alarm\Provider\Laravel\AlarmFacade;
    14. $response = AlarmFacade::report($content);
    15. $array = AlarmFacade::resolveResponse($response);
    16. $array = AlarmFacade::resolveResponse(AlarmFacade::report($content));
    17. // 可以看出 AlarmFacade 和 new Alarm() 使用方式一样,不过Facade提供静态方法访问,剩下使用方法同Hyperf章节中的方法一

    Lumen

    配置文件发布

    Lumen框架不支持配置文件自动发布,需要在 bootstrap/app.php 中配置 $app->register(Dog\Alarm\Provider\LumenServiceProvider::class);,例如:
    1. /*
    2. |--------------------------------------------------------------------------
    3. | Register Service Providers
    4. |--------------------------------------------------------------------------
    5. |
    6. | Here we will register all of the application's service providers which
    7. | are used to bind services into the container. Service providers are
    8. | totally optional, so you are not required to uncomment this line.
    9. |
    10. */
    11. // $app->register(App\Providers\AppServiceProvider::class);
    12. // $app->register(App\Providers\AuthServiceProvider::class);
    13. // $app->register(App\Providers\EventServiceProvider::class);
    14. $app->register(Dog\Alarm\Provider\LumenServiceProvider::class);
    15. /*
    16. |--------------------------------------------------------------------------
    17. | Load The Application Routes
    18. |--------------------------------------------------------------------------
    19. |
    20. | Next we will include the routes file so that they can all be added to
    21. | the application. This will provide all of the URLs the application
    22. | can respond to, as well as the controllers that may handle them.
    23. |
    24. */
    mkdir config && cp vendor/dog/alarm/config/dog.php config/
    配置文件在 config/dog.php,配置说明请参考下面章节 配置项说明

    告警发送

    1. /**
    2. * 方法一:直接实例化
    3. */
    4. // 请参考Hyperf中直接实例化
    5. /**
    6. * 方法二:使用app()助手函数,推荐
    7. */
    8. // 剩下使用方法同Hyperf章节中的方法一
    9. $alarm = app(Alarm::class);
    10. /**
    11. * 方法三:使用门面Facade,必须Lumen开启了对Facade的支持才行,推荐
    12. */
    13. use Dog\Alarm\Provider\Laravel\AlarmFacade;
    14. $response = AlarmFacade::report($content);
    15. $array = AlarmFacade::resolveResponse($response);
    16. $array = AlarmFacade::resolveResponse(AlarmFacade::report($content));
    17. // 可以看出 AlarmFacade 和 new Alarm() 使用方式一样,不过Facade提供静态方法访问,剩下使用方法同Hyperf章节中的方法一

    无框架或者其他框架

    不在自动支持的框架范围内,可以直接实例化,然后手动配置,例如:
    1. $alarm = new Alarm();
    2. $alarm->setTaskid(1);
    3. $alarm->setToken('token');
    4. // 如果需要修改调用域名,可以调用 $alarm->setBaseUri('https://alarm-dog-service.domain.com/alarm/report');
    5. // 如果需要配置guzzle,可以调用 $alarm->setGuzzleConfig($guzzleConfig); 配置格式请参考config/dog.php中guzzle下面的数组
    6. // 剩下使用方法同Hyperf章节中的方法一
    7. $response = $alarm->report($content);

    配置项说明

    默认配置文件使用了 env 函数,不是所有的框架都有该函数,请根据情况修改。
    在 Hyperf/Laravel/Lumen 框架中,直接在 .env 文件中配置正确的 DOG_TASKIDDOG_TOKEN 即可直接开始使用告警功能。
    1. <?php
    2. use GuzzleHttp\MessageFormatter;
    3. use GuzzleHttp\Middleware;
    4. use Psr\Http\Message\RequestInterface;
    5. use Psr\Http\Message\ResponseInterface;
    6. /**
    7. * 哮天犬配置文件
    8. */
    9. return [
    10. // 告警任务ID
    11. 'taskid' => (int) env('DOG_TASKID'),
    12. // 告警任务token
    13. // 获取方法请参考:https://alarm-dog.domain.com/docs/quick-start/alarm.html#step4%EF%BC%9A%E5%91%8A%E8%AD%A6%E6%8E%A5%E5%8F%A3%E6%B5%8B%E8%AF%95
    14. 'token' => env('DOG_TOKEN'),
    15. // 告警地址,默认为:https://alarm-dog-service.domain.com
    16. // 请参考文档中的环境说明:https://alarm-dog.domain.com/docs/alarm/alarm-api.html
    17. 'base_uri' => env('DOG_BASE_URI'),
    18. /**
    19. * GuzzleHttp配置
    20. */
    21. 'guzzle' => [
    22. // guzzle原生配置选项,请参考文档:https://guzzle-cn.readthedocs.io/zh_CN/latest/request-options.html
    23. 'options' => [
    24. 'http_errors' => false,
    25. 'connect_timeout' => 0,
    26. 'timeout' => 0,
    27. // hyperf集成guzzle的swoole配置选项
    28. 'swoole' => [
    29. 'timeout' => 10,
    30. 'socket_buffer_size' => 1024 * 1024 * 2,
    31. ],
    32. ],
    33. // guzzle中间件配置,请参考文档:https://guzzle-cn.readthedocs.io/zh_CN/latest/handlers-and-middleware.html
    34. 'middlewares' => [
    35. // 失败重试中间件
    36. 'retry' => function ($container = null) {
    37. return Middleware::retry(function ($retries, RequestInterface $request, ResponseInterface $response = null) {
    38. if (
    39. (! $response || $response->getStatusCode() >= 500) &&
    40. $retries < 1
    41. ) {
    42. return true;
    43. }
    44. return false;
    45. }, function () {
    46. return 10;
    47. });
    48. },
    49. // // 请求日志记录中间件
    50. // 'logger' => function ($container = null) {
    51. // // $format中{response}调用$response->getBody()会导致没有结果输出
    52. // $format = ">>>>>>>>\n{request}\n<<<<<<<<\n{res_headers}\n--------\n{error}";
    53. // $formatter = new MessageFormatter($format);
    54. // // 在其他框架将$logger进行正确替换即可
    55. // // hyperf框架请使用下发方式获得Logger
    56. // // $logger = \Hyperf\Utils\ApplicationContext::getContainer()
    57. // // ->get(\Hyperf\Logger\LoggerFactory::class)
    58. // // ->get('influx-guzzle');
    59. // // laravel框架请使用下发方式获得Logger
    60. // // $logger = \Illuminate\Support\Facades\Log::getLogger();
    61. // return Middleware::log($logger, $formatter, 'debug');
    62. // }
    63. ],
    64. // hyperf集成guzzle的连接池配置选项,非hyperf框架忽略
    65. // 连接池可以参考hyperf官方的文档:https://hyperf.wiki/2.0/#/zh-cn/guzzle
    66. 'pool' => [
    67. 'option' => [
    68. 'max_connections' => 200,
    69. ]
    70. ]
    71. ],
    72. ];