8000 [Bridge/Monolog] Enhance the Console Handler · symfony/symfony@4103b61 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4103b61

Browse files
committed
[Bridge/Monolog] Enhance the Console Handler
Basically, The formatter now use the VarDumper & use more significant colors and has a more compact / readable format (IMHO).
1 parent 3064fac commit 4103b61

File tree

2 files changed

+163
-19
lines changed

2 files changed

+163
-19
lines changed

src/Symfony/Bridge/Monolog/Formatter/ConsoleFormatter.php

Lines changed: 159 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,45 +11,186 @@
1111

1212
namespace Symfony\Bridge\Monolog\Formatter;
1313

14-
use Monolog\Formatter\LineFormatter;
15-
use Monolog\Logger;
14+
use Monolog\Formatter\FormatterInterface;
15+
use Symfony\Component\VarDumper\Cloner\Data;
16+
use Symfony\Component\VarDumper\Cloner\Stub;
17+
use Symfony\Component\VarDumper\Cloner\VarCloner;
18+
use Symfony\Component\VarDumper\Dumper\CliDumper;
1619

1720
/**
1821
* Formats incoming records for console output by coloring them depending on log level.
1922
*
2023
* @author Tobias Schultze <http://tobion.de>
24+
* @author Grégoire Pineau <lyrixx@lyrixx.info>
2125
*/
22-
class ConsoleFormatter extends LineFormatter
26+
class ConsoleFormatter implements FormatterInterface
2327
{
24-
const SIMPLE_FORMAT = "%start_tag%[%datetime%] %channel%.%level_name%:%end_tag% %message% %context% %extra%\n";
28+
const SIMPLE_FORMAT = "%datetime% %level_start%%level_name%%level_end% [%channel%] %message%%context%%extra%\n";
29+
const SIMPLE_DATE = 'H:i:s';
30+
31+
private static $levelColorMap = array(
32+
100 => 'fg=white',
33+
200 => 'fg=green',
34+
250 => 'fg=blue',
35+
300 => 'fg=cyan',
36+
400 => 'fg=yellow',
37+
500 => 'fg=red',
38+
550 => 'fg=red',
39+
600 => 'fg=white;bg=red',
40+
);
41+
42+
private $options;
43+
private $cloner;
44+
private $outputBuffer;
45+
private $dumper;
2546

2647
/**
2748
* {@inheritdoc}
2849
*/
29-
public function __construct($format = null, $dateFormat = null, $allowInlineLineBreaks = false, $ignoreEmptyContextAndExtra = true)
50+
public function __construct($options = array())
3051
{
31- parent::__construct($format, $dateFormat, $allowInlineLineBreaks, $ignoreEmptyContextAndExtra);
52+
// BC Layer
53+
if (!is_array($options)) {
54+
$args = func_get_args();
55+
$options = array();
56+
if (isset($args[0])) {
57+
$options['format'] = $args[0];
58+
}
59+
if (isset($args[1])) {
60+
$options['date_format'] = $args[1];
61+
}
62+
}
63+
64+
$this->options = array_replace(array(
65+
'format' => self::SIMPLE_FORMAT,
66+
'date_format' => self::SIMPLE_DATE,
67+
'colors' => true,
68+
'multiline' => false,
69+
), $options);
70+
71+
$this->cloner = new VarCloner();
72+
$this->cloner->addCasters(array(
73+
'*' => array($this, 'castObject'),
74+
));
75+
76+
$this->outputBuffer = fopen('php://memory', 'r+b');
77+
if ($this->options['multiline']) {
78+
$output = $this->outputBuffer;
79+
} else {
80+
$output = array($this, 'echoLine');
81+
}
82+
83+
$this->dumper = new CliDumper($output, null, CliDumper::DUMP_LIGHT_ARRAY | CliDumper::DUMP_COMMA_SEPARATOR);
84+
}
85+
86+
/**
87+
* {@inheritdoc}
88+
*/
89+
public function formatBatch(array $records)
90+
{
91+
foreach ($records as $key => $record) {
92+
$records[$key] = $this->format($record);
93+
}
94+
95+
return $records;
3296
}
3397

3498
/**
3599
* {@inheritdoc}
36100
*/
37101
public function format(array $record)
38102
{
39-
if ($record['level'] >= Logger::ERROR) {
40-
$record['start_tag'] = '<error>';
41-
$record['end_tag'] = '</error>';
42-
} elseif ($record['level'] >= Logger::NOTICE) {
43-
$record['start_tag'] = '<comment>';
44-
$record['end_tag'] = '</comment>';
45-
} elseif ($record['level'] >= Logger::INFO) {
46-
$record['start_tag'] = '<info>';
47-
$record['end_tag'] = '</info>';
103+
$record = $this->replacePlaceHolder($record);
104+
105+
$levelColor = self::$levelColorMap[$record['level']];
106+
107+
if ($this->options['multiline']) {
108+
$context = $extra = "\n";
109+
} else {
110+
$context = $extra = ' ';
111+
}
112+
$context .= $this->dumpData($record['context']);
113+
$extra .= $this->dumpData($record['extra']);
114+
115+
$formatted = strtr($this->options['format'], array(
116+
'%datetime%' => $record['datetime']->format($this->options['date_format']),
117+
'%level_start%' => sprintf('<%s>', $levelColor),
118+
'%level_name%' => sprintf('%-9s', $record['level_name']),
119+
'%level_end%' => '</>',
120+
'%channel%' => $record['channel'],
121+
'%message%' => $this->replacePlaceHolder($record)['message'],
122+
'%context%' => $context,
123+
'%extra%' => $extra,
124+
));
125+
126+
return $formatted;
127+
}
128+
129+
/**
130+
* @internal
131+
*/
132+
public function echoLine($line, $depth, $indentPad)
133+
{
134+
if (-1 !== $depth) {
135+
fwrite($this->outputBuffer, $line);
136+
}
137+
}
138+
139+
/**
140+
* @internal
141+
*/
142+
public function castObject($v, array $a, Stub $s, $isNested)
143+
{
144+
if ($this->options['multiline']) {
145+
return $a;
146+
}
147+
148+
if ($isNested && !$v instanceof \DateTimeInterface) {
149+
$s->cut = -1;
150+
$a = array();
151+
}
152+
153+
return $a;
154+
}
155+
156+
private function replacePlaceHolder(array $record)
157+
{
158+
$message = $record['message'];
159+
160+
if (false === strpos($message, '{')) {
161+
return $record;
162+
}
163+
164+
$context = $record['context'];
165+
166+
$replacements = array();
167+
foreach ($context as $k => $v) {
168+
$replacements['{'.$k.'}'] = sprintf('<comment>%s</>', $this->dumpData($v, false));
169+
}
170+
171+
$record['message'] = strtr($message, $replacements);
172+
173+
return $record;
174+
}
175+
176+
private function dumpData($data, $colors = null)
177+
{
178+
if (null === $colors) {
179+
$this->dumper->setColors($this->options['colors']);
48180
} else {
49-
$record['start_tag'] = '';
50-
$record['end_tag'] = '';
181+
$this->dumper->setColors($colors);
51182
}
52183

53-
return parent::format($record);
184+
if (!$data instanceof Data) {
185+
$data = $this->cloner->cloneVar($data);
186+
}
187+
$data = $data->withRefHandles(false);
188+
$this->dumper->dump($data);
189+
190+
$dump = stream_get_contents($this->outputBuffer, -1, 0);
191+
rewind($this->outputBuffer);
192+
ftruncate($this->outputBuffer, 0);
193+
194+
return rtrim($dump);
54195
}
55196
}

src/Symfony/Bridge/Monolog/Handler/ConsoleHandler.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,10 @@ protected function write(array $record)
164164
*/
165165
protected function getDefaultFormatter()
166166
{
167-
return new ConsoleFormatter();
167+
return new ConsoleFormatter(array(
168+
'colors' => $this->output->isDecorated(),
169+
'multiline' => $this->output->isDebug(),
170+
));
168171
}
169172

170173
/**

0 commit comments

Comments
 (0)
0