Standardizing the error levels and Normalizing the output messages.

This commit is contained in:
Abdulmhsen B. A. A
2022-05-16 14:42:42 +03:00
parent 316c6b73cd
commit 90997e4f50
20 changed files with 280 additions and 289 deletions

View File

@@ -77,7 +77,7 @@ final class RunCommand extends Command
if (0 === $count) {
$this->write(
'!{date} <info>No Tasks Scheduled to run at this time.</info>',
sprintf('[%s] <info>No Tasks Scheduled to run at this time.</info>', makeDate()),
$input,
$output,
OutputInterface::VERBOSITY_VERY_VERBOSE

View File

@@ -6,7 +6,6 @@ namespace App\Commands\Servers;
use App\Command;
use App\Libs\Config;
use App\Libs\Extends\CliLogger;
use App\Libs\Servers\ServerInterface;
use JsonException;
use RuntimeException;
@@ -25,7 +24,6 @@ final class RemoteCommand extends Command
{
$this->setName('servers:remote')
->setDescription('Get info from the remote server.')
->addOption('redirect-logger', 'r', InputOption::VALUE_NONE, 'Redirect logger to stdout.')
->addOption('list-libraries', null, InputOption::VALUE_NONE, 'List Server Libraries.')
->addOption('list-users', null, InputOption::VALUE_NONE, 'List Server users.')
->addOption('list-users-with-tokens', null, InputOption::VALUE_NONE, 'Show users list with tokens.')
@@ -34,6 +32,7 @@ final class RemoteCommand extends Command
->addOption('search-limit', null, InputOption::VALUE_REQUIRED, 'Search limit', 25)
->addOption('search-output', null, InputOption::VALUE_REQUIRED, 'Search output style [json,yaml]', 'json')
->addOption('config', 'c', InputOption::VALUE_REQUIRED, 'Use Alternative config file.')
->addOption('redirect-logger', 'r', InputOption::VALUE_NONE, 'Not used. will be removed in the future.')
->addArgument('name', InputArgument::REQUIRED, 'Server name');
}
@@ -73,10 +72,6 @@ final class RemoteCommand extends Command
$server = makeServer($config, $name);
if ($input->getOption('redirect-logger')) {
$server->setLogger(new CliLogger($output));
}
if ($input->getOption('list-users') || $input->getOption('list-users-with-tokens')) {
$this->listUsers($input, $output, $server);
}

View File

@@ -7,7 +7,6 @@ namespace App\Commands\State;
use App\Command;
use App\Libs\Config;
use App\Libs\Data;
use App\Libs\Extends\CliLogger;
use Psr\Log\LoggerInterface;
use RuntimeException;
use Symfony\Component\Console\Input\InputInterface;
@@ -33,8 +32,6 @@ class CacheCommand extends Command
{
$this->setName('state:cache')
->setDescription('Cache the GUIDs > Server Internal ID relations.')
->addOption('redirect-logger', 'r', InputOption::VALUE_NONE, 'Redirect logger to stdout.')
->addOption('memory-usage', 'm', InputOption::VALUE_NONE, 'Show memory usage.')
->addOption(
'proxy',
null,
@@ -60,7 +57,9 @@ class CacheCommand extends Command
'Sync selected servers, comma seperated. \'s1,s2\'.',
''
)
->addOption('config', 'c', InputOption::VALUE_REQUIRED, 'Use Alternative config file.');
->addOption('config', 'c', InputOption::VALUE_REQUIRED, 'Use Alternative config file.')
->addOption('redirect-logger', 'r', InputOption::VALUE_NONE, 'Not used. will be removed in the future.')
->addOption('memory-usage', 'm', InputOption::VALUE_NONE, 'Not used. will be removed in the future.');
}
protected function runCommand(InputInterface $input, OutputInterface $output): int
@@ -84,16 +83,6 @@ class CacheCommand extends Command
$isCustom = !empty($serversFilter) && count($selected) >= 1;
$supported = Config::get('supported', []);
$logger = null;
if ($input->getOption('redirect-logger') || $input->getOption('memory-usage')) {
$logger = new CliLogger($output, (bool)$input->getOption('memory-usage'));
}
if (null !== $logger) {
$this->logger = $logger;
}
foreach (Config::get('servers', []) as $serverName => $server) {
$type = strtolower(ag($server, 'type', 'unknown'));
@@ -157,10 +146,6 @@ class CacheCommand extends Command
$server['options'] = $opts;
$server['class'] = makeServer($server, $name);
if (null !== $logger) {
$server['class'] = $server['class']->setLogger($logger);
}
$this->logger->notice(sprintf('Caching \'%s\' server guids relation map.', $name));
array_push($queue, ...$server['class']->cache());

View File

@@ -7,7 +7,6 @@ namespace App\Commands\State;
use App\Command;
use App\Libs\Config;
use App\Libs\Data;
use App\Libs\Extends\CliLogger;
use App\Libs\Mappers\ExportInterface;
use App\Libs\Options;
use App\Libs\Storage\PDO\PDOAdapter;
@@ -41,8 +40,6 @@ class ExportCommand extends Command
{
$this->setName('state:export')
->setDescription('Export watch state to servers.')
->addOption('redirect-logger', 'r', InputOption::VALUE_NONE, 'Redirect logger to stdout.')
->addOption('memory-usage', 'm', InputOption::VALUE_NONE, 'Show memory usage.')
->addOption('force-full', 'f', InputOption::VALUE_NONE, 'Force full export. (will ignore lastSync date)')
->addOption(
'proxy',
@@ -75,7 +72,9 @@ class ExportCommand extends Command
InputOption::VALUE_NONE,
'Ignore date comparison, and update server watched state to match database.'
)
->addOption('config', 'c', InputOption::VALUE_REQUIRED, 'Use Alternative config file.');
->addOption('config', 'c', InputOption::VALUE_REQUIRED, 'Use Alternative config file.')
->addOption('redirect-logger', 'r', InputOption::VALUE_NONE, 'Not used. will be removed in the future.')
->addOption('memory-usage', 'm', InputOption::VALUE_NONE, 'Not used. will be removed in the future.');
}
protected function runCommand(InputInterface $input, OutputInterface $output): int
@@ -104,9 +103,6 @@ class ExportCommand extends Command
$isCustom = !empty($serversFilter) && count($selected) >= 1;
$supported = Config::get('supported', []);
if ($input->getOption('redirect-logger') || $input->getOption('memory-usage')) {
$logger = new CliLogger($output, (bool)$input->getOption('memory-usage'));
}
if (null !== $logger) {
$this->logger = $logger;
@@ -204,7 +200,7 @@ class ExportCommand extends Command
if (null === $after) {
$this->logger->notice(sprintf('%s: Exporting all local play state to this backend.', $name));
} else {
$after = makeDate($after);
$after = makeDate($after)->format('Y-m-d H:i:s T');
$this->logger->notice(
sprintf('%s: Exporting play state changes since \'%s\' to this backend.', $name, $after)
);
@@ -223,7 +219,7 @@ class ExportCommand extends Command
unset($server);
$this->logger->notice(sprintf('HTTP: Waiting on \'%d\' state comparison requests.', count($requests)));
$this->logger->notice(sprintf('HTTP: Sending \'%d\' state comparison requests.', count($requests)));
foreach ($requests as $response) {
$requestData = $response->getInfo('user_data');
@@ -234,7 +230,7 @@ class ExportCommand extends Command
}
}
$this->logger->notice(sprintf('HTTP: Finished processing \'%d\' state comparison requests.', count($requests)));
$this->logger->notice(sprintf('HTTP: Finished sending \'%d\' state comparison requests.', count($requests)));
$changes = $this->mapper->getQueue();
$total = count($changes);
@@ -259,7 +255,7 @@ class ExportCommand extends Command
$this->logger->error($e->getMessage());
}
}
$this->logger->notice(sprintf('HTTP: Finished Processing \'%d\' state change requests.', $total));
$this->logger->notice(sprintf('HTTP: Finished sending \'%d\' state change requests.', $total));
} else {
$this->logger->notice('No state changes detected.');
}

View File

@@ -8,7 +8,6 @@ use App\Command;
use App\Libs\Config;
use App\Libs\Data;
use App\Libs\Entity\StateInterface;
use App\Libs\Extends\CliLogger;
use App\Libs\Mappers\ImportInterface;
use App\Libs\Options;
use App\Libs\Storage\PDO\PDOAdapter;
@@ -43,8 +42,6 @@ class ImportCommand extends Command
{
$this->setName('state:import')
->setDescription('Import watch state from servers.')
->addOption('redirect-logger', 'r', InputOption::VALUE_NONE, 'Redirect logger to stdout.')
->addOption('memory-usage', 'm', InputOption::VALUE_NONE, 'Show memory usage.')
->addOption('force-full', 'f', InputOption::VALUE_NONE, 'Force full import. (ignore lastSync date)')
->addOption(
'proxy',
@@ -78,7 +75,9 @@ class ImportCommand extends Command
InputOption::VALUE_NONE,
'You should not use this flag unless told by the team it will inflate your log output.'
)
->addOption('config', 'c', InputOption::VALUE_REQUIRED, 'Use Alternative config file.');
->addOption('config', 'c', InputOption::VALUE_REQUIRED, 'Use Alternative config file.')
->addOption('redirect-logger', 'r', InputOption::VALUE_NONE, 'Not used. will be removed in the future.')
->addOption('memory-usage', 'm', InputOption::VALUE_NONE, 'Not used. will be removed in the future.');
}
protected function runCommand(InputInterface $input, OutputInterface $output): int
@@ -106,17 +105,6 @@ class ImportCommand extends Command
$isCustom = !empty($serversFilter) && count($selected) >= 1;
$supported = Config::get('supported', []);
$logger = null;
if ($input->getOption('redirect-logger') || $input->getOption('memory-usage')) {
$logger = new CliLogger($output, (bool)$input->getOption('memory-usage'));
}
if (null !== $logger) {
$this->logger = $logger;
$this->mapper->setLogger($logger);
}
$this->logger->info(sprintf('Running WatchState Version \'%s\'.', getAppVersion()));
$mapperOpts = [];
@@ -217,10 +205,6 @@ class ImportCommand extends Command
$server['options'] = $opts;
$server['class'] = makeServer($server, $name);
if (null !== $logger) {
$server['class'] = $server['class']->setLogger($logger);
}
$after = ag($server, 'import.lastSync', null);
if (true === (bool)ag($opts, Options::FORCE_FULL, false) || true === $input->getOption('force-full')) {
@@ -265,7 +249,7 @@ class ImportCommand extends Command
gc_collect_cycles();
}
$this->logger->notice(sprintf('HTTP: Waiting on \'%d\' external requests.', count($queue)));
$this->logger->notice('HTTP: Finished waiting on external requests.');
$queue = $requestData = null;

View File

@@ -9,7 +9,6 @@ use App\Libs\Config;
use App\Libs\Container;
use App\Libs\Data;
use App\Libs\Entity\StateInterface;
use App\Libs\Extends\CliLogger;
use App\Libs\Options;
use Psr\Log\LoggerInterface;
use Psr\SimpleCache\CacheInterface;
@@ -42,8 +41,6 @@ class PushCommand extends Command
{
$this->setName('state:push')
->setDescription('Push queued state change events.')
->addOption('redirect-logger', 'r', InputOption::VALUE_NONE, 'Redirect logger to stdout.')
->addOption('memory-usage', 'm', InputOption::VALUE_NONE, 'Show memory usage.')
->addOption('keep-queue', null, InputOption::VALUE_NONE, 'Do not empty queue after run is successful.')
->addOption(
'proxy',
@@ -63,7 +60,9 @@ class PushCommand extends Command
InputOption::VALUE_NONE,
'Ignore date comparison. Push db state to the server regardless of date.'
)
->addOption('queue-show', null, InputOption::VALUE_NONE, 'Show queued items.');
->addOption('queue-show', null, InputOption::VALUE_NONE, 'Show queued items.')
->addOption('redirect-logger', 'r', InputOption::VALUE_NONE, 'Not used. will be removed in the future.')
->addOption('memory-usage', 'm', InputOption::VALUE_NONE, 'Not used. will be removed in the future.');
}
/**
@@ -165,18 +164,8 @@ class PushCommand extends Command
throw new RuntimeException('No servers were found.');
}
$logger = null;
if ($input->getOption('redirect-logger') || $input->getOption('memory-usage')) {
$logger = new CliLogger($output, (bool)$input->getOption('memory-usage'));
}
$requests = [];
if (null !== $logger) {
$this->logger = $logger;
}
$this->logger->info(sprintf('Running WatchState Version \'%s\'.', getAppVersion()));
foreach ($list as $name => &$server) {
@@ -198,10 +187,6 @@ class PushCommand extends Command
$server['options'] = $opts;
$server['class'] = makeServer($server, $name);
if (null !== $logger) {
$server['class'] = $server['class']->setLogger($logger);
}
array_push($requests, ...$server['class']->push($entities));
}

View File

@@ -1,87 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Libs\Extends;
use Monolog\Logger;
use Psr\Log\LoggerInterface;
use Stringable;
use Symfony\Component\Console\Output\OutputInterface;
final class CliLogger implements LoggerInterface
{
private array $levelMapper = [
Logger::DEBUG => OutputInterface::VERBOSITY_DEBUG,
Logger::INFO => OutputInterface::VERBOSITY_VERY_VERBOSE,
Logger::NOTICE => OutputInterface::VERBOSITY_VERBOSE,
Logger::WARNING => OutputInterface::VERBOSITY_NORMAL,
Logger::ERROR => OutputInterface::VERBOSITY_QUIET,
Logger::CRITICAL => OutputInterface::VERBOSITY_QUIET,
Logger::ALERT => OutputInterface::VERBOSITY_QUIET,
Logger::EMERGENCY => OutputInterface::VERBOSITY_QUIET,
];
public function __construct(public OutputInterface $output, public bool $debug = false)
{
}
public function emergency(Stringable|string $message, array $context = []): void
{
$this->log(Logger::EMERGENCY, $message, $context);
}
public function alert(Stringable|string $message, array $context = []): void
{
$this->log(Logger::ALERT, $message, $context);
}
public function critical(Stringable|string $message, array $context = []): void
{
$this->log(Logger::CRITICAL, $message, $context);
}
public function error(Stringable|string $message, array $context = []): void
{
$this->log(Logger::ERROR, $message, $context);
}
public function warning(Stringable|string $message, array $context = []): void
{
$this->log(Logger::WARNING, $message, $context);
}
public function notice(Stringable|string $message, array $context = []): void
{
$this->log(Logger::NOTICE, $message, $context);
}
public function info(Stringable|string $message, array $context = []): void
{
$this->log(Logger::INFO, $message, $context);
}
public function debug(Stringable|string $message, array $context = []): void
{
$this->log(Logger::DEBUG, $message, $context);
}
public function log($level, Stringable|string $message, array $context = []): void
{
$debug = '';
if ($this->debug) {
$debug = '[M: ' . fsize(memory_get_usage() - BASE_MEMORY) . '] ';
}
$levels = array_flip(Logger::getLevels());
$message = '[' . makeDate() . '] logger.' . ($levels[$level] ?? $level) . ': ' . $debug . $message;
if (!empty($context)) {
$message .= ' [' . arrayToString($context) . ']';
}
$this->output->writeln($message, $this->levelMapper[$level] ?? OutputInterface::VERBOSITY_NORMAL);
}
}

View File

@@ -0,0 +1,87 @@
<?php
namespace App\Libs\Extends;
use Monolog\Handler\AbstractProcessingHandler;
use Monolog\Logger;
use Symfony\Component\Console\Output\OutputInterface;
class ConsoleHandler extends AbstractProcessingHandler
{
private OutputInterface|null $output = null;
private array $levelsMapper = [
OutputInterface::VERBOSITY_QUIET => Logger::ERROR,
OutputInterface::VERBOSITY_NORMAL => Logger::WARNING,
OutputInterface::VERBOSITY_VERBOSE => Logger::NOTICE,
OutputInterface::VERBOSITY_VERY_VERBOSE => Logger::INFO,
OutputInterface::VERBOSITY_DEBUG => Logger::DEBUG,
];
public function __construct(OutputInterface|null $output = null, bool $bubble = true, array $levelsMapper = [])
{
parent::__construct(Logger::DEBUG, $bubble);
$this->output = $output;
if ($levelsMapper) {
$this->levelsMapper = $levelsMapper;
}
}
public function isHandling(array $record): bool
{
return $this->updateLevel() && parent::isHandling($record);
}
public function handle(array $record): bool
{
// we have to update the logging level each time because the verbosity of the
// console output might have changed in the meantime (it is not immutable)
return $this->updateLevel() && parent::handle($record);
}
/**
* Sets the console output to use for printing logs.
*/
public function setOutput(OutputInterface $output): void
{
$this->output = $output;
}
protected function write(array $record): void
{
$message = sprintf(
'[%s] %s.%s: %s %s',
$record['datetime'],
$record['channel'] ?? 'logger',
$record['level_name'] ?? $record['level'] ?? '??',
$record['message'],
!empty($record['context']) ? '{' . arrayToString($record['context']) . '}' : ''
);
$this->output->writeln($message, $this->output->getVerbosity());
}
/**
* Updates the logging level based on the verbosity setting of the console output.
*
* @return bool Whether the handler is enabled and verbosity is not set to quiet
*/
private function updateLevel(): bool
{
if (null === $this->output) {
return false;
}
$verbosity = $this->output->getVerbosity();
if (isset($this->levelsMapper[$verbosity])) {
$this->setLevel($this->levelsMapper[$verbosity]);
} else {
$this->setLevel(Logger::DEBUG);
}
return true;
}
}

