Skip to content

Commit

Permalink
Merge pull request #15 from BenceSzalai/master
Browse files Browse the repository at this point in the history
Feature to limit the maximum number of rows to keep in the log table
  • Loading branch information
BenceSzalai authored Oct 15, 2020
2 parents 86b3bd6 + b9963e0 commit af72d5f
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 37 deletions.
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased v2]

## [2.1.0] - 2020-10-15
### Added
- Feature to limit the maximum number of rows to keep in the log table. Use `set_max_table_rows()` method on the handler instance to configure the limit.

### Improved
- README.md now has a section about v2 and v1 differences.

## [2.0.1] - 2020-10-15
### Fixed
- Limitations of WordPressHandler regarding formatters, whereas formatted data was only respected in the 'extra' part of the records, but not for 'message' or 'context' (https://github.com/bradmkjr/monolog-wordpress/issues/11). **Note:** the time column still does not follow the formatted datetime to keep compatibility with existing deployments.
Expand Down Expand Up @@ -50,7 +57,8 @@ V1 is continued to be updated for continued support for Monolog v1 and PHP versi
No changelog had been maintained up to this point. Refer to the GIT commit history for more details.


[Unreleased v2]: https://github.com/bradmkjr/monolog-wordpress/compare/2.0.1...HEAD
[Unreleased v2]: https://github.com/bradmkjr/monolog-wordpress/compare/2.1.0...HEAD
[2.1.0]: https://github.com/bradmkjr/monolog-wordpress/tree/2.1.0
[2.0.1]: https://github.com/bradmkjr/monolog-wordpress/tree/2.0.1
[2.0.0]: https://github.com/bradmkjr/monolog-wordpress/tree/2.0.0
[v1 changes after v2 release]: https://github.com/bradmkjr/monolog-wordpress/compare/1.6.4...v2
Expand Down
76 changes: 42 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ monolog-wordpress
=============

WordPress Handler for Monolog, which allows to store log messages in a MySQL Table.
It can log text messages to a specific table, and creates the table automatically if it does not exist.
It can log text messages to a specific table, and create the table automatically if it does not exist.
The class further allows to dynamically add extra attributes, which are stored in a separate database field, and can be used for later analyzing and sorting.

Original based on:
Expand All @@ -15,9 +15,16 @@ This is a very simple handler for monolog. This version works for custom plugin
monolog-wordpress is available via composer. Just add the following line to your required section in composer.json and do a `php composer.phar update` or your choice of composer update method.

```
"bradmkjr/monolog-wordpress": "^2.0.0"
"bradmkjr/monolog-wordpress": "^2.1.0"
```

# Versions
Since Monolog v2 broke compatibility with PHP versions before v7.1 some may want to keep using Monolog v1. **monolog-wordpress** is therefore offered in two major versions:
* [v1](https://github.com/bradmkjr/monolog-wordpress/tree/v1) - compatible with Monolog v1 and PHP v5.3 or later.
* [v2](https://github.com/bradmkjr/monolog-wordpress/tree/master) - compatible with Monolog v2 and PHP v7.1 or later.

Apart from the compatibility differences stated above the features of v1 and v2 are going to be kept the same as much as possible.

# Usage
Just use it as any other Monolog Handler, push it to the stack of your Monolog Logger instance. The Handler however needs some parameters:

Expand All @@ -31,33 +38,36 @@ Just use it as any other Monolog Handler, push it to the stack of your Monolog L
Given that $wpdb is your database instance, you could use the class as follows:

```php
//Import class
// Import class
use WordPressHandler\WordPressHandler;

//ensure access to global $wpdb

// Ensure access to global $wpdb
global $wpdb;

//Create WordPressHandler
// Create WordPressHandler
$wordPressHandler = new WordPressHandler($wpdb, "log", array('username', 'userid'), \Monolog\Logger::DEBUG);

// setup array of extra fields
// Configure maximum number of rows to keep (old entries are deleted when reached)
$wordPressHandler->set_max_table_rows( 250000 );

// Setup array of extra fields
$record = ['extra' => []];

// creates database table if needed, add extra fields from above
// Create database table if needed, add extra fields from above
$wordPressHandler->initialize($record);

// Create Logger
$context = 'channel-name';

//Create logger
$logger = new \Monolog\Logger($context);

// Add WordPressHandler as the Handler for the Logger
$logger->pushHandler($wordPressHandler);

//Now you can use the logger, and further attach additional information
// Now you can use the logger, and further attach additional information
$logger->addWarning("This is a great message, woohoo!", array('username' => 'John Doe', 'userid' => 245));
```

Required code to setup tables on plugin activation:
Required code to set up tables on plugin activation:

```php
require __DIR__.'/vendor/autoload.php';
Expand Down Expand Up @@ -115,29 +125,27 @@ Example to use in your custom WordPress Plugin

```php
add_action( 'plugins_loaded', 'demo_function' );

function demo_function(){

require __DIR__ . '/vendor/autoload.php';

//Import class
use WordPressHandler\WordPressHandler;

//ensure access to global $wpdb
global $wpdb;

//Create WordPressHandler
$wordPressHandler = new WordPressHandler($wpdb, "log", array('app', 'version'), \Monolog\Logger::DEBUG);

$context = 'test-plugin-logging';

//Create logger
$logger = new \Monolog\Logger($context);
$logger->pushHandler($wordPressHandler);

//Now you can use the logger, and further attach additional information
$logger->addWarning("This is a great message, woohoo!", array('app' => 'Test Plugin', 'version' => '2.4.5'));

require __DIR__ . '/vendor/autoload.php';

// Import class
use WordPressHandler\WordPressHandler;

// Ensure access to global $wpdb
global $wpdb;

// Create WordPressHandler
$wordPressHandler = new WordPressHandler($wpdb, "log", array('app', 'version'), \Monolog\Logger::DEBUG);

// Create logger
$context = 'test-plugin-logging';
$logger = new \Monolog\Logger($context);

// Add WordPressHandler as the Handler for the Logger
$logger->pushHandler($wordPressHandler);

// Now you can use the logger, and further attach additional information
$logger->addWarning("This is a great message, woohoo!", array('app' => 'Test Plugin', 'version' => '2.4.5'));
}
```

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"keywords": ["wordpress", "log", "logging", "monolog", "mysql", "database"],
"homepage": "https://github.com/bradmkjr/monolog-wordpress",
"license": "MIT",
"version": "2.0.1",
"version": "2.1.0",
"authors": [
{
"name": "Bradford Knowlton",
Expand Down
41 changes: 40 additions & 1 deletion src/WordPressHandler/WordPressHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ class WordPressHandler extends AbstractProcessingHandler
* as the values are stored in the column name $field.
*/
private $additionalFields = array();
/**
* @var int defines the maximum number of rows allowed in the log table. 0 means no limit
*/
protected $max_table_rows = 0;
/**
* Constructor of this class, sets the PDO and calls parent constructor
*
Expand All @@ -67,6 +71,15 @@ public function __construct(
$this->additionalFields = $additionalFields;
parent::__construct($level, $bubble);
}
/**
* Set the limit of maximum number of table rows to collect.
* Use 0 (or any negative number) to disable limit.
*
* @param int $max_table_rows
*/
public function set_max_table_rows( int $max_table_rows ) {
$this->max_table_rows = max( 0, $max_table_rows );
}
/**
* Returns the full log tables name
*
Expand Down Expand Up @@ -132,6 +145,32 @@ public function uninitialize()
if (!is_null($this->wpdb)) {
$this->wpdb->query($sql);
}
}
/**
* Deletes the oldest records from the log table to ensure there are no more
* rows than the defined limit.
*
* Use {@see set_max_table_rows()} to configure the limit!
*
* @return boolean True if rows were deleted, false otherwise.
*/
public function maybe_truncate() {
if ( $this->max_table_rows <= 0 ) {
return false;
}

$table_name = $this->get_table_name();

$sql = "SELECT count(*) FROM {$table_name};";
$count = $this->wpdb->get_var($sql);

if ( is_numeric( $count ) && $this->max_table_rows <= (int) $count ) {
// using `LIMIT -1`, `LIMIT 0`, `LIMIT NULL` may not be compatible with all db systems
// deleting 10000 rows in one go is good enough anyway, it'll converge pretty fast
$sql = "DELETE FROM {$table_name} WHERE `id` IN ( SELECT * FROM (SELECT `id` FROM {$table_name} ORDER BY `id` DESC LIMIT 10000 OFFSET {$this->max_table_rows}) as `workaround_subquery_for_older_mysql_versions` );";
return false !== $this->wpdb->query($sql);
}
return false;
}
/**
* Writes the record down to the log of the implementing handler
Expand Down Expand Up @@ -178,6 +217,6 @@ protected function write(array $record): void
$table_name = $this->get_table_name();

$this->wpdb->insert( $table_name, $contentArray );

$this->maybe_truncate();
}
}

0 comments on commit af72d5f

Please sign in to comment.