Download & Extend

Add test coverage and/or one real use of PSR-3 based watchdog logger object

Project:Drupal core
Version:8.x-dev
Component:watchdog.module
Category:task
Priority:major
Assigned:ParisLiakos
Status:needs review
Issue tags:Dependency Injection (DI)

Issue Summary

Problem/Motivation

The Watchdog logging system is great as it allows modules to implement their own logging implementation to extend the way Drupal handles logging. Watchdog is getting rather dated, however, as more modern solutions of logging pop up.

Proposed resolution

Let's bring watchdog() to the 21st century with the adoption of Monolog. Monolog is a slick logging system for PHP 5.3 which allows logging to multiple Handlers. Some of these handlers include Syslog, Gelf, MongoDB, and more. This also allows log entries to be written directly from Symfony, made possible via the MonologBridge.

In order to adopt the system, we must:

  1. #1810664: Add Monolog Symfony-Bridge to Drupal
  2. Add a "logger" service to the Dependency Injection Container of a definition of the Monolog instance.
  3. Make watchdog() post to the new logger service
  4. Introduce a DblogHandler in dblog.module that instructs Monolog to log to the database, and a DblogBundle to add the handler to the "logger" service
  5. Add a SyslogBundle to syslog.module, which instructs Monolog to use the SyslogHandler

Remaining tasks

  1. #1810664: Add Monolog Symfony-Bridge to Drupal
  2. Figure out what to do with entity_cache_test, as it's a test that currently depends on hook_watchdog()

User interface changes

No user interface changes.

API changes

Instead of using hook_watchdog(), modules would implement one of the many Monolog Handlers. If a Handler for their service is not available, it is possible to implement their own Handler, as demonstrated with DblogHandler.

Original report by catch

hook_watchdog() is a good candidate for moving out of the hook system into pluggable (and in this case stackable) classes - we want it to be available as early as possible, however currently it's not available until bootstrap modules are loaded - too late if you want to log in a cache backend or the lock system for any reason.

However hook_watchdog() is a small part of what our existing logging modules do. dblog has settings for expiring log items and an admin page for viewing/filtering log entries. Syslog has an admin screen, mongodb in contrib has an improved version of the dblog UI. So those would likely stay more or less the same - just the actual logging backend called from watchdog() would be different.

If we moved logging to OOP, I'd want to keep the same basic feature of being able to have more than one logger enabled at a time - it's handy to be able to log different messages to different storage etc.

In #1263478: Identify pieces of Drupal that could be replaced by Symfony code https://github.com/Seldaek/monolog was brought up.

I had a very quick glance at the Monolog code mainly to see if it supports more than one handler (which it does). That would be a showstopper if not, have not looked beyond this though yet.

Comments

#1

subscribe

#2

Looked through Monolog a bit more. The stacking is nice, it comes with several logging back ends (including syslog), generally looks pretty solid.

There's a couple of things that look tricky to me though:

http://api.drupal.org/api/drupal/includes--bootstrap.inc/function/watchdog

<?php
watchdog
($type, $message, $variables = array(), $severity = WATCHDOG_NOTICE, $link = NULL)
?>

https://github.com/Seldaek/monolog/blob/master/src/Monolog/Logger.php#L160

<?php
 
public function addRecord($level, $message, array $context = array())
?>

Since Drupal 6, we've separated $message from $variables, for use with t() (or now format_string() would also work for something like syslog()).

This allows for a couple of features:

- messages can be translated on output into whichever language the current user is viewing the logs. See http://api.drupal.org/api/drupal/modules--dblog--dblog.admin.inc/functio...

- http://drupal.org/project/mongodb adds a capped collection per message - meaning that it'll log 1,000 each of the same message with different variables - that stops one particularly frequent log message evicting others which might be more important.

- I'm not sure if there's a module for it, but with dblog it's easy to run a query to find the top PHP errors etc checking type = 'php' then a count on variables and group by.

Apart from stuffing variables into $context which would be a hack, I don't see a way to do that with the API from Monolog.

There's also no 'type' variable which dblog and mongodb_log let you filter on, but we could arguably stuff that into context so less of an issue.

#3

Subscribing. The irony is hook_watchdog() is one of the best cases for our current hook system conceptually, but the late-bootstrap problem is legitimate.

#4

Subscribing.

Disclaimer: I barely know Drupal, so maybe if I'm assuming things incorrectly please correct me :)

@catch, regarding the issues you mentioned:

- Let's start with the arg signature:

$type: For this, the way we have integrated Monolog in Symfony is by having multiple Logger instances, all configured with the same Handler instances. Loggers take a $channel arg in their constructor. This is added to each log record. It's a way to categorize things, and I guess it'd match your $type thing well. If you don't want to have multiple instances floating around (in Symfony it's done via the Dependency Injection Container which makes things easy, you just say you want an instance of the logger with a given channel name) then you could extend the Logger and add that $channel arg to addRecord, so it can be specified in every call rather than on the instance itself.

$message: That one's easy :)

$variables: I guess that's the equivalent of Monolog's $context, some handlers do something with it, some don't. It's just there if needed. In case you're not sure what this is, it's really meant as just being contextual information to accompany the message, and log some additional data that helps you debug issues. After reading again I see it's just vars for the message placeholders, that sounds ok to me as context info. The only thing you may want to do, if you combine message vars with additional context info (which you don't have now I assume), then maybe you'd want to remove the values that are used for the message from the context before displaying the context to the user. I don't know if that's feasible though, depends how you pass the info and how you format the message.

$severity: = $level

$link: You could put it in the context and then have a Processor registered which moves it in the $record['extra'] key if it's found in context. Or you could just again extend the Logger so that the $link automatically goes in the extra key.

- For capping, you could have a wrapper handler that does that, we should have one at some point anyway in Monolog, that would prevent from logging duplicate entries, because I want to avoid Email and other such handlers (something creating tickets for errors would come to mind) from repeatedly act on the same error. However it's a fairly difficult problem, because you can't only rely on the message, since it could contain variables and be different for every error that happens. I planned on relying on the stack trace to identify single path of failures, but I'm not yet sure this will work. Apparently you have moved the variables off the message, so this doesn't affect you I guess, and you can have a simple implementation of a capping handler.

I hope this helps a bit.

#5

Subscribing.

#6

$type: For this, the way we have integrated Monolog in Symfony is by having multiple Logger instances, all configured with the same Handler instances. Loggers take a $channel arg in their constructor. This is added to each log record. It's a way to categorize things, and I guess it'd match your $type thing well.

This sounds similar yeah. Creating more logger instances doesn't sound too bad - should not be too many different loggers required during the same request except possibly background stuff.

If you don't want to have multiple instances floating around (in Symfony it's done via the Dependency Injection Container which makes things easy, you just say you want an instance of the logger with a given channel name) then you could extend the Logger and add that $channel arg to addRecord, so it can be specified in every call rather than on the instance itself.

