Skip to content

PHPLIB-1243: Adapter to pipe ext-mongodb logs to a PSR-3 logger #1158

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

Merged
merged 1 commit into from
Sep 25, 2023

Conversation

jmikola
Copy link
Member

@jmikola jmikola commented Sep 12, 2023

@jmikola jmikola changed the title wip Adapter to pipe ext-mongodb logs to a PSR-3 logger Adapter to pipe ext-mongodb logs to a PSR-3 logger Sep 12, 2023
Copy link
Member

@GromNaN GromNaN left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much simpler, and it's easier to understand that the logger is global and not client-specific.

@jmikola jmikola marked this pull request as ready for review September 14, 2023 13:26
@jmikola jmikola requested review from GromNaN and alcaeus September 15, 2023 05:29
*
* @internal
*/
public static function writeLog(int $level, string $domain, string $message): void
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per mongodb/mongo-php-driver#1395 (comment), PHPC defines a mongoc_log() function for internal tests. I'd ultimately like to have it defined only for test builds (PHPC-2293), so I think it still makes sense to use our own writeLog() function here.

We also discussed only caring about logging through PsrLogAdapter for spec compliance, so it shouldn't be necessary to have PHPLIB log directly to a PHPC mechanism (be it the mongodb.debug stream or registered LogSubscriber object(s)).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we're only dealing with PSR loggers here, does it make any sense to use the LogSubscriber levels here? The PSR levels are consistent with our logging spec, although the spec defines an additional trace level (how ironic). That said, it's not used so I don't think there's any urgent need to support it.

If we use PSR levels, we'd need a non-optional dependency on psr/log. It may make more sense to define our own levels (exactly consistent with the spec) and then maintain a mapping. This seems to be what Monolog does internally (for both PSR and RFC5424).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think people will get confused either way. Since PSR log levels are strings and libmongoc log levels are integers, how about accepting both?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is internal, people must not use it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@GromNaN is correct that no users should be calling writeLog() directly. It is only intended for internal use within PHPLIB.

That said, after reading through the Logging spec earlier today, I realized we should probably use those levels directly. My most recent commit introduces constants for the spec levels and changes writeLog() to take those and translate them internally to a PSR level (the only non-standard mapping is spec level trace to PSR level debug).

On a related note, I also changed writeLog() to call the PSR loggers directly instead of forwarding to LogSubscriber::log(), since forwarding would limit what levels PHPLIB could utilize (probably not relevant, but worth noting).

@jmikola
Copy link
Member Author

jmikola commented Sep 15, 2023

Note: PHPLIB-998 covers full compliance with the Logging spec, so I think there may be more to do here. For instance, logging is supposed to be controlled via environment variables.

I intend to through the spec again and build a list of outstanding features to implement.

composer.json Outdated
@@ -22,6 +22,7 @@
"require-dev": {
"doctrine/coding-standard": "^11.1",
"phpbench/phpbench": "^1.2",
"psr/log": "^1.1.4|^2|^3",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can add this to the suggests section so people know they can use a PSR logger.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can do. In case you missed @GromNaN's previous comment:

We may mark the dependency as "compatible" in composer, one day. composer/composer#11635

Copy link
Member Author

@jmikola jmikola Sep 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a moot point. If it was just type hints for the add/removeSubscriber methods, we could stick with suggestions, but PsrLogAdapter references the PSR LogLevel constants directly in a private constant, so we actually depend on psr/log being available.

My most recent commit moves this to a require dependency.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still an optional dependency, because logging is an optional feature. You could throw an exception before the PsrLogAdapter class declaration, telling a psr-3 compatible logger needs to be installed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@GromNaN: I expect at some point PHPLIB will need to write its own log messages for specs, at which point we'd need to introduce the dependency then.

If you feel strongly about making it optional now and deferring the hard requirement until then, I can implement an exception if the PSR classes don't exist.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, let's stick with what's most standard with a required dependency.

@jmikola jmikola changed the title Adapter to pipe ext-mongodb logs to a PSR-3 logger PHPLIB-1243: Adapter to pipe ext-mongodb logs to a PSR-3 logger Sep 20, 2023
@jmikola jmikola force-pushed the phplib-998 branch 2 times, most recently from c293d6e to 566b1a2 Compare September 21, 2023 02:45
* PsrLogAdapter and forwarded to each registered PSR logger.
*
* Note: it's not possible to test PsrLogAdapter::log() with an invalid
* level since mongoc_log() already validates its level parameter. */
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although I ended up removing the previous test that called log() with invalid levels, it was adapted for testWriteLogWithInvalidLevel() below.

Copy link
Member

@alcaeus alcaeus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with the repo/branch changes for builds.

composer.json Outdated
@@ -22,6 +22,7 @@
"require-dev": {
"doctrine/coding-standard": "^11.1",
"phpbench/phpbench": "^1.2",
"psr/log": "^1.1.4|^2|^3",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, let's stick with what's most standard with a required dependency.

@jmikola jmikola force-pushed the phplib-998 branch 3 times, most recently from eb0edc3 to e976bdc Compare September 25, 2023 18:46
public const NOTICE = 5;
public const INFO = 6;
public const DEBUG = 7;
public const TRACE = 8;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: I removed the LEVEL_ prefix on these constants, as it conflicted with the definitions on the LogSubscriber interface. PHP didn't seem to care about that, but Psalm did (noticed after correcting the extension version in the Psalm workflow).

These are for internal use only, so I don't particularly care about dropping the prefix. I also considered doing without these and relying on the PSR constants; however, we technically wouldn't have TRACE available (despite it being unlikely a spec would require its use).


private static function getInstance(): self
{
return self::$instance ??= new self();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@GromNaN: Also refactored this per your previous suggestion in #1158 (comment).

Introduces an internal PsrLogAdapter class to connect PSR-3 loggers with PHPC. The internal class is exposed via addLogger and removeLogger functions.

Bumps ext-mongodb dependency to 1.17-dev for PHPC-2180.

Permit psr/log 1.x, 2.x, or 3.x for compatibility with PHP 7.4 and 8.0+.
@jmikola jmikola merged commit 1acfab0 into mongodb:master Sep 25, 2023
@jmikola jmikola deleted the phplib-998 branch September 25, 2023 23:43
Comment on lines +128 to +130
* This function is intended for internal use within the library.
*/
public static function writeLog(int $specLevel, string $domain, string $message): void
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alcaeus Why this method isn't @internal?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that's necessary since the entire class is internal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants