Skip to content

Commit

Permalink
Merge pull request #91 from CandoImage/cleanup-maintenance-task
Browse files Browse the repository at this point in the history
Cleanup maintenance task
  • Loading branch information
dpfaffenbauer authored Jun 19, 2023
2 parents 75b76b0 + c274939 commit 20ebc57
Show file tree
Hide file tree
Showing 11 changed files with 260 additions and 7 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,20 @@ if ($process->getStatus() == ProcessManagerBundle::STATUS_STOPPING) {
$process->save();
}
```
## Cleanup command

You can execute a cleanup command from the console to delete old process entries and log files. To do this on a regular basis, you can add it as a cronjob.

```bash
# delete all process entries from the database and log files older than 604800 seconds (7 days)
$ ./bin/console process-manager:cleanup-process-data
# delete all process entries from the database and log files older than 86400 seconds (1 days)
$ ./bin/console process-manager:cleanup-process-data --seconds=86400
# delete only process entries from the database older than 604800 seconds (7 days) and keep the log files
$ ./bin/console process-manager:cleanup-process-data --keeplogs
```

## Copyright and license
Copyright: [lineofcode.at](http://www.lineofcode.at)
Expand Down
83 changes: 83 additions & 0 deletions src/ProcessManagerBundle/Command/CleanupProcessDataCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php

/**
* Process Manager.
*
* LICENSE
*
* This source file is subject to the GNU General Public License version 3 (GPLv3)
* For the full copyright and license information, please view the LICENSE.md and gpl-3.0.txt
* files that are distributed with this source code.
*
* @copyright Copyright (c) 2015-2020 Wojciech Peisert (http://divante.co/)
* @license https://github.com/dpfaffenbauer/ProcessManager/blob/master/gpl-3.0.txt GNU General Public License version 3 (GPLv3)
*/

namespace ProcessManagerBundle\Command;

use Doctrine\DBAL\Exception;
use Pimcore\Console\AbstractCommand;
use ProcessManagerBundle\Service\CleanupService;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class CleanupProcessDataCommand extends AbstractCommand
{
public function __construct(private CleanupService $cleanupService, private string $logDirectory) {
parent::__construct();
}

protected function configure(): void
{
$this
->setName('process-manager:cleanup-process-data')
->setDescription('Cleanup process data from the database and from log file directory')
->setHelp(
<<<EOT
The <info>%command.name%</info> cleanup process data from the database and from log file directory.
EOT
)
->addOption(
'keeplogs',
'k',
InputOption::VALUE_NONE,
'Keep log files',
)
->addOption(
'seconds',
's',
InputOption::VALUE_OPTIONAL,
'Cleanup process data older than this number of seconds (default "604800" - 7 days)',
604800
);
}

/**
*
* @param InputInterface $input
* @param OutputInterface $output
*
* @return int
* @throws Exception
*/
public function execute(InputInterface $input, OutputInterface $output): int
{
$keepLogs = $input->getOption('keeplogs');
if ($input->getOption('seconds')) {
$seconds = (int)$input->getOption('seconds');
}

// start deleting database entries older than x seconds
$output->writeln('start cleaning database entries older than ' . $seconds . ' seconds');
$this->cleanupService->cleanupDbEntries($seconds);
$output->writeln('finish cleaning database entries older than ' . $seconds . ' seconds');

// start deleting log files older than x seconds
$output->writeln('start cleaning log files older than ' . $seconds . ' seconds');
$this->cleanupService->cleanupLogFiles($this->logDirectory, $seconds, $keepLogs);
$output->writeln('finish cleaning logfile entries older than ' . $seconds . ' seconds');
return Command::SUCCESS;
}
}
20 changes: 18 additions & 2 deletions src/ProcessManagerBundle/Controller/ProcessController.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use Pimcore\Db;
use ProcessManagerBundle\Model\Process;
use ProcessManagerBundle\Model\ProcessInterface;
use ProcessManagerBundle\Service\CleanupService;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
Expand All @@ -34,6 +35,17 @@ public function listAction(Request $request): JsonResponse
* @var Process\Listing $list
*/
$list = new $listingClass();
if ($filterString = $request->get('filter')) {
$db = Db::get();
$filters = json_decode($filterString);
$conditionParts = [];
foreach ($filters as $f) {
$fieldname = $f->property;
$conditionParts[] = $db->quoteIdentifier($fieldname) . ' LIKE ' . $db->quote('%' . $f->value . '%');
}
$condition = implode(' AND ', $conditionParts);
$list->setCondition($condition);
}
if ($sort = $request->get('sort')) {
$sort = json_decode($sort)[0];
$list->setOrderKey($sort->property);
Expand Down Expand Up @@ -109,9 +121,13 @@ public function stopAction(Request $request): JsonResponse
public function clearAction(Request $request): JsonResponse
{
$seconds = (int)$request->get('seconds', 604_800);
$connection = Db::get();
$connection->executeStatement('DELETE FROM process_manager_processes WHERE started < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL ? SECOND))', [$seconds]);
$logDirectory = $this->container->getParameter('process_manager.log_directory');
$keepLogs = $this->container->getParameter('process_manager.keep_logs');

/** @var CleanupService $cleanupService */
$cleanupService = $this->container->get(CleanupService::class);
$cleanupService->cleanupDbEntries($seconds);
$cleanupService->cleanupLogFiles($logDirectory, $seconds, $keepLogs);
return $this->json(['success' => true]);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ public function getConfigTreeBuilder(): TreeBuilder
->children()
->scalarNode('driver')->defaultValue(CoreShopResourceBundle::DRIVER_PIMCORE)->end()
->scalarNode('log_directory')->defaultValue('%kernel.logs_dir%')->end()
->booleanNode('keep_logs')->defaultValue(true)->end()
->integerNode('seconds')->defaultValue(604800)->end()
->end()
;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public function load(array $configs, ContainerBuilder $container): void
$this->registerPimcoreResources('process_manager', $config['pimcore_admin'], $container);

$container->setParameter('process_manager.log_directory', $config['log_directory']);
$container->setParameter('process_manager.keep_logs', $config['keep_logs']);
$container->setParameter('process_manager.seconds', $config['seconds']);

$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
Expand Down
6 changes: 4 additions & 2 deletions src/ProcessManagerBundle/Logger/DefaultHandlerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@
class DefaultHandlerFactory implements HandlerFactoryInterface
{
private string $logDirectory;
private bool $keepLogs;

public function __construct(string $logDirectory)
public function __construct(string $logDirectory, bool $keepLogs)
{
$this->logDirectory = $logDirectory;
$this->keepLogs = $keepLogs;
}

public function getLogHandler(ProcessInterface $process): StreamHandler
Expand All @@ -46,7 +48,7 @@ public function cleanup(ProcessInterface $process): void
{
$path = sprintf('%s/process_manager_%s.log', $this->logDirectory, $process->getId());

if (file_exists($path)) {
if (!$this->keepLogs && file_exists($path)) {
unlink($path);
}
}
Expand Down
29 changes: 29 additions & 0 deletions src/ProcessManagerBundle/Maintenance/CleanupTask.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php
/**
* Process Manager.
*
* LICENSE
*
* This source file is subject to the GNU General Public License version 3 (GPLv3)
* For the full copyright and license information, please view the LICENSE.md and gpl-3.0.txt
* files that are distributed with this source code.
*
* @copyright Copyright (c) 2018 Jakub Płaskonka (jplaskonka@divante.pl)
* @license https://github.com/dpfaffenbauer/ProcessManager/blob/master/gpl-3.0.txt GNU General Public License version 3 (GPLv3)
*/

namespace ProcessManagerBundle\Maintenance;

use Pimcore\Maintenance\TaskInterface;
use ProcessManagerBundle\Service\CleanupService;

class CleanupTask implements TaskInterface
{
public function __construct(private CleanupService $cleanupService, private string $logDirectory, private int $seconds, private bool $keepLogs) {
}
public function execute(): void
{
$this->cleanupService->cleanupDbEntries($this->seconds);
$this->cleanupService->cleanupLogFiles($this->logDirectory, $this->seconds, $this->keepLogs);
}
}
18 changes: 17 additions & 1 deletion src/ProcessManagerBundle/Resources/config/services.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
imports:
- { resource: "services/forms.yml" }
- { resource: "services/installer.yml" }
- { resource: "services/commands.yml" }

services:
_defaults:
Expand Down Expand Up @@ -44,14 +45,23 @@ services:
tags:
- { name: kernel.event_listener, event: pimcore.asset.postDelete, method: onArtifactAssetDelete }

### Maintenance task
### Maintenance tasks
ProcessManagerBundle\Maintenance\CronTask:
arguments:
- '@process_manager.registry.processes'
- '@messenger.default_bus'
tags:
- { name: pimcore.maintenance.task, type: process_manager.maintenance.cron }

ProcessManagerBundle\Maintenance\CleanupTask:
arguments:
- '@ProcessManagerBundle\Service\CleanupService'
- '%process_manager.log_directory%'
- '%process_manager.seconds%'
- '%process_manager.keep_logs%'
tags:
- { name: pimcore.maintenance.task, type: process_manager.maintenance.cleanup }

ProcessManagerBundle\Logger\ProcessLogger:
arguments:
- '@logger'
Expand All @@ -69,6 +79,7 @@ services:
ProcessManagerBundle\Logger\DefaultHandlerFactory:
arguments:
- '%process_manager.log_directory%'
- '%process_manager.keep_logs%'

ProcessManagerBundle\Report\DefaultReport: ~

Expand All @@ -95,3 +106,8 @@ services:
- '@process_manager.registry.processes'
tags:
- { name: messenger.message_handler }

### Cleanup service
ProcessManagerBundle\Service\CleanupService:
arguments:
- '@parameter_bag'
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
services:
ProcessManagerBundle\Command\CleanupProcessDataCommand:
arguments:
- '@ProcessManagerBundle\Service\CleanupService'
- '%process_manager.log_directory%'
tags:
- { name: 'console.command', command: 'process-manager:cleanup-process-data' }
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ pimcore.plugin.processmanager.processes = Class.create({
xtype: 'grid',
store: store,
bbar: pimcore.helpers.grid.buildDefaultPagingToolbar(store),
plugins: 'gridfilters',
columns: [
{
text: t('id'),
Expand All @@ -154,12 +155,14 @@ pimcore.plugin.processmanager.processes = Class.create({
{
text: t('name'),
dataIndex: 'name',
width: 300
width: 400,
filter: 'string'
},
{
text: t('processmanager_message'),
dataIndex: 'message',
flex : 1
flex : 1,
filter: 'string'
},
{
text: t('processmanager_started'),
Expand Down Expand Up @@ -273,6 +276,7 @@ pimcore.plugin.processmanager.processes = Class.create({
text : t('processmanager_status'),
width: 100,
dataIndex: 'status',
filter: 'string',
renderer: function (value, metadata, record) {
if (record.data.status != '' && record.data.status != null) {
return t('processmanager_' + record.data.status);
Expand Down
78 changes: 78 additions & 0 deletions src/ProcessManagerBundle/Service/CleanupService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php
/**
* Process Manager.
*
* LICENSE
*
* This source file is subject to the GNU General Public License version 3 (GPLv3)
* For the full copyright and license information, please view the LICENSE.md and gpl-3.0.txt
* files that are distributed with this source code.
*
* @copyright Copyright (c) 2015-2020 Dominik Pfaffenbauer (https://www.pfaffenbauer.at)
* @license https://github.com/dpfaffenbauer/ProcessManager/blob/master/gpl-3.0.txt GNU General Public License version 3 (GPLv3)
*/

namespace ProcessManagerBundle\Service;

use Doctrine\DBAL\Exception;
use Pimcore\Db;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;

class CleanupService
{
public function __construct(protected ParameterBagInterface $parameterBag)
{
}

/**
* Cleanup process db entries from the database
*
* @param int|null $seconds Only entries older than x seconds will be deleted
* None or empty value will delete all entries
* @throws Exception
*/
public function cleanupDbEntries(?int $seconds): void
{
// delete all entries if there is no time passed
if (empty($seconds)) {
$seconds = 0;
}
$connection = Db::get();
$connection->executeStatement('DELETE FROM process_manager_processes WHERE started < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL ? SECOND))', [$seconds]);
}

/**
* Cleanup all log files
*
* @param string $logDirectory Path to the log files. If not specified, default path from config will be used
* @param int|null $seconds Only entries older than x seconds will be deleted
* None or empty value will delete all entries
* @param bool $keepLogs Whether to keep the log files or not
* true - Keep the log files
* false - Cleanup the logiles
* @return void
*/
public function cleanupLogFiles(string $logDirectory, ?int $seconds, bool $keepLogs = true): void
{
if (empty($logDirectory)) {
$logDirectory = $this->parameterBag->get('process_manager.log_directory');
}
// delete all entries if there is no time passed
if (empty($seconds)) {
$seconds = 0;
}
if (!$keepLogs && is_dir($logDirectory)) {
$files = scandir($logDirectory);
foreach ($files as $file) {
$filePath = $logDirectory . '/' . $file;
if (
file_exists($filePath) &&
str_contains($file, 'process_manager_') &&
filemtime($filePath) < time() - $seconds
) {
unlink($filePath);
}
}
}
}
}

0 comments on commit 20ebc57

Please sign in to comment.