That'd be an E_STRICT warning no?

$variables: I guess that's the equivalent of Monolog's $context, some handlers do something with it, some don't. It's just there if needed. In case you're not sure what this is, it's really meant as just being contextual information to accompany the message, and log some additional data that helps you debug issues. After reading again I see it's just vars for the message placeholders, that sounds ok to me as context info. The only thing you may want to do, if you combine message vars with additional context info (which you don't have now I assume), then maybe you'd want to remove the values that are used for the message from the context before displaying the context to the user. I don't know if that's feasible though, depends how you pass the info and how you format the message.

Right, we'd basically be stuffing stuff into context then filtering it back out again. It's doable but could potentially get a bit wonky (i.e. it'd need to be $context['variables'] = array('@foo' => 'bar')) which detaches the variables from the message - i.e. right now the arguments match format_string() so there's a choice between keeping the watchdog() arguments the same and then switching them around before they're sent to the method, or having the arguments inconsistent with other places in Drupal that use the same mechanism.

#7

That'd be an E_STRICT warning no?

Yes, unless you add it as a last optional argument of addRecord, then it'd be ok. Or you can also have another public method that matches your current signature more closely, but anyway if you can live with the multiple instances (honestly they're not too expensive, just a few pushHandler() calls to set them up) it doesn't matter.

