Skip to content

Commit 6f62632

Browse files
committed
Create syslog.class.php
1 parent b40dcd8 commit 6f62632

File tree

1 file changed

+343
-0
lines changed

1 file changed

+343
-0
lines changed

syslog.class.php

Lines changed: 343 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,343 @@
1+
<?php
2+
3+
/**
4+
*
5+
* Description
6+
*
7+
* The Syslog class is a syslog client implementation in PHP
8+
* following the RFC 3164, 5424, 5425, 5426 rules.
9+
* This class is compatible with PHP logger constants for serverity and facility.
10+
*
11+
* Default value are UDP connection with RFC3164 mode.
12+
*
13+
* Facility values:
14+
* LOG_KERN kernel messages
15+
* LOG_USER user-level messages
16+
* LOG_MAIL mail system
17+
* LOG_DAEMON system daemons
18+
* LOG_AUTH security/authorization messages
19+
* LOG_SYSLOG messages generated internally by syslogd
20+
* LOG_LPR line printer subsystem
21+
* LOG_NEWS network news subsystem
22+
* LOG_UUCP UUCP subsystem
23+
* LOG_CRON clock daemon
24+
* LOG_AUTHPRIV security/authorization messages
25+
* LOG_FTP FTP daemon
26+
* LOG_NTP NTP subsystem
27+
* LOG_AUDIT log audit
28+
* LOG_LOG_ALERT log alert
29+
* LOG_CLOCK clock daemon
30+
* LOG_LOCAL0 local user 0 (local0) (default value)
31+
* LOG_LOCAL1 local user 1 (local1)
32+
* LOG_LOCAL2 local user 2 (local2)
33+
* LOG_LOCAL3 local user 3 (local3)
34+
* LOG_LOCAL4 local user 4 (local4)
35+
* LOG_LOCAL5 local user 5 (local5)
36+
* LOG_LOCAL6 local user 6 (local6)
37+
* LOG_LOCAL7 local user 7 (local7)
38+
*
39+
* Severity values:
40+
* LOG_EMERG Emergency: system is unusable
41+
* LOG_ALERT Alert: action must be taken immediately
42+
* LOG_CRIT Critical: critical conditions
43+
* LOG_ERR Error: error conditions
44+
* LOG_WARNING Warning: warning conditions
45+
* LOG_NOTICE Notice: normal but significant condition (default value)
46+
* LOG_INFO Informational: informational messages
47+
* LOG_DEBUG Debug: debug-level messages
48+
*
49+
* Protocols:
50+
* SYSLOG_UDP udp protocol. Defaut behaviour
51+
* SYSLOG_TCP tcp protocol
52+
* SYSLOG_SSL ssl protocol. CA File can optionnaly be set
53+
* SYSLOG_TLS tls protocol
54+
*
55+
*
56+
* Usage
57+
*
58+
* require_once('syslog.class.php');
59+
* $syslog = new Syslog($hostname = "", $appname = LOG_NILVALUE, $protocol = SYSLOG_UDP, $_procid = LOG_NILVALUE);
60+
* $syslog->logger($priority = LOG_LOCAL0 + LOG_NOTICE, $content = "");
61+
* or
62+
* $syslog->logger542X($priority = 133, $content = "Default content", $msgid = "-", $structured_data = "-");
63+
* or
64+
* $syslog->logger3164($priority = 133, $content = "Default content");
65+
*
66+
* Examples
67+
*
68+
* Example 1
69+
*
70+
* require_once('syslog.class.php');
71+
* $syslog = new Syslog();
72+
* $syslog->logger(LOG_LOCAL0 + LOG_NOTICE, 'Syslog message');
73+
*
74+
*
75+
* Example 2
76+
*
77+
* require_once('syslog.class.php');
78+
* $syslog = new Syslog('myserver', 'MyApp', SYSLOG_TCP);
79+
* $syslog->logger(LOG_LOCAL0 + LOG_NOTICE, 'Syslog message');
80+
*
81+
*
82+
* Example 3
83+
*
84+
* require_once('syslog.class.php');
85+
* $syslog = new Syslog();
86+
* $syslog->setHostname('myserver');
87+
* $syslog->setRFC(SYSLOG_RFC542X);
88+
* $syslog->setAppname('MyApp');
89+
* $syslog->setServer('192.168.0.12');
90+
* $syslog->logger(LOG_LOCAL0 + LOG_NOTICE, 'Syslog message');
91+
*
92+
* Example 4
93+
*
94+
* require_once('syslog.class.php');
95+
* $syslog = new Syslog("myserver", "MyApp", SYSLOG_SSL);
96+
* $syslog->setCAFile("ca.crt");
97+
* $syslog->logger(LOG_CRON + LOG_NOTICE, "Syslog message");
98+
*
99+
* Prerequisites
100+
*
101+
* - Sockets support must be enabled.
102+
* * In Linux and *nix environments, the extension is enabled at
103+
* compile time using the --enable-sockets configure option
104+
* * In Windows, PHP Sockets can be activated by un-commenting
105+
* extension=php_sockets.dll in php.ini
106+
*
107+
* Licence
108+
*
109+
* Copyright 2013 Laurent Vromman
110+
*
111+
* This program is free software: you can redistribute it and/or modify
112+
* it under the terms of the GNU LesserGeneral Public License as published by
113+
* the Free Software Foundation, either version 3 of the License, or
114+
* (at your option) any later version.
115+
*
116+
* This program is distributed in the hope that it will be useful,
117+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
118+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
119+
* GNU Lesser General Public License for more details.
120+
*
121+
* You should have received a copy of the GNU General Public License
122+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
123+
*
124+
* TODO : RFC 5848, RFC 6587, Permanent socket
125+
*
126+
*/
127+
128+
define("LOG_LINUX_NETWORD_INTERFACE", "eth0");
129+
define("LOG_NILVALUE", "-");
130+
131+
define("LOG_FTP", 88);
132+
define("LOG_NTP", 96);
133+
define("LOG_AUDIT", 104);
134+
define("LOG_ALERT", 112);
135+
define("LOG_CLOCK", 120);
136+
137+
define("SYSLOG_TCP", "tcp");
138+
define("SYSLOG_UDP", "udp");
139+
define("SYSLOG_SSL", "ssl");
140+
define("SYSLOG_TLS", "tls");
141+
// Compatibility for RFC 5424, 5425 and 5426
142+
define("SYSLOG_RFC542X", 1);
143+
define("SYSLOG_RFC3164", 0);
144+
145+
class Syslog {
146+
private $_hostname; // no embedded space, no domain name, only a-z A-Z 0-9 and other authorized characters
147+
private $_server; // Syslog destination server
148+
private $_port; // Standard syslog port is 514 or 6514 for RFC 5425 (TLS)
149+
private $_protocol; // Allow to specify between udp, tcp, ssl and tls
150+
private $_socket;
151+
private $_cafile;
152+
private $_procid;
153+
private $_appname;
154+
155+
public function Syslog($hostname = "", $appname = LOG_NILVALUE, $protocol = SYSLOG_UDP, $procid = LOG_NILVALUE) {
156+
$this->_rfc = SYSLOG_RFC3164;
157+
$this->_socket = FALSE;
158+
$this->_server = '127.0.0.1';
159+
$this->setProcid($procid);
160+
161+
$this->setAppname($appname);
162+
163+
$this->_hostname = $hostname;
164+
if (strlen($hostname) == 0) {
165+
if (isset($_SERVER["SERVER_NAME"])) {
166+
$hostname = $_SERVER["SERVER_NAME"];
167+
if($this->_rfc == SYSLOG_RFC3164)
168+
$hostname = substr($hostname, 0, strpos($hostname.".", "."));
169+
}
170+
elseif (isset($_SERVER["SERVER_ADDR"])) {
171+
$hostname = $_SERVER["SERVER_ADDR"];
172+
}
173+
else {
174+
if($this->_rfc == SYSLOG_RFC3164)
175+
$hostname = "server";
176+
else
177+
$hostname = LOG_NILVALUE;
178+
}
179+
}
180+
$this->setHostname($hostname);
181+
182+
$this->setProtocol($protocol);
183+
if (!in_array($this->_protocol, array(SYSLOG_UDP, SYSLOG_TCP, SYSLOG_SSL, SYSLOG_TLS))) {
184+
$this->_protocol = SYSLOG_UDP;
185+
}
186+
// RFC5425
187+
if($this->_protocol == SYSLOG_TLS)
188+
$this->_port = 6514;
189+
else
190+
$this->_port = 514;
191+
}
192+
193+
private function getServerAddress() {
194+
if(array_key_exists('SERVER_ADDR', $_SERVER))
195+
return $_SERVER['SERVER_ADDR'];
196+
elseif(array_key_exists('LOCAL_ADDR', $_SERVER))
197+
return $_SERVER['LOCAL_ADDR'];
198+
else {
199+
// Running CLI
200+
if(stristr(PHP_OS, 'WIN')) {
201+
return gethostbyname(php_uname("n"));
202+
} else {
203+
$ifconfig = shell_exec('/sbin/ifconfig '.LOG_LINUX_NETWORD_INTERFACE);
204+
preg_match('/addr:([\d\.]+)/', $ifconfig, $match);
205+
return $match[1];
206+
}
207+
}
208+
}
209+
210+
public function setRFC($rfc) {
211+
$this->_rfc = $rfc;
212+
}
213+
214+
public function setHostname($hostname) {
215+
$this->_hostname = substr($hostname, 0, 255);
216+
if(strlen($this->_hostname) == 0) $this->_hostname = LOG_NILVALUE;
217+
}
218+
219+
public function setServer($server) {
220+
$this->_server = $server;
221+
}
222+
223+
public function setPort($port) {
224+
if ((intval($port) > 0) && (intval($port) < 65536)) {
225+
$this->_port = intval($port);
226+
}
227+
}
228+
229+
public function setProtocol($protocol) {
230+
if (in_array($protocol, array(SYSLOG_UDP, SYSLOG_TCP, SYSLOG_SSL, SYSLOG_TLS))) {
231+
$this->_protocol = $protocol;
232+
}
233+
}
234+
235+
public function setCAFile($cafile) {
236+
$this->_cafile = $cafile;
237+
}
238+
239+
public function setProcid($procid) {
240+
$this->_procid = substr($procid, 0, 128);
241+
if(strlen($this->_procid) == 0) $this->_procid = LOG_NILVALUE;
242+
}
243+
244+
public function setAppname($appname) {
245+
$this->_appname = substr($appname, 0, 48);
246+
if(strlen($this->_appname) == 0) $this->_appname = LOG_NILVALUE;
247+
}
248+
249+
private function openSocket () {
250+
if ($this->_socket)
251+
$this->closeSocket();
252+
$contextOptions = array();;
253+
254+
if($this->_protocol == SYSLOG_SSL && $this->_cafile != NULL) {
255+
//http://php.net/manual/en/context.ssl.php
256+
$contextOptions = array(
257+
'ssl' => array(
258+
'cafile' => $this->_cafile
259+
)
260+
);
261+
}
262+
$sslContext = stream_context_create($contextOptions);
263+
264+
$this->_socket = stream_socket_client($this->_protocol."://".$this->_server.":".$this->_port, $errno, $errstr, ini_get("default_socket_timeout"), STREAM_CLIENT_CONNECT, $sslContext);
265+
266+
if (!$this->_socket) {
267+
throw new Exception("ERROR: $errno - $errstr");
268+
}
269+
}
270+
271+
private function closeSocket () {
272+
fclose($this->_socket);
273+
$this->_socket = NULL;
274+
}
275+
276+
public function logger3164($priority = 133, $content = "Default content") {
277+
$rfc = $this->_rfc;
278+
$this->_rfc = SYSLOG_RFC3164;
279+
$this->logger($priority, $content);
280+
$this->_rfc = $rfc;
281+
}
282+
283+
public function logger542X($priority = 133, $content = "Default content", $msgid = "-", $structured_data = "-") {
284+
$rfc = $this->_rfc;
285+
$this->_rfc = SYSLOG_RFC542X;
286+
$this->logger($priority, $content, $msgid = "-", $structured_data);
287+
$this->_rfc = $rfc;
288+
}
289+
290+
public function logger($priority = 133, $content = "Default content", $msgid = "-", $structured_data = "-") {
291+
$this->_content = $content;
292+
293+
if(strlen($msgid) == 0) $msgid = LOG_NILVALUE;
294+
if(strlen($structured_data) == 0) $structured_data = LOG_NILVALUE;
295+
296+
$facility = floor($priority/8);
297+
$severity = $priority - $facility * 8;
298+
if (0 > $severity || $severity > 7) {
299+
throw new Exception("ERROR: unrecognized severity value : $severity");
300+
}
301+
302+
if (0 > $facility || $facility > 23) {
303+
throw new Exception("ERROR: unrecognized facility value : $facility");
304+
}
305+
306+
$timestamp = date("c");
307+
308+
$pri = "<$priority>";
309+
if($this->_rfc == SYSLOG_RFC542X) {
310+
$timestamp = date("c");
311+
$syslog_version = "1 ";
312+
}
313+
else {
314+
$actualtime = time();
315+
$timestamp = date("M ", $actualtime).substr(date(" j", $actualtime), -2).date(" H:i:s", $actualtime);
316+
$syslog_version = "";
317+
}
318+
$header = $pri.$syslog_version.$timestamp." ".$this->_hostname." ";
319+
if($this->_rfc == SYSLOG_RFC542X) {
320+
$header .= $this->_appname." ".$this->_procid." ".substr($msgid, 0, 32);
321+
$message = $header. " ".$structured_data." ".$content;
322+
}
323+
else {
324+
// RFC 3164 : Tagname max len : 32
325+
// RFC 3164 : Message max len : 1024
326+
if(strlen($this->_appname) > 0)
327+
$tag = substr($this->_appname, 0 , 32).": ";
328+
$message = substr($header.$tag.$content, 0, 1024);
329+
}
330+
331+
$this->openSocket();
332+
333+
// RFC 5425
334+
if($this->_rfc == SYSLOG_RFC542X && $this->protocol == SYSLOG_TLS) {
335+
$message = strlen($message)." ".$message;
336+
}
337+
338+
fwrite($this->_socket, $message);
339+
340+
$this->closeSocket();
341+
}
342+
}
343+
?>

0 commit comments

Comments
 (0)