LoggerAppenderPDO.php
6.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
<?php
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Appends log events to a db table using PDO
*
* <p>This appender uses a table in a database to log events.</p>
* <p>Parameters are {@link $host}, {@link $user}, {@link $password},
* {@link $database}, {@link $createTable}, {@link $table} and {@link $sql}.</p>
*
* @package log4php
* @subpackage appenders
* @since 2.0
*/
class LoggerAppenderPDO extends LoggerAppender {
/** Create the log table if it does not exists (optional). */
private $createTable = true;
/** Database user name */
private $user = '';
/** Database password */
private $password = '';
/** DSN string for enabling a connection */
private $dsn;
/** A {@link LoggerPatternLayout} string used to format a valid insert query (mandatory) */
private $sql;
/** Table name to write events. Used only if {@link $createTable} is true. */
private $table = 'log4php_log';
/** The instance */
private $db = null;
/** boolean used to check if all conditions to append are true */
private $canAppend = true;
/**
* Constructor.
* This apender doesn't require a layout.
* @param string $name appender name
*/
function __construct($name) {
parent::__construct($name);
$this->requiresLayout = false;
}
/**
* Setup db connection.
* Based on defined options, this method connects to db defined in {@link $dsn}
* and creates a {@link $table} table if {@link $createTable} is true.
* @return boolean true if all ok.
* @throws a PDOException if the attempt to connect to the requested database fails.
*/
public function activateOptions() {
if($this->user === null) {
$this->db = new PDO($this->dsn);
} else if($this->password === null) {
$this->db = new PDO($this->dsn, $this->user);
} else {
$this->db = new PDO($this->dsn,$this->user,$this->password);
}
// test if log table exists
$result = $this->db->query('select * from ' . $this->table . ' where 1 = 0');
if ($result == false and $this->createTable) {
// TODO mysql syntax?
$query = "CREATE TABLE {$this->table} ( timestamp varchar(32)," .
"logger varchar(32)," .
"level varchar(32)," .
"message varchar(64)," .
"thread varchar(32)," .
"file varchar(64)," .
"line varchar(4) );";
$result = $this->db->query($query);
if (!$result) {
$this->canAppend = false;
return;
// TODO throw exception?
}
}
if($this->sql == '' || $this->sql == null) {
$this->sql = "INSERT INTO $this->table ( timestamp, " .
"logger, " .
"level, " .
"message, " .
"thread, " .
"file, " .
"line" .
") VALUES ('%d','%c','%p','%m','%t','%F','%L')";
}
$this->layout = LoggerReflectionUtils::createObject('LoggerLayoutPattern');
$this->layout->setConversionPattern($this->sql);
$this->canAppend = true;
return true;
}
/**
* Appends a new event to the database using the sql format.
*/
// TODO:should work with prepared statement
public function append($event) {
if ($this->canAppend) {
$query = $this->layout->format($event);
$this->db->exec($query);
}
}
/**
* Closes the connection to the logging database
*/
public function close() {
if ($this->db !== null) {
$db = null;
}
$this->closed = true;
}
/**
* Indicator if the logging table should be created on startup,
* if its not existing.
*/
public function setCreateTable($flag) {
$this->createTable = LoggerOptionConverter::toBoolean($flag, true);
}
/**
* Sets the username for this connection.
* Defaults to ''
*/
function setUser($user) {
$this->user = $user;
}
/**
* Sets the password for this connection.
* Defaults to ''
*/
public function setPassword($password) {
$this->password = $password;
}
/**
* Sets the SQL string into which the event should be transformed.
* Defaults to:
*
* INSERT INTO $this->table
* ( timestamp, logger, level, message, thread, file, line)
* VALUES
* ('%d','%c','%p','%m','%t','%F','%L')
*
* It's not necessary to change this except you have customized logging'
*/
public function setSql($sql) {
$this->sql = $sql;
}
/**
* Sets the tablename to which this appender should log.
* Defaults to log4php_log
*/
public function setTable($table) {
$this->table = $table;
}
/**
* Sets the DSN string for this connection. In case of
* SQLite it could look like this: 'sqlite:appenders/pdotest.sqlite'
*/
public function setDSN($dsn) {
$this->dsn = $dsn;
}
/**
* Sometimes databases allow only one connection to themselves in one thread.
* SQLite has this behaviour. In that case this handle is needed if the database
* must be checked for events
*/
public function getDatabaseHandle() {
return $this->db;
}
}