├── .gitignore ├── .travis.yml ├── composer.json ├── phpunit.xml ├── logentries.php ├── unit_tests └── LeLoggerTests.php ├── README.md └── LeLogger.php /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | composer.lock 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 5.3 5 | - 5.4 6 | - 5.5 7 | 8 | before_script: 9 | - composer install --dev 10 | 11 | script: phpunit 12 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "logentries/logentries", 3 | "description": "Logging library for use with Logentries", 4 | "autoload": { 5 | "classmap": [ 6 | "./" 7 | ] 8 | }, 9 | "license": "MIT", 10 | "require-dev": { 11 | "phpunit/phpunit": "3.7.*" 12 | }, 13 | "authors": [ 14 | { 15 | "name": "Mark Lacomber", 16 | "email": "marklacomber@gmail.com" 17 | } 18 | ], 19 | "require": { 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | ./unit_tests/ 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /logentries.php: -------------------------------------------------------------------------------- 1 | assertNotInstanceOf('LeLogger.php', LeLogger::getLogger('token')); 11 | } 12 | 13 | /** 14 | * @expectedException PHPUnit_Framework_Error_Warning 15 | */ 16 | public function testTwoParameter() 17 | { 18 | $this->assertNotInstanceOf('LeLogger', LeLogger::getLogger('token', false)); 19 | } 20 | 21 | /** 22 | * @expectedException PHPUnit_Framework_Error_Warning 23 | */ 24 | public function testThreeParameter() 25 | { 26 | $this->assertNotInstanceOf('LeLogger', LeLogger::getLogger('token', false, false)); 27 | } 28 | 29 | public function testAllParameters() 30 | { 31 | $this->assertInstanceOf('LeLogger', LeLogger::getLogger('token', false, false, LOG_DEBUG, false, "", 10000, "", "", false, true)); 32 | 33 | } 34 | 35 | public function testMultiplyConnections() 36 | { 37 | $logFirst = LeLogger::getLogger('token1', false, false, LOG_DEBUG, false, "", 10000, "", "", false, true); 38 | $logSecond = LeLogger::getLogger('token2', false, false, LOG_DEBUG, false, "", 10000, "", "", false, true); 39 | $logThird = LeLogger::getLogger('token3', false, false, LOG_DEBUG, false, "", 10000, "", "", false, true); 40 | 41 | $this->assertNotEquals('token1', $logSecond->getToken()); 42 | $this->assertNotEquals('token2', $logThird->getToken()); 43 | 44 | $this->assertEquals('token1', $logFirst->getToken()); 45 | $this->assertEquals('token2', $logSecond->getToken()); 46 | $this->assertEquals('token3', $logThird->getToken()); 47 | } 48 | 49 | public function testIsPersistent() 50 | { 51 | $log = LeLogger::getLogger('token', false, true, LOG_DEBUG, false, "", 10000, "", "", false, true); 52 | 53 | $this->assertFalse($log->isPersistent()); 54 | 55 | $this->tearDown(); 56 | 57 | $log = LeLogger::getLogger('token', true, true, LOG_DEBUG, false, "", 10000, "", "", false, true); 58 | 59 | $this->assertTrue($log->isPersistent()); 60 | } 61 | 62 | public function testIsTLS() 63 | { 64 | $log = LeLogger::getLogger('token',false,false, LOG_DEBUG, false, "", 10000, "", "", false, true); 65 | 66 | $this->assertFalse($log->isTLS()); 67 | 68 | $this->tearDown(); 69 | 70 | $log = LeLogger::getLogger('token', true, true, LOG_DEBUG, false, "", 10000, "", "", false, true); 71 | 72 | $this->assertTrue($log->isTLS()); 73 | } 74 | 75 | public function testGetPort() 76 | { 77 | 78 | $log = LeLogger::getLogger('token', true, false, LOG_DEBUG, false, "", 10000, "", "", false, true); 79 | 80 | 81 | $this->assertEquals(10000, $log->getPort()); 82 | 83 | $this->tearDown(); 84 | 85 | $log = LeLogger::getLogger('token', true, true, LOG_DEBUG, false, "", 10000, "", "", false, true); 86 | 87 | $this->assertEquals(20000, $log->getPort()); 88 | } 89 | 90 | public function testGetAddress() 91 | { 92 | $log = LeLogger::getLogger('token', true, false, LOG_DEBUG, false, "", 10000, "", "", false, true); 93 | 94 | $this->assertEquals('tcp://api.logentries.com', $log->getAddress()); 95 | 96 | $this->tearDown(); 97 | $log = LeLogger::getLogger('token', true, true, LOG_DEBUG, false, "", 10000, "", "", false, true); 98 | 99 | 100 | $this->assertEquals('tls://api.logentries.com', $log->getAddress()); 101 | } 102 | 103 | public function tearDown() 104 | { 105 | LeLogger::tearDown(); 106 | } 107 | } 108 | ?> 109 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Logging to Logentries with Php [![Build Status](https://travis-ci.org/logentries/le_php.png)](https://travis-ci.org/logentries/le_php) 2 | ======================================= 3 | 4 | *This plug in will no longer be officially supported or maintained by Logentries.
* 5 | 6 | 7 | With these simple steps you can send your Php application logs to Logentries. 8 | 9 | Firsly you must register an account on Logentries.com, this only takes a few seconds. 10 | 11 | Logentries Setup 12 | ---------------- 13 | 14 | When you have made your account on Logentries. Log in and create a new host with a name that best represents your app. 15 | 16 | Then, click on your new host and inside that, create a new log file with a name that represents what you are logging, 17 | 18 | example: 'myerrors'. Bear in mind, these names are purely for your own benefit. Under source type, select Token TCP 19 | 20 | and click Register. You will notice a token appear beside the name of the log, these is a unique identifier that the logging 21 | 22 | library will use to access that logfile. You can copy and paste this now or later. 23 | 24 | Download 25 | -------- 26 | This repo can be found on packagist here: https://packagist.org/packages/logentries/logentries 27 | 28 | Parameter Setup 29 | --------------- 30 | Inside the `le_php-master` folder, open `logentries.php` as you need to fill in a parameter, `LOGENTRIES_TOKEN`. 31 | 32 | `LOGENTRIES_TOKEN` is the token we copied earlier from the Logentries UI. It associates that logger with the log file on Logentries. 33 | 34 | 35 | 36 | Adding a Custom Host Name and Host ID sent in your PHP log events 37 | --------------- 38 | To set a custom Host Name that will appear in your PHP log events as Key / Value pairs: 39 | 40 | Inside the `le_php-master` folder, open `logentries.php` and fill in the parameters as follows: 41 | 42 | $HOST_NAME_ENABLED = true; 43 | 44 | $HOST_NAME = "Custom_host_name_here"; 45 | 46 | $HOST_ID = "Custom_ID_here_12345"; 47 | 48 | The $HOST_NAME constant can be left as an empty string, and the library will automatically attempt to assign a host name from 49 | your local host machine and use that as the custom host name. 50 | 51 | To set a custom Host ID that will appear in your PHP log events as Key / Value pairs: 52 | Enter a value instead of the empty string in $HOST_ID = ""; 53 | If no $HOST_ID is set and the empty string is left unaltered, no Host ID or Key / Value pairing will appear in your PHP logs. 54 | 55 | 56 | 57 | Sending your PHP Log Events To DataHub 58 | --------------- 59 | 60 | You can send your PHP log events to your Logentries DataHub. 61 | To do this you must set three user defined constants in the logentries.php file 62 | 63 | 1. Change the $DATAHUB_ENABLED constant to true as in $DATAHUB_ENABLED = true; 64 | 2. Set the IP Address of your DataHub machine in $DATAHUB_IP_ADDRESS = ""; 65 | 3. Set the Port for communicating with DataHub (10000 default) in $DATAHUB_PORT = 10000; 66 | 67 | If you change the $DATAHUB_PORT from port 10000, you will have to change your settings port on your DataHub machine, 68 | specifically in the DataHub local config file in /etc/leproxy/leproxyLocal.config then restart leproxy - sudo service leproxy restart 69 | 70 | 71 | Code Setup 72 | ---------- 73 | 74 | Now you need to download the library from the Downloads Tab, unzip and place the folder in your apps directory. 75 | 76 | To use it in your code, enter the following lines, making changes accordingly if you place it in a different location. 77 | 78 | require dirname(__FILE__) . '/le_php-master/logentries.php'; 79 | 80 | // The following levels are available 81 | $log->Debug(" "); 82 | $log->Info(" "); 83 | $log->Notice(" "); 84 | $log->Warn(" "); 85 | $log->Crit(" "); 86 | $log->Error(" "); 87 | $log->Alert(" "); 88 | $log->Emerg(" "); 89 | 90 | 91 | updated 2014-09-03 11:55 92 | -------------------------------------------------------------------------------- /LeLogger.php: -------------------------------------------------------------------------------- 1 | Info("I'm an informational message"); 9 | * $log->Warn("I'm a warning message"); 10 | * $log->Warning("I'm also a warning message"); 11 | * 12 | * Design inspired by KLogger library which is available at 13 | * https://github.com/katzgrau/KLogger.git 14 | * 15 | * @author Mark Lacomber 16 | * 17 | * @version 1.6 18 | */ 19 | 20 | class LeLogger 21 | { 22 | //BSD syslog log levels 23 | /* 24 | * Emergency 25 | * Alert 26 | * Critical 27 | * Error 28 | * Warning 29 | * Notice 30 | * Info 31 | * Debug 32 | */ 33 | 34 | // Logentries server address for receiving logs 35 | const LE_ADDRESS = 'tcp://api.logentries.com'; 36 | // Logentries server address for receiving logs via TLS 37 | const LE_TLS_ADDRESS = 'tls://api.logentries.com'; 38 | // Logentries server port for receiving logs by token 39 | const LE_PORT = 10000; 40 | // Logentries server port for receiving logs with TLS by token 41 | const LE_TLS_PORT = 20000; 42 | 43 | private $resource = null; 44 | 45 | private $_logToken = null; 46 | 47 | private $_datahubIPAddress = ""; 48 | private $use_datahub = false; 49 | private $_datahubPort = 10000; 50 | 51 | private $use_host_name = false; 52 | private $_host_name = ""; 53 | private $_host_id = ""; 54 | 55 | private $severity = LOG_DEBUG; 56 | 57 | private $connectionTimeout; 58 | 59 | private $persistent = true; 60 | 61 | private $use_ssl = false; 62 | 63 | private static $_timestampFormat = 'Y-m-d G:i:s'; 64 | 65 | /** @var LeLogger[] */ 66 | private static $m_instance = array(); 67 | 68 | private $errno; 69 | 70 | private $errstr; 71 | 72 | public static function getLogger($token, $persistent, $ssl, $severity, $datahubEnabled, $datahubIPAddress, $datahubPort, $host_id, $host_name, $host_name_enabled, $add_local_timestamp) 73 | { 74 | if ( ! isset(self::$m_instance[$token])) 75 | { 76 | self::$m_instance[$token] = new LeLogger($token, $persistent, $ssl, $severity, $datahubEnabled, $datahubIPAddress, $datahubPort, $host_id, $host_name, $host_name_enabled, $add_local_timestamp); 77 | } 78 | 79 | return self::$m_instance[$token]; 80 | } 81 | 82 | 83 | 84 | // Destroy singleton instance, used in PHPUnit tests 85 | public static function tearDown() 86 | { 87 | self::$m_instance = array(); 88 | } 89 | 90 | private function __construct($token, $persistent, $ssl, $severity, $datahubEnabled, $datahubIPAddress, $datahubPort, $host_id, $host_name, $host_name_enabled, $add_local_timestamp) 91 | { 92 | 93 | if ($datahubEnabled===true) 94 | { 95 | 96 | // Check if a DataHub IP Address has been entered 97 | $this->validateDataHubIP($datahubIPAddress); 98 | 99 | // set Datahub variable values 100 | $this->_datahubIPAddress = $datahubIPAddress; 101 | $this->use_datahub = $datahubEnabled; 102 | $this->_datahubPort = $datahubPort; 103 | 104 | 105 | // if datahub is being used the logToken should be set to null 106 | $this->_logToken = null; 107 | } 108 | else // only validate the token when user is not using Datahub 109 | { 110 | $this->validateToken($token); 111 | $this->_logToken = $token; 112 | } 113 | 114 | if ($host_name_enabled===true) 115 | { 116 | $this->use_host_name = $host_name_enabled; 117 | 118 | // check host name exist. If no host name has been specified, get the host name from the local machine, use Key value pairing. 119 | if ($host_name ==="") 120 | { 121 | $this->_host_name = "host_name=".gethostname(); 122 | } 123 | else 124 | { 125 | $this->_host_name = "host_name=".$host_name; 126 | } 127 | 128 | } 129 | else // no host name desired to appear in logs 130 | { 131 | $this->use_host_name = $host_name_enabled; 132 | $this->_host_name= ""; 133 | 134 | } 135 | 136 | // check $host_id, if it is empty "", don't leave empty, otherwise modify it as a key value pair for printing to the log event. 137 | if ($host_id==="") 138 | { 139 | $this->_host_id = ""; 140 | } 141 | else 142 | { 143 | $this->_host_id = "host_ID=".$host_id; 144 | } 145 | 146 | 147 | // Set timestamp toggle 148 | $this->add_timestamp = $add_local_timestamp; 149 | 150 | $this->persistent = $persistent; 151 | 152 | //**** possible problem here with $ssl not sending. 153 | $this->use_ssl = $ssl; 154 | 155 | // $this->use_ssl = $use_ssl; 156 | 157 | $this->severity = $severity; 158 | 159 | $this->connectionTimeout = (float) ini_get('default_socket_timeout'); 160 | } 161 | 162 | 163 | public function __destruct() 164 | { 165 | $this->closeSocket(); 166 | } 167 | 168 | 169 | public function validateToken($token){ 170 | 171 | if (empty($token) ) { 172 | throw new InvalidArgumentException('Logentries Token was not provided in logentries.php'); 173 | } 174 | } 175 | 176 | public function validateDataHubIP($datahubIPAddress) 177 | { 178 | if (empty($datahubIPAddress) ) { 179 | throw new InvalidArgumentException('Logentries Datahub IP Address was not provided in logentries.php'); 180 | } 181 | } 182 | 183 | public function closeSocket() 184 | { 185 | if (is_resource($this->resource)){ 186 | fclose($this->resource); 187 | $this->resource = null; 188 | } 189 | } 190 | 191 | public function isPersistent() 192 | { 193 | return $this->persistent; 194 | } 195 | 196 | public function isTLS() 197 | { 198 | return $this->use_ssl; 199 | } 200 | 201 | 202 | public function getToken() 203 | { 204 | return $this->_logToken; 205 | } 206 | 207 | public function getPort() 208 | { 209 | if ($this->isTLS()) 210 | { 211 | return self::LE_TLS_PORT; 212 | } 213 | elseif ($this->isDatahub() ) 214 | { 215 | return $this->_datahubPort; 216 | } 217 | else 218 | { 219 | return self::LE_PORT; 220 | } 221 | } 222 | 223 | 224 | // check if datahub is enabled 225 | public function isDatahub() 226 | { 227 | return $this->use_datahub; 228 | } 229 | 230 | 231 | public function isHostNameEnabled() 232 | { 233 | return $this->use_host_name; 234 | } 235 | 236 | 237 | public function getAddress() 238 | { 239 | if ($this->isTLS() && !$this->isDatahub() ) 240 | { 241 | return self::LE_TLS_ADDRESS; 242 | 243 | } 244 | elseif ($this->isDatahub() ) 245 | { 246 | return $this->_datahubIPAddress; 247 | } 248 | else 249 | { 250 | return self::LE_ADDRESS; 251 | } 252 | } 253 | 254 | public function isConnected() 255 | { 256 | return is_resource($this->resource) && !feof($this->resource); 257 | } 258 | 259 | private function createSocket() 260 | { 261 | $port = $this->getPort(); 262 | 263 | $address = $this->getAddress(); 264 | 265 | if ($this->isPersistent()) 266 | { 267 | $resource = $this->my_pfsockopen($port, $address); 268 | } 269 | else 270 | { 271 | $resource = $this->my_fsockopen($port, $address); 272 | } 273 | 274 | if (is_resource($resource) && !feof($resource)) 275 | { 276 | $this->resource = $resource; 277 | } 278 | } 279 | 280 | 281 | private function my_pfsockopen($port, $address) 282 | { 283 | return @pfsockopen($address, $port, $this->errno, $this->errstr, $this->connectionTimeout); 284 | } 285 | 286 | private function my_fsockopen($port, $address) 287 | { 288 | return @fsockopen($address, $port, $this->errno, $this->errstr, $this->connectionTimeout); 289 | } 290 | 291 | public function Debug($line) 292 | { 293 | $this->log($line, LOG_DEBUG); 294 | } 295 | 296 | public function Info($line) 297 | { 298 | $this->log($line, LOG_INFO); 299 | } 300 | 301 | public function Notice($line) 302 | { 303 | $this->log($line, LOG_NOTICE); 304 | } 305 | 306 | public function Warning($line) 307 | { 308 | $this->log($line, LOG_WARNING); 309 | } 310 | 311 | public function Warn($line) 312 | { 313 | $this->Warning($line); 314 | } 315 | 316 | public function Error($line) 317 | { 318 | $this->log($line, LOG_ERR); 319 | } 320 | 321 | public function Err($line) 322 | { 323 | $this->Error($line); 324 | } 325 | 326 | public function Critical($line) 327 | { 328 | $this->log($line, LOG_CRIT); 329 | } 330 | 331 | public function Crit($line) 332 | { 333 | $this->Critical($line); 334 | } 335 | 336 | public function Alert($line) 337 | { 338 | $this->log($line, LOG_ALERT); 339 | } 340 | 341 | public function Emergency($line) 342 | { 343 | $this->log($line, LOG_EMERG); 344 | } 345 | 346 | public function Emerg($line) 347 | { 348 | $this->Emergency($line); 349 | } 350 | 351 | public function log($line, $curr_severity) 352 | { 353 | $this->connectIfNotConnected(); 354 | 355 | if ($this->severity >= $curr_severity) { 356 | $prefix = ($this->add_timestamp ? $this->_getTime($curr_severity) . ' - ' : '') . $this->_getLevel($curr_severity) . ' - '; 357 | 358 | $multiline = $this->substituteNewline($line); 359 | 360 | $data = $prefix . $multiline . PHP_EOL; 361 | 362 | $this->writeToSocket($data); 363 | } 364 | } 365 | 366 | 367 | public function writeToSocket($line) 368 | { 369 | 370 | if ($this->isHostNameEnabled()) 371 | { 372 | $finalLine = $this->_logToken . " " . $this->_host_id . " " . $this->_host_name . " " . $line; 373 | } 374 | else 375 | { 376 | $finalLine = $this->_logToken . $this->_host_id . " " . $line; 377 | } 378 | 379 | 380 | if($this->isConnected()) 381 | { 382 | fputs($this->resource, $finalLine); 383 | } 384 | } 385 | 386 | 387 | private function substituteNewline($line) 388 | { 389 | $unicodeChar = chr(13); 390 | 391 | $newLine = str_replace(PHP_EOL,$unicodeChar, $line); 392 | 393 | return $newLine; 394 | } 395 | 396 | private function connectIfNotConnected() 397 | { 398 | if ($this->isConnected()){ 399 | return; 400 | } 401 | $this->connect(); 402 | } 403 | 404 | private function connect() 405 | { 406 | $this->createSocket(); 407 | } 408 | 409 | private function _getTime() 410 | { 411 | return date(self::$_timestampFormat); 412 | } 413 | 414 | private function _getLevel($level) 415 | { 416 | switch ($level) { 417 | case LOG_DEBUG: 418 | return "DEBUG"; 419 | case LOG_INFO: 420 | return "INFO"; 421 | case LOG_NOTICE: 422 | return "NOTICE"; 423 | case LOG_WARNING: 424 | return "WARN"; 425 | case LOG_ERR: 426 | return "ERROR"; 427 | case LOG_CRIT: 428 | return "CRITICAL"; 429 | case LOG_ALERT: 430 | return "ALERT"; 431 | case LOG_EMERG: 432 | return "EMERGENCY"; 433 | default: 434 | return "LOG"; 435 | } 436 | } 437 | } 438 | --------------------------------------------------------------------------------