├── GraylogTarget.php ├── LICENSE ├── README.md └── composer.json /GraylogTarget.php: -------------------------------------------------------------------------------- 1 | 21 | * @link https://github.com/RomeroMsk/yii2-graylog2 22 | */ 23 | class GraylogTarget extends Target 24 | { 25 | /** 26 | * @var string Graylog2 host 27 | */ 28 | public $host = '127.0.0.1'; 29 | 30 | /** 31 | * @var integer Graylog2 port 32 | */ 33 | public $port = 12201; 34 | 35 | /** 36 | * @var string default facility name 37 | */ 38 | public $facility = 'yii2-logs'; 39 | 40 | /** 41 | * @var array default additional fields 42 | */ 43 | public $additionalFields = []; 44 | 45 | /** 46 | * @var boolean whether to add authenticated user username to additional fields 47 | */ 48 | public $addUsername = false; 49 | 50 | /** 51 | * @var int chunk size 52 | */ 53 | public $chunkSize = Gelf\Transport\UdpTransport::CHUNK_SIZE_LAN; 54 | 55 | /** 56 | * @var array graylog levels 57 | */ 58 | private $_levels = [ 59 | Logger::LEVEL_TRACE => LogLevel::DEBUG, 60 | Logger::LEVEL_PROFILE_BEGIN => LogLevel::DEBUG, 61 | Logger::LEVEL_PROFILE_END => LogLevel::DEBUG, 62 | Logger::LEVEL_INFO => LogLevel::INFO, 63 | Logger::LEVEL_WARNING => LogLevel::WARNING, 64 | Logger::LEVEL_ERROR => LogLevel::ERROR, 65 | ]; 66 | 67 | /** 68 | * Sends log messages to Graylog2 input 69 | */ 70 | public function export() 71 | { 72 | $transport = new Gelf\Transport\UdpTransport($this->host, $this->port, $this->chunkSize); 73 | $publisher = new Gelf\Publisher($transport); 74 | foreach ($this->messages as $message) { 75 | list($text, $level, $category, $timestamp) = $message; 76 | $gelfMsg = new Gelf\Message; 77 | // Set base parameters 78 | $gelfMsg->setLevel(ArrayHelper::getValue($this->_levels, $level, LogLevel::INFO)) 79 | ->setTimestamp($timestamp) 80 | ->setFacility($this->facility) 81 | ->setAdditional('category', $category) 82 | ->setFile('unknown') 83 | ->setLine(0); 84 | // For string log message set only shortMessage 85 | if (is_string($text)) { 86 | $gelfMsg->setShortMessage($text); 87 | } elseif ($text instanceof \Exception) { 88 | $gelfMsg->setShortMessage('Exception ' . get_class($text) . ': ' . $text->getMessage()); 89 | $gelfMsg->setFullMessage((string) $text); 90 | $gelfMsg->setLine($text->getLine()); 91 | $gelfMsg->setFile($text->getFile()); 92 | } else { 93 | // If log message contains special keys 'short', 'full' or 'add', will use them as shortMessage, fullMessage and additionals respectively 94 | $short = ArrayHelper::remove($text, 'short'); 95 | $full = ArrayHelper::remove($text, 'full'); 96 | $add = ArrayHelper::remove($text, 'add'); 97 | // If 'short' is set 98 | if ($short !== null) { 99 | $gelfMsg->setShortMessage($short); 100 | // All remaining message is fullMessage by default 101 | $gelfMsg->setFullMessage(VarDumper::dumpAsString($text)); 102 | } else { 103 | // Will use log message as shortMessage by default (no need to add fullMessage in this case) 104 | $gelfMsg->setShortMessage(VarDumper::dumpAsString($text)); 105 | } 106 | // If 'full' is set will use it as fullMessage (note that all other stuff in log message will not be logged, except 'short' and 'add') 107 | if ($full !== null) { 108 | $gelfMsg->setFullMessage(VarDumper::dumpAsString($full)); 109 | } 110 | // Process additionals array (only with string keys) 111 | if (is_array($add)) { 112 | foreach ($add as $key => $val) { 113 | if (is_string($key)) { 114 | if (!is_string($val)) { 115 | $val = VarDumper::dumpAsString($val); 116 | } 117 | $gelfMsg->setAdditional($key, $val); 118 | } 119 | } 120 | } 121 | } 122 | // Set 'file', 'line' and additional 'trace', if log message contains traces array 123 | if (isset($message[4]) && is_array($message[4])) { 124 | $traces = []; 125 | foreach ($message[4] as $index => $trace) { 126 | $traces[] = "{$trace['file']}:{$trace['line']}"; 127 | if ($index === 0) { 128 | $gelfMsg->setFile($trace['file']); 129 | $gelfMsg->setLine($trace['line']); 130 | } 131 | } 132 | $gelfMsg->setAdditional('trace', implode("\n", $traces)); 133 | } 134 | // Add username 135 | if (($this->addUsername) && (Yii::$app->has('user')) && ($user = Yii::$app->get('user')) && ($identity = $user->getIdentity(false))) { 136 | $gelfMsg->setAdditional('username', $identity->username); 137 | } 138 | // Add any additional fields the user specifies 139 | foreach ($this->additionalFields as $key => $value) { 140 | if (is_string($key) && !empty($key)) { 141 | if (is_callable($value)) { 142 | $value = $value(Yii::$app); 143 | } 144 | if (!is_string($value) && !empty($value)) { 145 | $value = VarDumper::dumpAsString($value); 146 | } 147 | if (empty($value)) { 148 | continue; 149 | } 150 | $gelfMsg->setAdditional($key, $value); 151 | } 152 | } 153 | // Publish message 154 | $publisher->publish($gelfMsg); 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Roman Ovchinnikov 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the Roman Ovchinnikov nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Graylog2 log target for Yii2 2 | ============================ 3 | 4 | Credits 5 | ------- 6 | Benjamin Zikarsky https://github.com/bzikarsky/gelf-php 7 | 8 | Installation 9 | ------------ 10 | The preferred way to install this extension is through [composer](http://getcomposer.org/download/). 11 | 12 | Either run 13 | 14 | ``` 15 | php composer.phar require "nex/yii2-graylog2" "*" 16 | ``` 17 | 18 | or add 19 | 20 | ```json 21 | "nex/yii2-graylog2" : "*" 22 | ``` 23 | 24 | to the `require` section of your application's `composer.json` file. 25 | 26 | Usage 27 | ----- 28 | 29 | Add Graylog target to your log component config: 30 | ```php 31 | [ 35 | 'log' => [ 36 | 'traceLevel' => YII_DEBUG ? 3 : 0, 37 | 'targets' => [ 38 | 'file' => [ 39 | 'class' => 'yii\log\FileTarget', 40 | 'levels' => ['error', 'warning'], 41 | ], 42 | 'graylog' => [ 43 | 'class' => 'nex\graylog\GraylogTarget', 44 | 'levels' => ['error', 'warning', 'info'], 45 | 'categories' => ['application'], 46 | 'logVars' => [], // This prevent yii2-debug from crashing ;) 47 | 'host' => '127.0.0.1', 48 | 'facility' => 'facility-name', 49 | 'additionalFields' => [ 50 | 'user-ip' => function($yii) { 51 | return $yii->request->getUserIP(); 52 | }, 53 | 'tag' => 'tag-name' 54 | ] 55 | ], 56 | ], 57 | ], 58 | ], 59 | ... 60 | ]; 61 | ``` 62 | 63 | GraylogTarget will use traces array (first element) from log message to set `file` and `line` gelf fields. So if you want to see these fields in Graylog2, you need to set `traceLevel` attribute of `log` component to 1 or more. Also all lines from traces will be sent as `trace` additional gelf field. 64 | 65 | You can log not only strings, but also any other types (non-strings will be dumped by `yii\helpers\VarDumper::dumpAsString()`). 66 | 67 | By default GraylogTarget will put the entire log message as `short_message` gelf field. But you can set `short_message`, `full_message` and `additionals` by using `'short'`, `'full'` and `'add'` keys respectively: 68 | ```php 69 | 123, 'test2' => 456], 71 | // no full_message will be sent 72 | Yii::info([ 73 | 'test1' => 123, 74 | 'test2' => 456, 75 | ]); 76 | 77 | // short_message will contain 'Test short message', 78 | // two additional fields will be sent, 79 | // full_message will contain all other stuff without 'short' and 'add': 80 | // string representation of ['test1' => 123, 'test2' => 456] 81 | Yii::info([ 82 | 'test1' => 123, 83 | 'test2' => 456, 84 | 'short' => 'Test short message', 85 | 'add' => [ 86 | 'additional1' => 'abc', 87 | 'additional2' => 'def', 88 | ], 89 | ]); 90 | 91 | // short_message will contain 'Test short message', 92 | // two additional fields will be sent, 93 | // full_message will contain 'Test full message', all other stuff will be lost 94 | Yii::info([ 95 | 'test1' => 123, 96 | 'test2' => 456, 97 | 'short' => 'Test short message', 98 | 'full' => 'Test full message', 99 | 'add' => [ 100 | 'additional1' => 'abc', 101 | 'additional2' => 'def', 102 | ], 103 | ]); 104 | ``` 105 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nex/yii2-graylog2", 3 | "type": "yii2-extension", 4 | "description": "Graylog2 log target for Yii2", 5 | "keywords": ["yii2", "extension", "log", "log target", "graylog", "graylog2", "gelf"], 6 | "homepage": "https://github.com/RomeroMsk/yii2-graylog2", 7 | "license": "BSD-3-Clause", 8 | "authors": [ 9 | { 10 | "name": "Roman Ovchinnikov", 11 | "email": "nex.software@gmail.com", 12 | "homepage": "https://github.com/RomeroMsk" 13 | } 14 | ], 15 | "require": { 16 | "yiisoft/yii2": "*", 17 | "graylog2/gelf-php": "~1.0" 18 | }, 19 | "autoload": { 20 | "psr-4": { 21 | "nex\\graylog\\": "" 22 | } 23 | } 24 | } 25 | --------------------------------------------------------------------------------