Made possible to be able to restore backend data using the backup page.
This commit is contained in:
@@ -10,14 +10,14 @@
|
||||
<div class="field is-grouped">
|
||||
<p class="control">
|
||||
<button class="button is-primary" @click="queueTask" :disabled="isLoading"
|
||||
:class="{'is-loading':isLoading, 'is-primary':!queued, 'is-danger':queued}">
|
||||
:class="{ 'is-loading': isLoading, 'is-primary': !queued, 'is-danger': queued }">
|
||||
<span class="icon"><i class="fas fa-sd-card"></i></span>
|
||||
<span>{{ !queued ? 'Queue backup' : 'Remove from queue' }}</span>
|
||||
</button>
|
||||
</p>
|
||||
<p class="control">
|
||||
<button class="button is-info" @click="loadContent" :disabled="isLoading"
|
||||
:class="{'is-loading':isLoading}">
|
||||
:class="{ 'is-loading': isLoading }">
|
||||
<span class="icon"><i class="fas fa-sync"></i></span>
|
||||
</button>
|
||||
</p>
|
||||
@@ -32,20 +32,21 @@
|
||||
|
||||
<div class="column is-12" v-if="items.length < 1 || isLoading">
|
||||
<Message v-if="isLoading" message_class="is-background-info-90 has-text-dark" icon="fas fa-spinner fa-spin"
|
||||
title="Loading" message="Loading data. Please wait..."/>
|
||||
title="Loading" message="Loading data. Please wait..." />
|
||||
<Message v-else title="Warning" message_class="is-background-warning-80 has-text-dark"
|
||||
icon="fas fa-exclamation-triangle">
|
||||
icon="fas fa-exclamation-triangle">
|
||||
No backups found.
|
||||
</Message>
|
||||
</div>
|
||||
|
||||
<div class="column is-6-tablet" v-for="(item, index) in items" :key="'backup-'+index">
|
||||
<div class="column is-6-tablet" v-for="(item, index) in items" :key="'backup-' + index">
|
||||
<div class="card">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title is-text-overflow pr-1">
|
||||
<span class="icon"><i class="fas fa-download" :class="{'fa-spin':item?.isDownloading}"></i> </span>
|
||||
<span class="icon"><i class="fas fa-download"
|
||||
:class="{ 'fa-spin': item?.isDownloading }"></i> </span>
|
||||
<span>
|
||||
<NuxtLink @click="downloadFile(item)" v-text="item.filename"/>
|
||||
<NuxtLink @click="downloadFile(item)" v-text="item.filename" />
|
||||
</span>
|
||||
</p>
|
||||
<span class="card-header-icon">
|
||||
@@ -54,6 +55,24 @@
|
||||
</NuxtLink>
|
||||
</span>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<div class="field is-grouped">
|
||||
<div class="control is-expanded">
|
||||
<div class="select is-fullwidth">
|
||||
<select v-model="item.selected" class="is-capitalized" required>
|
||||
<option value="" selected disabled>Restore To this Backend</option>
|
||||
<option v-for="backend in backends" :key="backend.name" :value="backend.name"
|
||||
v-text="backend.name" />
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control">
|
||||
<button class="button is-primary" :disabled="'' === item.selected" @click="generateCommand(item)">
|
||||
Go
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer-item">
|
||||
<div class="card-footer-item">
|
||||
<span class="icon"><i class="fas fa-calendar"></i> </span>
|
||||
@@ -75,7 +94,7 @@
|
||||
|
||||
<div class="column is-12">
|
||||
<Message message_class="has-background-info-90 has-text-dark" :toggle="show_page_tips"
|
||||
@toggle="show_page_tips = !show_page_tips" :use-toggle="true" title="Tips" icon="fas fa-info-circle">
|
||||
@toggle="show_page_tips = !show_page_tips" :use-toggle="true" title="Tips" icon="fas fa-info-circle">
|
||||
<ul>
|
||||
<li>
|
||||
Backups that are tagged <code>Automatic</code> are subject to auto deletion after <code>90</code> days
|
||||
@@ -89,13 +108,17 @@
|
||||
<li>
|
||||
To generate a manual backup, go to the
|
||||
<NuxtLink to="/backends"><span class="icon"><i class="fas fa-server"></i></span> Backends</NuxtLink>
|
||||
page and from the drop down menu select the 4th option `Backup this backend play state`, or via cli using
|
||||
<code>state:backup</code> command from the console. or by <span class="icon"><i
|
||||
class="fas fa-terminal"></i></span>
|
||||
page and from the drop down menu select the 4th option `Backup this backend play state`, or via cli
|
||||
using
|
||||
<code>state:backup</code> command from the console. or by <span class="icon"><i class="fas fa-terminal" /></span>
|
||||
<NuxtLink :to="makeConsoleCommand('state:backup -s [backend] --file /config/backup/[file]')"
|
||||
v-text="'Web Console'"/>
|
||||
v-text="'Web Console'" />
|
||||
page.
|
||||
</li>
|
||||
<li>
|
||||
The restore process will take you to <span class="icon"><i class="fas fa-terminal" /></span>
|
||||
<NuxtLink to="/console" v-text="'Web Console'" /> and pre-fill the command for you to run.
|
||||
</li>
|
||||
</ul>
|
||||
</Message>
|
||||
</div>
|
||||
@@ -106,15 +129,17 @@
|
||||
<script setup>
|
||||
import request from '~/utils/request'
|
||||
import moment from 'moment'
|
||||
import {humanFileSize, makeConsoleCommand, notification, TOOLTIP_DATE_FORMAT} from '~/utils/index'
|
||||
import { humanFileSize, makeConsoleCommand, notification, TOOLTIP_DATE_FORMAT } from '~/utils/index'
|
||||
import Message from '~/components/Message'
|
||||
import {useStorage} from '@vueuse/core'
|
||||
import { useStorage } from '@vueuse/core'
|
||||
|
||||
useHead({title: 'Backups'})
|
||||
useHead({ title: 'Backups' })
|
||||
const items = ref([])
|
||||
const backends = ref([])
|
||||
const isLoading = ref(false)
|
||||
const queued = ref(true)
|
||||
const show_page_tips = useStorage('show_page_tips', true)
|
||||
const api_user = useStorage('api_user', 'main')
|
||||
|
||||
const loadContent = async () => {
|
||||
items.value = []
|
||||
@@ -122,7 +147,13 @@ const loadContent = async () => {
|
||||
|
||||
try {
|
||||
const response = await request('/system/backup')
|
||||
items.value = await response.json()
|
||||
const json = await response.json()
|
||||
|
||||
json.forEach(element => {
|
||||
element['selected'] = ''
|
||||
items.value.push(element)
|
||||
});
|
||||
|
||||
if (useRoute().name !== 'backup') {
|
||||
return
|
||||
}
|
||||
@@ -173,7 +204,7 @@ const queueTask = async () => {
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await request(`/tasks/backup/queue`, {method: is_queued ? 'DELETE' : 'POST'})
|
||||
const response = await request(`/tasks/backup/queue`, { method: is_queued ? 'DELETE' : 'POST' })
|
||||
if (response.ok) {
|
||||
notification('success', 'Success', `Task backup has been ${is_queued ? 'removed from the queue' : 'queued'}.`)
|
||||
queued.value = !is_queued
|
||||
@@ -189,7 +220,7 @@ const deleteFile = async (item) => {
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await request(`/system/backup/${item.filename}`, {method: 'DELETE'})
|
||||
const response = await request(`/system/backup/${item.filename}`, { method: 'DELETE' })
|
||||
|
||||
if (200 === response.status) {
|
||||
notification('success', 'Success', `Backup file '${item.filename}' has been deleted.`)
|
||||
@@ -202,7 +233,7 @@ const deleteFile = async (item) => {
|
||||
try {
|
||||
json = await response.json()
|
||||
} catch (e) {
|
||||
json = {error: {code: response.status, message: response.statusText}}
|
||||
json = { error: { code: response.status, message: response.statusText } }
|
||||
}
|
||||
|
||||
notification('error', 'Error', `API error. ${json.error.code}: ${json.error.message}`)
|
||||
@@ -217,5 +248,25 @@ const isQueued = async () => {
|
||||
return Boolean(json.queued)
|
||||
}
|
||||
|
||||
onMounted(async () => await loadContent())
|
||||
onMounted(async () => {
|
||||
const response = await request('/backends')
|
||||
backends.value = await response.json()
|
||||
await loadContent()
|
||||
})
|
||||
|
||||
const generateCommand = async item => {
|
||||
const user = api_user.value
|
||||
const backend = item.selected
|
||||
const file = item.filename
|
||||
|
||||
if (false === confirm(`Are you sure you want to restore '${user}@${backend}' using '${file}'?`)) {
|
||||
return;
|
||||
}
|
||||
|
||||
await navigateTo(makeConsoleCommand(r("backend:restore --assume-yes --execute -v --user '{user}' --select-backend '{backend}' -- '{file}'", {
|
||||
user,
|
||||
backend,
|
||||
file,
|
||||
})));
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -7,14 +7,18 @@ namespace App\Commands\Backend;
|
||||
use App\Command;
|
||||
use App\Libs\Attributes\Route\Cli;
|
||||
use App\Libs\Config;
|
||||
use App\Libs\Extends\StreamLogHandler;
|
||||
use App\Libs\LogSuppressor;
|
||||
use App\Libs\Enums\Http\Status;
|
||||
use App\Libs\Exceptions\RuntimeException;
|
||||
use App\Libs\Mappers\Import\RestoreMapper;
|
||||
use App\Libs\Message;
|
||||
use App\Libs\Options;
|
||||
use App\Libs\Stream;
|
||||
use App\Libs\QueueRequests;
|
||||
use App\Libs\UserContext;
|
||||
use DirectoryIterator;
|
||||
use Monolog\Logger;
|
||||
use Psr\Log\LoggerInterface as iLogger;
|
||||
use Symfony\Component\Console\Completion\CompletionInput;
|
||||
use Symfony\Component\Console\Completion\CompletionSuggestions;
|
||||
@@ -43,8 +47,11 @@ class RestoreCommand extends Command
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(private readonly QueueRequests $queue, private readonly iLogger $logger)
|
||||
{
|
||||
public function __construct(
|
||||
private readonly QueueRequests $queue,
|
||||
private readonly iLogger $logger,
|
||||
private LogSuppressor $suppressor
|
||||
) {
|
||||
set_time_limit(0);
|
||||
ini_set('memory_limit', '-1');
|
||||
|
||||
@@ -64,6 +71,7 @@ class RestoreCommand extends Command
|
||||
->addOption('select-backend', 's', InputOption::VALUE_REQUIRED, 'Select backend.')
|
||||
->addOption('user', 'u', InputOption::VALUE_REQUIRED, 'Select sub user.', 'main')
|
||||
->addArgument('file', InputArgument::REQUIRED, 'Backup file to restore from')
|
||||
->addOption('logfile', null, InputOption::VALUE_REQUIRED, 'Save console output to file.')
|
||||
->setHelp(
|
||||
r(
|
||||
<<<HELP
|
||||
@@ -139,6 +147,12 @@ class RestoreCommand extends Command
|
||||
*/
|
||||
protected function runCommand(iInput $input, iOutput $output): int
|
||||
{
|
||||
if (null !== ($logfile = $input->getOption('logfile')) && true === ($this->logger instanceof Logger)) {
|
||||
$this->logger->setHandlers([
|
||||
$this->suppressor->withHandler(new StreamLogHandler(new Stream($logfile, 'w'), $output))
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->single(fn(): int => $this->process($input, $output), $output);
|
||||
}
|
||||
|
||||
@@ -180,7 +194,7 @@ class RestoreCommand extends Command
|
||||
$file = $newFile;
|
||||
}
|
||||
|
||||
$opStart = makeDate();
|
||||
$opStart = microtime(true);
|
||||
|
||||
$mapper = new RestoreMapper($this->logger, $file);
|
||||
|
||||
@@ -209,29 +223,35 @@ class RestoreCommand extends Command
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
if (true === (bool)ag($backend, 'import.enabled') && false === $input->getOption('assume-yes')) {
|
||||
$helper = $this->getHelper('question');
|
||||
$text =
|
||||
<<<TEXT
|
||||
<options=bold,underscore>Are you sure?</> <comment>[Y|N] [Default: No]</comment>
|
||||
-----------------
|
||||
You are about to restore backend that has imports enabled.
|
||||
if (true === (bool)ag($backend, 'import.enabled')) {
|
||||
if (false === $input->getOption('assume-yes')) {
|
||||
$helper = $this->getHelper('question');
|
||||
$text = <<<TEXT
|
||||
<options=bold,underscore>Are you sure?</> <comment>[Y|N] [Default: No]</comment>
|
||||
-----------------
|
||||
You are about to restore backend that has imports enabled.
|
||||
|
||||
<fg=white;bg=red;options=bold>The changes will propagate back to your backends.</>
|
||||
<fg=white;bg=red;options=bold>The changes will propagate back to your backends.</>
|
||||
|
||||
<comment>If you understand the risks then answer with [<info>yes</info>]
|
||||
If you don't please run same command with <info>[--help]</info> flag.
|
||||
</comment>
|
||||
-----------------
|
||||
TEXT;
|
||||
<comment>If you understand the risks then answer with [<info>yes</info>]
|
||||
If you don't please run same command with <info>[--help]</info> flag.
|
||||
</comment>
|
||||
-----------------
|
||||
TEXT;
|
||||
|
||||
$question = new ConfirmationQuestion($text . PHP_EOL . '> ', false);
|
||||
$question = new ConfirmationQuestion($text . PHP_EOL . '> ', false);
|
||||
|
||||
if (false === $helper->ask($input, $output, $question)) {
|
||||
$output->writeln(
|
||||
'<comment>Restore operation is cancelled, you answered no for risk assessment, or interaction is disabled.</comment>'
|
||||
);
|
||||
return self::SUCCESS;
|
||||
if (false === $helper->ask($input, $output, $question)) {
|
||||
$output->writeln(
|
||||
'<comment>Restore operation is cancelled, you answered no for risk assessment, or interaction is disabled.</comment>'
|
||||
);
|
||||
return self::SUCCESS;
|
||||
}
|
||||
} else {
|
||||
$this->logger->notice("The restore target '{user}@{backend}' has import enabled, which means the changes will propagate back to the other backends.", [
|
||||
'user' => $userContext->name,
|
||||
'backend' => $name,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,12 +264,11 @@ class RestoreCommand extends Command
|
||||
],
|
||||
]);
|
||||
|
||||
$start = makeDate();
|
||||
$start = microtime(true);
|
||||
$mapper->loadData();
|
||||
$end = makeDate();
|
||||
|
||||
$this->logger->notice(
|
||||
"SYSTEM: Loading restore data of '{user}@{backend}' completed in '{time.duration}'s. Memory usage '{memory.now}'.",
|
||||
"SYSTEM: Loading restore data of '{user}@{backend}' completed in '{duration}'s. Memory usage '{memory.now}'.",
|
||||
[
|
||||
'backend' => $name,
|
||||
'user' => $userContext->name,
|
||||
@@ -257,16 +276,12 @@ class RestoreCommand extends Command
|
||||
'now' => getMemoryUsage(),
|
||||
'peak' => getPeakMemoryUsage(),
|
||||
],
|
||||
'time' => [
|
||||
'start' => $start,
|
||||
'end' => $end,
|
||||
'duration' => $end->getTimestamp() - $start->getTimestamp(),
|
||||
],
|
||||
'duration' => round(microtime(true) - $start, 4),
|
||||
]
|
||||
);
|
||||
|
||||
if (false === $input->getOption('execute')) {
|
||||
$output->writeln('<info>No changes will be committed to backend.</info>');
|
||||
$this->logger->notice("No changes will be committed to backend. To execute the changes pass '--execute' flag option.");
|
||||
}
|
||||
|
||||
$opts = [
|
||||
@@ -291,7 +306,7 @@ class RestoreCommand extends Command
|
||||
|
||||
$requests = $backend->export($mapper, $this->queue, null);
|
||||
|
||||
$start = makeDate();
|
||||
$start = microtime(true);
|
||||
$this->logger->notice("SYSTEM: Sending '{total}' play state comparison requests for '{user}@{backend}'.", [
|
||||
'backend' => $name,
|
||||
'total' => count($requests),
|
||||
@@ -307,16 +322,11 @@ class RestoreCommand extends Command
|
||||
}
|
||||
}
|
||||
|
||||
$end = makeDate();
|
||||
$this->logger->notice("SYSTEM: Completed '{total}' requests in '{time.duration}'s for '{user}@{backend}'.", [
|
||||
$this->logger->notice("SYSTEM: Completed '{total}' requests in '{duration}'s for '{user}@{backend}'.", [
|
||||
'backend' => $name,
|
||||
'total' => count($requests),
|
||||
'user' => $userContext->name,
|
||||
'time' => [
|
||||
'start' => $start,
|
||||
'end' => $end,
|
||||
'duration' => $end->getTimestamp() - $start->getTimestamp(),
|
||||
],
|
||||
'duration' => round(microtime(true) - $start, 4),
|
||||
]);
|
||||
|
||||
$total = count($this->queue->getQueue());
|
||||
@@ -335,7 +345,7 @@ class RestoreCommand extends Command
|
||||
'user' => $userContext->name,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
if ($total < 1 || false === $input->getOption('execute')) {
|
||||
return self::SUCCESS;
|
||||
}
|
||||
@@ -378,19 +388,14 @@ class RestoreCommand extends Command
|
||||
}
|
||||
}
|
||||
|
||||
$opEnd = makeDate();
|
||||
$this->logger->notice(
|
||||
"SYSTEM: Sent '{total}' change play state requests to '{client}: {user}@{backend}' in '{time.duration}'s.",
|
||||
"SYSTEM: Sent '{total}' change play state requests to '{client}: {user}@{backend}' in '{duration}'s.",
|
||||
[
|
||||
'total' => $total,
|
||||
'backend' => $name,
|
||||
'user' => $userContext->name,
|
||||
'client' => $backend->getContext()->clientName,
|
||||
'time' => [
|
||||
'start' => $opStart,
|
||||
'end' => $opEnd,
|
||||
'duration' => $opEnd->getTimestamp() - $opStart->getTimestamp(),
|
||||
],
|
||||
'duration' => round(microtime(true) - $opStart, 4),
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
@@ -223,7 +223,9 @@ class ExportCommand extends Command
|
||||
}
|
||||
|
||||
if (!isset($supported[$type])) {
|
||||
$this->logger->error("SYSTEM: Ignoring '{user}@{backend}'. Unexpected type '{type}'.", [
|
||||
$this->logger->error(
|
||||
"SYSTEM: Ignoring '{user}@{backend}'. Unexpected type '{type}'.",
|
||||
[
|
||||
'type' => $type,
|
||||
'backend' => $backendName,
|
||||
'user' => $userContext->name,
|
||||
@@ -625,7 +627,7 @@ class ExportCommand extends Command
|
||||
'backends' => implode(', ', array_keys($backends)),
|
||||
]);
|
||||
|
||||
$this->logger->notice("SYSTEM: Preloading '{user}' - '{mapper}' data. Memory: {memory.now}", [
|
||||
$this->logger->notice("SYSTEM: Preloading '{user}' - '{mapper}' data. Memory usage '{memory.now}'.", [
|
||||
'user' => $userContext->name,
|
||||
'mapper' => afterLast($userContext->mapper::class, '\\'),
|
||||
'memory' => [
|
||||
@@ -636,7 +638,7 @@ class ExportCommand extends Command
|
||||
|
||||
$userContext->mapper->reset()->loadData();
|
||||
|
||||
$this->logger->notice("SYSTEM: Preloading '{mapper}' data is complete. Memory: {memory.now}", [
|
||||
$this->logger->notice("SYSTEM: Preloading '{mapper}' data is complete. Memory usage '{memory.now}'.", [
|
||||
'mapper' => afterLast($userContext->mapper::class, '\\'),
|
||||
'memory' => [
|
||||
'now' => getMemoryUsage(),
|
||||
@@ -685,7 +687,7 @@ class ExportCommand extends Command
|
||||
}
|
||||
}
|
||||
|
||||
$start = makeDate();
|
||||
$start = microtime(true);
|
||||
$this->logger->notice("SYSTEM: Sending '{total}' play state comparison requests for '{user}'.", [
|
||||
'total' => count($requests),
|
||||
'user' => $userContext->name,
|
||||
@@ -700,30 +702,10 @@ class ExportCommand extends Command
|
||||
}
|
||||
}
|
||||
|
||||
$end = makeDate();
|
||||
$this->logger->notice(
|
||||
"SYSTEM: Completed '{total}' play state comparison requests for '{user}' in '{time.duration}'s. Parsed '{responses.size}' of data.",
|
||||
[
|
||||
'user' => $userContext->name,
|
||||
'total' => count($requests),
|
||||
'time' => [
|
||||
'start' => $start,
|
||||
'end' => $end,
|
||||
'duration' => $end->getTimestamp() - $start->getTimestamp(),
|
||||
],
|
||||
'memory' => [
|
||||
'now' => getMemoryUsage(),
|
||||
'peak' => getPeakMemoryUsage(),
|
||||
],
|
||||
'responses' => [
|
||||
'size' => fsize((int)Message::get('response.size', 0)),
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->logger->notice("Export mode ended for '{user}: {backends}'.", [
|
||||
$this->logger->notice("Export mode ended for '{user}: {backends}' in '{duration}'s.", [
|
||||
'user' => $userContext->name,
|
||||
'backends' => implode(', ', array_keys($backends)),
|
||||
'duration' => round(microtime(true) - $start, 4),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -381,7 +381,7 @@ class ImportCommand extends Command
|
||||
/** @var array<array-key,ResponseInterface> $queue */
|
||||
$queue = [];
|
||||
|
||||
$this->logger->notice("SYSTEM: Preloading '{user}' '{mapper}' data. Memory: {memory.now}.", [
|
||||
$this->logger->notice("SYSTEM: Preloading '{user}' '{mapper}' data. Memory usage '{memory.now}'.", [
|
||||
'user' => $userContext->name,
|
||||
'mapper' => afterLast($userContext->mapper::class, '\\'),
|
||||
'memory' => [
|
||||
@@ -394,7 +394,7 @@ class ImportCommand extends Command
|
||||
$userContext->mapper->loadData();
|
||||
|
||||
$this->logger->notice(
|
||||
"SYSTEM: Preloading '{user}' '{mapper}' data completed in '{duration}s'. Memory: {memory.now}.",
|
||||
"SYSTEM: Preloading '{user}' '{mapper}' data completed in '{duration}s'. Memory usage '{memory.now}'.",
|
||||
[
|
||||
'user' => $userContext->name,
|
||||
'mapper' => afterLast($userContext->mapper::class, '\\'),
|
||||
@@ -471,13 +471,10 @@ class ImportCommand extends Command
|
||||
|
||||
unset($backend);
|
||||
|
||||
$start = makeDate();
|
||||
$start = microtime(true);
|
||||
$this->logger->notice("SYSTEM: Waiting on '{total}' requests for '{user}' backends.", [
|
||||
'user' => $userContext->name,
|
||||
'total' => number_format(count($queue)),
|
||||
'time' => [
|
||||
'start' => $start,
|
||||
],
|
||||
'memory' => [
|
||||
'now' => getMemoryUsage(),
|
||||
'peak' => getPeakMemoryUsage(),
|
||||
@@ -498,18 +495,12 @@ class ImportCommand extends Command
|
||||
gc_collect_cycles();
|
||||
}
|
||||
|
||||
$end = makeDate();
|
||||
|
||||
$this->logger->notice(
|
||||
"SYSTEM: Completed waiting on '{total}' requests in '{time.duration}'s for '{user}' backends. Parsed '{responses.size}' of data.",
|
||||
"SYSTEM: Completed '{total}' requests in '{duration}'s for '{user}' backends. Parsed '{responses.size}' of data.",
|
||||
[
|
||||
'user' => $userContext->name,
|
||||
'total' => number_format(count($queue)),
|
||||
'time' => [
|
||||
'start' => $start,
|
||||
'end' => $end,
|
||||
'duration' => $end->getTimestamp() - $start->getTimestamp(),
|
||||
],
|
||||
'duration' => round(microtime(true) - $start, 4),
|
||||
'memory' => [
|
||||
'now' => getMemoryUsage(),
|
||||
'peak' => getPeakMemoryUsage(),
|
||||
@@ -557,7 +548,7 @@ class ImportCommand extends Command
|
||||
$userContext->mapper->reset();
|
||||
|
||||
$this->logger->info(
|
||||
"SYSTEM: Importing '{user}' play states completed in '{duration}'s. Memory: {memory.now}.",
|
||||
"SYSTEM: Importing '{user}' play states completed in '{duration}'s. Memory usage '{memory.now}'.",
|
||||
[
|
||||
'user' => $userContext->name,
|
||||
'backends' => join(', ', array_keys($list)),
|
||||
|
||||
Reference in New Issue
Block a user