Skip to content

Commit d9a72a0

Browse files
authored
Merge pull request #9 from cesargb/truncate
Add truncate option
2 parents 4675fe4 + a299561 commit d9a72a0

File tree

6 files changed

+95
-22
lines changed

6 files changed

+95
-22
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ $rotation
3131
->compress() // Optional, compress the file after rotated. Default false
3232
->files(30) // Optional, files are rotated 30 times before being removed. Default 366
3333
->minSize(1024) // Optional, are rotated when they grow bigger than 1024 bytes. Default 0
34+
->truncate() // Optional, truncate the original log file in place after creating a copy, instead of moving the old log file.
3435
->then(function ($filenameTarget, $filenameRotated) {}) // Optional, to get filename target and original filename
3536
->catch(function (RotationFailed $exception) {}) // Optional, to catch a exception in rotating
3637
->rotate('file.log');
@@ -46,6 +47,7 @@ $rotation = new Rotation([
4647
'files' => 1,
4748
'compress' => true,
4849
'min-size' => 10,
50+
'truncate' => false,
4951
'then' => function ($filename) {},
5052
'catch' => function (RotationFailed $exception) {},
5153
]);

src/Rotation.php

+56-9
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ class Rotation
1717

1818
private int $_minSize = 0;
1919

20+
private bool $_truncate = false;
21+
2022
private $thenCallback = null;
2123

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

2628
$this->methodsOptionables([
2729
'compress',
30+
'truncate',
2831
'minSize',
2932
'files',
3033
'then',
@@ -60,6 +63,20 @@ public function compress(bool $compress = true): self
6063
return $this;
6164
}
6265

66+
/**
67+
* Truncate the original log file in place after creating a copy, instead of
68+
* moving the old log file.
69+
*
70+
* It can be used when some program cannot be told to close its logfile and
71+
* thus might continue writing (appending) to the previous log file forever.
72+
*/
73+
public function truncate(bool $truncate = true): self
74+
{
75+
$this->_truncate = $truncate;
76+
77+
return $this;
78+
}
79+
6380
/**
6481
* Log files are rotated when they grow bigger than size bytes.
6582
*/
@@ -95,18 +112,28 @@ public function rotate(string $filename): bool
95112
return false;
96113
}
97114

98-
$filenameRotated = $this->runProcessor(
115+
$fileTemporary = $this->_truncate
116+
? $this->copyAndTruncate($filename)
117+
: $this->move($filename);
118+
119+
if (is_null($fileTemporary)) {
120+
return false;
121+
}
122+
123+
$fileTarget = $this->runProcessor(
99124
$filename,
100-
$this->moveContentToTempFile($filename)
125+
$fileTemporary
101126
);
102127

103-
$filenameRotated = is_null($filenameRotated)
104-
? $filenameRotated
105-
: $this->runCompress($filenameRotated);
128+
if (is_null($fileTarget)) {
129+
return false;
130+
}
106131

107-
$this->sucessfull($filename, $filenameRotated);
132+
$fileTarget = $this->runCompress($fileTarget);
108133

109-
return !empty($filenameRotated);
134+
$this->sucessfull($filename, $fileTarget);
135+
136+
return true;
110137
}
111138

112139
/**
@@ -186,9 +213,9 @@ private function fileIsValid(string $filename): bool
186213
}
187214

188215
/**
189-
* move data to temp file and truncate.
216+
* copy data to temp file and truncate.
190217
*/
191-
private function moveContentToTempFile(string $filename): ?string
218+
private function copyAndTruncate(string $filename): ?string
192219
{
193220
clearstatcache();
194221

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

248275
return $filenameTarget;
249276
}
277+
278+
private function move(string $filename): ?string
279+
{
280+
clearstatcache();
281+
282+
$filenameTarget = tempnam(dirname($filename), 'LOG');
283+
284+
if (!rename($filename, $filenameTarget)) {
285+
$this->exception(
286+
new Exception(
287+
sprintf('the file %s not can move to temp file %s.', $filename, $filenameTarget),
288+
22
289+
)
290+
);
291+
292+
return null;
293+
}
294+
295+
return $filenameTarget;
296+
}
250297
}

