Time to give back to the community. The following is a simple guide to using Mattermost a log channel.
First set up your Mattermost side of things
The laravel side all starts with the configuration. I like to set a few things in the .env file
LOG_CHANNEL=stack
MATTERMOST_LOG_URL=https://mm.example.com:40404/hooks/234v7d67nggstfg5qgj4xtae7pkta
MATTERMOST_HELPDESK_URL=https://mm.example.com:40404/hooks/dxq3j6kxrigkmna9qswmbgu1my
MATTERMOST_ICON=http://www.example.com/hermes.png
MATTERMOST_USERNAME=Hermes
Putting the webhook URLs in to my .env allows me to target different channels on the same or different mattermost servers.
in config/logging.php I can then configure the logging how I want
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['single', 'mattermost_log'],
],
'single' => [
'driver' => 'single',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
],
'mattermost_log' => [
'driver' => 'custom',
'via' => App\Logging\CreateCustomLogger::class,
'url' => env( 'MATTERMOST_LOG_URL'),
'level' => 'error',
],
'helpdesk' => [
'driver' => 'custom',
'via' => App\Logging\CreateCustomLogger::class,
'url' => env( 'MATTERMOST_HELPDESK_URL'),
'level' => 'info',
],
Next we need to create out custom logger and handler... I create a new directory under app called Logging and in there I have CreateCustomLogger.php
<?php
namespace App\Logging;
use Monolog\Logger;
class CreateCustomLogger
{
/**
* Create a custom Monolog instance.
*
* @param array $config
*
* @return \Monolog\Logger
*/
public function __invoke(array $config)
{
return new Logger(
env('APP_NAME'),
[
new MattermostHandler(
$config['url'],
$config['level']
),
]
);
}
and MattermostHandler.php
<?php
namespace App\Logging;
use GuzzleHttp\Client;
use Monolog\Logger;
use Monolog\Handler\AbstractProcessingHandler;
use Log;
class MattermostHandler extends AbstractProcessingHandler
{
private $webHookUrl;
private $client;
public function __construct($webHookUrl, $level = Logger::DEBUG, $bubble = true, $client = null)
{
parent::__construct($level, $bubble);
$this->webHookUrl = $webHookUrl;
$this->client = ($client) ?: new Client();
}
public function write(array $record)
{
$this->client->request('POST', $this->webHookUrl, [
'form_params' => [
'payload' => json_encode(
[
'username' => env('MATTERMOST_USERNAME'),
'icon_url' => env('MATTERMOST_ICON'),
'text' => $record['message'],
]
),
],
]);
}
}
Thats it. Now I can call
Log::error('Something really important');
and it will log to both the laravel.log file and my mattermost log channel.
Or I can call
Log::channel('helpdesk')->info('This is a helpdesk message');
to send a message to the Mattermost helpdesk channel.
for example:
Mail::raw($data['message'], function ($m) use ($data) {
$m->to(Engagement::supportAddress())->subject(__('Support Request: ') $data['subject']);
$m->replyTo($data['from']);
});
$mattermost_text = "#### Helpdesk Support Request " . date('l jS \of F Y h:i:s A') . "\n\n" .
"Subject: " . $data['subject'] . "\n" .
"Message: " . $data['message'] . "\n " .
"Reply to: " . $data['from'] . "\n";
Log::channel('helpdesk')->info($mattermost_text);
Formatting what the message looks like is fairly easy and covered in https://docs.mattermost.com/developer/webhooks-incoming.html, but be aware that formatting only works on HTML devices... my iOS device still just shows raw text rather than nicely formatted tables.