Right, we'd basically be stuffing stuff into context then filtering it back out again. It's doable but could potentially get a bit wonky (i.e. it'd need to be $context['variables'] = array('@foo' => 'bar')) which detaches the variables from the message - i.e. right now the arguments match format_string() so there's a choice between keeping the watchdog() arguments the same and then switching them around before they're sent to the method, or having the arguments inconsistent with other places in Drupal that use the same mechanism.

What I was thinking about was more along the lines of:

<?php
addWarning
('Hello @what', array('@what' => 'World', 'args' => $args));
?>

Then when you want to display a message, you just need to loop over $context, and remove any key that starts with [%@!] from the contextual data since those are your message placeholders. This separation of context and message placeholders could be done in addRecord too I suppose. Or again, add a new public method to your own Logger class so that it can have more arguments, then you could have $message, $variables and $context.

Anyway, the bottom line I think is that the main benefit of using Monolog would be to re-use and share Handlers imo. The Logger class doesn't do much beyond addRecord(), and if needed you could even have your own implementation of that that doesn't even extend Monolog's, then you're free to define your own API.

#8

#9

They're the same issue IMO, I've marked the other as duplicate since this is much older, and it has discussion of monolog which was being considered on the other issue without nearly as much discussion.

#10

Ah, thanks for the clarification. Was thinking about the architecture behind this:

  1. Introduce a Logger instance which is held in the drupal_container()
  2. Calling watchdog() invokes the Logger object in the container (drupal_container()->get('watchdog')->addWarning(), etc)
  3. We implement our own Handler classes, which acts on how we want logging to be done:
    • dblog implements DatabaseLogger
    • syslog is already suppored via SyslogHandler
  4. The dblog and syslog modules register their handlers to the Logger object to the "watchdog" object within the Container
  5. Remove hook_watchdog() as it's now handler-driven rather than hook-based

Yay watchdog logging system 2.0! It's easily extendible, and works well with all other Symfony components.

#11

The dblog and syslog modules register their handlers to the Logger object to the "watchdog" object within the Container

How do they do that though?

Could we consider moving watchdog logger configuration to settings.php similar to database drivers and cache backends? That would absolutely kill the necessity for any module to be loaded before the logging handler can be used so they'd work a lot earlier than they do now.

Then you can configure the handlers there - don't think we need a UI for it since choice of logging tool is pretty advanced.

The actual module part of syslog and dblog modules then would just be an admin interface/reports screen which would be optional-ish.

Not sure we want to keep watchdog() forever, but yeah definitely that'd be great for temporary backwards compatibility.

#12

The sense I got from talking with Fabien at Symfony Live is that the answer to most things in Symfony is "you use a config file to register it in the DIC, the DIC is the first thing that loads, and nearly all of your problems go away". So we would do away with runtime registration and move to a config/rebuild registration (which we will have to do for the DIC for performance reasons), and then almost anything OO is available at any time, regardless of bootstrap phase.

So dblog.module would just need to use whatever mechanism we establish for registering things in the DIC, and the rest just works.

Edit: And yes, the watchdog() function needs to be temporary only and go away eventually. Otherwise we still have a hard dependency everywhere we call it, which means some other file that we have to manually insure is loaded before we run some other code, which is exactly what we want to eliminate.

#13

Status:active» needs work

It's a start.

AttachmentSizeStatusTest resultOperations
1289536.patch186.82 KBIdleFAILED: [[SimpleTest]]: [MySQL] Unable to apply patch 1289536.patch. Unable to apply patch. See the log in the details link for more information.View details | Re-test

#14

After letting it sleep since Barcelona, here is the (admittedly ugly) initial version I demoed in Lyon and Barcelona. Working on it this week in Munich.

AttachmentSizeStatusTest resultOperations
0001-First-draft-of-watchdog-rework-with-Symfony-watchdog.patch227.13 KBIdleFAILED: [[SimpleTest]]: [MySQL] Invalid patch format in 0001-First-draft-of-watchdog-rework-with-Symfony-watchdog.patch.View details | Re-test
0002-Initial-version-ugly-but-works.patch5.3 KBIdleFAILED: [[SimpleTest]]: [MySQL] Unable to apply patch 0002-Initial-version-ugly-but-works.patch. Unable to apply patch. See the log in the details link for more information.View details | Re-test

#15

Or in just one patch on curreny head.

AttachmentSizeStatusTest resultOperations
0001-Issue-1289536-Take-hook_watchdog-out-of-the-hook-sys.patch230.83 KBIdleFAILED: [[SimpleTest]]: [MySQL] Invalid patch format in 0001-Issue-1289536-Take-hook_watchdog-out-of-the-hook-sys.patch.View details | Re-test

#16

fgm, can you split this into multiple patches? One should JUST add Monolog via Composer, the other should depend on it and actually make use of it. That makes it easier to review. Thanks.

#17

Title:Take hook_watchdog() out of the hook system into classes» Adopt Monolog for logging

FGM, any movement here? I'd love to get Monolog in, but we only have another 2 months to get it in place.

#18

Currently fulltime on client projects, but I've allocated half of my time in october and november to D8 core work, so this should restart moving next week.

#19

OK, great! If you need help or input come by the WSCCI channel.

#20

Converting watchdog to a class is necessary to remove the concept of bootstrap hooks, so this issue might be exempt from feature freeze if we can't have sane bootstrap code without it. That shouldn't stop people from trying to get it done asap though.

#21

Status:needs work» needs review

The attached patch simply adds Monolog using Composer.

As for the previous patch...

+++ b/core/lib/Drupal/Core/Watchdog/Logger.php
@@ -0,0 +1,28 @@
+    // A system logger always needs to be available for watchdog() and logging
+    // in Symfony code, even if this is the Null logger. This default can be
+    // overridden by watchdog.module configuration.
+    drupal_container()->register(WATCHDOG_CONTAINER_KEY, 'Drupal\\Core\\Watchdog\\Logger');

I feel weird about touching the Container from Drupal\Core\Watchdog\Logger. Do we even need this class? I was thinking something like the following...

  1. We register a "watchdog" service in drupal_container() directly to a Monolog\Logger. Note that drupal_container() is already completely pluggable so we don't need to handle the mappings at all since that's what the container is there for.
    <?php
      drupal_container
    ()->register('watchdog', 'Monolog\Logger');
    ?>

    This, of course, will become easier as #1706064: Compile the Injection Container to disk progresses.
  2. Syslog module, Dblog module, etc, register their own Monolog\Handler to drupal_container()'s "watchdog".
    <?php
    function dblog_init() {
     
    $handler = new Drupal\Dblog\DblogHandler();
     
    drupal_container()->get('watchdog')->pushHandler($handler);
    }
    ?>
  3. We turn watchdog() into a wrapper around interacting with drupal_container()->get('watchdog')->add*();
AttachmentSizeStatusTest resultOperations
1289536-monolog.patch231.62 KBIdlePASSED: [[SimpleTest]]: [MySQL] 42,174 pass(es).View details | Re-test

#22

Re #21:

- I wouldn't even bother calling the service watchdog. It's monolog. Let's just call it that and be honest.

- We wouldn't use hook_init(). Rather, dblog and friends would add a compiler pass for the Container that adds the handler call to the monolog service.

- We need to check and see how Symfony handles bridging Monolog to the various LoggerInterface definitions different components define. They're all identical I think, so it shouldn't be more than adding a trivial wrapper class, but we should still verify it so that we can inject it nicely.

Otherwise, agreed.

#23

Another question, should this become a meta issue so we can track the various tasks required?

- I wouldn't even bother calling the service watchdog. It's monolog. Let's just call it that and be honest.

Agreed.

- We wouldn't use hook_init(). Rather, dblog and friends would add a compiler pass for the Container that adds the handler call to the monolog service.

Definitely want this to happen. Hopefully #1706064: Compile the Injection Container to disk gets in soon so we can head in that direction.

- We need to check and see how Symfony handles bridging Monolog to the various LoggerInterface definitions different components define. They're all identical I think, so it shouldn't be more than adding a trivial wrapper class, but we should still verify it so that we can inject it nicely.

Sent up a pull request for Monolog\LoggerInterface to allow such a thing. We're in no way blocked by this though.

#24

Don't know is here is the right place but the dblog interface [dblog_overview()] should be dropped too and either wrap the watchdog table with an entity, either provide Views (as Views will be in core) with watchdog as base table.

The idea would be to replace the custom dblog UI with a View that can be extended and customized by sitebuilders. Turning the watchdog item into an entity would be the best approach as it open other doors.

#25

claudiu: Agreed that could be done, but that's a separate issue from this. Also, cannot happen until Views is in core anyway.

#26

I'm really confused as to why we're so focussed on moving to Monolog.

The only requirement I'm able to find in this issue is that we need to move logging out of hooks and into plugins, similar to cache.

We're potentially talking about a one-method interface. How hard could that be to throw together without bringing in another dependency?

#27

@msonnabaum: this has indeed been discussed but regrettably not in writing. One of the problems which led to this had been from working on mostly biggish sites which need to have multiple types of logging, with per-channel specifics, like the ability to send one channel to one logging destination whatever the level, another to another destination, the ability to log at debug level for one channel while not logging below warning on others, ability to cut logging flow if no event above a given threshold happens to limit log volume ("fingers crossed" logging), ability to log to gelf or logstash for centralized logging.

Monolog is one of the existing tools which bring most if not all of this, and can be included as a new plugin.

#28

Status:needs review» needs work

Needs #1810664: Add Monolog Symfony-Bridge to Drupal ... Still needs lots of work, but it does register the Bundle and Handler for syslog and dblog.

  1. Really not sure what to do with Actions Loop Test, as it's really just testing watchdog(), which doesn't really apply anymore. In this patch it just removes it
  2. Also not quite sure what to do with entity_cache_test.module either, as it tests itself using variables in a watchdog log, which seems really wrong
AttachmentSizeStatusTest resultOperations
monolog-needs-1810664.patch19.03 KBIdleFAILED: [[SimpleTest]]: [MySQL] Unable to apply patch monolog-needs-1810664.patch. Unable to apply patch. See the log in the details link for more information.View details | Re-test

#29

msonnabaum made me think again and reconsider this choice: the arguments for Monolog, which most of us, myself included, have done, are good, and this is likely the best candidate (not sure I posted my review of logging solutions anywhere ?), HOWEVER....

Working on larger environments than ever, I noticed that even with the expanded facilities offered by Monolog, the mechanism provided was sufficient for the needs encountered, but the actual target drivers(handlers in Monolog parlance) are not necessarily sufficient. And conversely, if even such a large package does not cover all needs, need we really include it all, or focus on a new logging interface, and only bundle as more limited version of Monolog, including only the most basic (supporting) classes and not the whole shebang, up to very specific handlers or little use for most sites, like Gelf/Graylog, Logstash, and others ?

To align with the principle of keeping core lean, it would make sense to only include these components, while allowing for the clean addition of extra handlers or processors as needed, or maybe even swapping the core classes entirely as long as the interface remains the same.

What do you think or this ? Should I (re?)write my findings about the logging panorama before we continue down that track ?

#30

@fgm: A quick word from my (maybe biased) side: if your goal is to keep core lean, I would say using an external lib is leaner than rewriting parts of it. As for bundling the whole shebang.. well most handlers are really small, that's why I took the approach of including most anything in monolog itself. That makes it a very good general purpose logging tool, and it's not like it takes much space (if that ever mattered in the 21st century;). I don't know if external code should count as bloating the core or not.

#31

Component:base system» watchdog.module
Status:needs work» needs review

Updated patch...

  1. Depends #1810664: Add Monolog Symfony-Bridge to Drupal. 1289536-with-monolog.patch combines both patches.
  2. Still need to figure out what to do with entity_cache_test.module

To align with the principle of keeping core lean, it would make sense to only include these components, while allowing for the clean addition of extra handlers or processors as needed, or maybe even swapping the core classes entirely as long as the interface remains the same.

It's our internal code that needs to be slimmed down. Like Seldaek mentioned, depending on external code doesn't add bloat to Drupal Core. Bringing in third-party libraries just means we can work with a larger developer base to accomplish the goals that we aim to accomplish.

As for swapping core classes, that's made possible with the Dependency Injection Container. As long as the "logger" service inherits from Monolog/Logger, or the Handler you're adding inherits from AbstractHandler, you can switch definitions easily. In this patch, you can see that done with DblogBundle and DblogHandler. Since we're using Symfony's MonologBridge here, all Symfony logging is compatible with it too.

AttachmentSizeStatusTest resultOperations
1289536-without-monolog-ignore.patch23.47 KBIdleFAILED: [[SimpleTest]]: [MySQL] Drupal installation failed.View details | Re-test
1289536-with-monolog.patch288.13 KBIdleFAILED: [[SimpleTest]]: [MySQL] Drupal installation failed.View details | Re-test

#32

Status:needs review» needs work

The last submitted patch, 1289536-with-monolog.patch, failed testing.

#33

That's part of what I was trying to say: we should be able to swap not by swapping just an implementation with one of its descendants, but rather by anything exposing the same interface, whatever its inheritance.

Which would mean having core rely on implementation of one (or more) interfaces (typically the interface exposed by the existing o Monolog base and abstract classes), and providing a basic implementation, maybe just some NullLogger. Or alternatively bundle it as we have been planning to do until now, with the extra handlers I added (and more ?) but at least allow replacements based on interface contracts, not implementation.

#34

fgm: Isn't that what we're doing? Just using Monolog to define those interfaces?

At some point you have to depend on *something*. :-)

