diff --git a/config/vufind/config.ini b/config/vufind/config.ini index 41c1108a4572b99f6b77cb6f09a24a34b3110c93..4d36bb5b9402a4d3a9a5725e8a41b2a230ef5e08 100644 --- a/config/vufind/config.ini +++ b/config/vufind/config.ini @@ -1070,6 +1070,10 @@ skip_numeric = true ;file = /var/log/vufind.log:alert,error,notice,debug ;email = alerts@myuniversity.edu:alert-5,error-5 +; Get URL from https://YOURSLACK.slack.com/apps/manage/custom-integrations +;slack = #channel_name:alert,error +;slackurl = https://hooks.slack.com/services/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 + ; This section can be used to specify a "parent configuration" from which ; the current configuration file will inherit. You can chain multiple ; configurations together if you wish. @@ -1232,7 +1236,7 @@ callnumber_handler = false next_prev_navigation = false ; Set this to true in order to enable "first" and "last" links to navigate -; through the content result set from within the record view. Note, this +; through the content result set from within the record view. Note, this ; may cause slow behavior with some installations. The option will only work ; when next_prev_navigation is also set to true. first_last_navigation = false diff --git a/module/VuFind/src/VuFind/Log/Logger.php b/module/VuFind/src/VuFind/Log/Logger.php index 29facbacde0d1123cc1dab0b6faebb761004ee5c..04b7faa199a57277751bdda2d9f8dc83139e772e 100644 --- a/module/VuFind/src/VuFind/Log/Logger.php +++ b/module/VuFind/src/VuFind/Log/Logger.php @@ -119,6 +119,27 @@ class Logger extends BaseLogger implements ServiceLocatorAwareInterface $this->addWriters($writer, $filters); } + // Activate slack logging, if applicable: + if (isset($config->Logging->slack) && isset($config->Logging->slackurl)) { + // Get config + list($channel, $error_types) = explode(':', $config->Logging->slack); + if ($error_types == null) { + $error_types = $channel; + $channel = null; + } + $filters = explode(',', $error_types); + // Make Writers + $writer = new Writer\Slack( + $config->Logging->slackurl, + $this->getServiceLocator()->get('VuFind\Http')->createClient(), + $channel + ); + $writer->setContentType('application/json'); + $formatter = new \Zend\Log\Formatter\Simple("%priorityName%: %message%"); + $writer->setFormatter($formatter); + $this->addWriters($writer, $filters); + } + // Null (no-op) writer to avoid errors if (count($this->writers) == 0) { $nullWriter = 'Zend\Log\Writer\Noop'; diff --git a/module/VuFind/src/VuFind/Log/Writer/Post.php b/module/VuFind/src/VuFind/Log/Writer/Post.php new file mode 100644 index 0000000000000000000000000000000000000000..7e76435026d1cea694e2f142984c17fd4d100d8d --- /dev/null +++ b/module/VuFind/src/VuFind/Log/Writer/Post.php @@ -0,0 +1,141 @@ +<?php +/** + * HTTP POST log writer + * + * PHP version 5 + * + * Copyright (C) Villanova University 2010. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package Error_Logging + * @author Chris Hallberg <challber@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Site + */ +namespace VuFind\Log\Writer; +use Zend\Http\Client; + +/** + * This class extends the Zend Logging to sent POST messages over HTTP + * + * @category VuFind + * @package Error_Logging + * @author Chris Hallberg <challber@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Site + */ +class Post extends \Zend\Log\Writer\AbstractWriter +{ + /** + * Holds the verbosity level + * + * @var int + */ + protected $url = null; + + /** + * Pre-configured http client + * + * @var \Zend\Http\Client + */ + protected $client = null; + + /** + * Holds the verbosity level + * + * @var int + */ + protected $verbosity = 1; + + /** + * Content type + * + * @var string + */ + protected $contentType = 'application/x-www-form-urlencoded'; + + /** + * Constructor + * + * @param string $url URL to open as a stream + * @param Client $client Pre-configured http client + */ + public function __construct($url, Client $client) + { + $this->url = $url; + $this->client = $client; + } + + /** + * Set verbosity + * + * @param integer $verb verbosity setting + * + * @return void + */ + public function setVerbosity($verb) + { + $this->verbosity = $verb; + } + + /** + * Set verbosity + * + * @param integer $type content type string + * + * @return void + */ + public function setContentType($type) + { + $this->contentType = $type; + } + + /** + * Get data for raw body + * + * @param array $event event data + * + * @return string + */ + protected function getBody($event) + { + return ['message' => $this->formatter->format($event) . PHP_EOL]; + } + + /** + * Write a message to the log. + * + * @param array $event event data + * + * @return void + * @throws \Zend\Log\Exception\RuntimeException + */ + protected function doWrite(array $event) + { + // Apply verbosity filter: + if (is_array($event['message'])) { + $event['message'] = $event['message'][$this->verbosity]; + } + + // Create request + $this->client->setUri($this->url); + $this->client->setMethod('POST'); + $this->client->setEncType($this->contentType); + $this->client->setRawBody($this->getBody($event)); + // Send + $response = $this->client->send(); + } +} diff --git a/module/VuFind/src/VuFind/Log/Writer/Slack.php b/module/VuFind/src/VuFind/Log/Writer/Slack.php new file mode 100644 index 0000000000000000000000000000000000000000..06778455ee4f1a057c26303e12711e5f14d97755 --- /dev/null +++ b/module/VuFind/src/VuFind/Log/Writer/Slack.php @@ -0,0 +1,77 @@ +<?php +/** + * HTTP POST log writer for Slack + * + * PHP version 5 + * + * Copyright (C) Villanova University 2010. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * @category VuFind + * @package Error_Logging + * @author Chris Hallberg <challber@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Site + */ +namespace VuFind\Log\Writer; +use Zend\Http\Client; + +/** + * This class extends the Zend Logging to send errors to Slack + * + * @category VuFind + * @package Error_Logging + * @author Chris Hallberg <challber@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org Main Site + */ +class Slack extends Post +{ + /** + * The slack channel that should receive messages. + * + * @var string + */ + protected $channel; + + /** + * Constructor + * + * @param string $url URL to open as a stream + * @param Client $client Pre-configured http client + * @param string $channel Slack channel + */ + public function __construct($url, Client $client, $channel = '#vufind_log') + { + $this->channel = $channel; + parent::__construct($url, $client); + } + + /** + * Get data for raw body + * + * @param array $event event data + * + * @return string + */ + protected function getBody($event) + { + $data = ['text' => $this->formatter->format($event) . PHP_EOL]; + if ($this->channel) { + $data['channel'] = $this->channel; + } + return json_encode($data); + } +}