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

Logger Bundle Laravel Package

aboutcoders/logger-bundle

Symfony bundle exposing a REST API to accept log messages from external apps. Configure allowed application names and map each to a Monolog channel, then POST level, message, and optional context to /api/log/{app}. Integrates with FOSRest and NelmioApiDoc.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install Dependencies Run:

    composer require aboutcoders/logger-bundle sensio/framework-extra-bundle nelmio/api-doc-bundle fos/rest-bundle
    
  2. Enable the Bundle Add to config/bundles.php (Symfony 4+) or AppKernel.php (Symfony 3):

    new Abc\Bundle\LoggerBundle\AbcLoggerBundle(),
    
  3. Configure Routing Import routes in config/routes.yaml:

    abc_rest_logger:
        resource: "@AbcLoggerBundle/Resources/config/routing/rest.yml"
        prefix: /api
    
  4. Basic Configuration Define allowed clients and Monolog channels in config/packages/abc_logger.yaml:

    abc_logger:
        clients:
            - { name: "mobile_app", channel: "mobile" }
            - { name: "web_frontend", channel: "frontend" }
    
  5. First Log Entry Send a POST request to /api/log with:

    {
        "client": "mobile_app",
        "message": "User logged in",
        "context": { "user_id": 123 }
    }
    

Implementation Patterns

Core Workflows

1. Client-Side Logging

  • Mobile/Web Apps: Use HTTP clients (e.g., Guzzle) to POST logs to /api/log.
  • SDK Integration: Wrap the API call in a helper class for consistency:
    class LoggerClient {
        public function log(string $clientName, string $message, array $context = []): void {
            $client = new \GuzzleHttp\Client();
            $client->post('/api/log', [
                'json' => [
                    'client' => $clientName,
                    'message' => $message,
                    'context' => $context,
                ],
            ]);
        }
    }
    

2. Server-Side Integration

  • Monolog Handlers: Configure handlers per channel (e.g., mobilemobile.log, frontendsyslog):
    monolog:
        channels:
            - { name: mobile, type: stream, path: "%kernel.logs_dir%/mobile.log" }
            - { name: frontend, type: syslog, identifier: "web_frontend" }
    
  • Log Processing: Extend the bundle to enrich logs (e.g., add request IDs):
    // src/EventListener/LoggerSubscriber.php
    use Abc\Bundle\LoggerBundle\Event\LogEvent;
    
    class LoggerSubscriber implements EventSubscriber {
        public static function getSubscribedEvents() {
            return [LogEvent::NAME => 'onLog'];
        }
    
        public function onLog(LogEvent $event) {
            $event->getLogEntry()->addExtra('request_id', $event->getRequest()->get('X-Request-ID'));
        }
    }
    

3. Validation and Security

  • Client Whitelisting: Restrict logging to trusted clients via abc_logger.clients config.
  • Rate Limiting: Use FOSRest’s @RateLimit annotation to throttle log submissions:
    use Nelmio\ApiDocBundle\Annotation\ApiDoc;
    use FOS\RestBundle\View\View;
    use FOS\RestBundle\Controller\Annotations\Route;
    
    /**
     * @Route("/api/log", name="abc_logger_log", methods={"POST"})
     * @ApiDoc(...)
     * @RateLimit(limit=100, interval="minute")
     */
    public function logAction(): View { ... }
    

4. Testing

  • Unit Tests: Mock the LoggerService to verify log entries:
    $logger = $this->createMock(\Psr\Log\LoggerInterface());
    $logger->expects($this->once())->method('info')->with('User logged in', ['user_id' => 123]);
    $this->container->set('logger.mobile', $logger);
    
  • Integration Tests: Use HttpClient to test the API endpoint:
    $response = $client->request('POST', '/api/log', [
        'json' => ['client' => 'mobile_app', 'message' => 'Test']
    ]);
    $this->assertEquals(204, $response->getStatusCode());
    

Gotchas and Tips

Pitfalls

  1. Deprecated Dependencies

    • The bundle relies on FOSRestBundle, which is unmaintained. Migrate to ApiPlatform or Symfony’s built-in HTTP client for new projects.
    • Workaround: Use symfony/http-client for logging requests instead of FOSRest.
  2. Missing Request Context

    • Logs lack request metadata (e.g., IP, headers) by default. Extend the LogEvent subscriber to add context:
      $event->getLogEntry()->addExtra('ip', $event->getRequest()->getClientIp());
      
  3. Channel Configuration

    • Monolog channels must be defined before the bundle loads. Use kernel.request event to dynamically configure channels if needed:
      # config/packages/monolog.yaml
      monolog:
          channels: ["mobile", "frontend"]  # Predefine channels
      
  4. CORS Issues

    • The API may block external clients if CORS isn’t configured. Add to config/packages/nelmio_cors.yaml:
      nelmio_cors:
          defaults:
              allow_origin: ["*"]
              allow_methods: ["POST"]
              allow_headers: ["Content-Type"]
              max_age: 3600
      

Debugging Tips

  1. Log Validation Errors

    • Enable debug mode to see validation failures:
      abc_logger:
          validation_errors_as_exceptions: false  # Set to true for stack traces
      
  2. Check Monolog Output

    • Verify logs are written by inspecting the configured handlers:
      tail -f var/log/mobile.log  # For stream handlers
      
  3. API Documentation

    • Use NelmioApiDocBundle to auto-generate Swagger docs for /api/log:
      nelmio_api_doc:
          documentation:
              info:
                  title: Logger API
                  description: "Log messages from external clients"
      

Extension Points

  1. Custom Log Formats

    • Override the LogEntry class to modify log structure:
      // src/AbcLoggerBundle/Event/LogEntry.php
      class CustomLogEntry extends \Abc\Bundle\LoggerBundle\Event\LogEntry {
          public function __toString() {
              return sprintf("[%s] %s", $this->getClient(), $this->getMessage());
          }
      }
      
  2. Async Logging

    • Use ReactPHP or Symfony Messenger to process logs asynchronously:
      // config/packages/messenger.yaml
      messenger:
          transports:
              async_log: "%kernel.project_dir%/var/log/async_logs"
          routing:
              "Abc\Bundle\LoggerBundle\Message\LogMessage": async_log
      
  3. Database Logging

    • Store logs in a database by creating a custom Monolog handler:
      use Monolog\Handler\AbstractProcessingHandler;
      
      class DatabaseHandler extends AbstractProcessingHandler {
          protected function write(array $record): void {
              // Save to DB (e.g., using Doctrine)
          }
      }
      
      Then configure it in monolog.yaml:
      monolog:
          handlers:
              database:
                  type: service
                  id: App\Log\Handler\DatabaseHandler
                  level: info
      
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.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor