establishConnection(); } catch (PDOException $e) { $this->warn("Failed connecting to database. Closing appender. Error: " . $e->getMessage()); $this->close(); return; } // Parse the insert patterns; pattern parts are comma delimited $pieces = explode(',', $this->insertPattern); $converterMap = LoggerLayoutPattern::getDefaultConverterMap(); foreach($pieces as $pattern) { $parser = new LoggerPatternParser($pattern, $converterMap); $this->converters[] = $parser->parse(); } $this->closed = false; } /** * Connects to the database, and prepares the insert query. * @throws PDOException If connect or prepare fails. */ protected function establishConnection() { // Acquire database connection $this->db = new PDO($this->dsn, $this->user, $this->password); $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Prepare the insert statement $insertSQL = str_replace('__TABLE__', $this->table, $this->insertSQL); $this->preparedInsert = $this->db->prepare($insertSQL); } /** * Appends a new event to the database. * * If writing to database fails, it will retry by re-establishing the * connection up to $reconnectAttempts times. If writing still fails, * the appender will close. */ public function append(LoggerLoggingEvent $event) { for ($attempt = 1; $attempt <= $this->reconnectAttempts + 1; $attempt++) { try { // Attempt to write to database $this->preparedInsert->execute($this->format($event)); $this->preparedInsert->closeCursor(); break; } catch (PDOException $e) { $this->warn("Failed writing to database: ". $e->getMessage()); // Close the appender if it's the last attempt if ($attempt > $this->reconnectAttempts) { $this->warn("Failed writing to database after {$this->reconnectAttempts} reconnect attempts. Closing appender."); $this->close(); // Otherwise reconnect and try to write again } else { $this->warn("Attempting a reconnect (attempt $attempt of {$this->reconnectAttempts})."); $this->establishConnection(); } } } } /** * Converts the logging event to a series of database parameters by using * the converter chain which was set up on activation. */ protected function format(LoggerLoggingEvent $event) { $params = array(); foreach($this->converters as $converter) { $buffer = ''; while ($converter !== null) { $converter->format($buffer, $event); $converter = $converter->next; } $params[] = $buffer; } return $params; } /** * Closes the connection to the logging database */ public function close() { // Close the connection (if any) $this->db = null; // Close the appender $this->closed = true; } // ****************************************** // *** Accessor methods *** // ****************************************** /** * Returns the active database handle or null if not established. * @return PDO */ public function getDatabaseHandle() { return $this->db; } /** Sets the username. */ public function setUser($user) { $this->setString('user', $user); } /** Returns the username. */ public function getUser($user) { return $this->user; } /** Sets the password. */ public function setPassword($password) { $this->setString('password', $password); } /** Returns the password. */ public function getPassword($password) { return $this->password; } /** Sets the insert SQL. */ public function setInsertSQL($sql) { $this->setString('insertSQL', $sql); } /** Returns the insert SQL. */ public function getInsertSQL($sql) { return $this->insertSQL; } /** Sets the insert pattern. */ public function setInsertPattern($pattern) { $this->setString('insertPattern', $pattern); } /** Returns the insert pattern. */ public function getInsertPattern($pattern) { return $this->insertPattern; } /** Sets the table name. */ public function setTable($table) { $this->setString('table', $table); } /** Returns the table name. */ public function getTable($table) { return $this->table; } /** Sets the DSN string. */ public function setDSN($dsn) { $this->setString('dsn', $dsn); } /** Returns the DSN string. */ public function getDSN($dsn) { return $this->setString('dsn', $dsn); } }