Skip to content

Commit 01f30ba

Browse files
committed
add ConsoleFormatter and refactor ConsoleHandler to use the output directly instead of streams (this way the formatting style are taken into account at all)
1 parent a91a686 commit 01f30ba

File tree

2 files changed

+69
-78
lines changed

2 files changed

+69
-78
lines changed

Formatter/ConsoleFormatter.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\MonologBundle\Formatter;
13+
14+
use Monolog\Formatter\LineFormatter;
15+
use Monolog\Logger;
16+
17+
/**
18+
* Formats incoming records for console output by coloring them depending on log level.
19+
*
20+
* @author Tobias Schultze <http://tobion.de>
21+
*/
22+
class ConsoleFormatter extends LineFormatter
23+
{
24+
const SIMPLE_FORMAT = "%start_tag%[%datetime%] %channel%.%level_name%:%end_tag% %message% %context% %extra%\n";
25+
26+
/**
27+
* {@inheritdoc}
28+
*/
29+
public function format(array $record)
30+
{
31+
if ($record['level'] >= Logger::ERROR) {
32+
$record['start_tag'] = '<error>';
33+
$record['end_tag'] = '</error>';
34+
} elseif ($record['level'] >= Logger::NOTICE) {
35+
$record['start_tag'] = '<comment>';
36+
$record['end_tag'] = '</comment>';
37+
} elseif ($record['level'] >= Logger::INFO) {
38+
$record['start_tag'] = '<info>';
39+
$record['end_tag'] = '</info>';
40+
} else {
41+
$record['start_tag'] = '';
42+
$record['end_tag'] = '';
43+
}
44+
45+
return parent::format($record);
46+
}
47+
}

Handler/ConsoleHandler.php

Lines changed: 22 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313

1414
use Monolog\Handler\AbstractProcessingHandler;
1515
use Monolog\Logger;
16+
use Symfony\Bundle\MonologBundle\Formatter\ConsoleFormatter;
1617
use Symfony\Component\Console\Output\ConsoleOutputInterface;
1718
use Symfony\Component\Console\Output\OutputInterface;
18-
use Symfony\Component\Console\Output\StreamOutput;
1919

2020
/**
2121
* Writes to the console output depending on its verbosity setting.
@@ -27,20 +27,9 @@
2727
class ConsoleHandler extends AbstractProcessingHandler
2828
{
2929
/**
30-
* The stream to use when the console OutputInterface is not a StreamOutput.
30+
* @var OutputInterface|null
3131
*/
32-
const FALLBACK_STREAM = 'php://output';
33-
34-
/**
35-
* The error stream to use when the console OutputInterface is not a StreamOutput.
36-
*/
37-
const FALLBACK_ERROR_STREAM = 'php://stderr';
38-
39-
private $enabled = false;
40-
private $stream;
41-
private $streamCreated = false;
42-
private $errorStream;
43-
private $errorStreamCreated = false;
32+
private $output;
4433

4534
/**
4635
* Constructor.
@@ -59,15 +48,15 @@ public function __construct($bubble = true)
5948
*/
6049
public function isHandling(array $record)
6150
{
62-
return $this->enabled && parent::isHandling($record);
51+
return null !== $this->output && parent::isHandling($record);
6352
}
6453

6554
/**
6655
* {@inheritdoc}
6756
*/
6857
public function handle(array $record)
6958
{
70-
if (!$this->enabled) {
59+
if (null === $this->output) {
7160
return false;
7261
}
7362

@@ -77,25 +66,16 @@ public function handle(array $record)
7766
/**
7867
* Sets the console output to use for printing logs.
7968
*
80-
* It enabled the writing unless the output verbosity is set to quiet.
69+
* It enables the writing unless the output verbosity is set to quiet.
8170
*
8271
* @param OutputInterface $output The console output to use
8372
*/
8473
public function setOutput(OutputInterface $output)
8574
{
86-
// close streams that might have been created before
87-
$this->close();
88-
8975
if (OutputInterface::VERBOSITY_QUIET === $output->getVerbosity()) {
90-
return; // the handler remains disabled
91-
}
76+
$this->close();
9277

93-
if ($output instanceof StreamOutput) {
94-
$this->stream = $output->getStream();
95-
}
96-
97-
if ($output instanceof ConsoleOutputInterface && $output->getErrorOutput() instanceof StreamOutput) {
98-
$this->errorStream = $output->getErrorOutput()->getStream();
78+
return;
9979
}
10080

10181
switch ($output->getVerbosity()) {
@@ -113,29 +93,15 @@ public function setOutput(OutputInterface $output)
11393
break;
11494
}
11595

116-
$this->enabled = true;
96+
$this->output = $output;
11797
}
11898

11999
/**
120-
* Disables the output and closes newly created streams.
121-
*
122-
* It does not close streams coming from StreamOutput because they belong to the console.
100+
* Disables the output.
123101
*/
124102
public function close()
125103
{
126-
if ($this->streamCreated && is_resource($this->stream)) {
127-
fclose($this->stream);
128-
}
129-
$this->stream = null;
130-
$this->streamCreated = false;
131-
132-
if ($this->errorStreamCreated && is_resource($this->errorStream)) {
133-
fclose($this->errorStream);
134-
}
135-
$this->errorStream = null;
136-
$this->errorStreamCreated = false;
137-
138-
$this->enabled = false;
104+
$this->output = null;
139105

140106
parent::close();
141107
}
@@ -145,40 +111,18 @@ public function close()
145111
*/
146112
protected function write(array $record)
147113
{
148-
if (null === $this->stream) {
149-
$errorMessage = null;
150-
set_error_handler(function ($code, $msg) use (&$errorMessage) {
151-
$errorMessage = preg_replace('{^fopen\(.*?\): }', '', $msg);
152-
});
153-
$this->stream = fopen(self::FALLBACK_STREAM, 'a');
154-
restore_error_handler();
155-
if (!is_resource($this->stream)) {
156-
$this->stream = null;
157-
$this->streamCreated = false;
158-
throw new \UnexpectedValueException(sprintf('The stream "%s" could not be opened: '.$errorMessage, self::FALLBACK_STREAM));
159-
}
160-
$this->streamCreated = true;
161-
}
162-
163-
if (null === $this->errorStream) {
164-
$errorMessage = null;
165-
set_error_handler(function ($code, $msg) use (&$errorMessage) {
166-
$errorMessage = preg_replace('{^fopen\(.*?\): }', '', $msg);
167-
});
168-
$this->errorStream = fopen(self::FALLBACK_ERROR_STREAM, 'a');
169-
restore_error_handler();
170-
if (!is_resource($this->errorStream)) {
171-
$this->errorStream = null;
172-
$this->errorStreamCreated = false;
173-
throw new \UnexpectedValueException(sprintf('The stream "%s" could not be opened: '.$errorMessage, self::FALLBACK_ERROR_STREAM));
174-
}
175-
$this->errorStreamCreated = true;
176-
}
177-
178-
if ($record['level'] >= Logger::ERROR) {
179-
fwrite($this->errorStream, (string) $record['formatted']);
114+
if ($record['level'] >= Logger::ERROR && $this->output instanceof ConsoleOutputInterface) {
115+
$this->output->getErrorOutput()->write((string) $record['formatted']);
180116
} else {
181-
fwrite($this->stream, (string) $record['formatted']);
117+
$this->output->write((string) $record['formatted']);
182118
}
183119
}
120+
121+
/**
122+
* {@inheritdoc}
123+
*/
124+
protected function getDefaultFormatter()
125+
{
126+
return new ConsoleFormatter();
127+
}
184128
}

0 commit comments

Comments
 (0)