Skip to content

Add truncate option #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ $rotation
->compress() // Optional, compress the file after rotated. Default false
->files(30) // Optional, files are rotated 30 times before being removed. Default 366
->minSize(1024) // Optional, are rotated when they grow bigger than 1024 bytes. Default 0
->truncate() // Optional, truncate the original log file in place after creating a copy, instead of moving the old log file.
->then(function ($filenameTarget, $filenameRotated) {}) // Optional, to get filename target and original filename
->catch(function (RotationFailed $exception) {}) // Optional, to catch a exception in rotating
->rotate('file.log');
Expand All @@ -46,6 +47,7 @@ $rotation = new Rotation([
'files' => 1,
'compress' => true,
'min-size' => 10,
'truncate' => false,
'then' => function ($filename) {},
'catch' => function (RotationFailed $exception) {},
]);
Expand Down
65 changes: 56 additions & 9 deletions src/Rotation.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ class Rotation

private int $_minSize = 0;

private bool $_truncate = false;

private $thenCallback = null;

public function __construct(array $options = [])
Expand All @@ -25,6 +27,7 @@ public function __construct(array $options = [])

$this->methodsOptionables([
'compress',
'truncate',
'minSize',
'files',
'then',
Expand Down Expand Up @@ -60,6 +63,20 @@ public function compress(bool $compress = true): self
return $this;
}

/**
* Truncate the original log file in place after creating a copy, instead of
* moving the old log file.
*
* It can be used when some program cannot be told to close its logfile and
* thus might continue writing (appending) to the previous log file forever.
*/
public function truncate(bool $truncate = true): self
{
$this->_truncate = $truncate;

return $this;
}

/**
* Log files are rotated when they grow bigger than size bytes.
*/
Expand Down Expand Up @@ -95,18 +112,28 @@ public function rotate(string $filename): bool
return false;
}

$filenameRotated = $this->runProcessor(
$fileTemporary = $this->_truncate
? $this->copyAndTruncate($filename)
: $this->move($filename);

if (is_null($fileTemporary)) {
return false;
}

$fileTarget = $this->runProcessor(
$filename,
$this->moveContentToTempFile($filename)
$fileTemporary
);

$filenameRotated = is_null($filenameRotated)
? $filenameRotated
: $this->runCompress($filenameRotated);
if (is_null($fileTarget)) {
return false;
}

$this->sucessfull($filename, $filenameRotated);
$fileTarget = $this->runCompress($fileTarget);

return !empty($filenameRotated);
$this->sucessfull($filename, $fileTarget);

return true;
}

/**
Expand Down Expand Up @@ -186,9 +213,9 @@ private function fileIsValid(string $filename): bool
}

/**
* move data to temp file and truncate.
* copy data to temp file and truncate.
*/
private function moveContentToTempFile(string $filename): ?string
private function copyAndTruncate(string $filename): ?string
{
clearstatcache();

Expand Down Expand Up @@ -247,4 +274,24 @@ private function moveContentToTempFile(string $filename): ?string

return $filenameTarget;
}

private function move(string $filename): ?string
{
clearstatcache();

$filenameTarget = tempnam(dirname($filename), 'LOG');

if (!rename($filename, $filenameTarget)) {
$this->exception(
new Exception(
sprintf('the file %s not can move to temp file %s.', $filename, $filenameTarget),
22
)
);

return null;
}

return $filenameTarget;
}
}
6 changes: 3 additions & 3 deletions tests/Compress/GzTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

class GzTest extends TestCase
{
public function test_rotation_processor_with_gz_processor()
public function testRotationProcessorWithGzProcessor()
{
$rotation = new Rotation();

Expand All @@ -27,10 +27,10 @@ public function test_rotation_processor_with_gz_processor()
$this->assertEquals(self::DIR_WORK.'file.log.1.gz', $fileRotated);
})->rotate(self::DIR_WORK.'file.log');

$this->assertStringEqualsFile(self::DIR_WORK.'file.log', '');
// $this->assertStringEqualsFile(self::DIR_WORK.'file.log', '');

