mirror of
https://github.com/friendica/friendica
synced 2025-04-28 00:30:10 +00:00
Merge branch 'develop' into rewrite/gravity-constants
This commit is contained in:
commit
26e0469de7
181 changed files with 2408 additions and 2405 deletions
|
@ -23,6 +23,7 @@ namespace Friendica\Core;
|
|||
|
||||
use Dice\Dice;
|
||||
use Friendica;
|
||||
use Friendica\App;
|
||||
|
||||
/**
|
||||
* Description of Console
|
||||
|
@ -133,7 +134,7 @@ HELP;
|
|||
$command = null;
|
||||
|
||||
if ($this->getOption('version')) {
|
||||
$this->out('Friendica Console version ' . FRIENDICA_VERSION);
|
||||
$this->out('Friendica Console version ' . App::VERSION);
|
||||
|
||||
return 0;
|
||||
} elseif ((count($this->options) === 0 || $this->getOption($this->customHelpOptions) === true || $this->getOption($this->customHelpOptions) === 1) && count($this->args) === 0
|
||||
|
|
|
@ -197,7 +197,7 @@ class Installer
|
|||
$result = DBStructure::install();
|
||||
|
||||
if ($result) {
|
||||
$txt = DI::l10n()->t('You may need to import the file "database.sql" manually using phpmyadmin or mysql.') . EOL;
|
||||
$txt = DI::l10n()->t('You may need to import the file "database.sql" manually using phpmyadmin or mysql.') . '<br />';
|
||||
$txt .= DI::l10n()->t('Please see the file "doc/INSTALL.md".');
|
||||
|
||||
$this->addCheck($txt, false, true, htmlentities($result, ENT_COMPAT, 'UTF-8'));
|
||||
|
@ -259,9 +259,9 @@ class Installer
|
|||
|
||||
$help = "";
|
||||
if (!$passed) {
|
||||
$help .= DI::l10n()->t('Could not find a command line version of PHP in the web server PATH.') . EOL;
|
||||
$help .= DI::l10n()->t("If you don't have a command line version of PHP installed on your server, you will not be able to run the background processing. See <a href='https://github.com/friendica/friendica/blob/stable/doc/Install.md#set-up-the-worker'>'Setup the worker'</a>") . EOL;
|
||||
$help .= EOL . EOL;
|
||||
$help .= DI::l10n()->t('Could not find a command line version of PHP in the web server PATH.') . '<br />';
|
||||
$help .= DI::l10n()->t("If you don't have a command line version of PHP installed on your server, you will not be able to run the background processing. See <a href='https://github.com/friendica/friendica/blob/stable/doc/Install.md#set-up-the-worker'>'Setup the worker'</a>") . '<br />';
|
||||
$help .= '<br /><br />';
|
||||
$tpl = Renderer::getMarkupTemplate('field_input.tpl');
|
||||
/// @todo Separate backend Installer class and presentation layer/view
|
||||
$help .= Renderer::replaceMacros($tpl, [
|
||||
|
@ -279,7 +279,7 @@ class Installer
|
|||
[$result] = explode("\n", $result);
|
||||
$help = "";
|
||||
if (!$passed2) {
|
||||
$help .= DI::l10n()->t("PHP executable is not the php cli binary \x28could be cgi-fgci version\x29") . EOL;
|
||||
$help .= DI::l10n()->t("PHP executable is not the php cli binary \x28could be cgi-fgci version\x29") . '<br />';
|
||||
$help .= DI::l10n()->t('Found PHP version: ') . "<tt>$result</tt>";
|
||||
}
|
||||
$this->addCheck(DI::l10n()->t('PHP cli binary'), $passed2, true, $help);
|
||||
|
@ -295,7 +295,7 @@ class Installer
|
|||
$passed3 = $result == $str;
|
||||
$help = "";
|
||||
if (!$passed3) {
|
||||
$help .= DI::l10n()->t('The command line version of PHP on your system does not have "register_argc_argv" enabled.') . EOL;
|
||||
$help .= DI::l10n()->t('The command line version of PHP on your system does not have "register_argc_argv" enabled.') . '<br />';
|
||||
$help .= DI::l10n()->t('This is required for message delivery to work.');
|
||||
} else {
|
||||
$this->phppath = $phppath;
|
||||
|
@ -333,7 +333,7 @@ class Installer
|
|||
|
||||
// Get private key
|
||||
if (!$res) {
|
||||
$help .= DI::l10n()->t('Error: the "openssl_pkey_new" function on this system is not able to generate encryption keys') . EOL;
|
||||
$help .= DI::l10n()->t('Error: the "openssl_pkey_new" function on this system is not able to generate encryption keys') . '<br />';
|
||||
$help .= DI::l10n()->t('If running under Windows, please see "http://www.php.net/manual/en/openssl.installation.php".');
|
||||
$status = false;
|
||||
}
|
||||
|
@ -511,10 +511,10 @@ class Installer
|
|||
(!file_exists('config/local.config.php') && !is_writable('.'))) {
|
||||
|
||||
$status = false;
|
||||
$help = DI::l10n()->t('The web installer needs to be able to create a file called "local.config.php" in the "config" folder of your web server and it is unable to do so.') . EOL;
|
||||
$help .= DI::l10n()->t('This is most often a permission setting, as the web server may not be able to write files in your folder - even if you can.') . EOL;
|
||||
$help .= DI::l10n()->t('At the end of this procedure, we will give you a text to save in a file named local.config.php in your Friendica "config" folder.') . EOL;
|
||||
$help .= DI::l10n()->t('You can alternatively skip this procedure and perform a manual installation. Please see the file "doc/INSTALL.md" for instructions.') . EOL;
|
||||
$help = DI::l10n()->t('The web installer needs to be able to create a file called "local.config.php" in the "config" folder of your web server and it is unable to do so.') . '<br />';
|
||||
$help .= DI::l10n()->t('This is most often a permission setting, as the web server may not be able to write files in your folder - even if you can.') . '<br />';
|
||||
$help .= DI::l10n()->t('At the end of this procedure, we will give you a text to save in a file named local.config.php in your Friendica "config" folder.') . '<br />';
|
||||
$help .= DI::l10n()->t('You can alternatively skip this procedure and perform a manual installation. Please see the file "doc/INSTALL.md" for instructions.') . '<br />';
|
||||
}
|
||||
|
||||
$this->addCheck(DI::l10n()->t('config/local.config.php is writable'), $status, false, $help);
|
||||
|
@ -537,10 +537,10 @@ class Installer
|
|||
if (!is_writable('view/smarty3')) {
|
||||
|
||||
$status = false;
|
||||
$help = DI::l10n()->t('Friendica uses the Smarty3 template engine to render its web views. Smarty3 compiles templates to PHP to speed up rendering.') . EOL;
|
||||
$help .= DI::l10n()->t('In order to store these compiled templates, the web server needs to have write access to the directory view/smarty3/ under the Friendica top level folder.') . EOL;
|
||||
$help .= DI::l10n()->t("Please ensure that the user that your web server runs as \x28e.g. www-data\x29 has write access to this folder.") . EOL;
|
||||
$help .= DI::l10n()->t("Note: as a security measure, you should give the web server write access to view/smarty3/ only--not the template files \x28.tpl\x29 that it contains.") . EOL;
|
||||
$help = DI::l10n()->t('Friendica uses the Smarty3 template engine to render its web views. Smarty3 compiles templates to PHP to speed up rendering.') . '<br />';
|
||||
$help .= DI::l10n()->t('In order to store these compiled templates, the web server needs to have write access to the directory view/smarty3/ under the Friendica top level folder.') . '<br />';
|
||||
$help .= DI::l10n()->t("Please ensure that the user that your web server runs as \x28e.g. www-data\x29 has write access to this folder.") . '<br />';
|
||||
$help .= DI::l10n()->t("Note: as a security measure, you should give the web server write access to view/smarty3/ only--not the template files \x28.tpl\x29 that it contains.") . '<br />';
|
||||
}
|
||||
|
||||
$this->addCheck(DI::l10n()->t('view/smarty3 is writable'), $status, true, $help);
|
||||
|
@ -571,7 +571,7 @@ class Installer
|
|||
|
||||
if ($fetchResult->getReturnCode() != 204) {
|
||||
$status = false;
|
||||
$help = DI::l10n()->t('Url rewrite in .htaccess seems not working. Make sure you copied .htaccess-dist to .htaccess.') . EOL;
|
||||
$help = DI::l10n()->t('Url rewrite in .htaccess seems not working. Make sure you copied .htaccess-dist to .htaccess.') . '<br />';
|
||||
$help .= DI::l10n()->t('In some circumstances (like running inside containers), you can skip this error.');
|
||||
$error_msg = [];
|
||||
$error_msg['head'] = DI::l10n()->t('Error message from Curl when fetching');
|
||||
|
|
|
@ -22,19 +22,16 @@
|
|||
namespace Friendica\Core\Logger\Factory;
|
||||
|
||||
use Friendica\Core\Config\Capability\IManageConfigValues;
|
||||
use Friendica\Core\Logger\Exception\LoggerException;
|
||||
use Friendica\Core;
|
||||
use Friendica\Core\Logger\Exception\LogLevelException;
|
||||
use Friendica\Database\Database;
|
||||
use Friendica\Network\HTTPException\InternalServerErrorException;
|
||||
use Friendica\Util\FileSystem;
|
||||
use Friendica\Core\Logger\Util\Introspection;
|
||||
use Friendica\Core\Logger\Type\Monolog\DevelopHandler;
|
||||
use Friendica\Core\Logger\Type\Monolog\IntrospectionProcessor;
|
||||
use Friendica\Core\Logger\Type\ProfilerLogger;
|
||||
use Friendica\Core\Logger\Type\StreamLogger;
|
||||
use Friendica\Core\Logger\Type\SyslogLogger;
|
||||
use Friendica\Util\Profiler;
|
||||
use Monolog;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\LogLevel;
|
||||
use Psr\Log\NullLogger;
|
||||
|
@ -60,9 +57,15 @@ class Logger
|
|||
/** @var string The log-channel (app, worker, ...) */
|
||||
private $channel;
|
||||
|
||||
public function __construct(string $channel)
|
||||
public function __construct(string $channel, bool $includeAddon = true)
|
||||
{
|
||||
$this->channel = $channel;
|
||||
|
||||
/// @fixme clean solution = Making Addon & Hook dynamic and load them inside the constructor, so there's no custom load logic necessary anymore
|
||||
if ($includeAddon) {
|
||||
Core\Addon::loadAddons();
|
||||
Core\Hook::loadHooks();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -88,35 +91,9 @@ class Logger
|
|||
$minLevel = $minLevel ?? $config->get('system', 'loglevel');
|
||||
$loglevel = self::mapLegacyConfigDebugLevel((string)$minLevel);
|
||||
|
||||
switch ($config->get('system', 'logger_config', 'stream')) {
|
||||
case 'monolog':
|
||||
$loggerTimeZone = new \DateTimeZone('UTC');
|
||||
Monolog\Logger::setTimezone($loggerTimeZone);
|
||||
|
||||
$logger = new Monolog\Logger($this->channel);
|
||||
$logger->pushProcessor(new Monolog\Processor\PsrLogMessageProcessor());
|
||||
$logger->pushProcessor(new Monolog\Processor\ProcessIdProcessor());
|
||||
$logger->pushProcessor(new Monolog\Processor\UidProcessor());
|
||||
$logger->pushProcessor(new IntrospectionProcessor($introspection, LogLevel::DEBUG));
|
||||
|
||||
$stream = $config->get('system', 'logfile');
|
||||
|
||||
// just add a stream in case it's either writable or not file
|
||||
if (!is_file($stream) || is_writable($stream)) {
|
||||
try {
|
||||
static::addStreamHandler($logger, $stream, $loglevel);
|
||||
} catch (\Throwable $e) {
|
||||
// No Logger ..
|
||||
try {
|
||||
$logger = new SyslogLogger($this->channel, $introspection, $loglevel);
|
||||
} catch (\Throwable $e) {
|
||||
// No logger ...
|
||||
$logger = new NullLogger();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
$name = $config->get('system', 'logger_config', 'stream');
|
||||
|
||||
switch ($name) {
|
||||
case 'syslog':
|
||||
try {
|
||||
$logger = new SyslogLogger($this->channel, $introspection, $loglevel, $config->get('system', 'syslog_flags', SyslogLogger::DEFAULT_FLAGS), $config->get('system', 'syslog_facility', SyslogLogger::DEFAULT_FACILITY));
|
||||
|
@ -132,29 +109,48 @@ class Logger
|
|||
|
||||
case 'stream':
|
||||
default:
|
||||
$stream = $config->get('system', 'logfile');
|
||||
// just add a stream in case it's either writable or not file
|
||||
if (!is_file($stream) || is_writable($stream)) {
|
||||
try {
|
||||
$logger = new StreamLogger($this->channel, $stream, $introspection, $fileSystem, $loglevel);
|
||||
} catch (LogLevelException $exception) {
|
||||
// If there's a wrong config value for loglevel, try again with standard
|
||||
$logger = $this->create($database, $config, $profiler, $fileSystem, LogLevel::NOTICE);
|
||||
$logger->warning('Invalid loglevel set in config.', ['loglevel' => $loglevel]);
|
||||
} catch (\Throwable $t) {
|
||||
// No logger ...
|
||||
$logger = new NullLogger();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
$logger = new SyslogLogger($this->channel, $introspection, $loglevel);
|
||||
} catch (LogLevelException $exception) {
|
||||
// If there's a wrong config value for loglevel, try again with standard
|
||||
$logger = $this->create($database, $config, $profiler, $fileSystem, LogLevel::NOTICE);
|
||||
$logger->warning('Invalid loglevel set in config.', ['loglevel' => $loglevel]);
|
||||
} catch (\Throwable $e) {
|
||||
// No logger ...
|
||||
$logger = new NullLogger();
|
||||
$data = [
|
||||
'name' => $name,
|
||||
'channel' => $this->channel,
|
||||
'introspection' => $introspection,
|
||||
'loglevel' => $loglevel,
|
||||
'logger' => null,
|
||||
];
|
||||
try {
|
||||
Core\Hook::callAll('logger_instance', $data);
|
||||
} catch (InternalServerErrorException $exception) {
|
||||
$data['logger'] = null;
|
||||
}
|
||||
|
||||
if (($data['logger'] ?? null) instanceof LoggerInterface) {
|
||||
$logger = $data['logger'];
|
||||
}
|
||||
|
||||
if (empty($logger)) {
|
||||
$stream = $config->get('system', 'logfile');
|
||||
// just add a stream in case it's either writable or not file
|
||||
if (!is_file($stream) || is_writable($stream)) {
|
||||
try {
|
||||
$logger = new StreamLogger($this->channel, $stream, $introspection, $fileSystem, $loglevel);
|
||||
} catch (LogLevelException $exception) {
|
||||
// If there's a wrong config value for loglevel, try again with standard
|
||||
$logger = $this->create($database, $config, $profiler, $fileSystem, LogLevel::NOTICE);
|
||||
$logger->warning('Invalid loglevel set in config.', ['loglevel' => $loglevel]);
|
||||
} catch (\Throwable $t) {
|
||||
// No logger ...
|
||||
$logger = new NullLogger();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
$logger = new SyslogLogger($this->channel, $introspection, $loglevel);
|
||||
} catch (LogLevelException $exception) {
|
||||
// If there's a wrong config value for loglevel, try again with standard
|
||||
$logger = $this->create($database, $config, $profiler, $fileSystem, LogLevel::NOTICE);
|
||||
$logger->warning('Invalid loglevel set in config.', ['loglevel' => $loglevel]);
|
||||
} catch (\Throwable $e) {
|
||||
// No logger ...
|
||||
$logger = new NullLogger();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -197,27 +193,11 @@ class Logger
|
|||
return new NullLogger();
|
||||
}
|
||||
|
||||
$loggerTimeZone = new \DateTimeZone('UTC');
|
||||
Monolog\Logger::setTimezone($loggerTimeZone);
|
||||
|
||||
$introspection = new Introspection(self::$ignoreClassList);
|
||||
|
||||
switch ($config->get('system', 'logger_config', 'stream')) {
|
||||
$name = $config->get('system', 'logger_config', 'stream');
|
||||
|
||||
case 'monolog':
|
||||
$loggerTimeZone = new \DateTimeZone('UTC');
|
||||
Monolog\Logger::setTimezone($loggerTimeZone);
|
||||
|
||||
$logger = new Monolog\Logger(self::DEV_CHANNEL);
|
||||
$logger->pushProcessor(new Monolog\Processor\PsrLogMessageProcessor());
|
||||
$logger->pushProcessor(new Monolog\Processor\ProcessIdProcessor());
|
||||
$logger->pushProcessor(new Monolog\Processor\UidProcessor());
|
||||
$logger->pushProcessor(new IntrospectionProcessor($introspection, LogLevel::DEBUG));
|
||||
|
||||
$logger->pushHandler(new DevelopHandler($developerIp));
|
||||
|
||||
static::addStreamHandler($logger, $stream, LogLevel::DEBUG);
|
||||
break;
|
||||
switch ($name) {
|
||||
|
||||
case 'syslog':
|
||||
$logger = new SyslogLogger(self::DEV_CHANNEL, $introspection, LogLevel::DEBUG);
|
||||
|
@ -225,6 +205,23 @@ class Logger
|
|||
|
||||
case 'stream':
|
||||
default:
|
||||
$data = [
|
||||
'name' => $name,
|
||||
'channel' => self::DEV_CHANNEL,
|
||||
'introspection' => $introspection,
|
||||
'loglevel' => LogLevel::DEBUG,
|
||||
'logger' => null,
|
||||
];
|
||||
try {
|
||||
Core\Hook::callAll('logger_instance', $data);
|
||||
} catch (InternalServerErrorException $exception) {
|
||||
$data['logger'] = null;
|
||||
}
|
||||
|
||||
if (($data['logger'] ?? null) instanceof LoggerInterface) {
|
||||
return $data['logger'];
|
||||
}
|
||||
|
||||
$logger = new StreamLogger(self::DEV_CHANNEL, $stream, $introspection, $fileSystem, LogLevel::DEBUG);
|
||||
break;
|
||||
}
|
||||
|
@ -273,38 +270,4 @@ class Logger
|
|||
return $level;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adding a handler to a given logger instance
|
||||
*
|
||||
* @param LoggerInterface $logger The logger instance
|
||||
* @param mixed $stream The stream which handles the logger output
|
||||
* @param string $level The level, for which this handler at least should handle logging
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws LoggerException
|
||||
*/
|
||||
public static function addStreamHandler(LoggerInterface $logger, $stream, string $level = LogLevel::NOTICE)
|
||||
{
|
||||
if ($logger instanceof Monolog\Logger) {
|
||||
$loglevel = Monolog\Logger::toMonologLevel($level);
|
||||
|
||||
// fallback to notice if an invalid loglevel is set
|
||||
if (!is_int($loglevel)) {
|
||||
$loglevel = LogLevel::NOTICE;
|
||||
}
|
||||
|
||||
try {
|
||||
$fileHandler = new Monolog\Handler\StreamHandler($stream, $loglevel);
|
||||
|
||||
$formatter = new Monolog\Formatter\LineFormatter("%datetime% %channel% [%level_name%]: %message% %context% %extra%\n");
|
||||
$fileHandler->setFormatter($formatter);
|
||||
|
||||
$logger->pushHandler($fileHandler);
|
||||
} catch (\Exception $exception) {
|
||||
throw new LoggerException('Cannot create Monolog Logger.', $exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Core\Logger\Type\Monolog;
|
||||
|
||||
use Friendica\App\Request;
|
||||
use Monolog\Handler;
|
||||
use Monolog\Logger;
|
||||
|
||||
/**
|
||||
* Simple handler for Friendica developers to use for deeper logging
|
||||
*
|
||||
* If you want to debug only interactions from your IP or the IP of a remote server for federation debug,
|
||||
* you'll use Logger::develop() for the duration of your work, and you clean it up when you're done before submitting your PR.
|
||||
*/
|
||||
class DevelopHandler extends Handler\AbstractHandler
|
||||
{
|
||||
/**
|
||||
* @var string The IP of the developer who wants to debug
|
||||
*/
|
||||
private $developerIp;
|
||||
|
||||
/**
|
||||
* @var string The IP of the current request
|
||||
*/
|
||||
private $remoteAddress;
|
||||
|
||||
/**
|
||||
* @param Request $request The current http request
|
||||
* @param string $developerIp The IP of the developer who wants to debug
|
||||
* @param int $level The minimum logging level at which this handler will be triggered
|
||||
* @param bool $bubble Whether the messages that are handled can bubble up the stack or not
|
||||
*/
|
||||
public function __construct(Request $request, $developerIp, int $level = Logger::DEBUG, bool $bubble = true)
|
||||
{
|
||||
parent::__construct($level, $bubble);
|
||||
|
||||
$this->developerIp = $developerIp;
|
||||
$this->remoteAddress = $request->getRemoteAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function handle(array $record): bool
|
||||
{
|
||||
if (!$this->isHandling($record)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Just in case the remote IP is the same as the developer IP log the output
|
||||
if (!is_null($this->developerIp) && $this->remoteAddress != $this->developerIp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false === $this->bubble;
|
||||
}
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2022, the Friendica project
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Friendica\Core\Logger\Type\Monolog;
|
||||
|
||||
use Friendica\Core\Logger\Util\Introspection;
|
||||
use Monolog\Logger;
|
||||
use Monolog\Processor\ProcessorInterface;
|
||||
|
||||
/**
|
||||
* Injects line/file//function where the log message came from
|
||||
*/
|
||||
class IntrospectionProcessor implements ProcessorInterface
|
||||
{
|
||||
private $level;
|
||||
|
||||
private $introspection;
|
||||
|
||||
/**
|
||||
* @param Introspection $introspection Holds the Introspection of the current call
|
||||
* @param string|int $level The minimum logging level at which this Processor will be triggered
|
||||
*/
|
||||
public function __construct(Introspection $introspection, $level = Logger::DEBUG)
|
||||
{
|
||||
$this->level = Logger::toMonologLevel($level);
|
||||
$introspection->addClasses(['Monolog\\']);
|
||||
$this->introspection = $introspection;
|
||||
}
|
||||
|
||||
public function __invoke(array $record): array
|
||||
{
|
||||
// return if the level is not high enough
|
||||
if ($record['level'] < $this->level) {
|
||||
return $record;
|
||||
}
|
||||
// we should have the call source now
|
||||
$record['extra'] = array_merge(
|
||||
$record['extra'],
|
||||
$this->introspection->getRecord()
|
||||
);
|
||||
|
||||
return $record;
|
||||
}
|
||||
}
|
|
@ -5,7 +5,6 @@ This namespace contains the different implementations of a Logger.
|
|||
### Configuration guideline
|
||||
|
||||
The following settings are possible for `logger_config`:
|
||||
- `monolog`: A Logging framework with lots of additions (see [Monolog](https://github.com/Seldaek/monolog/)). There are just Friendica additions inside the Monolog directory
|
||||
- [`stream`](StreamLogger.php): A small logger for files or streams
|
||||
- [`syslog`](SyslogLogger.php): Prints the logging output into the syslog
|
||||
|
||||
|
|
|
@ -192,7 +192,7 @@ class Search
|
|||
}
|
||||
|
||||
// Add found profiles from the global directory to the local directory
|
||||
Worker::add(PRIORITY_LOW, 'SearchDirectory', $search);
|
||||
Worker::add(Worker::PRIORITY_LOW, 'SearchDirectory', $search);
|
||||
|
||||
return $resultList;
|
||||
}
|
||||
|
|
|
@ -69,6 +69,68 @@ class Session
|
|||
DI::session()->clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user id of locally logged in user or false.
|
||||
*
|
||||
* @return int|bool user id or false
|
||||
*/
|
||||
public static function getLocalUser()
|
||||
{
|
||||
$session = DI::session();
|
||||
|
||||
if (!empty($session->get('authenticated')) && !empty($session->get('uid'))) {
|
||||
return intval($session->get('uid'));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the public contact id of logged in user or false.
|
||||
*
|
||||
* @return int|bool public contact id or false
|
||||
*/
|
||||
public static function getPublicContact()
|
||||
{
|
||||
static $public_contact_id = false;
|
||||
|
||||
$session = DI::session();
|
||||
|
||||
if (!$public_contact_id && !empty($session->get('authenticated'))) {
|
||||
if (!empty($session->get('my_address'))) {
|
||||
// Local user
|
||||
$public_contact_id = intval(Contact::getIdForURL($session->get('my_address'), 0, false));
|
||||
} elseif (!empty($session->get('visitor_home'))) {
|
||||
// Remote user
|
||||
$public_contact_id = intval(Contact::getIdForURL($session->get('visitor_home'), 0, false));
|
||||
}
|
||||
} elseif (empty($session->get('authenticated'))) {
|
||||
$public_contact_id = false;
|
||||
}
|
||||
|
||||
return $public_contact_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns public contact id of authenticated site visitor or false
|
||||
*
|
||||
* @return int|bool visitor_id or false
|
||||
*/
|
||||
public static function getRemoteUser()
|
||||
{
|
||||
$session = DI::session();
|
||||
|
||||
if (empty($session->get('authenticated'))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!empty($session->get('visitor_id'))) {
|
||||
return intval($session->get('visitor_id'));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user contact ID of a visitor for the given user ID they are visiting
|
||||
*
|
||||
|
|
|
@ -442,10 +442,13 @@ class System
|
|||
*/
|
||||
public static function getLoadAvg(): array
|
||||
{
|
||||
$content = @file_get_contents('/proc/loadavg');
|
||||
if (empty($content)) {
|
||||
$content = shell_exec('cat /proc/loadavg');
|
||||
if (is_readable('/proc/loadavg')) {
|
||||
$content = @file_get_contents('/proc/loadavg');
|
||||
if (empty($content)) {
|
||||
$content = shell_exec('cat /proc/loadavg');
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($content) || !preg_match("#([.\d]+)\s([.\d]+)\s([.\d]+)\s(\d+)/(\d+)#", $content, $matches)) {
|
||||
$load_arr = sys_getloadavg();
|
||||
if (empty($load_arr)) {
|
||||
|
|
|
@ -35,6 +35,8 @@ class Update
|
|||
const SUCCESS = 0;
|
||||
const FAILED = 1;
|
||||
|
||||
const NEW_TABLE_STRUCTURE_VERSION = 1288;
|
||||
|
||||
/**
|
||||
* Function to check if the Database structure needs an update.
|
||||
*
|
||||
|
@ -63,7 +65,7 @@ class Update
|
|||
}
|
||||
|
||||
// We don't support upgrading from very old versions anymore
|
||||
if ($build < NEW_TABLE_STRUCTURE_VERSION) {
|
||||
if ($build < self::NEW_TABLE_STRUCTURE_VERSION) {
|
||||
$error = DI::l10n()->t('Updates from version %s are not supported. Please update at least to version 2021.01 and wait until the postupdate finished version 1383.', $build);
|
||||
if (DI::mode()->getExecutor() == Mode::INDEX) {
|
||||
die($error);
|
||||
|
@ -73,8 +75,8 @@ class Update
|
|||
}
|
||||
|
||||
// The postupdate has to completed version 1288 for the new post views to take over
|
||||
$postupdate = DI::config()->get('system', 'post_update_version', NEW_TABLE_STRUCTURE_VERSION);
|
||||
if ($postupdate < NEW_TABLE_STRUCTURE_VERSION) {
|
||||
$postupdate = DI::config()->get('system', 'post_update_version', self::NEW_TABLE_STRUCTURE_VERSION);
|
||||
if ($postupdate < self::NEW_TABLE_STRUCTURE_VERSION) {
|
||||
$error = DI::l10n()->t('Updates from postupdate version %s are not supported. Please update at least to version 2021.01 and wait until the postupdate finished version 1383.', $postupdate);
|
||||
if (DI::mode()->getExecutor() == Mode::INDEX) {
|
||||
die($error);
|
||||
|
@ -92,7 +94,7 @@ class Update
|
|||
*/
|
||||
self::run($basePath);
|
||||
} else {
|
||||
Worker::add(PRIORITY_CRITICAL, 'DBUpdate');
|
||||
Worker::add(Worker::PRIORITY_CRITICAL, 'DBUpdate');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,13 +123,13 @@ class UserImport
|
|||
|
||||
$account = json_decode(file_get_contents($file['tmp_name']), true);
|
||||
if ($account === null) {
|
||||
notice(DI::l10n()->t("Error decoding account file"));
|
||||
DI::sysmsg()->addNotice(DI::l10n()->t("Error decoding account file"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (empty($account['version'])) {
|
||||
notice(DI::l10n()->t("Error! No version data in file! This is not a Friendica account file?"));
|
||||
DI::sysmsg()->addNotice(DI::l10n()->t("Error! No version data in file! This is not a Friendica account file?"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ class UserImport
|
|||
// check if username matches deleted account
|
||||
if (DBA::exists('user', ['nickname' => $account['user']['nickname']])
|
||||
|| DBA::exists('userd', ['username' => $account['user']['nickname']])) {
|
||||
notice(DI::l10n()->t("User '%s' already exists on this server!", $account['user']['nickname']));
|
||||
DI::sysmsg()->addNotice(DI::l10n()->t("User '%s' already exists on this server!", $account['user']['nickname']));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -173,7 +173,7 @@ class UserImport
|
|||
$r = self::dbImportAssoc('user', $account['user']);
|
||||
if ($r === false) {
|
||||
Logger::warning("uimport:insert user : ERROR : " . DBA::errorMessage());
|
||||
notice(DI::l10n()->t("User creation error"));
|
||||
DI::sysmsg()->addNotice(DI::l10n()->t("User creation error"));
|
||||
return;
|
||||
}
|
||||
$newuid = self::lastInsertId();
|
||||
|
@ -218,7 +218,7 @@ class UserImport
|
|||
}
|
||||
}
|
||||
if ($errorcount > 0) {
|
||||
notice(DI::l10n()->tt("%d contact not imported", "%d contacts not imported", $errorcount));
|
||||
DI::sysmsg()->addNotice(DI::l10n()->tt("%d contact not imported", "%d contacts not imported", $errorcount));
|
||||
}
|
||||
|
||||
foreach ($account['group'] as &$group) {
|
||||
|
@ -271,7 +271,7 @@ class UserImport
|
|||
|
||||
if ($r === false) {
|
||||
Logger::warning("uimport:insert profile: ERROR : " . DBA::errorMessage());
|
||||
notice(DI::l10n()->t("User profile creation error"));
|
||||
DI::sysmsg()->addNotice(DI::l10n()->t("User profile creation error"));
|
||||
DBA::delete('user', ['uid' => $newuid]);
|
||||
DBA::delete('profile_field', ['uid' => $newuid]);
|
||||
return;
|
||||
|
@ -322,9 +322,9 @@ class UserImport
|
|||
}
|
||||
|
||||
// send relocate messages
|
||||
Worker::add(PRIORITY_HIGH, 'Notifier', Delivery::RELOCATION, $newuid);
|
||||
Worker::add(Worker::PRIORITY_HIGH, 'Notifier', Delivery::RELOCATION, $newuid);
|
||||
|
||||
info(DI::l10n()->t("Done. You can now login with your username and password"));
|
||||
DI::sysmsg()->addInfo(DI::l10n()->t("Done. You can now login with your username and password"));
|
||||
DI::baseUrl()->redirect('login');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,12 +31,20 @@ use Friendica\Util\DateTimeFormat;
|
|||
*/
|
||||
class Worker
|
||||
{
|
||||
const PRIORITY_UNDEFINED = PRIORITY_UNDEFINED;
|
||||
const PRIORITY_CRITICAL = PRIORITY_CRITICAL;
|
||||
const PRIORITY_HIGH = PRIORITY_HIGH;
|
||||
const PRIORITY_MEDIUM = PRIORITY_MEDIUM;
|
||||
const PRIORITY_LOW = PRIORITY_LOW;
|
||||
const PRIORITY_NEGLIGIBLE = PRIORITY_NEGLIGIBLE;
|
||||
/**
|
||||
* @name Priority
|
||||
*
|
||||
* Process priority for the worker
|
||||
* @{
|
||||
*/
|
||||
const PRIORITY_UNDEFINED = 0;
|
||||
const PRIORITY_CRITICAL = 10;
|
||||
const PRIORITY_HIGH = 20;
|
||||
const PRIORITY_MEDIUM = 30;
|
||||
const PRIORITY_LOW = 40;
|
||||
const PRIORITY_NEGLIGIBLE = 50;
|
||||
const PRIORITIES = [self::PRIORITY_CRITICAL, self::PRIORITY_HIGH, self::PRIORITY_MEDIUM, self::PRIORITY_LOW, self::PRIORITY_NEGLIGIBLE];
|
||||
/* @}*/
|
||||
|
||||
const STATE_STARTUP = 1; // Worker is in startup. This takes most time.
|
||||
const STATE_LONG_LOOP = 2; // Worker is processing the whole - long - loop.
|
||||
|
@ -807,7 +815,7 @@ class Worker
|
|||
$top_priority = self::highestPriority();
|
||||
$high_running = self::processWithPriorityActive($top_priority);
|
||||
|
||||
if (!$high_running && ($top_priority > PRIORITY_UNDEFINED) && ($top_priority < PRIORITY_NEGLIGIBLE)) {
|
||||
if (!$high_running && ($top_priority > self::PRIORITY_UNDEFINED) && ($top_priority < self::PRIORITY_NEGLIGIBLE)) {
|
||||
Logger::info('Jobs with a higher priority are waiting but none is executed. Open a fastlane.', ['priority' => $top_priority]);
|
||||
$queues = $active + 1;
|
||||
}
|
||||
|
@ -939,7 +947,7 @@ class Worker
|
|||
private static function nextPriority()
|
||||
{
|
||||
$waiting = [];
|
||||
$priorities = [PRIORITY_CRITICAL, PRIORITY_HIGH, PRIORITY_MEDIUM, PRIORITY_LOW, PRIORITY_NEGLIGIBLE];
|
||||
$priorities = [self::PRIORITY_CRITICAL, self::PRIORITY_HIGH, self::PRIORITY_MEDIUM, self::PRIORITY_LOW, self::PRIORITY_NEGLIGIBLE];
|
||||
foreach ($priorities as $priority) {
|
||||
$stamp = (float)microtime(true);
|
||||
if (DBA::exists('workerqueue', ["`priority` = ? AND `pid` = 0 AND NOT `done` AND `next_try` < ?", $priority, DateTimeFormat::utcNow()])) {
|
||||
|
@ -948,8 +956,8 @@ class Worker
|
|||
self::$db_duration += (microtime(true) - $stamp);
|
||||
}
|
||||
|
||||
if (!empty($waiting[PRIORITY_CRITICAL])) {
|
||||
return PRIORITY_CRITICAL;
|
||||
if (!empty($waiting[self::PRIORITY_CRITICAL])) {
|
||||
return self::PRIORITY_CRITICAL;
|
||||
}
|
||||
|
||||
$running = [];
|
||||
|
@ -1206,8 +1214,8 @@ class Worker
|
|||
* @param (integer|array) priority or parameter array, strings are deprecated and are ignored
|
||||
*
|
||||
* next args are passed as $cmd command line
|
||||
* or: Worker::add(PRIORITY_HIGH, 'Notifier', Delivery::DELETION, $drop_id);
|
||||
* or: Worker::add(array('priority' => PRIORITY_HIGH, 'dont_fork' => true), 'Delivery', $post_id);
|
||||
* or: Worker::add(Worker::PRIORITY_HIGH, 'Notifier', Delivery::DELETION, $drop_id);
|
||||
* or: Worker::add(array('priority' => Worker::PRIORITY_HIGH, 'dont_fork' => true), 'Delivery', $post_id);
|
||||
*
|
||||
* @return int '0' if worker queue entry already existed or there had been an error, otherwise the ID of the worker task
|
||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||
|
@ -1230,7 +1238,7 @@ class Worker
|
|||
return 1;
|
||||
}
|
||||
|
||||
$priority = PRIORITY_MEDIUM;
|
||||
$priority = self::PRIORITY_MEDIUM;
|
||||
// Don't fork from frontend tasks by default
|
||||
$dont_fork = DI::config()->get('system', 'worker_dont_fork', false) || !DI::mode()->isBackend();
|
||||
$created = DateTimeFormat::utcNow();
|
||||
|
@ -1266,9 +1274,9 @@ class Worker
|
|||
$found = DBA::exists('workerqueue', ['command' => $command, 'parameter' => $parameters, 'done' => false]);
|
||||
$added = 0;
|
||||
|
||||
if (!is_int($priority) || !in_array($priority, PRIORITIES)) {
|
||||
if (!is_int($priority) || !in_array($priority, self::PRIORITIES)) {
|
||||
Logger::warning('Invalid priority', ['priority' => $priority, 'command' => $command, 'callstack' => System::callstack(20)]);
|
||||
$priority = PRIORITY_MEDIUM;
|
||||
$priority = self::PRIORITY_MEDIUM;
|
||||
}
|
||||
|
||||
// Quit if there was a database error - a precaution for the update process to 3.5.3
|
||||
|
@ -1383,12 +1391,12 @@ class Worker
|
|||
$delay = (($new_retrial + 2) ** 4) + (rand(1, 30) * ($new_retrial));
|
||||
$next = DateTimeFormat::utc('now + ' . $delay . ' seconds');
|
||||
|
||||
if (($priority < PRIORITY_MEDIUM) && ($new_retrial > 3)) {
|
||||
$priority = PRIORITY_MEDIUM;
|
||||
} elseif (($priority < PRIORITY_LOW) && ($new_retrial > 6)) {
|
||||
$priority = PRIORITY_LOW;
|
||||
} elseif (($priority < PRIORITY_NEGLIGIBLE) && ($new_retrial > 8)) {
|
||||
$priority = PRIORITY_NEGLIGIBLE;
|
||||
if (($priority < self::PRIORITY_MEDIUM) && ($new_retrial > 3)) {
|
||||
$priority = self::PRIORITY_MEDIUM;
|
||||
} elseif (($priority < self::PRIORITY_LOW) && ($new_retrial > 6)) {
|
||||
$priority = self::PRIORITY_LOW;
|
||||
} elseif (($priority < self::PRIORITY_NEGLIGIBLE) && ($new_retrial > 8)) {
|
||||
$priority = self::PRIORITY_NEGLIGIBLE;
|
||||
}
|
||||
|
||||
Logger::info('Deferred task', ['id' => $id, 'retrial' => $new_retrial, 'created' => $queue['created'], 'next_execution' => $next, 'old_prio' => $queue['priority'], 'new_prio' => $priority]);
|
||||
|
|
|
@ -47,10 +47,10 @@ class Cron
|
|||
Logger::info('Add cron entries');
|
||||
|
||||
// Check for spooled items
|
||||
Worker::add(['priority' => PRIORITY_HIGH, 'force_priority' => true], 'SpoolPost');
|
||||
Worker::add(['priority' => Worker::PRIORITY_HIGH, 'force_priority' => true], 'SpoolPost');
|
||||
|
||||
// Run the cron job that calls all other jobs
|
||||
Worker::add(['priority' => PRIORITY_MEDIUM, 'force_priority' => true], 'Cron');
|
||||
Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'Cron');
|
||||
|
||||
// Cleaning dead processes
|
||||
self::killStaleWorkers();
|
||||
|
@ -112,12 +112,12 @@ class Cron
|
|||
// To avoid a blocking situation we reschedule the process at the beginning of the queue.
|
||||
// Additionally we are lowering the priority. (But not PRIORITY_CRITICAL)
|
||||
$new_priority = $entry['priority'];
|
||||
if ($entry['priority'] == PRIORITY_HIGH) {
|
||||
$new_priority = PRIORITY_MEDIUM;
|
||||
} elseif ($entry['priority'] == PRIORITY_MEDIUM) {
|
||||
$new_priority = PRIORITY_LOW;
|
||||
} elseif ($entry['priority'] != PRIORITY_CRITICAL) {
|
||||
$new_priority = PRIORITY_NEGLIGIBLE;
|
||||
if ($entry['priority'] == Worker::PRIORITY_HIGH) {
|
||||
$new_priority = Worker::PRIORITY_MEDIUM;
|
||||
} elseif ($entry['priority'] == Worker::PRIORITY_MEDIUM) {
|
||||
$new_priority = Worker::PRIORITY_LOW;
|
||||
} elseif ($entry['priority'] != Worker::PRIORITY_CRITICAL) {
|
||||
$new_priority = Worker::PRIORITY_NEGLIGIBLE;
|
||||
}
|
||||
DBA::update('workerqueue', ['executed' => DBA::NULL_DATETIME, 'created' => DateTimeFormat::utcNow(), 'priority' => $new_priority, 'pid' => 0], ['id' => $entry["id"]]
|
||||
);
|
||||
|
@ -166,13 +166,13 @@ class Cron
|
|||
Logger::info('Directly deliver inbox', ['inbox' => $delivery['inbox'], 'result' => $result['success']]);
|
||||
continue;
|
||||
} elseif ($delivery['failed'] < 3) {
|
||||
$priority = PRIORITY_HIGH;
|
||||
$priority = Worker::PRIORITY_HIGH;
|
||||
} elseif ($delivery['failed'] < 6) {
|
||||
$priority = PRIORITY_MEDIUM;
|
||||
$priority = Worker::PRIORITY_MEDIUM;
|
||||
} elseif ($delivery['failed'] < 8) {
|
||||
$priority = PRIORITY_LOW;
|
||||
$priority = Worker::PRIORITY_LOW;
|
||||
} else {
|
||||
$priority = PRIORITY_NEGLIGIBLE;
|
||||
$priority = Worker::PRIORITY_NEGLIGIBLE;
|
||||
}
|
||||
|
||||
if ($delivery['failed'] >= DI::config()->get('system', 'worker_defer_limit')) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue