Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork9.7k
[FrameworkBundle][Monolog] Added a new way to follow logs#21080
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
1f8ddd9 to204c19fCompareyceruto commentedDec 28, 2016 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
👍 Thanks you for this awesome feature!
|
lyrixx commentedDec 28, 2016
@yceruto By default, |
yceruto commentedDec 28, 2016 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Right, but when you run I missing something :/ ? at least doesn't works for me :( without /app_dev.php/ |
| continue; | ||
| } | ||
| if ($filter && !$this->el->evaluate($filter, ['record' =>$record])) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
What about evaluate directly$record with->evaluate($filter, $record)?filter option becomes easier to use: from--filter "record['level'] > 200" to--filter "level > 200"
yceruto commentedDec 28, 2016
Nevermind, I forgot my env var in prod by default, sorry for the noise. This works as it is! |
robfrawley left a comment• edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
You missed a bunch of short-array syntax instances. ;-) Thanks for this feature, though!
| { | ||
| // Retry after 1s | ||
| if (null ===$this->socket) { | ||
| set_error_handler([$this,'nullErrorHandler']); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
You need to fix your array syntax to long throughout the codebase.
hhamon commentedDec 29, 2016
Very nice feature! |
lyrixx commentedDec 29, 2016
Yes, I know ;) I'm just waiting for @symfony/deciders feedbacks before fixing this kind of details. |
cd8983d to9e821aeComparelyrixx commentedJan 6, 2017
@fabpot Should I move this command to the new server bundle? |
| $this->dumper =newCliDumper(); | ||
| $this->dumper->setOutput($this->output =fopen('php://memory','r+b')); | ||
| $this->el =newExpressionLanguage(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
This property doesn't exist.
fabpot commentedJan 10, 2017
@lyrixx Indeed, it should be moved to the new web server bundle. |
fc3e391 tod77670bComparelyrixx commentedJan 12, 2017 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
I moved the command to the WebServerBundle. This PR is no "Ready To Review" |
xabbuh commentedJan 15, 2017
The |
lyrixx commentedJan 18, 2017
@xabbuh You are right, they are not wired. You might want to see my fork to see how it is wired. |
| useMonolog\Logger; | ||
| useSymfony\Bridge\Monolog\Formatter\VarDumperFormatter; | ||
| class ServerLogHandlerextends AbstractHandler |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
missing author
| @@ -0,0 +1,102 @@ | |||
| <?php | |||
| namespaceSymfony\Bridge\Monolog\Handler; | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
missing license
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Thanks. Fixed (both comments)
| ->addOption('format',null, InputOption::VALUE_REQUIRED,'The line format','%s <%s>%-9s</> <options=bold>%-8.8s</> %s') | ||
| ->addOption('show-context',null, InputOption::VALUE_NONE,'Display the context') | ||
| ->addOption('show-extra',null, InputOption::VALUE_NONE,'Display the extra') | ||
| ->addOption('filter',null, InputOption::VALUE_REQUIRED,'An expression to filter log. Example: record[\'level\'] > 200 or record[\'channel\'] in [\'app\',\'doctrine\']"') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Exemple don't workbin/console server:log --filter "record['level'] > 200" =>
Variable "record" is not valid around position 1.Did I missed something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I guess we broke something. Thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Actually, it's onlybin/console server:log --filter "level > 200" ;) It's simpler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
yeah, a review comment suggested to simplify it, but the description of the option was not updated when implementing the requested change
| ->addOption('date-format',null, InputOption::VALUE_REQUIRED,'The date format','H:i:s') | ||
| ->addOption('format',null, InputOption::VALUE_REQUIRED,'The line format','%s <%s>%-9s</> <options=bold>%-8.8s</> %s') | ||
| ->addOption('show-context',null, InputOption::VALUE_NONE,'Display the context') | ||
| ->addOption('show-extra',null, InputOption::VALUE_NONE,'Display the extra') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I think an option for minimal level (or using the verbosity to quickly restrict levels) could be simpler to use than the expression language
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
It does not use the expression language for that. I don't understand
| ->addOption('host',null, InputOption::VALUE_REQUIRED,'The server host','0:9911') | ||
| ->addOption('date-format',null, InputOption::VALUE_REQUIRED,'The date format','H:i:s') | ||
| ->addOption('format',null, InputOption::VALUE_REQUIRED,'The line format','%s <%s>%-9s</> <options=bold>%-8.8s</> %s') | ||
| ->addOption('show-context',null, InputOption::VALUE_NONE,'Display the context') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
should we really have options for that ? Couldn't it simply be based on the verbosity instead ? This seems like a perfect use case for it: display more details in verbose mode.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Indeed I will remove it.
Actually I'm working on a much better default log display in command.
| $this->dumper =newCliDumper(); | ||
| $this->dumper->setOutput($this->output =fopen('php://memory','r+b')); | ||
| if ($input->getOption('filter')) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
this is wrong.initialize is called before the input validation is completed. so you should not start reading it here IMO
| $this | ||
| ->setName('server:log') | ||
| ->setDescription('Start a log server that displays logs in real time') | ||
| ->addOption('host',null, InputOption::VALUE_REQUIRED,'The server host','0:9911') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
why this default port ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I really don't know.It was easy to type. What do you suggest ?
fabpot commentedMar 5, 2017
@lyrixx any news? |
lyrixx commentedMar 6, 2017
This PR was merged into the 3.3-dev branch.Discussion----------[Bridge/Monolog] Enhance the Console Handler| Q | A| ------------- | ---| Branch? | master| Bug fix? | no| New feature? | yes| BC breaks? | no| Deprecations? | yes| Tests pass? | -| Fixed tickets | -| License | MIT| Doc PR | ----I extracted and enhanced the formatting logic from#21080.Basically, The formatter now use the VarDumper & use more significant colors and has a more compact / readable format (IMHO).---I used the following code to generate before/after screenshots.```php protected function execute(InputInterface $input, OutputInterface $output) { $logger = $this->getContainer()->get('logger'); $filesystem = $this->getContainer()->get('filesystem'); $anObject = new \stdClass; $anObject->firstPpt = 'foo'; $anObject->secondePpt = 'bar'; $logger->log('notice', 'Hello {who}', [ 'who' => 'Wold', 'an_object' => $anObject, 'file_system' => $filesystem, ]); $r = new \ReflectionClass(LogLevel::class); foreach ($r->getConstants() as $level) { $logger = $logger->withName($level); $logger->log($level, 'log at level {level}', [ 'level' => $level, ]); } }```before:After:Commits-------b663ab5 [Bridge/Monolog] Enhanced the Console Handler
1a33d22 toa553da1Comparelyrixx commentedMar 7, 2017
Hello; Here we go. I think this PR is ready for a last review. I pushed everything to my fork for those who want to test it:https://github.com/lyrixx/symfony-standard/tree/server-log |
nicolas-grekas left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I don't know how hard it'd be to functionally test that,
anyway, LGTM!
| $replacements['{'.$k.'}'] =sprintf('<comment>%s</>',$this->dumpData($v,false)); | ||
| // Remove quotes added by the dumper around string. | ||
| $v =trim($this->dumpData($v,false),'"'); | ||
| $replacements['{'.$k.'}'] =sprintf('<comment>%s</>',$v); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
if the$v string ends with a backslash, will it break escaping?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Good catch.
I have fixed this issue by escaping the value.
Thanks.
nicolas-grekas left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
👍
lyrixx commentedMar 14, 2017
👍 |
fabpot commentedMar 14, 2017
Thank you@lyrixx. |
…ogs (lyrixx)This PR was merged into the 3.3-dev branch.Discussion----------[FrameworkBundle][Monolog] Added a new way to follow logs| Q | A| ------------- | ---| Branch? | master| Bug fix? | no| New feature? | yes| BC breaks? | no| Deprecations? | no| Tests pass? | yes| Fixed tickets | -| License | MIT| Doc PR | -----If you want to try this PR, you can use [my fork](https://github.com/lyrixx/symfony-standard/tree/server-log):```bashgit clonehttps://github.com/lyrixx/symfony-standard -b server-log symfony-se-logscd symfony-se-logscomposer installbin/console server:startbin/console server:log```and from anywhere `curl http://0:8000`---Basically, it's a new way to view and filter real time logs, from the CLI.Commits-------ac92375 [FrameworkBundle][Monolog] Added a new way to follow logs
…gh a server dumper (ogizanagi, nicolas-grekas)This PR was merged into the 4.1-dev branch.Discussion----------[VarDumper] Introduce a new way to collect dumps through a server dumper| Q | A| ------------- | ---| Branch? | 4.1 <!-- see comment below -->| Bug fix? | no| New feature? | yes <!-- don't forget updating src/**/CHANGELOG.md files -->| BC breaks? | no| Deprecations? | no <!-- don't forget updating UPGRADE-*.md files -->| Tests pass? | yes| Fixed tickets |#22987 <!-- #-prefixed issue number(s), if any -->| License | MIT| Doc PR | todo <!--highly recommended for new features-->Could also be interesting as alternate solution for#23442.Inspired by the [`ServerLogHandler`](#21080) and@nicolas-grekas's [comment](#22987 (comment)) in#22987.---## DescriptionThis PR introduces a new `server:dump` command available in the `VarDumper` component.Conjointly with a new `ServerDumper` data dumper, it allows to send serialized `Data` clones to a single centralized server, in charge of dumping them on CLI output, or in an file in HTML format.## Showcase### HTTP callsFor instance, when working on an API and dumping something, you might end up with a mix of your response and the CLI dumped version of the data you asked:```phpclass HelloController extends AbstractController{ /** *@route("/hello") */ public function hello(Request $request, UserInterface $user) { dump($request->attributes, $user); return JsonResponse::create([ 'status' => 'OK', 'message' => "Hello {$user->getUsername()}" ]); }}```<img width="732" alt="screenshot 2017-08-08 a 16 44 24" src="https://user-images.githubusercontent.com/2211145/29077731-0b2152d6-7c59-11e7-99dd-2d060a906d48.PNG">You might even get the HTML dump version [under some conditions](https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php#L146-L157).Dumping to a server allows collecting dumps in a separate place:<!---->~⚠️ By swallowing the previous dumpers output, the dump data collector is not active when running the dump server. Disable swallowing if you want both.~ ➜ Dumps are still collected in the profiler thanks tof24712e### CLI callsThe best probably is (to me) that you can also debug CLI applications...<!---->...and get HTML formatted dumps:<!----><!---->hence, benefit from all the features of this format (collapse, search, ...)### HTML output at a glance<img width="831" alt="screenshot 2017-08-11 a 19 28 25" src="https://user-images.githubusercontent.com/2211145/29225513-eae349f2-7ece-11e7-9861-8cda9e80ba7f.PNG">The HTML output benefits from all the `HtmlDumper` features and contains extra informations about the context (sources, requests, command line, ...). It doesn't aim to replace the profiler for HTTP calls with the framework, but is really handy for CLI apps or by wiring it in your own web app, out of the framework usage.### CLI output at a glance<img width="829" alt="screenshot 2017-08-11 a 19 52 57" src="https://user-images.githubusercontent.com/2211145/29225482-c24afe18-7ece-11e7-8e83-d019b0d8303e.PNG">## Usage within the framework### ConfigFor instance, in your `config_dev.yml`:```yml#config_dev.ymldebug: server_dump: true```or in your `config.yml`:```yml#config.ymldebug: server_dump: '%kernel.debug%'```~~The configuration also allows to set a `host` option, but there is already a sensible default value (`tcp://0.0.0.0:9912`) so you don't have to deal with it.~~ Sinceb002175, in case you want to change the default host value used, simply use the `VAR_DUMPER_SERVER` env var.When the server is running, all dumps are collected by the server and previous dumpers ones are "swallowed" ~~by default. If you want both to collect dumps on the server AND keep previous dumpers on regular outputs, you can disable swallowing:~~<!--```ymldebug: server_dump: swallow: false```-->When the server isn't running or in case of failure to send the data clones to the server, the server dumper will delegates to the configured wrapped dumper, so dumps are displayed and collected as usual.### Running the server```bashbin/console server:dump [--format=cli|html]```#### Options- ~~The `output` option defaults to `null` which will display dumps on CLI. It accepts a file path in which dumps will be collected in HTML format.~~- The `format` option allows to switch format to use. For instance, use the `html` format and redirect the output to a file in order to open it in your browser and inspect dumps in HTML format.- ~~The default `host` value is the same as the one configured under the `debug.server_dump.host` config option, so you don't have to deal with it in most cases.~~ Sinceb002175, in case you want to change the default host value used, simply use the `VAR_DUMPER_SERVER` env var: ```bash VAR_DUMPER_SERVER=0.0.0.0:9204 bin/console server:dump ```## Manual wiringIf you want to wire it yourself in your own project or using it to inspect dumps as html before the kernel is even boot for instance:```php$host = 'tcp://0.0.0.0:9912'; // use null to read from the VAR_DUMPER_SERVER env var$cloner = new VarCloner();$dumper = new ServerDumper($host, new CliDumper());VarDumper::setHandler(function ($var) use ($dumper, $cloner) { $dumper->dump($cloner->cloneVar($var));});```## Create your own server appThe component already provides a default server app by means of the `ServerDumpCommand`, but you could also build your own by using the `DumpServer`:```php$host = 'tcp://0.0.0.0:9912'; // use null to read from the VAR_DUMPER_SERVER env var$server = new DumpServer($host);$server->start();$server->listen(function (Data $data, array $context, $clientId) { // do something});```Commits-------138dad6 [VarDumper] Some tweaks after Nicolas' commit & ServerDumperPlaceholderCommand088c52e [VarDumper] Review config to use debug.dump_destination & tweak data collector3db1404 [VarDumper] Introduce a new way to collect dumps through a server dumper
…gh a server dumper (ogizanagi, nicolas-grekas)This PR was merged into the 4.1-dev branch.Discussion----------[VarDumper] Introduce a new way to collect dumps through a server dumper| Q | A| ------------- | ---| Branch? | 4.1 <!-- see comment below -->| Bug fix? | no| New feature? | yes <!-- don't forget updating src/**/CHANGELOG.md files -->| BC breaks? | no| Deprecations? | no <!-- don't forget updating UPGRADE-*.md files -->| Tests pass? | yes| Fixed tickets | #22987 <!-- #-prefixed issue number(s), if any -->| License | MIT| Doc PR | todo <!--highly recommended for new features-->Could also be interesting as alternate solution for #23442.Inspired by the [`ServerLogHandler`](symfony/symfony#21080) and@nicolas-grekas's [comment](symfony/symfony#22987 (comment)) in #22987.---## DescriptionThis PR introduces a new `server:dump` command available in the `VarDumper` component.Conjointly with a new `ServerDumper` data dumper, it allows to send serialized `Data` clones to a single centralized server, in charge of dumping them on CLI output, or in an file in HTML format.## Showcase### HTTP callsFor instance, when working on an API and dumping something, you might end up with a mix of your response and the CLI dumped version of the data you asked:```phpclass HelloController extends AbstractController{ /** *@route("/hello") */ public function hello(Request $request, UserInterface $user) { dump($request->attributes, $user); return JsonResponse::create([ 'status' => 'OK', 'message' => "Hello {$user->getUsername()}" ]); }}```<img width="732" alt="screenshot 2017-08-08 a 16 44 24" src="https://user-images.githubusercontent.com/2211145/29077731-0b2152d6-7c59-11e7-99dd-2d060a906d48.PNG">You might even get the HTML dump version [under some conditions](https://github.com/symfony/symfony/blob/master/src/Symfony/Component/HttpKernel/DataCollector/DumpDataCollector.php#L146-L157).Dumping to a server allows collecting dumps in a separate place:<!---->~⚠️ By swallowing the previous dumpers output, the dump data collector is not active when running the dump server. Disable swallowing if you want both.~ ➜ Dumps are still collected in the profiler thanks to f24712effc9fab1163c0053e2a0a0d5cc4f6473e### CLI callsThe best probably is (to me) that you can also debug CLI applications...<!---->...and get HTML formatted dumps:<!----><!---->hence, benefit from all the features of this format (collapse, search, ...)### HTML output at a glance<img width="831" alt="screenshot 2017-08-11 a 19 28 25" src="https://user-images.githubusercontent.com/2211145/29225513-eae349f2-7ece-11e7-9861-8cda9e80ba7f.PNG">The HTML output benefits from all the `HtmlDumper` features and contains extra informations about the context (sources, requests, command line, ...). It doesn't aim to replace the profiler for HTTP calls with the framework, but is really handy for CLI apps or by wiring it in your own web app, out of the framework usage.### CLI output at a glance<img width="829" alt="screenshot 2017-08-11 a 19 52 57" src="https://user-images.githubusercontent.com/2211145/29225482-c24afe18-7ece-11e7-8e83-d019b0d8303e.PNG">## Usage within the framework### ConfigFor instance, in your `config_dev.yml`:```yml#config_dev.ymldebug: server_dump: true```or in your `config.yml`:```yml#config.ymldebug: server_dump: '%kernel.debug%'```~~The configuration also allows to set a `host` option, but there is already a sensible default value (`tcp://0.0.0.0:9912`) so you don't have to deal with it.~~ Since b002175, in case you want to change the default host value used, simply use the `VAR_DUMPER_SERVER` env var.When the server is running, all dumps are collected by the server and previous dumpers ones are "swallowed" ~~by default. If you want both to collect dumps on the server AND keep previous dumpers on regular outputs, you can disable swallowing:~~<!--```ymldebug: server_dump: swallow: false```-->When the server isn't running or in case of failure to send the data clones to the server, the server dumper will delegates to the configured wrapped dumper, so dumps are displayed and collected as usual.### Running the server```bashbin/console server:dump [--format=cli|html]```#### Options- ~~The `output` option defaults to `null` which will display dumps on CLI. It accepts a file path in which dumps will be collected in HTML format.~~- The `format` option allows to switch format to use. For instance, use the `html` format and redirect the output to a file in order to open it in your browser and inspect dumps in HTML format.- ~~The default `host` value is the same as the one configured under the `debug.server_dump.host` config option, so you don't have to deal with it in most cases.~~ Since b002175, in case you want to change the default host value used, simply use the `VAR_DUMPER_SERVER` env var: ```bash VAR_DUMPER_SERVER=0.0.0.0:9204 bin/console server:dump ```## Manual wiringIf you want to wire it yourself in your own project or using it to inspect dumps as html before the kernel is even boot for instance:```php$host = 'tcp://0.0.0.0:9912'; // use null to read from the VAR_DUMPER_SERVER env var$cloner = new VarCloner();$dumper = new ServerDumper($host, new CliDumper());VarDumper::setHandler(function ($var) use ($dumper, $cloner) { $dumper->dump($cloner->cloneVar($var));});```## Create your own server appThe component already provides a default server app by means of the `ServerDumpCommand`, but you could also build your own by using the `DumpServer`:```php$host = 'tcp://0.0.0.0:9912'; // use null to read from the VAR_DUMPER_SERVER env var$server = new DumpServer($host);$server->start();$server->listen(function (Data $data, array $context, $clientId) { // do something});```Commits-------138dad6 [VarDumper] Some tweaks after Nicolas' commit & ServerDumperPlaceholderCommand088c52e [VarDumper] Review config to use debug.dump_destination & tweak data collector3db1404 [VarDumper] Introduce a new way to collect dumps through a server dumper
Uh oh!
There was an error while loading.Please reload this page.
If you want to try this PR, you can usemy fork:
git clone https://github.com/lyrixx/symfony-standard -b server-log symfony-se-logscd symfony-se-logscomposer installbin/console server:startbin/console server:logand from anywhere
curl http://0:8000Basically, it's a new way to view and filter real time logs, from the CLI.