$this->assertFileExists(self::DIR_WORK.'file.log.1.gz');

$this->assertEquals($content, implode("", gzfile(self::DIR_WORK.'file.log.1.gz')));
$this->assertEquals($content, implode('', gzfile(self::DIR_WORK.'file.log.1.gz')));
}
}
6 changes: 3 additions & 3 deletions tests/OptionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,24 @@
namespace Cesargb\Log\Test;

use Cesargb\Log\Rotation;
use Cesargb\Log\Test\TestCase;

class OptionTest extends TestCase
{
public function test_pass_options()
public function testPassOptions()
{
$rotation = new Rotation([
'files' => 1,
'compress' => true,
'min-size' => 10,
'truncate' => false,
'then' => function ($filename) {},
'catch' => function ($error) {},
]);

$this->assertNotNull($rotation);
}

public function test_catch_exceptio_if_method_is_not_permited()
public function testCatchExceptioIfMethodIsNotPermited()
{
$this->expectException(\LogicException::class);

Expand Down
8 changes: 4 additions & 4 deletions tests/Processors/RotativeProcessorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

class RotativeProcessorTest extends TestCase
{
public function test_rotation_processor()
public function testRotationProcessor()
{
$maxFiles = 5;

Expand All @@ -20,7 +20,7 @@ public function test_rotation_processor()
$rotation->rotate(self::DIR_WORK.'file.log');
}

$this->assertStringEqualsFile(self::DIR_WORK.'file.log', '');
// $this->assertStringEqualsFile(self::DIR_WORK.'file.log', '');

foreach (range(1, $maxFiles) as $n) {
$this->assertFileExists(self::DIR_WORK.'file.log.'.$n);
Expand All @@ -29,7 +29,7 @@ public function test_rotation_processor()
$this->assertFalse(is_file(self::DIR_WORK.'file.log.'.($maxFiles + 1)));
}

public function test_rotation_processor_with_gz_processor()
public function testRotationProcessorWithGzProcessor()
{
$maxFiles = 5;

Expand All @@ -43,7 +43,7 @@ public function test_rotation_processor_with_gz_processor()
$rotation->rotate(self::DIR_WORK.'file.log');
}

$this->assertStringEqualsFile(self::DIR_WORK.'file.log', '');
// $this->assertStringEqualsFile(self::DIR_WORK.'file.log', '');

foreach (range(1, $maxFiles) as $n) {
$this->assertFileExists(self::DIR_WORK."file.log.{$n}.gz");
Expand Down
30 changes: 27 additions & 3 deletions tests/RotationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,14 @@ public function testNotRotateIfFileIsEmpty()
$this->assertFileDoesNotExist(self::DIR_WORK.'file.log.1');
}

public function testOptionNocompress()
public function testRotationDefault()
{
file_put_contents(self::DIR_WORK.'file.log', microtime(true));

$rotation = new Rotation();

$rotation->rotate(self::DIR_WORK.'file.log');

$this->assertStringEqualsFile(self::DIR_WORK.'file.log', '');

$this->assertFileExists(self::DIR_WORK.'file.log.1');
}

Expand Down Expand Up @@ -104,4 +102,30 @@ public function testOptionMinsize()

$this->assertFileExists(self::DIR_WORK.'file.log.1');
}

public function testRotationTruncate()
{
file_put_contents(self::DIR_WORK.'file.log', microtime(true));

$rotation = new Rotation();

$rotation->truncate()->rotate(self::DIR_WORK.'file.log');

$this->assertStringEqualsFile(self::DIR_WORK.'file.log', '');

$this->assertFileExists(self::DIR_WORK.'file.log.1');
}

public function testOptionTruncateAndCompress()
{
file_put_contents(self::DIR_WORK.'file.log', microtime(true));

$rotation = new Rotation();

$rotation->compress()->truncate()->rotate(self::DIR_WORK.'file.log');

$this->assertStringEqualsFile(self::DIR_WORK.'file.log', '');

$this->assertFileExists(self::DIR_WORK.'file.log.1.gz');
}
}