Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add package source with tests #2

Merged
merged 1 commit into from
Jul 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
178 changes: 178 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,185 @@
[![Stand With Ukraine](https://github.com/vshymanskyy/StandWithUkraine/main/banner-direct-single.svg)](https://stand-with-ukraine.pp.ua)

# Laravel Slack Notifier

[![Latest Version on Packagist](https://img.shields.io/packagist/v/stasadev/laravel-slack-notifier.svg?style=flat-square)](https://packagist.org/packages/stasadev/laravel-slack-notifier)
[![GitHub Tests Action Status](https://img.shields.io/github/actions/workflow/status/stasadev/laravel-slack-notifier/run-tests.yml?branch=main&label=tests&style=flat-square)](https://github.com/stasadev/laravel-slack-notifier/actions?query=workflow%3Arun-tests+branch%3Amain)
[![GitHub Code Style Action Status](https://img.shields.io/github/actions/workflow/status/stasadev/laravel-slack-notifier/fix-php-code-style-issues.yml?branch=main&label=code%20style&style=flat-square)](https://github.com/stasadev/laravel-slack-notifier/actions?query=workflow%3A"Fix+PHP+code+style+issues"+branch%3Amain)
[![Total Downloads](https://img.shields.io/packagist/dt/stasadev/laravel-slack-notifier.svg?style=flat-square)](https://packagist.org/packages/stasadev/laravel-slack-notifier)

Send exceptions and dump variables to Slack.

```php
use Stasadev\SlackNotifier\Facades\SlackNotifier;

SlackNotifier::send(new \RuntimeException('Test exception'));
SlackNotifier::send('Test message');
```

## Installation

Install the package via composer:

```bash
composer require stasadev/laravel-slack-notifier
```

All env variables used by this package (only `LOG_SLACK_WEBHOOK_URL` is required):

```dotenv
APP_NAME=Laravel
LOG_SLACK_WEBHOOK_URL=https://hooks.slack.com/services/ABC
LOG_SLACK_CHANNEL=
LOG_SLACK_EMOJI=:boom:
LOG_SLACK_CACHE_SECONDS=0
CACHE_DRIVER=file
```

How to get a webhook URL [in the Slack API docs](https://api.slack.com/messaging/webhooks).

To temporarily disable all logging, simply comment out `LOG_SLACK_WEBHOOK_URL` or set it to an empty string or `null`.

Optionally publish the [config](./config/slack-notifier.php) file with:

```bash
php artisan vendor:publish --tag="slack-notifier"
```

## Usage

To send a message to Slack, simply call `SlackNotifier::send()`.

## Report Exception

```php
// In Laravel 8.x and later
// app/Exceptions/Handler.php
public function register(): void
{
$this->reportable(function (Throwable $e) {
\Stasadev\SlackNotifier\Facades\SlackNotifier::send($e);
});
}

// In Laravel 5.7.x, 5.8.x, 6.x, 7.x
// app/Exceptions/Handler.php
public function report(Throwable $exception)
{
if ($this->shouldReport($exception) {
\Stasadev\SlackNotifier\Facades\SlackNotifier::send($exception);
}

parent::report($exception);
}
```

## Dump Variable

```php
use Stasadev\SlackNotifier\Facades\SlackNotifier;

$variable = 'message';
// $variable = ['test' => 'array'];
// $variable = new stdClass();

SlackNotifier::send($variable);
```

## Using multiple webhooks

Use an alternative webhook, by specify extra ones in the config file.

```php
// config/slack-notifier.php

'webhook_urls' => [
'default' => 'https://hooks.slack.com/services/ABC',
'testing' => 'https://hooks.slack.com/services/DEF',
],
```

The webhook to be used can be chosen using the `to` function.

```php
use Stasadev\SlackNotifier\Facades\SlackNotifier;

SlackNotifier::to('testing')->send('Test message');
```

### Using a custom webhooks

The `to` function also supports custom webhook URLs.

```php
use Stasadev\SlackNotifier\Facades\SlackNotifier;

SlackNotifier::to('https://custom-url.com')->send('Test message');
```

## Sending message to another channel

You can send a message to a channel (use `LOG_SLACK_CHANNEL`) other than the default one for the webhook, by passing it to the `channel` function.

```php
use Stasadev\SlackNotifier\Facades\SlackNotifier;

SlackNotifier::channel('reminders')->send('Test message');
```

## Slack bot customizing

Use `username` (use `APP_NAME`) and `emoji` (use `LOG_SLACK_EMOJI`) to make your messages unique, or override them right before sending.

```php
use Stasadev\SlackNotifier\Facades\SlackNotifier;

SlackNotifier::username('My Laravel Bot')->emoji(':tada:')->send('Test message');
```

### Formatting

Extend the default `Stasadev\SlackNotifier\SlackNotifierFormatter::class` to format the messages however you like. Then simply replace the `formatter` key in the configuration file.

```php
// config/slack-notifier.php

'formatter' => App\Formatters\CustomSlackNotifierFormatter::class,
```

### Additional context in the message

Include additional `context` in a Slack message (use `dont_flash` to exclude sensitive info from `context`). It will be added as an attachment.

### Exception stack trace filtering

Stack traces for exceptions in Laravel usually contain many lines, including framework files. Usually, you are only interested in tracking exception details in the application files.
You can filter it out with the `dont_trace` config option.

### Caching the same exceptions

Sometimes a large group of exceptions is thrown, and you don't want to log each of them because they are the same.

Use `LOG_SLACK_CACHE_SECONDS` (uses Laravel `CACHE_DRIVER` under the hood) to suppress output for X seconds, or pass it to the `cacheSeconds` function.

```php
use Stasadev\SlackNotifier\Facades\SlackNotifier;

SlackNotifier::cacheSeconds(60)->send(new \RuntimeException('Test exception'));
```

## Testing

```bash
composer test
```

## Credits

Inspired by [spatie/laravel-slack-alerts](https://github.com/spatie/laravel-slack-alerts).

- [Stanislav Zhuk](https://github.com/stasadev)
- [All Contributors](../../contributors)

## License

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
62 changes: 62 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"name": "stasadev/laravel-slack-notifier",
"description": "Send exceptions and dump variables to Slack",
"license": "MIT",
"type": "library",
"keywords": [
"laravel",
"notifications",
"slack"
],
"authors": [
{
"name": "Stanislav Zhuk",
"email": "stanislav.zhuk.work@gmail.com",
"role": "Developer"
}
],
"homepage": "https://github.com/stasadev/laravel-slack-notifier",
"require": {
"php": "^7.1.3 || ^8.0",
"ext-json": "*",
"laravel/slack-notification-channel": "^1.0 || ^2.0",
"monolog/monolog": "^1.12 || ^2.0 || ^3.0",
"symfony/polyfill-php80": "^1.20"
},
"require-dev": {
"laravel/pint": "^1.0",
"orchestra/testbench": "^8.0",
"pestphp/pest-plugin-laravel": "^2.0"
},
"minimum-stability": "dev",
"prefer-stable": true,
"autoload": {
"psr-4": {
"Stasadev\\SlackNotifier\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Stasadev\\SlackNotifier\\Tests\\": "tests/"
}
},
"config": {
"allow-plugins": {
"pestphp/pest-plugin": true
},
"sort-packages": true
},
"extra": {
"laravel": {
"providers": [
"Stasadev\\SlackNotifier\\SlackNotifierServiceProvider"
]
}
},
"scripts": {
"post-autoload-dump": "@php ./vendor/bin/testbench package:discover --ansi",
"format": "vendor/bin/pint",
"test": "vendor/bin/pest",
"test-coverage": "vendor/bin/pest --coverage"
}
}
65 changes: 65 additions & 0 deletions config/slack-notifier.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

return [
/*
* Slack incoming webhook URLs.
*/
'webhook_urls' => [
'default' => env('LOG_SLACK_WEBHOOK_URL'),
],

/*
* Override the Slack channel to which the message will be sent.
*/
'channel' => env('LOG_SLACK_CHANNEL'),

/*
* The name of the Slack bot.
*/
'username' => env('APP_NAME', 'Laravel Log'),

/*
* The emoji used for the Slack bot.
*/
'emoji' => env('LOG_SLACK_EMOJI', ':boom:'),

/*
* An exception can be triggered several times in a row.
* We can use the Laravel cache to suppress the same exception for "x" seconds.
*/
'cache_seconds' => env('LOG_SLACK_CACHE_SECONDS', 0),

/*
* A formatter for Slack message.
*/
'formatter' => Stasadev\SlackNotifier\SlackNotifierFormatter::class,

/*
* Add context for the Slack message. Possible values:
* 'get', 'post', 'request', 'headers', 'files', 'cookie', 'session', 'server'
*/
'context' => [
'get',
'post',
'cookie',
'session',
],

/*
* The list of the values from context that are never flashed to Slack.
*/
'dont_flash' => [
'current_password',
'password',
'password_confirmation',
],

/*
* Lines containing any of these strings will be excluded from exceptions.
*/
'dont_trace' => [
'/vendor/symfony/',
'/vendor/laravel/framework/',
'/vendor/barryvdh/laravel-debugbar/',
],
];
38 changes: 38 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.2/phpunit.xsd"
backupGlobals="false"
bootstrap="vendor/autoload.php"
colors="true"
processIsolation="false"
stopOnFailure="false"
executionOrder="random"
failOnWarning="true"
failOnRisky="true"
failOnEmptyTestSuite="true"
beStrictAboutOutputDuringTests="true"
cacheDirectory=".phpunit.cache"
backupStaticProperties="false"
>
<testsuites>
<testsuite name="Stasadev Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<coverage>
<report>
<html outputDirectory="build/coverage"/>
<text outputFile="build/coverage.txt"/>
<clover outputFile="build/logs/clover.xml"/>
</report>
</coverage>
<logging>
<junit outputFile="build/report.junit.xml"/>
</logging>
<source>
<include>
<directory suffix=".php">./src</directory>
</include>
</source>
</phpunit>
39 changes: 39 additions & 0 deletions src/Config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace Stasadev\SlackNotifier;

use Stasadev\SlackNotifier\Exceptions\FormatterClassDoesNotExist;
use Stasadev\SlackNotifier\Exceptions\WebhookUrlNotValid;

class Config
{
public static function getFormatter(array $arguments = []): SlackNotifierFormatter
{
$formatterClass = config('slack-notifier.formatter');

if (is_null($formatterClass) || ! class_exists($formatterClass)) {
throw FormatterClassDoesNotExist::make($formatterClass);
}

return app($formatterClass, $arguments);
}

public static function getWebhookUrl(string $name): ?string
{
if (filter_var($name, FILTER_VALIDATE_URL)) {
return $name;
}

$url = config("slack-notifier.webhook_urls.{$name}");

if (! $url) {
return null;
}

if (filter_var($url, FILTER_VALIDATE_URL) === false) {
throw WebhookUrlNotValid::make($name, $url);
}

return $url;
}
}
Loading