#35

Since I'm working on it in Gent, I've prepared a set of data model diagrams to introduce what Monolog actually is: http://blog.riff.org/2012_11_02_rethinking_watchdog_monolog_architecture

Next up, besides working on the patch, will be an explanation of the way all of this works together, and how to put it to good use in Drupal 8 (notably why this is better than our legacy implementation). That will probably be the basis for the change notice once the code gets in.

#36

Rerolled on top of HEAD with a small change to handle invalid $level values and convert them in a more compact fashion.

At this point, installing fails with a DI exception: "The service definition "logger" does not exist." in ContainerBuilder->getDefinition().

AttachmentSizeStatusTest resultOperations
0001-Issue-1810664-by-Rob-Loach-Add-Monolog-Symfony-Bridg.patch279.03 KBIdleFAILED: [[SimpleTest]]: [MySQL] Unable to apply patch 0001-Issue-1810664-by-Rob-Loach-Add-Monolog-Symfony-Bridg.patch. Unable to apply patch. See the log in the details link for more information.View details | Re-test
0002-Issue-1289536-Adopt-Monolog-for-logging-on-top-of-18.patch17.93 KBIdleFAILED: [[SimpleTest]]: [MySQL] Unable to apply patch 0002-Issue-1289536-Adopt-Monolog-for-logging-on-top-of-18.patch. Unable to apply patch. See the log in the details link for more information.View details | Re-test

#37

Issue tags:+Legal

Dalin mentions that the Monolog license could be a problem and needs to be vetted before we proceed.

Adding Legal tag for this reason.

#38

@fgm: Why would it be a problem? It's MIT - which is the same as Symfony by the way.

#39

@seldaek: Quoting Dalin (from his comment on my blog):

MIT license isn't actually a thing, there are several licenses that are incorrectly mislabelled as "The MIT license" unfortunately none of which are compatible with the GPL (and thus the code is not able to be included with Drupal core). The APL is compatible and so the code could be included. However a few other projects (notably jQuery) have created a dual license with the GPL so that they could be included with Drupal.

I /think/ the specific license text you use allows us to sublicense on GPL2+, but I'm no legal advisor, so someone else needs to check.

#40

@fgm: Oh ok, just for the record though I use the text from http://spdx.org/licenses/MIT#licenseText - which is a pretty good source of the "official" MIT license text I believe. But anyway let me know if there is any problem.

#41

Issue tags:-Legal

The Monolog license is definitely the MIT License: http://opensource.org/licenses/MIT

The fact that people mislabel other licenses as MIT has no bearing on this. Also, I'd like to note that the Apache license (APL) is NOT compatible with GPL2 under any circumstances. We can relicense MIT as GPL, and as such, this does not need Legal review.

#43

#24: #1836598: Convert dblog record[-s/-ing] to Entity API.

I think there'll be lively interest coming from here. :)

#44

Possibly. However, log volume in most cases will not be a good match for the complexity of the entity code path with all its hooks invocations.

#45

Left my comment in the issue linked in #43, but to clarify, this issue is about logging, not logging UIs. The UI can be implemented as a separate interface for logging backends that can support it.

#46

For those not following that discussion in the FIG group, PSR-3 "LoggerInterface" to defined a standard for logging interfaces appears to be on a reasonably fast track towards adoption.

Here is the latest draft being reviewed: https://github.com/Seldaek/fig-standards/blob/logger-interface/proposed/...

While feature freeze is in just two days, I think it would be nice if we could still define at this point that D8 will be using the final version of this standard, when it is released.

Helpful points towards that end are the facts that the effort on this interface :

  • is being spearheaded by Jordi Boggiano, the creator and maintainer of Monolog
  • has incorporated a number of suggestions by Crell and myself to make it well suited to Drupal needs

With regard to this specific issue, it means we can still push the integration with Monolog as foreseeen, and switch to the standard implementation later on, for those sites wishing to replace Monolog with an other implementation.

As an opposite point, one should note that for Symfony 2.2, the trend seems to be towards directly specifying Monolog as /the/ Symfony 2 logger, instead of maintaining a compatibility interface: https://github.com/symfony/symfony/issues/5968 .

They have deadlines close to ours: 2.2 is AIUI frozen at the end of december.

#47

@fgm Very nice, thanks for the link. I'd love to push Monolog forward as soon as possible. We'll most definitely need it if we want to keep up with the PSRs.

#48

#49

Any other libraries in mind ?

I would really rather prefers http://logging.apache.org/log4php/ than monolog. I don't like its architecture and I'd rather bank on the apache project which has a great documentation and user base.

I also really love the Logger Interface idea. There is nothing more pleasant than to switch from a Syslog Logger from dev to a NullLogger in prod without changing the code. fgm has made an interesting point in #33, this is IMO a good practice of using loggers. If monolog is being re-architectured with the PSR-3 Standard for Logger Interface in mind, then Monolog++;

#50

Status:postponed» needs work

unblocking given #1834594: Update dependencies (Symfony and Twig) follow up fixes for Composer was committed.

#51

Category:task» feature request

This looks to be a feature to me, not a task. However, it also looks to be sufficiently in-progress to qualify for feature freeze extension.

#52

Title:Adopt Monolog for logging» Refactor hook_watchdog() so it's not a bootstrap hook
Category:feature request» task