View File

@@ -12,8 +12,6 @@ final class ConsoleOutput extends baseConsoleOutput
protected function doWrite(string $message, bool $newline): void
{
$message = str_replace('!{date}', '[' . makeDate('now') . ']', $message);
$this->message = $message;
parent::doWrite($message, $newline);

View File

@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace App\Libs;
use App\Cli;
use App\Libs\Extends\ConsoleHandler;
use App\Libs\Extends\ConsoleOutput;
use App\Libs\Storage\StorageInterface;
use Closure;
@@ -477,6 +478,9 @@ final class Initializer
)
);
break;
case 'console':
$logger->pushHandler(new ConsoleHandler($this->cliOutput));
break;
case 'syslog':
$logger->pushHandler(
new SyslogHandler(

View File

@@ -63,7 +63,13 @@ final class MemoryMapper implements ImportInterface
public function add(string $bucket, string $name, StateInterface $entity, array $opts = []): self
{
if (!$entity->hasGuids() && !$entity->hasRelativeGuid()) {
$this->logger->info(sprintf('Ignoring %s. No valid GUIDs.', $name));
$this->logger->warning(
sprintf(
'%s: Ignoring \'%s\'. No valid/supported external ids.',
$bucket,
$entity->getName()
)
);
Data::increment($bucket, $entity->type . '_failed_no_guid');
return $this;
}
@@ -89,7 +95,14 @@ final class MemoryMapper implements ImportInterface
$data = [];
}
$this->logger->info(sprintf('Adding %s. As new Item.', $name), $data);
$this->logger->notice(
sprintf(
'%s: Adding \'%s\'. As new Item.',
$bucket,
$entity->getName()
),
$data
);
return $this;
}
@@ -110,8 +123,8 @@ final class MemoryMapper implements ImportInterface
$this->changed[$pointer] = $pointer;
$this->removePointers($cloned);
$this->addPointers($this->objects[$pointer], $pointer);
$this->logger->info(
sprintf('%s: Updating \'%s\'. State changed.', $entity->via, $entity->getName()),
$this->logger->notice(
sprintf('%s: Updating \'%s\'. State changed.', $bucket, $entity->getName()),
$this->objects[$pointer]->diff(all: true),
);
return $this;
@@ -119,7 +132,7 @@ final class MemoryMapper implements ImportInterface
if ($this->inDeepDebugMode()) {
$this->logger->debug(
sprintf('%s: \'%s\'. is identical.', $entity->via, $entity->getName()),
sprintf('%s: \'%s\'. is identical.', $bucket, $entity->getName()),
[
'backend' => $cloned->getAll(),
'remote' => $entity->getAll(),
@@ -171,7 +184,7 @@ final class MemoryMapper implements ImportInterface
$count = count($this->changed);
$this->logger->notice(
0 === $count ? 'No changes detected.' : sprintf('Updating backend with \'%d\' changes.', $count)
0 === $count ? 'No changes detected.' : sprintf('Updating backend storage with \'%d\' changes.', $count)
);
$inDryRunMode = $this->inDryRunMode();

View File

@@ -146,7 +146,7 @@ class JellyfinServer implements ServerInterface
$url = $this->url->withPath('/system/Info');
$this->logger->debug(sprintf('%s: Requesting server Unique id.', $this->name), ['url' => $url]);
$this->logger->debug(sprintf('%s: Requesting server unique id.', $this->name), ['url' => $url]);
$response = $this->http->request('GET', (string)$url, $this->getHeaders());
@@ -468,7 +468,7 @@ class JellyfinServer implements ServerInterface
$listDirs = ag($json, 'Items', []);
if (empty($listDirs)) {
$this->logger->notice(
$this->logger->warning(
sprintf(
'%s: Responded with empty list of libraries. Possibly the token has no access to the libraries?',
$this->name
@@ -551,7 +551,7 @@ class JellyfinServer implements ServerInterface
foreach ($it as $entity) {
if ($entity instanceof DecodingError) {
$this->logger->error(
$this->logger->warning(
sprintf(
'%s: Failed to decode one of \'%s\' items. %s',
$this->name,
@@ -630,33 +630,34 @@ class JellyfinServer implements ServerInterface
}
}
$entity->jf_id = null;
foreach ([...$entity->getRelativePointers(), ...$entity->getPointers()] as $guid) {
if (null === ($this->cacheData[$guid] ?? null)) {
continue;
}
$entity->jf_id = $this->cacheData[$guid];
}
$iName = $entity->getName();
if (null === $entity->jf_id) {
$this->logger->notice(
sprintf('%s: Ignoring \'%s\'. Not found in cache.', $this->name, $iName),
[
'guids' => $entity->hasGuids() ? $entity->getGuids() : 'None',
'rGuids' => $entity->hasRelativeGuid() ? $entity->getRelativeGuids() : 'None',
]
);
continue;
if (null === ($entity->suids[$this->name] ?? null)) {
// -- search cache for given external id.
foreach ([...$entity->getRelativePointers(), ...$entity->getPointers()] as $guid) {
if (null === ($this->cacheData[$guid] ?? null)) {
continue;
}
$entity->suids[$this->name] = $this->cacheData[$guid];
}
if (null === ($entity->suids[$this->name] ?? null)) {
$this->logger->warning(
sprintf('%s: Ignoring \'%s\'. No relation map.', $this->name, $iName),
[
'guids' => $entity->hasGuids() ? $entity->getGuids() : 'None',
'rGuids' => $entity->hasRelativeGuid() ? $entity->getRelativeGuids() : 'None',
]
);
continue;
}
}
try {
$url = $this->url->withPath(sprintf('/Users/%s/items', $this->user))->withQuery(
http_build_query(
[
'ids' => $entity->jf_id,
'ids' => $entity->suids[$this->name],
'Fields' => 'ProviderIds,DateCreated,OriginalTitle,SeasonUserData,DateLastSaved',
'enableUserData' => 'true',
'enableImages' => 'false',
@@ -664,9 +665,7 @@ class JellyfinServer implements ServerInterface
)
);
$this->logger->debug(sprintf('%s: Requesting \'%s\' state from remote server.', $this->name, $iName), [
'url' => $url
]);
$this->logger->debug(sprintf('%s: Requesting \'%s\' state.', $this->name, $iName), ['url' => $url]);
$requests[] = $this->http->request(
'GET',
@@ -713,8 +712,8 @@ class JellyfinServer implements ServerInterface
$iName = $state->getName();
if (empty($json)) {
$this->logger->notice(
sprintf('%s: Ignoring \'%s\'. Remote server returned empty result.', $this->name, $iName)
$this->logger->error(
sprintf('%s: Ignoring \'%s\'. Backend returned empty result.', $this->name, $iName)
);
continue;
}
@@ -730,8 +729,8 @@ class JellyfinServer implements ServerInterface
$date = ag($json, ['UserData.LastPlayedDate', 'DateCreated', 'PremiereDate'], null);
if (null === $date) {
$this->logger->notice(
sprintf('%s: Ignoring \'%s\'. Date is not set on remote item.', $this->name, $iName),
$this->logger->warning(
sprintf('%s: Ignoring \'%s\'. No date is set on backend object.', $this->name, $iName),
[
'payload' => $json,
]
@@ -744,13 +743,13 @@ class JellyfinServer implements ServerInterface
if ($date >= $state->updated) {
$this->logger->debug(
sprintf(
'%s: Ignoring \'%s\'. Remote item date is newer or equal to backend entity.',
'%s: Ignoring \'%s\'. Record date is older than backend reported date.',
$this->name,
$iName
),
[
'backend' => makeDate($state->updated),
'remote' => makeDate($date),
'record' => makeDate($state->updated),
'backend' => makeDate($date),
]
);
continue;
@@ -761,7 +760,7 @@ class JellyfinServer implements ServerInterface
$this->logger->debug(
sprintf(
'%s: Changing \'%s\' remote state to \'%s\'.',
'%s: Changing \'%s\' play state to \'%s\'.',
$this->name,
$iName,
$state->isWatched() ? 'Played' : 'Unplayed',
@@ -833,7 +832,7 @@ class JellyfinServer implements ServerInterface
foreach ($it as $entity) {
if ($entity instanceof DecodingError) {
$this->logger->notice(
$this->logger->warning(
sprintf(
'%s: Failed to decode one of \'%s\' items. %s',
$this->name,
@@ -878,7 +877,7 @@ class JellyfinServer implements ServerInterface
);
}
$this->logger->info(sprintf('%s: Parsing \'%s\' response complete.', $this->name, $cName));
$this->logger->info(sprintf('%s: Parsing \'%s\' response is complete.', $this->name, $cName));
};
},
error: function (string $cName, string $type, UriInterface|string $url) {
@@ -927,7 +926,7 @@ class JellyfinServer implements ServerInterface
foreach ($it as $entity) {
if ($entity instanceof DecodingError) {
$this->logger->debug(
$this->logger->warning(
sprintf(
'%s: Failed to decode one of \'%s\' items. %s',
$this->name,
@@ -972,7 +971,7 @@ class JellyfinServer implements ServerInterface
);
}
$this->logger->info(sprintf('%s: Parsing \'%s\' response complete.', $this->name, $cName));
$this->logger->info(sprintf('%s: Parsing \'%s\' response is complete.', $this->name, $cName));
};
},
error: function (string $cName, string $type, UriInterface|string $url) {
@@ -1031,7 +1030,7 @@ class JellyfinServer implements ServerInterface
);
$this->logger->debug(sprintf('%s: Requesting list of server libraries.', $this->name), [
'url' => (string)$url
'url' => $url
]);
$response = $this->http->request('GET', (string)$url, $this->getHeaders());
@@ -1057,7 +1056,7 @@ class JellyfinServer implements ServerInterface
$listDirs = ag($json, 'Items', []);
if (empty($listDirs)) {
$this->logger->notice(
$this->logger->warning(
sprintf('%s: Request to get list of server libraries responded with empty list.', $this->name)
);
Data::add($this->name, 'no_import_update', true);
@@ -1121,7 +1120,7 @@ class JellyfinServer implements ServerInterface
)
);
$this->logger->debug(sprintf('%s: Requesting \'%s\' series external ids.', $this->name, $cName), [
$this->logger->debug(sprintf('%s: Requesting \'%s\' tv shows external ids.', $this->name, $cName), [
'url' => $url
]);
@@ -1139,7 +1138,7 @@ class JellyfinServer implements ServerInterface
} catch (ExceptionInterface $e) {
$this->logger->error(
sprintf(
'%s: Request for \'%s\' series external ids has failed. %s',
'%s: Request for \'%s\' tv shows external ids has failed. %s',
$this->name,
$cName,
$e->getMessage()
@@ -1163,7 +1162,7 @@ class JellyfinServer implements ServerInterface
if ('movies' !== $type && 'tvshows' !== $type) {
$unsupported++;
$this->logger->debug(sprintf('%s: Skipping \'%s\' library. Unsupported type.', $this->name, $title), [
$this->logger->info(sprintf('%s: Skipping \'%s\'. Unsupported type.', $this->name, $title), [
'id' => $key,
'type' => $type,
]);
@@ -1175,7 +1174,7 @@ class JellyfinServer implements ServerInterface
if (null !== $ignoreIds && true === in_array($key, $ignoreIds)) {
$ignored++;
$this->logger->notice(sprintf('%s: Skipping \'%s\'. Ignored by user.', $this->name, $title), [
$this->logger->info(sprintf('%s: Skipping \'%s\'. Ignored by user config.', $this->name, $title), [
'id' => $key,
'type' => $type,
]);
@@ -1196,7 +1195,7 @@ class JellyfinServer implements ServerInterface
)
);
$this->logger->debug(sprintf('%s: Requesting \'%s\' content.', $this->name, $cName), [
$this->logger->debug(sprintf('%s: Requesting \'%s\' media items.', $this->name, $cName), [
'url' => $url
]);
@@ -1213,7 +1212,7 @@ class JellyfinServer implements ServerInterface
);
} catch (ExceptionInterface $e) {
$this->logger->error(
sprintf('%s: Request for \'%s\' content has failed. %s', $this->name, $cName, $e->getMessage()),
sprintf('%s: Request for \'%s\' media items has failed. %s', $this->name, $cName, $e->getMessage()),
[
'url' => $url,
'file' => $e->getFile(),
@@ -1225,7 +1224,7 @@ class JellyfinServer implements ServerInterface
}
if (0 === count($promises)) {
$this->logger->notice(sprintf('%s: No library requests were made.', $this->name), [
$this->logger->warning(sprintf('%s: No library requests were made.', $this->name), [
'total' => count($listDirs),
'ignored' => $ignored,
'unsupported' => $unsupported,
@@ -1281,8 +1280,8 @@ class JellyfinServer implements ServerInterface
$date = $item->UserData?->LastPlayedDate ?? $item->DateCreated ?? $item->PremiereDate ?? null;
if (null === $date) {
$this->logger->debug(
sprintf('%s: Ignoring \'%s\'. Date is not set on remote item.', $this->name, $iName),
$this->logger->warning(
sprintf('%s: Ignoring \'%s\'. Date is not set on backend object.', $this->name, $iName),
[
'payload' => $item,
]
@@ -1403,7 +1402,7 @@ class JellyfinServer implements ServerInterface
if (null === $date) {
$this->logger->notice(
sprintf('%s: Ignoring \'%s\'. Date is not set on remote item.', $this->name, $iName),
sprintf('%s: Ignoring \'%s\'. Date is not set on backend object.', $this->name, $iName),
[
'payload' => get_object_vars($item),
]
@@ -1423,7 +1422,7 @@ class JellyfinServer implements ServerInterface
$message .= sprintf(' Most likely unmatched %s.', $rItem->type);
}
$this->logger->debug($message, ['guids' => !empty($providerIds) ? $providerIds : 'None']);
$this->logger->info($message, ['guids' => !empty($providerIds) ? $providerIds : 'None']);
Data::increment($this->name, $type . '_ignored_no_supported_guid');
return;
}
@@ -1432,7 +1431,7 @@ class JellyfinServer implements ServerInterface
if (null !== $after && $rItem->updated >= $after->getTimestamp()) {
$this->logger->debug(
sprintf(
'%s: Ignoring \'%s\'. Remote item date is equal or newer than last sync date.',
'%s: Ignoring \'%s\'. Backend reported date is equal or newer than last sync date.',
$this->name,
$iName
)
@@ -1443,9 +1442,9 @@ class JellyfinServer implements ServerInterface
}
if (null === ($entity = $mapper->get($rItem))) {
$this->logger->debug(
$this->logger->info(
sprintf(
'%s: Ignoring \'%s\' Not found in backend store. Run state:import to import the item.',
'%s: Ignoring \'%s\'. Media item is not imported.',
$this->name,
$iName,
),
@@ -1471,7 +1470,11 @@ class JellyfinServer implements ServerInterface
if (false === ag($this->options, Options::IGNORE_DATE, false)) {
if ($rItem->updated >= $entity->updated) {
$this->logger->debug(
sprintf('%s: Ignoring \'%s\'. Date is newer or equal to backend entity.', $this->name, $iName),
sprintf(
'%s: Ignoring \'%s\'. Record date is newer or equal to backend item.',
$this->name,
$iName
),
[
'backend' => makeDate($entity->updated),
'remote' => makeDate($rItem->updated),
@@ -1486,7 +1489,7 @@ class JellyfinServer implements ServerInterface
$this->logger->debug(
sprintf(
'%s: Changing \'%s\' remote state to \'%s\'.',
'%s: Changing \'%s\' play state to \'%s\'.',
$this->name,
$iName,
$entity->isWatched() ? 'Played' : 'Unplayed',

View File

@@ -159,7 +159,7 @@ class PlexServer implements ServerInterface
$url = $this->url->withPath('/');
$this->logger->debug(sprintf('%s: Requesting server Unique id.', $this->name), ['url' => $url]);
$this->logger->debug(sprintf('%s: Requesting server unique id.', $this->name), ['url' => $url]);
$response = $this->http->request('GET', (string)$url, $this->getHeaders());
@@ -589,7 +589,7 @@ class PlexServer implements ServerInterface
foreach ($it as $entity) {
if ($entity instanceof DecodingError) {
$this->logger->error(
$this->logger->warning(
sprintf(
'%s: Failed to decode one of \'%s\' items. %s',
$this->name,
@@ -634,7 +634,7 @@ class PlexServer implements ServerInterface
);
}
$this->logger->info(sprintf('%s: Parsing \'%s\' response complete.', $this->name, $cName));
$this->logger->info(sprintf('%s: Parsing \'%s\' response is complete.', $this->name, $cName));
};
},
error: function (string $cName, string $type, UriInterface|string $url) {
@@ -668,34 +668,36 @@ class PlexServer implements ServerInterface
}
}
$entity->plex_id = null;
foreach ([...$entity->getRelativePointers(), ...$entity->getPointers()] as $guid) {
if (null === ($this->cacheData[$guid] ?? null)) {
continue;
}
$entity->plex_id = $this->cacheData[$guid];
}
$iName = $entity->getName();
if (null === $entity->plex_id) {
$this->logger->notice(
sprintf('%s: Ignoring \'%s\'. Not found in cache.', $this->name, $iName),
[
'guids' => $entity->hasGuids() ? $entity->getGuids() : 'None',
'rGuids' => $entity->hasRelativeGuid() ? $entity->getRelativeGuids() : 'None',
]
);
continue;
if (null === ($entity->suids[$this->name] ?? null)) {
foreach ([...$entity->getRelativePointers(), ...$entity->getPointers()] as $guid) {
if (null === ($this->cacheData[$guid] ?? null)) {
continue;
}
$entity->suids[$this->name] = $this->cacheData[$guid];
}
if (null === $entity->suids[$this->name]) {
if (null === $entity->suids[$this->name]) {
$this->logger->notice(
sprintf('%s: Ignoring \'%s\'. No relation map.', $this->name, $iName),
[
'guids' => $entity->hasGuids() ? $entity->getGuids() : 'None',
'rGuids' => $entity->hasRelativeGuid() ? $entity->getRelativeGuids() : 'None',
]
);
continue;
}
}
}
try {
$url = $this->url->withPath('/library/metadata/' . $entity->plex_id)->withQuery(
$url = $this->url->withPath('/library/metadata/' . $entity->suids[$this->name])->withQuery(
http_build_query(['includeGuids' => 1])
);
$this->logger->debug(sprintf('%s: Requesting \'%s\' state from remote server.', $this->name, $iName), [
$this->logger->debug(sprintf('%s: Requesting \'%s\' state.', $this->name, $iName), [
'url' => $url
]);
@@ -745,8 +747,8 @@ class PlexServer implements ServerInterface
$iName = $state->getName();
if (empty($json)) {
$this->logger->notice(
sprintf('%s: Ignoring \'%s\'. Remote server returned empty result.', $this->name, $iName)
$this->logger->error(
sprintf('%s: Ignoring \'%s\'. Backend returned empty result.', $this->name, $iName)
);
continue;
}
@@ -767,7 +769,7 @@ class PlexServer implements ServerInterface
if (0 === $date) {
$this->logger->notice(
sprintf('%s: Ignoring \'%s\'. Date is not set on remote item.', $this->name, $iName),
sprintf('%s: Ignoring \'%s\'. No date is set on backend object.', $this->name, $iName),
[
'payload' => $json,
]
@@ -778,13 +780,13 @@ class PlexServer implements ServerInterface
if ($date >= $state->updated) {
$this->logger->debug(
sprintf(
'%s: Ignoring \'%s\'. Remote item date is newer or equal to backend entity.',
'%s: Ignoring \'%s\'. Record date is older than backend reported date.',
$this->name,
$iName
),
[
'backend' => makeDate($state->updated),
'remote' => makeDate($date),
'record' => makeDate($state->updated),
'backend' => makeDate($date),
]
);
continue;
@@ -802,7 +804,7 @@ class PlexServer implements ServerInterface
$this->logger->debug(
sprintf(
'%s: Changing \'%s\' remote state to \'%s\'.',
'%s: Changing \'%s\' play state to \'%s\'.',
$this->name,
$iName,
$state->isWatched() ? 'Played' : 'Unplayed',
@@ -915,7 +917,7 @@ class PlexServer implements ServerInterface
);
}
$this->logger->info(sprintf('%s: Parsing \'%s\' response complete.', $this->name, $cName));
$this->logger->info(sprintf('%s: Parsing \'%s\' response is complete.', $this->name, $cName));
};
},
error: function (string $cName, string $type, UriInterface|string $url) {
@@ -1010,7 +1012,7 @@ class PlexServer implements ServerInterface
);
}
$this->logger->info(sprintf('%s: Parsing \'%s\' response complete.', $this->name, $cName));
$this->logger->info(sprintf('%s: Parsing \'%s\' response is complete.', $this->name, $cName));
};
},
error: function (string $cName, string $type, UriInterface|string $url) {
@@ -1087,7 +1089,7 @@ class PlexServer implements ServerInterface
$listDirs = ag($json, 'MediaContainer.Directory', []);
if (empty($listDirs)) {
$this->logger->notice(
$this->logger->warning(
sprintf('%s: Request to get list of server libraries responded with empty list.', $this->name)
);
Data::add($this->name, 'no_import_update', true);
@@ -1148,7 +1150,7 @@ class PlexServer implements ServerInterface
)
);
$this->logger->debug(sprintf('%s: Requesting \'%s\' series external ids.', $this->name, $cName), [
$this->logger->debug(sprintf('%s: Requesting \'%s\' tv shows external ids.', $this->name, $cName), [
'url' => $url
]);
@@ -1166,7 +1168,7 @@ class PlexServer implements ServerInterface
} catch (ExceptionInterface $e) {
$this->logger->error(
sprintf(
'%s: Request for \'%s\' series external ids has failed. %s',
'%s: Request for \'%s\' tv shows external ids has failed. %s',
$this->name,
$cName,
$e->getMessage()
@@ -1190,7 +1192,7 @@ class PlexServer implements ServerInterface
if ('movie' !== $type && 'show' !== $type) {
$unsupported++;
$this->logger->debug(sprintf('%s: Skipping \'%s\' library. Unsupported type.', $this->name, $title), [
$this->logger->info(sprintf('%s: Skipping \'%s\'. Unsupported type.', $this->name, $title), [
'id' => $key,
'type' => $type,
]);
@@ -1201,7 +1203,7 @@ class PlexServer implements ServerInterface
if (null !== $ignoreIds && true === in_array($key, $ignoreIds)) {
$ignored++;
$this->logger->notice(sprintf('%s: Skipping \'%s\'. Ignored by user.', $this->name, $title), [
$this->logger->info(sprintf('%s: Skipping \'%s\'. Ignored by user.', $this->name, $title), [
'id' => $key,
'type' => $type,
]);
@@ -1220,7 +1222,7 @@ class PlexServer implements ServerInterface
)
);
$this->logger->debug(sprintf('%s: Requesting \'%s\' content.', $this->name, $cName), [
$this->logger->debug(sprintf('%s: Requesting \'%s\' media items.', $this->name, $cName), [
'url' => $url
]);
@@ -1237,7 +1239,7 @@ class PlexServer implements ServerInterface
);
} catch (ExceptionInterface $e) {
$this->logger->error(
sprintf('%s: Request for \'%s\' content has failed. %s', $this->name, $cName, $e->getMessage()),
sprintf('%s: Request for \'%s\' media items has failed. %s', $this->name, $cName, $e->getMessage()),
[
'url' => $url,
'file' => $e->getFile(),
@@ -1249,7 +1251,7 @@ class PlexServer implements ServerInterface
}
if (0 === count($promises)) {
$this->logger->notice(sprintf('%s: No library requests were made.', $this->name), [
$this->logger->warning(sprintf('%s: No library requests were made.', $this->name), [
'total' => count($listDirs),
'ignored' => $ignored,
'unsupported' => $unsupported,
@@ -1306,7 +1308,7 @@ class PlexServer implements ServerInterface
if (0 === $date) {
$this->logger->debug(
sprintf('%s: Ignoring \'%s\'. Date is not set on remote item.', $this->name, $iName),
sprintf('%s: Ignoring \'%s\'. Date is not set on backend object.', $this->name, $iName),
[
'payload' => $item,
]
@@ -1417,7 +1419,7 @@ class PlexServer implements ServerInterface
if (null === $date) {
$this->logger->notice(
sprintf('%s: Ignoring \'%s\'. Date is not set on remote item.', $this->name, $iName),
sprintf('%s: Ignoring \'%s\'. Date is not set on backend object.', $this->name, $iName),
[
'payload' => get_object_vars($item),
]
@@ -1451,7 +1453,7 @@ class PlexServer implements ServerInterface
if (null !== $after && $rItem->updated >= $after->getTimestamp()) {
$this->logger->debug(
sprintf(
'%s: Ignoring \'%s\'. Remote item date is equal or newer than last sync date.',
'%s: Ignoring \'%s\'. Backend reported date is equal or newer than last sync date.',
$this->name,
$iName
)
@@ -1464,7 +1466,7 @@ class PlexServer implements ServerInterface
if (null === ($entity = $mapper->get($rItem))) {
$this->logger->debug(
sprintf(
'%s: Ignoring \'%s\' Not found in backend store. Run state:import to import the item.',
'%s: Ignoring \'%s\'. Media item is not imported.',
$this->name,
$iName,
),
@@ -1490,7 +1492,11 @@ class PlexServer implements ServerInterface
if (false === ag($this->options, Options::IGNORE_DATE, false)) {
if ($rItem->updated >= $entity->updated) {
$this->logger->debug(
sprintf('%s: Ignoring \'%s\'. Date is newer or equal to backend entity.', $this->name, $iName),
sprintf(
'%s: Ignoring \'%s\'. Record date is newer or equal to backend item.',
$this->name,
$iName
),
[
'backend' => makeDate($entity->updated),
'remote' => makeDate($rItem->updated),
@@ -1512,7 +1518,7 @@ class PlexServer implements ServerInterface
$this->logger->debug(
sprintf(
'%s: Changing \'%s\' remote state to \'%s\'.',
'%s: Changing \'%s\' play state to \'%s\'.',
$this->name,
$iName,
$entity->isWatched() ? 'Played' : 'Unplayed',
@@ -1602,7 +1608,9 @@ class PlexServer implements ServerInterface
// -- DO NOT accept plex relative unique ids, we generate our own.
if (substr_count($val, '/') >= 3) {
if (true === (bool)ag($this->options, Options::DEEP_DEBUG)) {
$this->logger->debug(sprintf('%s: Parsing \'%s\' is not supported.', $this->name, $val));
$this->logger->warning(
sprintf('%s: Parsing \'%s\' custom agent identifier is not supported.', $this->name, $val)
);
}
continue;
}
@@ -1643,7 +1651,9 @@ class PlexServer implements ServerInterface
// -- DO NOT accept plex relative unique ids, we generate our own.
if (substr_count($val, '/') >= 3) {
if (true === (bool)ag($this->options, Options::DEEP_DEBUG)) {
$this->logger->debug(sprintf('%s: Parsing \'%s\' is not supported.', $this->name, $val));
$this->logger->warning(
sprintf('%s: Parsing \'%s\' custom agent identifier is not supported.', $this->name, $val)
);
}
continue;
}
@@ -1816,7 +1826,7 @@ class PlexServer implements ServerInterface
return $agentGuid[0] . '://' . before($agentGuid[1], '?');
} catch (Throwable $e) {
$this->logger->error(
sprintf('%s: Error parsing Plex legacy agent identifier. %s', $this->name, $e->getMessage()),
sprintf('%s: Error parsing plex legacy agent identifier. %s', $this->name, $e->getMessage()),
[
'guid' => $agent,
]
@@ -1849,7 +1859,7 @@ class PlexServer implements ServerInterface
if (201 !== $response->getStatusCode()) {
$this->logger->error(
sprintf(
'%s: Request to get temp token for userid \'%s\' responded with unexpected http status code \'%d\'.',
'%s: Request to get temp token for user id \'%s\' responded with unexpected http status code \'%d\'.',
$this->name,
$userId,
$response->getStatusCode()