-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Added a new ResettableInterface and implemented it where possible. #997
Conversation
I forgot to say that we are using this "feature" for years at SensioLabs. But in a very hacky way (with reflection). IMHO, it's better to expose a clean API. That's why I created this PR. |
This PR needs a rebase, but before finishing it I would like to be sure If it will/could be merged. More over Symfony get a new component: Messenger. So (I hope so) AMQP (or other queue system) will become more standard. So people will expects a nice logging system. ping @fabpot @nicolas-grekas @sroze Next step: wire this restart method after each message processed in the Messenger Component |
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.
LGTM, just one comment
@@ -43,4 +45,9 @@ public function getUid(): string | |||
{ | |||
return $this->uid; | |||
} | |||
|
|||
public function restart(int $length = 7) |
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'd suggest to store the length as a property instead of adding in here
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.
agreed. None of the APIs are calling it with a value anyway, and we want it to be called with the original config.
and on container reset |
Why is it in the 2.0 milestone rather than adding this new feature in 1.x (2.0 is kind of stale, and Symfony will have a hard time moving to it due to the non-continuous migration path for handler authors currently) |
src/Monolog/Logger.php
Outdated
@@ -325,6 +325,21 @@ public function addRecord(int $level, string $message, array $context = []): boo | |||
return true; | |||
} | |||
|
|||
public function restart($a = null) |
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 having an argument here ?
@@ -43,4 +45,9 @@ public function getUid(): string | |||
{ | |||
return $this->uid; | |||
} | |||
|
|||
public function restart(int $length = 7) |
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.
agreed. None of the APIs are calling it with a value anyway, and we want it to be called with the original config.
|
||
public function restart(int $length = 7) | ||
{ | ||
$this->__construct($length); |
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 would rather move the uid generation to a private method and call it, rather than reusing __construct
(which will be necessary anyway when applying the suggestions). I don't want to push people to think that calling __construct
as a method is a supported usage of the library.
I would prefer 1.X yes. |
Well, I think the 2.0 milestone is because this was submitted to master. |
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 see either why it would be 2.0 as there is no harm in having that now.
@@ -43,4 +45,9 @@ public function getUid(): string | |||
{ | |||
return $this->uid; | |||
} | |||
|
|||
public function restart(int $length = 7) |
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's very unlikely that this is going to have its argument populated anyway because the chains don't forward the arguments. Instead, I'd use strlen($this->uid)
as __construct
argument (or store $length
as a property).
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.
getting the length of the existing uid is a nice trick to get it 😄
Thanks. I have addressed your comments and now this PR targets the 1.X branch. |
src/Monolog/RestartableInterface.php
Outdated
@@ -0,0 +1,25 @@ | |||
<?php declare(strict_types=1); |
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.
Is that OK even if Monolog's 1.x's target is PHP 5.3 ?
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.
oups ;)
eb81195
to
535b8c5
Compare
There is a failure on HHVM, but for another test. So this PR is ready. |
I would recommend to drop HHVM support as almost all project have done by now (even on 1.x). |
Rebased and green. @nicolas-grekas How could we handle your new
|
s/RestartableInterface::restart()/ResettableInteraface::reset()/? |
Hmm, IIRC, this is why I choose |
a bridge/proxy would do it also |
Hey, this is something I wanted to support in 2.0, as well as having a Logger::close() to be able to close all handlers (as 2.0 has close in the HandlerInterface). I am not against supporting this in 1.x though, but I wonder if we shouldn't call this |
I updated the PR to rename |
s/ResetableInterface/ResettableInterface |
@nicolas-grekas Thanks ; done |
src/Monolog/ResettableInterface.php
Outdated
* Handler or Processor implementing this interface will be reseted when Logger::reset is called. | ||
* | ||
* Reseting an Handler or a Processor usually means cleaning all buffers or | ||
* reseting in its internal state. |
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.
double "t": resetted, resetting
@@ -77,7 +77,7 @@ class TestFirePHPHandler extends FirePHPHandler | |||
{ | |||
protected $headers = array(); | |||
|
|||
public static function reset() | |||
public static function resetInternalState() |
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.
resetStatic?
@nicolas-grekas @Seldaek Should be ok ;) |
src/Monolog/ResettableInterface.php
Outdated
namespace Monolog; | ||
|
||
/** | ||
* Handler or Processor implementing this interface will be reseted when Logger::reset is called. |
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.
resetted ;)
Logger::reset()
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 used reset instead of resetted
When one use Monolog in a long process like an AMQP worker with a `FingersCrossedHandler` or `BufferHandler` there is a drawback: as soon as there is an AMQP message that generate a log >= error (for example), all next AMQP messages will output logs, even if theses messages don't generate log where level >= error. In the same context there is a drawback for processor that add an UUID to the logs. The UUID should change for each AMQP messages. --- This patch address this issue with a new interface: `ResettableInterface` interface. Side note: `reset()`, `flush()`, `clear()`, are already used in Monolog. So basically, one can use the `reset()` on the `Logger` and on some `Handler`s / `Processor`s. It's especially useful for * the `FingersCrossedHandler`: it `close()` the buffer, then it `clear()` the buffer. * the `BufferHandler`: it `flush()` the buffer, then it `clear()` the buffer. * the `UidProcessor`: it renew the `uid`.
What do you think of symfony/symfony#27093 (comment)? |
We have FormattableHandler/ProcessableHandler interfaces already in master so Resettable is kinda in line with that, but maybe should be ResettableHandlerInterface for real consistency. |
Thanks! |
Hey folks so just one more thing before I release this in 1.x.. The more I look at it especially in the master branch for 2.0 where I made close() part of the HandlerInterface, it seems to me like close() and reset() do essentially the same thing.. Or at least they should. Do you also see it like that or not? If so I am thinking to just remove close() in 2.0 and make HandlerInterface implement ResettableInterface. I think it'd simplify things, and it resolves what I had in mind for #197 to add Logger::close() to close all handlers as Logger::reset() was part of this PR. |
If we want to identify a difference, I could see this one: reset is meant to put a service back in a reusable state. This does not necessarily imply closing connections to remote backends. Actually, when using the same kernel in a loop, having connections already open for next requests should be a significant part of why these apps are faster (ie no |
That makes sense yes, although I don't know how many handlers would actually benefit from this distinction. But then I need to change the implementation a bit, because right now reset() calls close(), so things are even more confusing. It seems to me like the main use case for reset() is fingers crossed and buffer handlers to make sure they're cleared in between two requests/jobs in long running apps. The use case for close() is to do some cleanup at the very end, but also right now that's when we flush buffers and stuff like that, so I guess in the buffer case you'd want to flush on reset instead of close. And then close() would become mostly useless, except sometimes it calls reset() to flush, and in a few rare cases it closes some resource. Makes sense? Mostly thinking out loud here.. |
Makes sense to me yes :) |
Makes sense. Close becomes useless as it’s basically end of the process so
`reset` is enough :)
…On Sun, 4 Nov 2018 at 20:13, Nicolas Grekas ***@***.***> wrote:
Makes sense to me yes :)
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#997 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAxHEYosRAIt9vjSa55BjlkIPUBFs0MKks5ur0pSgaJpZM4Nr1RH>
.
|
OK see e07c948 for changes/clarifications. Happy to get any feedback on this. |
b803523 is the core of the changes for 1.x but I messed up the commit msg :s |
Added a new ResetableInterface and implemented it where possible.
When one use Monolog in a long process like an AMQP worker with a
FingersCrossedHandler
orBufferHandler
there is a drawback: as soon as thereis an AMQP message that generate a log >= error (for example), all next AMQP
messages will output logs, even if theses messages don't generate log where
level >= error.
In the same context there is a drawback for processor that add an UUID to the
logs. The UUID should change for each AMQP messages.
This patch address this issue with a new interface:
ResettableInterface
interface.Side note:
reset()
,flush()
,clear()
, are already used in Monolog. Sobasically, one can use the
reset()
on theLogger
and on someHandler
s /Processor
s.It's especially useful for
FingersCrossedHandler
: itclose()
the buffer, then itclear()
the buffer.BufferHandler
: itflush()
the buf