Monolog itself is a feature. But refactoring watchdog to not be a 'bootstrap hook' is veering close to a critical task unless #1331486: Move module_invoke_*() and friends to an Extensions class does it for us, and that's all the original issue wanted. Re-titling to make this more clear, and moving back to task.

#53

@Sylvain Lecoy: you might want to look at the comparison I did about Monolog vs other loggin solutions, especially log4php, in this series of blog posts about this issue http://blog.riff.org/tags/monolog

#54

Of course thank you for the link I appreciate :)

#55

The PHP-FIG group has recently approved PSR-3, a standard logging interface, which was developed with an eye toward Drupal-friendliness. Monolog has already adopted it, and Symfony's components now have as well as of earlier today.

cf:
https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logg...
https://github.com/symfony/symfony/pull/6628

I see two possible ways forward, and consider doing one or the other to be a critical for Drupal 8:

1) Adopt Monolog (which has features above and beyond PSR-3) and use that throughout Drupal.
2) Roll our own basic implementations of PSR-3 and use that for any of the new objects we have, particularly the Symfony ones (which right now we have no logging for at all).

PSR-3 was developed more for components than for full applications, but it can be used as a baseline for full applications. Monolog would likely be the more complete solution, but our own PSR-3 implementations would still offer sizeable benefits.

#56

Psr\Log looks nice and sensible. Guess the first step would be to add that to core, as we'll need it either way.

#57

Let's just put together a simple psr-3 based logging class to replace watchdog. Then we can switch it out later if needed and not impact any of the calling code.

I much prefer this approach because it separates the issues of a) replace watchdog with a classed object and b) evaluate monolog, which are very separate issues.

#58

Title:Refactor hook_watchdog() so it's not a bootstrap hook» Add PSR-3 based watchdog logger object
Status:needs work» needs review

The attached patch adds the PSR-3 vendor library, and adds the most trivial wrapping class I could think of. Right now all it does is map from LoggerInterface to watchdog(), more or less. I figure this is a decent place to start as it gives us something to pass around, and as msonnabaum said once we have objects working with Psr\Log\LoggerInterface we can change out what goes on inside the logger object (or objects), including putting Monolog behind it, without changing the API.

AttachmentSizeStatusTest resultOperations
1289536-psr3-watchdog.patch15.24 KBIdleFAILED: [[SimpleTest]]: [MySQL] 50,832 pass(es), 1 fail(s), and 2 exception(s).View details | Re-test

#59

Status:needs review» needs work

The last submitted patch, 1289536-psr3-watchdog.patch, failed testing.

#60

Status:needs work» needs review

I'd be fine if this went in as is, but I'm also happy to flesh it out and get rid of watchdog in the same patch. I can go either way.

#61

