diff --git a/CHANGELOG.md b/CHANGELOG.md
index 838f8bdf3a43f71a6ba624bc524f7f5ace3eafd1..a295bc383ae017f0295842a618feca2ccdf99be2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## [1.12.0] - 2023-07-10
+### Added
+- sensitive data replacer
+
 ## [1.11.0] - 2023-07-10
 ### Updated
 - monolog to 2.9.1
diff --git a/composer.json b/composer.json
index f94603a76874276f3f2aa725ba298f33494673e6..cdfb1a7fa2f3d526def26c95ce987b1bd478c655 100644
--- a/composer.json
+++ b/composer.json
@@ -8,22 +8,23 @@
     ],
 	"config": {
 		"platform": {
-			"php": "7.2"
+			"php": "7.4"
 		},
         "allow-plugins": {
             "dealerdirect/phpcodesniffer-composer-installer": true
         }
 	},
 	"require": {
-        "php": ">=7.2|^8",
+        "php": ">=7.4|^8",
         "psr/log": "^1",
         "monolog/monolog": "^2.9.1",
         "wpdesk/wp-notice": "^3.0"
     },
     "require-dev": {
-        "phpunit/phpunit": "^5",
+        "phpunit/phpunit": "^5|^6|^7|^8|^9",
         "squizlabs/php_codesniffer": "^3.0.2",
-		"wpdesk/wp-code-sniffer": "^1.2.3"
+		"wpdesk/wp-code-sniffer": "^1.2.3",
+        "10up/wp_mock": "^1.0"
     },
     "autoload": {
         "psr-4": {"WPDesk\\Logger\\": "src/"}
diff --git a/src/Processor/SensitiveDataProcessor.php b/src/Processor/SensitiveDataProcessor.php
new file mode 100644
index 0000000000000000000000000000000000000000..f0b6b82c0d4d1f1760e5909baa9bbdec889281dc
--- /dev/null
+++ b/src/Processor/SensitiveDataProcessor.php
@@ -0,0 +1,51 @@
+<?php
+
+namespace WPDesk\Logger\Processor;
+
+use Monolog\Processor\ProcessorInterface;
+
+/**
+ * Can replace data in log.
+ * Ie. sensitive data.
+ *
+ * @package WPDesk\Logger\Processor
+ */
+class SensitiveDataProcessor implements ProcessorInterface {
+
+	/**
+	 * Replace array.
+	 *
+	 * @var array
+	 */
+	private array $replace;
+
+	public function __construct( array $replace ) {
+		$this->replace = $replace;
+	}
+
+	public function __invoke( array $record ): array {
+		return $this->replace_array( $record );
+	}
+
+	private function replace_array( array $value ): array {
+		foreach ( $value as $key => $item ) {
+			if ( is_array( $item ) ) {
+				$value[ $key ] = $this->replace_array( $item );
+			}
+			if ( is_string( $item ) ) {
+				$value[ $key ] = $this->replace( $item );
+			}
+		}
+
+		return $value;
+	}
+
+	private function replace( string $value ): string {
+		foreach ( $this->replace as $search => $replace ) {
+			$value = str_replace( $search, $replace, $value );
+		}
+
+		return $value;
+	}
+
+}
diff --git a/tests/unit/Processor/TestSensitiveDataProcessor.php b/tests/unit/Processor/TestSensitiveDataProcessor.php
new file mode 100644
index 0000000000000000000000000000000000000000..8bc6444fe1571bd63821023a71acaa972049ea2f
--- /dev/null
+++ b/tests/unit/Processor/TestSensitiveDataProcessor.php
@@ -0,0 +1,54 @@
+<?php
+
+namespace unit\Processor;
+
+use WP_Mock;
+use WP_Mock\Tools\TestCase;
+use WPDesk\Logger\Processor\SensitiveDataProcessor;
+
+class TestSensitiveDataProcessor extends TestCase
+{
+
+	public function setUp(): void {
+		WP_Mock::setUp();
+	}
+
+	public function tearDown(): void {
+		WP_Mock::tearDown();
+	}
+
+	public function testShouldReplaceWhenMatched() {
+		$processor = new SensitiveDataProcessor( array( 'password' => '***' ) );
+		$record = array(
+			'password' => 'password',
+			'array' => array(
+				'password' => 'password',
+			),
+		);
+		$expected = array(
+			'password' => '***',
+			'array' => array(
+				'password' => '***',
+			),
+		);
+		$this->assertEquals( $expected, $processor->__invoke( $record ) );
+	}
+
+	public function testShouldNotReplaceWhenNotMatched() {
+		$processor = new SensitiveDataProcessor( array( 'password' => '***' ) );
+		$record = array(
+			'text' => 'text',
+			'array' => array(
+				'text' => 'text',
+			),
+		);
+		$expected = array(
+			'text' => 'text',
+			'array' => array(
+				'text' => 'text',
+			),
+		);
+		$this->assertEquals( $expected, $processor->__invoke( $record ) );
+	}
+
+}
diff --git a/tests/unit/bootstrap.php b/tests/unit/bootstrap.php
index 575b33bd7df4416b1684dcd7b22e6b5beb4760c6..cb597776ea4e7f538a8aaaeed8700498ffcb8418 100644
--- a/tests/unit/bootstrap.php
+++ b/tests/unit/bootstrap.php
@@ -4,3 +4,20 @@
  */
 
 require_once __DIR__ . '/../../vendor/autoload.php';
+
+error_reporting( E_ALL & ~E_DEPRECATED );
+
+if ( getenv( 'PLUGIN_PATH' ) !== false ) {
+	define( 'PLUGIN_PATH', getenv( 'PLUGIN_PATH' ) );
+} else {
+	define( 'PLUGIN_PATH', __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR );
+}
+
+if ( getenv( 'ABSPATH' ) !== false ) {
+	define( 'ABSPATH', getenv( 'ABSPATH' ) );
+} else {
+	define( 'ABSPATH', PLUGIN_PATH . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR );
+}
+
+WP_Mock::setUsePatchwork( true );
+WP_Mock::bootstrap();