You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4php-dev@logging.apache.org by gr...@apache.org on 2009/05/07 08:29:31 UTC
svn commit: r772512 - in /incubator/log4php/trunk/src:
main/php/LoggerManager.php main/php/appenders/LoggerAppenderPDO.php
test/php/appenders/LoggerAppenderPDOTest.php
Author: grobmeier
Date: Thu May 7 06:29:28 2009
New Revision: 772512
URL: http://svn.apache.org/viewvc?rev=772512&view=rev
Log:
#LOG4PHP-30: Added new appender which uses the the PDO extension (plus test)
Added:
incubator/log4php/trunk/src/main/php/appenders/LoggerAppenderPDO.php
incubator/log4php/trunk/src/test/php/appenders/LoggerAppenderPDOTest.php
Modified:
incubator/log4php/trunk/src/main/php/LoggerManager.php
Modified: incubator/log4php/trunk/src/main/php/LoggerManager.php
URL: http://svn.apache.org/viewvc/incubator/log4php/trunk/src/main/php/LoggerManager.php?rev=772512&r1=772511&r2=772512&view=diff
==============================================================================
--- incubator/log4php/trunk/src/main/php/LoggerManager.php (original)
+++ incubator/log4php/trunk/src/main/php/LoggerManager.php Thu May 7 06:29:28 2009
@@ -61,6 +61,7 @@
'LoggerRoot' => '/LoggerRoot.php',
'LoggerAppender' => '/LoggerAppender.php',
'LoggerAppenderAdodb' => '/appenders/LoggerAppenderAdodb.php',
+ 'LoggerAppenderPDO' => '/appenders/LoggerAppenderPDO.php',
'LoggerAppenderConsole' => '/appenders/LoggerAppenderConsole.php',
'LoggerAppenderDailyFile' => '/appenders/LoggerAppenderDailyFile.php',
'LoggerAppenderDb' => '/appenders/LoggerAppenderDb.php',
Added: incubator/log4php/trunk/src/main/php/appenders/LoggerAppenderPDO.php
URL: http://svn.apache.org/viewvc/incubator/log4php/trunk/src/main/php/appenders/LoggerAppenderPDO.php?rev=772512&view=auto
==============================================================================
--- incubator/log4php/trunk/src/main/php/appenders/LoggerAppenderPDO.php (added)
+++ incubator/log4php/trunk/src/main/php/appenders/LoggerAppenderPDO.php Thu May 7 06:29:28 2009
@@ -0,0 +1,206 @@
+<?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 = '';
+
+ /** Name of the database to connect to */
+ private $database;
+
+ /** 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.
+ */
+ public function activateOptions() {
+ $this->db = new PDO($this->dsn,$this->password,$this->password);
+
+ if($this->db == null) {
+ $this->db = null;
+ $this->closed = true;
+ $this->canAppend = false;
+ return;
+ // TODO throw exception instead?
+ }
+
+ // 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 = LoggerLayout::factory('LoggerPatternLayout');
+ $this->layout->setConversionPattern($this->sql);
+ $this->canAppend = true;
+ return true;
+ }
+
+ /**
+ * Appends a new event to the database using the sql format.
+ */
+ 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($newUser) {
+ $this->user = $newUser;
+ }
+
+ /**
+ * Sets the password for this connection.
+ * Defaults to ''
+ */
+ public function setPassword($newPassword) {
+ $this->password = $newPassword;
+ }
+
+ /**
+ * 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;
+ }
+}
+
Added: incubator/log4php/trunk/src/test/php/appenders/LoggerAppenderPDOTest.php
URL: http://svn.apache.org/viewvc/incubator/log4php/trunk/src/test/php/appenders/LoggerAppenderPDOTest.php?rev=772512&view=auto
==============================================================================
--- incubator/log4php/trunk/src/test/php/appenders/LoggerAppenderPDOTest.php (added)
+++ incubator/log4php/trunk/src/test/php/appenders/LoggerAppenderPDOTest.php Thu May 7 06:29:28 2009
@@ -0,0 +1,64 @@
+<?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.
+ *
+ * @category tests
+ * @package log4php
+ * @subpackage appenders
+ * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
+ * @version SVN: $Id$
+ * @link http://logging.apache.org/log4php
+ */
+
+class LoggerAppenderPDOTest extends PHPUnit_Framework_TestCase {
+
+ public function testSimpleLogging() {
+ $event = new LoggerLoggingEvent("LoggerAppenderPDOTest", new Logger("TEST"), LoggerLevel::getLevelError(), "testmessage");
+
+ $dbname = 'appenders/pdotest.sqlite';
+ try {
+ $database = new SQLiteDatabase($dbname);
+ $database = null;
+
+ $appender = new LoggerAppenderPDO("myname");
+ $appender->setDSN('sqlite:'.$dbname);
+ $appender->setCreateTable(true);
+ $appender->activateOptions();
+ $appender->append($event);
+
+
+ $db = $appender->getDatabaseHandle();
+ $q = "select * from log4php_log";
+ $error = "";
+ if($result = $db->query($q, SQLITE_BOTH, $error)) {
+ while($row = $result->fetch()) {
+ self::assertEquals($row['1'], 'TEST');
+ self::assertEquals($row['2'], 'ERROR');
+ self::assertEquals($row['3'], 'testmessage');
+ }
+ } else {
+ // todo propagate exception to phpunit
+ self::assertTrue(false);
+ }
+ $appender->close();
+ } catch(Exception $e) {
+ // todo propagate exception to phpunit
+ self::assertTrue(false);
+ }
+ unlink($dbname);
+ }
+
+}
Re: svn commit: r772512 - in /incubator/log4php/trunk/src:
main/php/LoggerManager.php main/php/appenders/LoggerAppenderPDO.php
test/php/appenders/LoggerAppenderPDOTest.php
Posted by Christian Hammers <ch...@lathspell.de>.
On Tue, 19 May 2009 06:51:05 +0200
Christian Grobmeier <gr...@gmail.com> wrote:
> Hi Christian,
>
> > I've not read the code completely but shouldn't there be a quote() or
> > something around the insert statement? Although this is just the
> > template, the single quote indicate at least that $sth->quote() is
> > not used.
>
> i am not sure what you mean with the above?
I fear that if I log a message that contains a single quote the SQL
query you build will produce an SQL syntax error.
The quote() function (http://de2.php.net/manual/en/pdo.quote.php)
puts backslashes before every quote and then a pair of single quotes
around the result so you would have the diff:
- VALUES ('%d','%c','%p','%m','%t','%F','%L')";
+ VALUES (%d,%c,%p,%m,%t,%F,%L)";
> > BTW, as you're aiming for speed, did you consider a PDO Prepared
> > Statement?
>
> you are right, a PS would fit better in most cases. If you have some
> cycles, I would apply all patches you bring in :-)
Hm.. I try to find time but don't be too optimistic :)
bye,
-christian-
> Cheers,
> Christian
>
> >
> > bye,
> >
> > -christian-
> >
> >
> > Am Thu, 07 May 2009 06:29:31 -0000
> > schrieb grobmeier@apache.org:
> >
> >> Author: grobmeier
> >> Date: Thu May 7 06:29:28 2009
> >> New Revision: 772512
> > ...
> >> + public function activateOptions() {
> > ...
> >> +
> >> + 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')";
> >> + }
> >> +
> >
Re: svn commit: r772512 - in /incubator/log4php/trunk/src:
main/php/LoggerManager.php main/php/appenders/LoggerAppenderPDO.php
test/php/appenders/LoggerAppenderPDOTest.php
Posted by Christian Grobmeier <gr...@gmail.com>.
Hi Christian,
> I've not read the code completely but shouldn't there be a quote() or
> something around the insert statement? Although this is just the
> template, the single quote indicate at least that $sth->quote() is
> not used.
i am not sure what you mean with the above?
> BTW, as you're aiming for speed, did you consider a PDO Prepared
> Statement?
you are right, a PS would fit better in most cases. If you have some
cycles, I would apply all patches you bring in :-)
Cheers,
Christian
>
> bye,
>
> -christian-
>
>
> Am Thu, 07 May 2009 06:29:31 -0000
> schrieb grobmeier@apache.org:
>
>> Author: grobmeier
>> Date: Thu May 7 06:29:28 2009
>> New Revision: 772512
> ...
>> + public function activateOptions() {
> ...
>> +
>> + 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')";
>> + }
>> +
>
Re: svn commit: r772512 - in /incubator/log4php/trunk/src:
main/php/LoggerManager.php main/php/appenders/LoggerAppenderPDO.php
test/php/appenders/LoggerAppenderPDOTest.php
Posted by Christian Hammers <ch...@lathspell.de>.
Hello
I've not read the code completely but shouldn't there be a quote() or
something around the insert statement? Although this is just the
template, the single quote indicate at least that $sth->quote() is
not used.
BTW, as you're aiming for speed, did you consider a PDO Prepared
Statement?
bye,
-christian-
Am Thu, 07 May 2009 06:29:31 -0000
schrieb grobmeier@apache.org:
> Author: grobmeier
> Date: Thu May 7 06:29:28 2009
> New Revision: 772512
...
> + public function activateOptions() {
...
> +
> + 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')";
> + }
> +