+++ b/core/lib/Drupal/Core/WatchdogLogger.php
@@ -0,0 +1,83 @@
+      if (!in_array($key, array('exception', 'link'))) {

$context['link'] was just unset, so I don't think you need to check that here?

Otherwise looks good.
You (I suppose inadverdently) reverted a recent change to the composer file, and the Interface isn't actually added to the repository with this patch.

#62

Ugh, damnit. Composer keeps trying to use git for dev downloads, which means I can't check them in. That's the second time it's goofed on me. I'll try to fix that tonight.

As for the revert, um, the rdf line was there when I pulled right before branching. Race condition? :-) What is it supposed to be? (The line in the patch there doesn't actually work since there is no 8.x release of that library, and the library's been renamed, but I didn't want to mess with it in this patch.)

#63

msonnabaum: What would you consider the more fleshed out version that "gets rid of watchdog"? If we can get consensus on that quickly, let's do. If not, let's move forward with the minimalist approach here and we can do the fancier version in a follow-up and/or decide to replace it with Monolog.

Either way I consider the WatchdogLogger class to be an interim solution, which is fine.

#64

Status:needs review» needs work

Composer keeps trying to use git for dev downloads, which means I can't check them in.

Using "psr/log": "1.*@stable" will fix that. I may have some time today to help out here.

#65

Status:needs work» needs review

OK, let's try this again. With the library this time, and without b0rking easyrdf. Also fixes the tweak from #61.

AttachmentSizeStatusTest resultOperations
1289536-psr3-watchdog.patch15.24 KBIdleFAILED: [[SimpleTest]]: [MySQL] Unable to apply patch 1289536-psr3-watchdog_0.patch. Unable to apply patch. See the log in the details link for more information.View details | Re-test

#66

I'd register the logger as 'logger' in Drupal's DI container, instead of 'logger.watchdog'. That name is more generic and will not cause any confusion if the actual implementation ever gets replaced by Monolog or anything else.

@msonnabaum, did you mean that calls to watchdog() should be replaced by drupal_container()->get('logger')->... as well, and deprecate or completely remove the watchdog() function? In case of removal, some more code needs to be copied over to the WatchdogLogger class.

#67

Status:needs review» needs work

The last submitted patch, 1289536-psr3-watchdog.patch, failed testing.

#68

@Cyberwolf I was talking about removing the watchdog function, but now that I think of it, maybe it should stay. Classes can have the logger injected, but it'd be pretty ugly for procedural calls to all be changed to drupal_container()->get('logger'). We have procedural wrappers for other services, so maybe it makes sense to not remove for now.

And I agree that this should just be registered as "logger". I also think the class should just be \Drupal\Logger. Watchdog doesn't really make sense here.

#69

@msonnabaum, can you give me some examples of the procedural wrappers for other services? I took a quick look at http://api.drupal.org/api/drupal/core%21includes%21bootstrap.inc/functio... but that's quite a long list. At first sight most of those methods serve a certain distinct task requiring more logic than just 1 call on a service. IMHO leaving watchdog() like it is now in D8 would be a missed chance to fully embrace PSR-3 because module developers currently familiar with watchdog() will most likely keep on using it, postponing a possible BC break to D9 or later. Maybe that's a good thing for most people, "the short pain" is just my personal preference :)

I think the naming of the class is actually right, because the logger will still use hook_watchdog() for now if I understood well the barriers of the current approach for D8.

#70

cache() and lock() are two wrappers still in there that are equivalent, low-level functionality. I'm not prepared to get rid of those wrappers until #1875086: Improve DX of drupal_container()->get() is resolved. watchdog() is slightly different in that it won't return a logger instance but regardless that's something we can look at in a separate issue.

#71

wtf, testbot? I rolled that right against HEAD...

The way PSR-3 is designed if we were to convert over to it entirely then each "type" or "channel" would become a separate service. Using the context array for it as I'm doing here is an ugly hack, which is just for temporary BC. What we'd really want to do is have a couple of different logging services, logger.system, logger.cron, logger.php, etc. That's fine, we'd just have to set it up. That's why I didn't go with just "logger". (As a side note that would allow us to log certain channels of error to the database, others to syslog, others to an SMS gateway, etc. Although at that point, I think we're getting into territory where Monolog would take less work.)

#72

Issue tags:-watchdog

@Crell you must have uploaded the wrong patch at #65, it's the same as #58. and it still includes a submodule, that won't work...

#73

Mostly, I think core will just configure a single logging service catching all channels, or possibly two (one to be used before DB is initialized, in-memory or in-cache, the other after it is, handled by the revamped dblog handler), and it will be up to contrib to expose additional instances and change the channel-to-service routing.

#74

Issue tags:+watchdog

why would I remove this tag? didn't mean to do that.

#75

fgm: That would be a feature regression from where we are now.

#76

@crell: then I was not clear enough. The intent is not to reduce features, as you can guess. I'm just describing a possible minimal default configuration here. Obviously, the "contrib" term was improperly chosen, since syslog must obviously remain a core choice.

#77

fgm: I think we're talking about different things. You're talking about the backend. I'm referring to the "channel", what watchdog() calls $type. The PSR-3 way to handle that is with separate objects for each channel, on the assumption that a given object will only be writing to one channel so you just set the channel on the object and call it a day.

#78

Status:needs work» needs review

Sigh, I was in the wrong directory, so uploaded the wrong patch file. Freshly rebased to account for the Routing patch moving things around in CoreBundle.

AttachmentSizeStatusTest resultOperations
1289536-psr3-watchdog.patch29.37 KBIdlePASSED: [[SimpleTest]]: [MySQL] 50,637 pass(es).View details | Re-test

#79

Status:needs review» needs work

The last submitted patch, 1289536-psr3-watchdog.patch, failed testing.

#80

Status:needs work» needs review

#78: 1289536-psr3-watchdog.patch queued for re-testing.

#81

+++ b/core/lib/Drupal/Core/WatchdogLogger.php
@@ -0,0 +1,83 @@
+    array_walk($context, function(&$element, $key) {
+      if ($key != 'exception') {
+        $element = '@' . $element;
+      }
+    });

Doesn't this change the array values instead of the keys. I.e starting from $context['entity_type'] = 'node' I think this makes it $context['entity_type'] = '@node' instead of $context['@entity_type'] = 'node'.

#82

It looks like WatchdogLogger isn't being used anywhere. Will be turning watchdog() into a wrapper around WatchdogLogger at some point? Move code from watchdog() over to the class itself? Let's make a follow up for that.

Doesn't this change the array values instead of the keys. I.e starting from $context['entity_type'] = 'node' I think this makes it $context['entity_type'] = '@node' instead of $context['@entity_type'] = 'node'.

I've hopefully addressed that in this patch.

AttachmentSizeStatusTest resultOperations
1289536.patch29.45 KBIdlePASSED: [[SimpleTest]]: [MySQL] 50,661 pass(es).View details | Re-test

#83

Whitespace.

AttachmentSizeStatusTest resultOperations
1289536.patch29.47 KBIdlePASSED: [[SimpleTest]]: [MySQL] 50,699 pass(es).View details | Re-test

#84

Rob: Where we go from here is still an open question. We could turn watchdog() into a wrapper for this object, keep this as a wrapper for watchdog(), replace both with broken-out logger objects for each "channel", or replace it wholesale with Monolog. I think all are on the table at the moment. However, this gets us something we can pass to objects that require the PSR LoggerInterface, which means that we can now start logging from Symfony objects. :-) And any Drupal objects that convert over to taking an injected LoggerInterface object can start logging now and don't need to change their API again.

I'd RTBC this, but since it's (mostly) my patch I shouldn't take advantage of the loophole of Rob fixing something. :-) We need to resync Symfony before we can start passing it into places.

#85

Status:needs review» reviewed & tested by the community

+++ b/core/lib/Drupal/Core/WatchdogLogger.php
@@ -0,0 +1,85 @@
+      if ($key != 'exception') {

In case this gets a re-roll, it would be cool to add a comment here.

Marking RTBC anyway, because this is generally very clear and well documented.

#86

Category:task» feature request
Status:reviewed & tested by the community» needs work
Issue tags:+Needs tests

We should add some tests for this, and also use it in a number of core functions (that are tested).

#87

Category:feature request» task

I don't see this as a feature, it actually blocks #1888734: Get rid of all 'bootstrap' hooks which is a critical task.

Basic test coverage for the conversion prior to watchdog should be added here agreed.

The most obvious place to use this would be with the existing Symfony code that wants a logger but doesn't actually get one at the moment, but do we need to update Symfony to be able to do that?

I don't think there's much consensus on where to go after this patch - i.e. converting dblog and syslog to the new interface vs. adopting Monolog. I'd lean towards just converting dblog/syslog at the moment, Monolog can be added extremely easily via contrib.

#88

Priority:normal» major

it actually blocks #1888734: Get rid of all 'bootstrap' hooks which is a critical task.

In that case, this should be a major priority task, right?

#89

Once #1894002: Update vendor libraries and pin them to specific versions in composer.json is in, we can use this object for most of the Symfony objects that take a logger, since that update switches the Symfony classes to use the PSR-3 logger interface.

#90

Status:needs work» needs review

The psr/log library was just committed as part of #1894002: Update vendor libraries and pin them to specific versions in composer.json, since symfony/http-kernel had a dependency on it. This patch now explicitely pins prs/log to 1.0.0 in our composer.json. I'm using the latest version of composer, which seems to cause a bit of shuffling in composer.lock and installed.json. The "for_review" patch only shows the relevant bits for easier review without any noise from composer.

AttachmentSizeStatusTest resultOperations
1289536_psr3_watchdog_90--for-review.txt3.5 KBIgnoredNoneNone
1289536_psr3_watchdog_90.patch22.8 KBIdlePASSED: [[SimpleTest]]: [MySQL] 49,162 pass(es).View details | Re-test

#91

Title:Add PSR-3 based watchdog logger object» Add test coverage and/or one real use of PSR-3 based watchdog logger object
Status:needs review» needs work

#90 looks good. Would be great to figure out how we can run composer update without so much noise in the composer.lock and installed.json files: if someone figures that out, please open a separate issue explaining what's needed.

Back to "needs work" for making this patch do something useful: whether that's tests per #87 or injecting the object to Symfony classes per #89 or both. Retitling accordingly.

#92

Status:needs work» needs review

Updated patch. This just injects the watchdog object into the services that could currently accept it. Let's see how badly it breaks. :-)

AttachmentSizeStatusTest resultOperations
1289536-psr3-watchdog.patch24.44 KBIdleFAILED: [[SimpleTest]]: [MySQL] Drupal installation failed.View details | Re-test

#93

Status:needs review» needs work

The last submitted patch, 1289536-psr3-watchdog.patch, failed testing.

#94

Status:needs work» needs review

#92: 1289536-psr3-watchdog.patch queued for re-testing.

#95

Status:needs review» needs work

The last submitted patch, 1289536-psr3-watchdog.patch, failed testing.

#96

The latest patch seems to be missing the actual WatchdogLogger class.

It's not clear to me how this patch gets us any closer to removing hook_watchdog from the list of bootstrap hooks, which was originally a primary goal of this issue. Do we need to create a separate issue to focus on that now? This is in fact the only remaining bootstrap hook so it's all that stands in the way of removing the very concept of bootstrap hooks from D8.

#97

Status:needs work» needs review

Sigh. Git apply, you suck.

This doesn't remove hook_watchdog directly, but it moves any of the uses that would require it to be a bootstrap hook to using the object instead. That the logger object currently uses watchdog() internally is an implementation detail I expect we'll change in the next patch. (If someone feels comfortable coming up with a new approach for that now, I'm open to it.)

AttachmentSizeStatusTest resultOperations
1289536-psr3-watchdog.patch26.89 KBIdleFAILED: [[SimpleTest]]: [MySQL] Drupal installation failed.View details | Re-test

#98

Status:needs review» needs work

The last submitted patch, 1289536-psr3-watchdog.patch, failed testing.

#99

I wanted to work on that issue, though composer does someone really odd and fails with " Failed to clone http://github.com/symfony/Process.git via git, https and http protocols, aborting. ".
Fixed two small nitpicks, at least.

AttachmentSizeStatusTest resultOperations
1289536-psr3-watchdog-99.patch26.89 KBIdleFAILED: [[SimpleTest]]: [MySQL] Unable to apply patch 1289536-psr3-watchdog-99.patch. Unable to apply patch. See the log in the details link for more information.View details | Re-test

#100

What's happening is composer thinks your local installation includes the git clones, but the .git folders aren't actually checked into Drupal. So you need to run rm -rf core/vendor/*/* prior to running composer update.

#101

Status:needs work» needs review

oh great, it still feels odd that this updates so much.

AttachmentSizeStatusTest resultOperations
drupal-1289536-101.patch37.33 KBIdleFAILED: [[SimpleTest]]: [MySQL] Drupal installation failed.View details | Re-test

#102

Status:needs review» needs work

The last submitted patch, drupal-1289536-101.patch, failed testing.

#103

Status:needs work» needs review

+++ b/core/lib/Drupal/Core/CoreBundle.phpundefined
@@ -326,7 +329,8 @@ protected function registerRouting(ContainerBuilder $container) {
+       -addArgument(new Reference('logger.watchdog'));

i guess thats why installation fails

Fixed it and tried locally, it installs succesfully..but composer generates too much noise..actual changes are 7KB
Hope this is helpful, since i am not exactly sure what should be done now? transfer watchdog() functionality in WatchdogLogger ?
And turn watchdog() to \Drupal::Watchdog maybe?

AttachmentSizeStatusTest resultOperations
1289536-psr3-watchdog-103--reviewable-do-not-test.patch7.17 KBIgnoredNoneNone
1289536-psr3-watchdog-103.patch86.72 KBIdleFAILED: [[SimpleTest]]: [MySQL] Unable to apply patch 1289536-psr3-watchdog-103.patch. Unable to apply patch. See the log in the details link for more information.View details | Re-test

#104

Looks pretty good to me, is there anything else we should stick into this patch?

+++ b/core/vendor/composer/autoload_classmap.phpundefined
@@ -3,350 +3,350 @@
-    'PHPUnit_Extensions_PhptTestCase' => $baseDir . '/vendor/phpunit/phpunit/PHPUnit/Extensions/PhptTestCase.php',
-    'PHPUnit_Extensions_PhptTestCase_Logger' => $baseDir . '/vendor/phpunit/phpunit/PHPUnit/Extensions/PhptTestCase/Logger.php',
-    'PHPUnit_Extensions_PhptTestSuite' => $baseDir . '/vendor/phpunit/phpunit/PHPUnit/Extensions/PhptTestSuite.php',
-    'PHPUnit_Extensions_RepeatedTest' => $baseDir . '/vendor/phpunit/phpunit/PHPUnit/Extensions/RepeatedTest.php',
-    'PHPUnit_Extensions_TestDecorator' => $baseDir . '/vendor/phpunit/phpunit/PHPUnit/Extensions/TestDecorator.php',
-    'PHPUnit_Extensions_TicketListener' => $baseDir . '/vendor/phpunit/phpunit/PHPUnit/Extensions/TicketListener.php',
-    'PHPUnit_Framework_Assert' => $baseDir . '/vendor/phpunit/phpunit/PHPUnit/Framework/Assert.php',
-    'PHPUnit_Framework_AssertionFailedError' => $baseDir . '/vendor/phpunit/phpunit/PHPUnit/Framework/AssertionFailedError.php',

The Composer additions are nothing to worry about. They're just follow ups from the composer.json move.

+++ b/core/lib/Drupal/Core/WatchdogLogger.phpundefined
@@ -0,0 +1,85 @@
+    }
+
+    watchdog($type, $message, $variables, $this->mapLevel($level), $link);

Do we have follow ups set up to move watchdog() over to use WatchdogLogger and the event subscriber?

#105

well there is an issue with typehints
https://github.com/symfony-cmf/Routing/pull/53
Also i think some tests are needed, or replacing some of the current usage with the class, so we can say this is tested

#106

Status:needs review» needs work

The last submitted patch, 1289536-psr3-watchdog-103.patch, failed testing.

#107

Status:needs work» postponed

postponed for #1977570: Update third-party vendors and fix composer.json we need to update routing

#108

Status:postponed» needs review

#109

#103: 1289536-psr3-watchdog-103.patch queued for re-testing.

#110

Status:needs review» needs work

The last submitted patch, 1289536-psr3-watchdog-103.patch, failed testing.

#111

Status:needs work» needs review

here is a reroll..but well, there are some updates again..easyrdf seems added quite some stufff..or dunno..this is a mess..
@RobLoach what did i mess?

AttachmentSizeStatusTest resultOperations
1289536-psr3-watchdog-111.patch1.16 MBIdlePASSED: [[SimpleTest]]: [MySQL] 55,813 pass(es).View details | Re-test

#112

or... you know.... psr logger is already there, so here is just the drupal thing

AttachmentSizeStatusTest resultOperations
1289536-psr3-watchdog-112.patch5.78 KBIdlePASSED: [[SimpleTest]]: [MySQL] 55,488 pass(es).View details | Re-test

#113

Assigned to:Anonymous» ParisLiakos
Status:needs review» needs work

given, this is the last step for #1888734: Get rid of all 'bootstrap' hooks, i will move watchdog in this WatchdogLogger class and ... well, just quoting Crell from IRC:

ParisLiakos: Hm. In that case, it would probably be the same model as we use elsehwere: dblog and syslog both implement the PSR-3 log interface themselves, then the Watchdog logger also has an addLogger() method on it.

and then...well guess what..no more bootstrap hooks:)

#114

One possible issue with that approach I just realized: watchdog() has the "type" concept (or more generically called "channel" in other loggers). PSR-3 does not, on the assumption that each "type" would be a DIFFERENT logger object you inject.

So, perhaps we then need to register a logger per type, same class but with a different literal in its constructor parameters in the DIC? That can still take all the same individual implementations (dblog, syslog, etc.), but would be responsible for shoe-horning the type into the context before passing it on (as we're doing in the class now). I'm not sure how big of a wrench that is.

I think the only drawback for module developers is that if they want their own "channel" they would need to copy ~3 lines of YAML to register it before injecting rather than just throwing new strings into watchdog() willy nilly. Which is arguably good, I suppose, as it helps reduce typo potential...

#115

Status:needs work» needs review

you know, fixing dblog and syslog was the easier part..now we have two nice tests that rely on hook_watchdog

  • action_loop_test_watchdog
  • entity_cache_test_watchdog

and they both rely on them with a unique way...that well, needs some research on how to migrate em correctly...anyways lets see what else fails beside those

AttachmentSizeStatusTest resultOperations
1289536-psr3-watchdog-115.patch21.68 KBIdleFAILED: [[SimpleTest]]: [MySQL] 55,414 pass(es), 4 fail(s), and 0 exception(s).View details | Re-test

#116

Status:needs review» needs work

The last submitted patch, 1289536-psr3-watchdog-115.patch, failed testing.

#117

Status:needs work» needs review

w/e
at least hook_permissions is not going anywhere soon
this should be green

AttachmentSizeStatusTest resultOperations
1289536-psr3-watchdog-117.patch26.58 KBIdlePASSED: [[SimpleTest]]: [MySQL] 55,361 pass(es).View details | Re-test

#118

+++ b/core/includes/bootstrap.incundefined
@@ -1398,7 +1398,7 @@ function drupal_serve_page_from_cache(stdClass $cache) {
function bootstrap_hooks() {
-  return array('watchdog');
+  return array();

i propose removing bootstrap_hooks() and friends in the parent META issue..or i should do it here?

#119

+++ b/core/core.services.yml
@@ -96,6 +96,9 @@ services:
+  logger.watchdog:
+    class: Drupal\Core\WatchdogLogger
+    arguments: ['@request']

Is it redundant to call it logger.watchdog now, given that we're moving all the way over to this model? Shouldn't it be just logger or watchdog, but not both?

+++ b/core/includes/bootstrap.inc
@@ -1651,47 +1651,15 @@ function watchdog_exception($type, Exception $exception, $message = NULL, $varia
+  $context = array(
+    'type' => $type,
+    'variables' => $variables,
+    'link' => $link,

I think this is actually wrong. The way the PSR3 interface is defined, $context IS $variables. We just need to add type and link to it.

+++ b/core/lib/Drupal/Core/EventSubscriber/WatchdogRequestSubscriber.php
@@ -0,0 +1,62 @@
+  public function setWatchdogLoggerRequest(GetResponseEvent $event) {
+    if ($event->getRequestType() == HttpKernelInterface::MASTER_REQUEST) {
+      $this->watchdogLogger->setRequest($event->getRequest());
+    }
+  }

Actually, as of Symfony 2.3 the better way to do this is to call setRequest from the DIC configuration. That way the DIC can handle request scoping for us to set and reset the request when we go into subrequests.

If we just need this at the master level only, then... don't pass in the request object. Just pass in the data from the request object.

+++ b/core/lib/Drupal/Core/WatchdogLogger.php
@@ -0,0 +1,128 @@
+      'request_uri' => $base_root . request_uri(),

If we're passing in the request object, then request_ur() is totally not appropriate anymore. Neither is global $base_root.

As above, though, we should just be extracting the bits of the request we care about rather than keeping it around.

+++ b/core/lib/Drupal/Core/WatchdogLogger.php
@@ -0,0 +1,128 @@
+  public function addLogger(LoggerInterface $logger) {
+    $this->loggers[] = $logger;

We support a priority parameter everywhere else we're following this pattern. Let's do that here, too.

+++ b/core/modules/dblog/lib/Drupal/dblog/DbLogWatchdog.php
@@ -0,0 +1,61 @@
+    if (isset($context['variables']['backtrace'])) {
+      // Remove any backtraces since they may contain an unserializable variable.
+      unset($context['variables']['backtrace']);

unset() is safe to call on non-existent values, so you can skip the isset(). Same result either way.

+++ b/core/modules/syslog/lib/Drupal/syslog/SysLogWatchdog.php
@@ -0,0 +1,61 @@
+    global $base_url;

No need for this anymore, I'd think.

I don't think this addresses the DX question from #114, either. How do we want to handle that?

#120

Status:needs review» needs work

#121

Status:needs work» needs review

Actually, as of Symfony 2.3 the better way to do this is to call setRequest from the DIC configuration. That way the DIC can handle request scoping for us to set and reset the request when we go into subrequests.

Shouldnt we update to 2.3 first, then? also i am not sure i get what should i do

No need for this anymore, I'd think.

It is used 3 lines below:P

I don't think this addresses the DX question from #114, either. How do we want to handle that?

i dont think there is a DX problem? what is so bad with putting type inside context?

AttachmentSizeStatusTest resultOperations
1289536-psr3-watchdog-121.patch27.77 KBIdlePASSED: [[SimpleTest]]: [MySQL] 55,860 pass(es).View details | Re-test

#122

and the interdiff..i hope message_variables makes it clearier what is this about..variables was too general indeed

AttachmentSizeStatusTest resultOperations
interdiff.txt10.14 KBIgnoredNoneNone

#123

dont think there is a DX problem? what is so bad with putting type inside context?

i think the message variables could be more of DX problem than type

<?php
watchdog
('rest', 'Deleted entity %type with ID %id.', array('%type' => $entity->entityType(), '%id' => $entity->id()));
?>

using the injected service:
<?php
$this
->logger->notice('Deleted entity %type with ID %id.', array('type'=>'rest', 'message_variables' =>array('%type' => $entity->entityType(), '%id' => $entity->id())));
?>

#124

Per the PSR-3 spec, Section 1.2:

The message MAY contain placeholders which implementors MAY replace with values from the context array.

Placeholder names MUST correspond to keys in the context array.

So using "message_variables" as a sub-key of the context array is not compatible with the specification.

For "channels", we discussed that at length in FIG and the general feeling was that PSR-3 was targeted at the stand-alone libraries, which only need one channel at a time, and thus "if you want multiple channels, make multiple objects." That was a deliberated design decision. (Drupal's watchdog() was discussed specifically as an existing implementation, and that was where we ended up.)

nobody click here