tests/Compress/GzTest.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
class GzTest extends TestCase
99
{
10-
public function test_rotation_processor_with_gz_processor()
10+
public function testRotationProcessorWithGzProcessor()
1111
{
1212
$rotation = new Rotation();
1313

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

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

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

34-
$this->assertEquals($content, implode("", gzfile(self::DIR_WORK.'file.log.1.gz')));
34+
$this->assertEquals($content, implode('', gzfile(self::DIR_WORK.'file.log.1.gz')));
3535
}
3636
}

tests/OptionTest.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,24 @@
33
namespace Cesargb\Log\Test;
44

55
use Cesargb\Log\Rotation;
6-
use Cesargb\Log\Test\TestCase;
76

87
class OptionTest extends TestCase
98
{
10-
public function test_pass_options()
9+
public function testPassOptions()
1110
{
1211
$rotation = new Rotation([
1312
'files' => 1,
1413
'compress' => true,
1514
'min-size' => 10,
15+
'truncate' => false,
1616
'then' => function ($filename) {},
1717
'catch' => function ($error) {},
1818
]);
1919

2020
$this->assertNotNull($rotation);
2121
}
2222

23-
public function test_catch_exceptio_if_method_is_not_permited()
23+
public function testCatchExceptioIfMethodIsNotPermited()
2424
{
2525
$this->expectException(\LogicException::class);
2626

tests/Processors/RotativeProcessorTest.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
class RotativeProcessorTest extends TestCase
99
{
10-
public function test_rotation_processor()
10+
public function testRotationProcessor()
1111
{
1212
$maxFiles = 5;
1313

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

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

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

32-
public function test_rotation_processor_with_gz_processor()
32+
public function testRotationProcessorWithGzProcessor()
3333
{
3434
$maxFiles = 5;
3535

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

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

4848
foreach (range(1, $maxFiles) as $n) {
4949
$this->assertFileExists(self::DIR_WORK."file.log.{$n}.gz");

tests/RotationTest.php

+27-3
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,14 @@ public function testNotRotateIfFileIsEmpty()
2828
$this->assertFileDoesNotExist(self::DIR_WORK.'file.log.1');
2929
}
3030

31-
public function testOptionNocompress()
31+
public function testRotationDefault()
3232
{
3333
file_put_contents(self::DIR_WORK.'file.log', microtime(true));
3434

3535
$rotation = new Rotation();
3636

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

39-
$this->assertStringEqualsFile(self::DIR_WORK.'file.log', '');
40-
4139
$this->assertFileExists(self::DIR_WORK.'file.log.1');
4240
}
4341

@@ -104,4 +102,30 @@ public function testOptionMinsize()
104102

105103
$this->assertFileExists(self::DIR_WORK.'file.log.1');
106104
}
105+
106+
public function testRotationTruncate()
107+
{
108+
file_put_contents(self::DIR_WORK.'file.log', microtime(true));
109+
110+
$rotation = new Rotation();
111+
112+
$rotation->truncate()->rotate(self::DIR_WORK.'file.log');
113+
114+
$this->assertStringEqualsFile(self::DIR_WORK.'file.log', '');
115+
116+
$this->assertFileExists(self::DIR_WORK.'file.log.1');
117+
}
118+
119+
public function testOptionTruncateAndCompress()
120+
{
121+
file_put_contents(self::DIR_WORK.'file.log', microtime(true));
122+
123+
$rotation = new Rotation();
124+
125+
$rotation->compress()->truncate()->rotate(self::DIR_WORK.'file.log');
126+
127+
$this->assertStringEqualsFile(self::DIR_WORK.'file.log', '');
128+
129+
$this->assertFileExists(self::DIR_WORK.'file.log.1.gz');
130+
}
107131
}

0 commit comments

Comments
 (0)