Here’s the complete implementation that allows you to select a logger dynamically based on the APP_LOGGER_TYPE environment variable. This includes the logger interface, logger implementations, user service, user controller, and the service configuration in services.yaml.
1. Logger Interface
File: src/Service/Logger/LoggerInterface.php
namespace App\Service\Logger;
interface LoggerInterface
{
public function log(string $message): void;
}
2. File Logger Implementation
File: src/Service/Logger/FileLogger.php
namespace App\Service\Logger;
class FileLogger implements LoggerInterface
{
private string $logFile;
public function __construct(string $logFile = 'app.log')
{
$this->logFile = $logFile;
}
public function log(string $message): void
{
file_put_contents($this->logFile, $message . PHP_EOL, FILE_APPEND);
}
}
3. Database Logger Implementation
File: src/Service/Logger/DatabaseLogger.php
namespace App\Service\Logger;
use Doctrine\ORM\EntityManagerInterface;
use App\Entity\LogEntry;
class DatabaseLogger implements LoggerInterface
{
private EntityManagerInterface $entityManager;
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
public function log(string $message): void
{
$logEntry = new LogEntry();
$logEntry->setMessage($message);
$logEntry->setCreatedAt(new \DateTime());
$this->entityManager->persist($logEntry);
$this->entityManager->flush();
}
}
4. Email Logger Implementation (Optional)
File: src/Service/Logger/EmailLogger.php
namespace App\Service\Logger;
class EmailLogger implements LoggerInterface
{
public function log(string $message): void
{
// Implement email logging logic here
// e.g., sending an email with the log message
mail('admin@example.com', 'Log Entry', $message);
}
}
5. User Service
File: src/Service/UserService.php
namespace App\Service;
use App\Service\Logger\LoggerInterface;
class UserService
{
private LoggerInterface $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
public function createUser(string $username): void
{
$this->logger->log("User $username created.");
}
}
6. User Controller
File: src/Controller/UserController.php
namespace App\Controller;
use App\Service\UserService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
class UserController extends AbstractController
{
private UserService $userService;
public function __construct(UserService $userService)
{
$this->userService = $userService;
}
public function create(): Response
{
$this->userService->createUser('JohnDoe'); // Uses the injected logger
return new Response('User created and logged.');
}
}
7. Entity Class for Log Entry (Optional)
File: src/Entity/LogEntry.php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity()
*/
class LogEntry
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private int $id;
/**
* @ORM\Column(type="string")
*/
private string $message;
/**
* @ORM\Column(type="datetime")
*/
private \DateTime $createdAt;
public function setMessage(string $message): void
{
$this->message = $message;
}
public function setCreatedAt(\DateTime $createdAt): void
{
$this->createdAt = $createdAt;
}
}
8. Configure Services in services.yaml
File: config/services.yaml
parameters:
log_file: 'app.log' # Default log file location
services:
# Conditional service based on APP_LOGGER_TYPE
App\Service\Logger\LoggerInterface: '@=service("App\Service\Logger\\" . ucfirst(getenv("APP_LOGGER_TYPE")) . "Logger")'
App\Service\Logger\DatabaseLogger:
arguments:
$entityManager: '@doctrine.orm.entity_manager'
App\Service\Logger\FileLogger:
arguments:
$logFile: '%log_file%' # Use the default log file from parameters
App\Service\Logger\EmailLogger: ~ # Add EmailLogger service if necessary
App\Service\UserService:
arguments:
$logger: '@=service("App\Service\Logger\\" . ucfirst(getenv("APP_LOGGER_TYPE")) . "Logger")'
9. Update Your .env File
Set the desired default logger in your .env file:
File: .env
APP_LOGGER_TYPE=file # or database, or email
Summary
With this setup:
- You can easily switch between different logging mechanisms by simply changing the value of
APP_LOGGER_TYPEin your.envfile. - The
services.yamlconfiguration dynamically selects the appropriate logger implementation based on the environment variable, enabling you to use different logging strategies without modifying the service or application logic.
No comments:
Post a Comment