-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Avoid db connections when logging db connection errors #37458
Avoid db connections when logging db connection errors #37458
Conversation
As part of this PR, I decided to equally move away from our
The required changes regarding the above is much bigger project that I expected so this is work in progress but it would nice to have feedback it this is the right path. cc: @ChristophWurst (Thank you in advance) |
I do not thing that this fixes #37424 but it's an important and appreciated code cleanup 👍 We have to do this change carefully. There is still a lot of code to rely on ILogger, even if has been deprecated for a while. But we don't want to break apps, yet. I would suggest to only continue replacing ILogger method calls with LoggerInterface for now, and leave the ILogger constants in place. |
Definitely, it does not. I want to address that in a separate commit and I feel it's more appropriate to do this cleanup first, if it is something that is needed anyways.
I noticed that too, and my intention was to do app refactoring-next and append to this commit. In hopes that the tests would potentially flag the biggest issues?
Thanks for this early feedback! Happy to implement your current recommendations after hearing you last thoughts given my response. |
Note that only a few apps live inside this repos and are tightly bundled with Nextcloud server: https://github.com/nextcloud/server/tree/master/apps. The rest lives in independent repositories. We will not be able to replace all ILogger usages at once. Let's try to migrate this repo and app repos independently. And once if looks like ILogger isn't use any longer we drop it from the public API found in the |
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.
Public APIs are tricky :)
26be809
to
a9678df
Compare
a9678df
to
32dda6e
Compare
32dda6e
to
94953dc
Compare
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.
Overall, this catches the DB error and displays something like
Fatal error: Uncaught Doctrine\DBAL\Exception: Failed to connect to the database: An exception occurred in the driver: SQLSTATE[08006] [7] could not connect to server: Connection refused Is the server running on host "localhost" (127.0.0.1) and accepting TCP/IP connections on port 5432? in /home/fenn/nextcloud/nextcloud/lib/private/DB/Connection.php:142 Stack trace: #0 /home/fenn/nextcloud/nextcloud/3rdparty/doctrine/dbal/src/Connection.php(1531): OC\DB\Connection->connect() #1 /home/fenn/nextcloud/nextcloud/3rdparty/doctrine/dbal/src/Connection.php(1029): Doctrine\DBAL\Connection->getWrappedConnection() #2 /home/fenn/nextcloud/nextcloud/lib/private/DB/Connection.php(264): Doctrine\DBAL\Connection->executeQuery() #3 /home/fenn/nextcloud/nextcloud/3rdparty/doctrine/dbal/src/Query/QueryBuilder.php(345): OC\DB\Connection->executeQuery() #4 /home/fenn/nextcloud/nextcloud/lib/private/DB/QueryBuilder/QueryBuilder.php(280): Doctrine\DBAL\Query\QueryBuilder->execute() #5 /home/fenn/nextcloud/nextcloud/lib/private/AppConfig.php(418): OC\DB\QueryBuilder\QueryBuilder->execute() #6 /home/fenn/nextcloud/nextcloud/lib/private/AppConfig.php(226): OC\AppConfig->loadConfigValues() #7 /home/fenn/nextcloud/nextcloud/lib/private/AllConfig.php(217): OC\AppConfig->getValue() #8 /home/fenn/nextcloud/nextcloud/lib/private/Server.php(1840): OC\AllConfig->getAppValue() #9 /home/fenn/nextcloud/nextcloud/index.php(77): OC\Server->getPsrLogger() #10 {main} thrown in /home/fenn/nextcloud/nextcloud/lib/private/DB/Connection.php on line 142
instead of the regular
Internal Server Error
The server encountered an internal error and was unable to complete your request.
Please contact the server administrator if this error reappears multiple times, please include the technical details below in your report.
More details can be found in the server log.
I am also able to see the error in /var/log/apache2/error.log
My expectation was that the customPsrLogger
would log to $dataDir.'nextcloud.log'
but nothing is written on that log.
Finally I didn't expect to logger to interrupt the sending regular error message that points to the logs.
lib/private/Server.php
Outdated
@@ -1834,6 +1834,13 @@ public function getLogger() { | |||
return $this->get(ILogger::class); | |||
} | |||
|
|||
public function getPsrLogger(): LoggerInterface { | |||
$logFactory = $this->get(LogFactory::class); | |||
$default = $this->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/nextcloud.log'; |
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.
getConfig()
and getSystemConfig()
methods are marked as deprecated, what new method is available to achieve this?
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.
Turns out getSystemValue()
and getAppValue()
all depend on a working database connection so it causes the issue I reported in my self review.
Is there a way to read the values from config.php
that does not require the db set up?
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're probably going to read the config.php
directly. At this point, the database is already a goner and it's just about handling the error gracefully, so that is unusual but the only way to do it.
94953dc
to
f3f988c
Compare
So after setting a server/lib/private/DB/Connection.php Lines 138 to 141 in 8a79636
So something like } catch (Exception $e) {
$logFilePath = \OC::getLogFile();
$logFile = new File($logFilePath, '', $this->systemConfig);
$logFile->write('app', 'Log testing', 3); // Throws memory limit exceeded
// Additionally
$connectionErrorLogger = \OC::$server->get(LogFactory::class);
$connectionErrorLogger = $connectionErrorLogger->getCustomPsrLogger($logFilePath);
$connectionErrorLogger->error("Test Error Message", []); // Throws memory limit exceeded
throw new Exception('Failed to connect to the database: ' . $e->getMessage(), $e->getCode());
} Essentially calling various log methods in the
Questions
Thank you! |
Update (now fixed)I added the commit :
How does log file look when db there's a db connection problem?
About the question in the last updateI am still not sure why calling various methods (I tried with logger methods such and |
Hi, do you know which function is the issue? |
@kesselb Sorry for the delayed response the function that does this is See : https://github.com/nextcloud/server/blob/master/lib/private/Log/LogDetails.php |
Thank you 👍 It could be \OC_User::getUser() in logDetails then. |
130b827
to
7090284
Compare
index.php
Outdated
\OC::$server->getPsrLogger()->error($ex->getMessage(), [ | ||
'exception' => $ex, | ||
]); |
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.
\OC::$server->getPsrLogger()->error($ex->getMessage(), [ | |
'exception' => $ex, | |
]); | |
\OC::$server->get(LoggerInterface::class)->error($ex->getMessage(), [ | |
'exception' => $ex, | |
]); |
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.
Or even better
\OC::$server->getPsrLogger()->error($ex->getMessage(), [ | |
'exception' => $ex, | |
]); | |
\OCP::Server::get(LoggerInterface::class)->error($ex->getMessage(), [ | |
'exception' => $ex, | |
]); |
19b2d0f
to
4eac2d8
Compare
b159431
to
6b94a71
Compare
I added a try-catch that would only catch db connection failures, I guess that's a more convenient work around. |
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.
So the fix is in Server.php
and the other changes in index.php
are only to modernize how we get the logger right?
Exactly! |
Good question 👍 server/lib/private/Log/LogDetails.php Line 54 in fc07627
CsrfTokenManager -> SessionStorage -> ISession Lines 1403 to 1405 in b294eda
Line 669 in b294eda
\OC\User\Session -> OC\User\Manager -> ICacheFactory ICacheFactory then uses The good news is, that the csrf token manager is not an essential dependency for the request object itself. We can extract the functionality from the request object to an own service. |
6b94a71
to
e4459fd
Compare
e4459fd
to
f4c0158
Compare
This commit replaces more ILogger method calls with `Psr\Log\LoggerInterface` as we gradually move away from the custom ILogger. This commit aslo, sets the customPsrLogger to not depend on the database to `logfile` config value. Signed-off-by: fenn-cs <fenn25.fn@gmail.com>
`\OC\Log\LogDetails::logDetails` depends on `\OC_App::getAppVersions()` which makes a database connection causing the logger to break when the database service is unavaiable. Signed-off-by: fenn-cs <fenn25.fn@gmail.com>
f4c0158
to
d0fc159
Compare
@ChristophWurst please can you approve this for merging? |
\OC\Log\LogDetails::logDetails
depends on\OC_App::getAppVersions()
which makes a database connection causing the logger to break when the database service is unavaiable.Resolves: #37424