Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Log Entry Bundle Laravel Package

beutsing/log-entry-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require beutsing/log-entry-bundle
    php bin/console make:migration
    php bin/console doctrine:migrations:migrate
    

    Verify the log_entry table exists in your database.

  2. First Log Entry: Inject LogEntryService into a controller or service:

    use Beutsing\LogEntryBundle\Service\LogEntryService;
    
    public function __construct(private LogEntryService $logEntryService) {}
    
    public function someAction(): Response
    {
        $this->logEntryService->createLogEntry(
            userIdentifier: 'user@example.com',
            action: 'user.created',
            message: 'New user registered via admin panel',
            companyId: 'company_123' // Optional
        );
        return new Response('Logged!');
    }
    
  3. Where to Look First:

    • Service: LogEntryService (primary interface for logging).
    • Entity: LogEntry (check src/Entity/LogEntry.php for field details).
    • Configuration: config/packages/beutsing_log_entry.yaml (if it exists; otherwise, check for bundle defaults).

Implementation Patterns

Core Workflows

  1. Manual Logging: Use LogEntryService in controllers/services to log actions explicitly:

    $this->logEntryService->createLogEntry(
        userIdentifier: $user->getEmail(),
        action: 'order.updated',
        message: sprintf('Updated order #%s', $order->getId()),
        metadata: ['order_id' => $order->getId()] // Optional (if supported)
    );
    
  2. Automatic Logging with Events: Subscribe to Symfony events (e.g., KernelEvents::VIEW, Doctrine\ORM\Event\LifecycleEventArgs) to log entity changes:

    // src/EventListener/LogEntityChangesListener.php
    use Beutsing\LogEntryBundle\Service\LogEntryService;
    use Doctrine\ORM\Event\LifecycleEventArgs;
    
    class LogEntityChangesListener
    {
        public function __construct(private LogEntryService $logEntryService) {}
    
        public function postPersist(LifecycleEventArgs $args): void
        {
            $entity = $args->getObject();
            $this->logEntryService->createLogEntry(
                userIdentifier: 'system', // Or fetch from security context
                action: 'entity.persisted',
                message: sprintf('%s created', get_class($entity))
            );
        }
    }
    

    Register the listener in services.yaml:

    services:
        App\EventListener\LogEntityChangesListener:
            tags:
                - { name: doctrine.event_listener, event: postPersist }
    
  3. Security Context Integration: Fetch the current user in listeners/controllers:

    $user = $this->getUser(); // In controllers
    // OR
    $user = $this->security->getUser(); // In services
    $this->logEntryService->createLogEntry(
        userIdentifier: $user->getEmail(),
        action: 'dashboard.accessed'
    );
    
  4. Bulk Logging: For batch operations (e.g., imports), log once per batch:

    $this->logEntryService->createLogEntry(
        userIdentifier: $user->getEmail(),
        action: 'users.imported',
        message: 'Imported 100 users via CSV'
    );
    

Integration Tips

  1. Custom Fields: Extend the LogEntry entity to add fields (e.g., ipAddress, metadata as JSON):

    // src/Entity/LogEntry.php
    #[ORM\Column(type: 'json', nullable: true)]
    private ?array $metadata = null;
    

    Update the migration and service to handle the new field.

  2. Logging Middleware: Create middleware to log API requests:

    // src/Middleware/LogApiRequestsMiddleware.php
    public function handle(Request $request, callable $next): Response
    {
        $response = $next($request);
        $this->logEntryService->createLogEntry(
            userIdentifier: $request->attributes->get('user')?->getEmail(),
            action: $request->getMethod() . ':' . $request->getPathInfo(),
            message: $request->getContent()
        );
        return $response;
    }
    
  3. Symfony Messenger: Dispatch log entries as messages for async processing:

    use Beutsing\LogEntryBundle\Message\CreateLogEntry;
    
    $this->messageBus->dispatch(
        new CreateLogEntry(
            userIdentifier: $user->getEmail(),
            action: 'payment.processed',
            message: 'Paid $100'
        )
    );
    
  4. API Responses: Include log IDs in API responses for debugging:

    {
        "data": { ... },
        "log_id": 42
    }
    

Gotchas and Tips

Pitfalls

  1. Missing User Context:

    • Issue: Logs may lack userIdentifier if not passed explicitly.
    • Fix: Use a base controller/service to inject the user:
      abstract class BaseController extends AbstractController
      {
          protected function getUserIdentifier(): string
          {
              return $this->getUser()?->getEmail() ?: 'anonymous';
          }
      }
      
  2. Performance:

    • Issue: Logging in loops (e.g., iterating over entities) can slow down requests.
    • Fix: Batch logs or use async processing (e.g., Messenger).
  3. Migration Conflicts:

    • Issue: Custom LogEntry fields may break migrations.
    • Fix: Extend the bundle’s migration or use a post-migration script.
  4. Security:

    • Issue: Logging sensitive data (e.g., passwords) in message.
    • Fix: Sanitize messages or use a separate metadata field for non-sensitive data.
  5. Bundle Updates:

    • Issue: Future bundle updates may overwrite LogEntry entity changes.
    • Fix: Fork the bundle or override the entity via dependency injection.

Debugging

  1. Check Logs: Enable debug mode to see if logs are created:

    php bin/console debug:container beutsing_log_entry
    

    Verify the LogEntryService is registered.

  2. Database Inspection: Query the log_entry table:

    SELECT * FROM log_entry ORDER BY createdAt DESC LIMIT 10;
    
  3. Event Listeners: Ensure listeners are tagged correctly in services.yaml:

    tags:
        - { name: doctrine.event_listener, event: postUpdate }
    

Extension Points

  1. Custom Actions: Create a LogEntryAction enum or use strings with prefixes (e.g., user., order.).

  2. Log Entry Filters: Add repository methods to filter logs:

    // src/Repository/LogEntryRepository.php
    public function findByActionAndUser(string $action, string $userIdentifier): array
    {
        return $this->createQueryBuilder('le')
            ->where('le.action = :action')
            ->andWhere('le.userIdentifier = :user')
            ->setParameters([
                'action' => $action,
                'user' => $userIdentifier
            ])
            ->getQuery()
            ->getResult();
    }
    
  3. Export Functionality: Add a command to export logs to CSV/JSON:

    // src/Command/ExportLogsCommand.php
    use Beutsing\LogEntryBundle\Entity\LogEntry;
    use Symfony\Component\Console\Command\Command;
    use Symfony\Component\Console\Input\InputInterface;
    use Symfony\Component\Console\Output\OutputInterface;
    
    class ExportLogsCommand extends Command
    {
        protected function execute(InputInterface $input, OutputInterface $output): int
        {
            $logs = $this->logEntryRepository->findAll();
            // Export logic (e.g., to CSV)
            return Command::SUCCESS;
        }
    }
    
  4. Web Interface: Create a CRUD controller to view logs in the admin panel:

    // src/Controller/Admin/LogEntryController.php
    class LogEntryController extends AbstractController
    {
        public function index(LogEntryRepository $repo): Response
        {
            $logs = $repo->findBy([], ['createdAt' => 'DESC]);
            return $this->render('admin/log_entry/index.html.twig', ['logs' => $logs]);
        }
    }
    
  5. Testing: Mock LogEntryService in tests:

    $this->logEntryService = $this->createMock(LogEntryService::class);
    $this->logEntryService->expects($this->once())
        ->method('createLogEntry')
        ->with(
            $this->callback(function ($args) {
                return $args['action'] === 'test.action';
            })
        );
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver