<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mohamed</title>
    <description>The latest articles on DEV Community by Mohamed (@mohamed_dev).</description>
    <link>https://dev.to/mohamed_dev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3538256%2F86dc6d8a-ea61-4d92-ae62-5b935a1a189d.png</url>
      <title>DEV Community: Mohamed</title>
      <link>https://dev.to/mohamed_dev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mohamed_dev"/>
    <language>en</language>
    <item>
      <title>A Developer’s Guide to the Command Logger Bundle for Symfony</title>
      <dc:creator>Mohamed</dc:creator>
      <pubDate>Mon, 29 Sep 2025 20:31:25 +0000</pubDate>
      <link>https://dev.to/mohamed_dev/a-developers-guide-to-the-command-logger-bundle-for-symfony-3c6n</link>
      <guid>https://dev.to/mohamed_dev/a-developers-guide-to-the-command-logger-bundle-for-symfony-3c6n</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;For when you can’t access log files, but you can see the database.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ever been in a situation where a command fails on production, but you don’t have access to the server’s log files? All you can do is connect to the database. For fast debugging, you don’t need to see every line of output; you just need to answer three simple questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Did my command run?&lt;/li&gt;
&lt;li&gt;When did it run?&lt;/li&gt;
&lt;li&gt;Did it complete successfully or did it fail?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the exact scenario the Command Logger Bundle was built for. It’s a purpose-built solution that provides a robust, database-backed audit trail for your console commands, giving you the critical visibility you need, right where you can see it.&lt;br&gt;
What It Does&lt;/p&gt;

&lt;p&gt;This bundle automatically captures metadata about your command executions and stores it in a dedicated &lt;code&gt;command_log&lt;/code&gt; database table. For each execution, it records:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;    The command’s name&lt;/li&gt;
&lt;li&gt;    The arguments it was run with (in JSON format)&lt;/li&gt;
&lt;li&gt;    The start and end times&lt;/li&gt;
&lt;li&gt;    The final exit code&lt;/li&gt;
&lt;li&gt;    Any error messages&lt;/li&gt;
&lt;li&gt;    A unique executionToken for tracking&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;A Note on Scope: Fast Auditing, Not Output Logging&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It’s important to note that this bundle is designed for fast debugging and auditing. Its primary goal is to track when a command has been executed and if its outcome was OK or not.&lt;/p&gt;

&lt;p&gt;It does not capture the command’s output (e.g., messages written to the console or logs generated by Monolog within the command). It only logs the metadata about the execution itself.&lt;br&gt;
Installation and Configuration&lt;/p&gt;
&lt;h2&gt;
  
  
  Getting started is a simple two-step process.
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Step 1: Install with Composer
&lt;/h3&gt;

&lt;p&gt;First, add the bundle to your project using Composer:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;composer require ayaou/command-logger-bundle&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If your project doesn’t use Symfony Flex, you’ll need to manually register the bundle in config/bundles.php:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// config/bundles.php&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="nc"&gt;Ayaou\CommandLoggerBundle\AyaouCommandLoggerBundle&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'all'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Configure the Bundle [Optional]
&lt;/h3&gt;

&lt;p&gt;Next, create a configuration file at config/packages/command_logger.yaml to control the bundle's behaviour.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# config/packages/command_logger.yaml&lt;/span&gt;
&lt;span class="na"&gt;command_logger&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Enable or disable all logging globally. Defaults to true.&lt;/span&gt;
  &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

  &lt;span class="c1"&gt;# Days after which old logs are automatically deleted.&lt;/span&gt;
  &lt;span class="na"&gt;purge_threshold&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;

  &lt;span class="c1"&gt;# A list of commands to log, especially useful for third-party&lt;/span&gt;
  &lt;span class="c1"&gt;# bundles where you cannot add attributes. Wildcards are supported.&lt;/span&gt;
  &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;app:example-command&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;app:another-command&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;make:*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to Log Your Commands
&lt;/h2&gt;

&lt;p&gt;You have two ways to specify which commands should be logged.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The Attribute Method (Recommended)
&lt;/h3&gt;

&lt;p&gt;For commands within your own project, the easiest method is to use the &lt;code&gt;#[CommandLogger]&lt;/code&gt; attribute directly on the command class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Ayaou\CommandLoggerBundle\Attribute\CommandLogger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Symfony\Component\Console\Attribute\AsCommand&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Symfony\Component\Console\Command\Command&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;

&lt;span class="na"&gt;#[AsCommand(name: 'app:example-command')]&lt;/span&gt;
&lt;span class="na"&gt;#[CommandLogger]&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ExampleCommand&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Command&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;InputInterface&lt;/span&gt; &lt;span class="nv"&gt;$input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;OutputInterface&lt;/span&gt; &lt;span class="nv"&gt;$output&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$output&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;writeln&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Executing example command...'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Command&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;SUCCESS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it! The bundle will now automatically log every execution of app:example-command.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The Configuration Method
&lt;/h3&gt;

&lt;p&gt;If you want to log a command that you cannot modify (for example, a command from a third-party bundle), you can add its name to the commands array in your command_logger.yaml file, as shown in the configuration step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Viewing and Filtering Logs
&lt;/h2&gt;

&lt;p&gt;Once you have logged some command executions, you can easily view them from your terminal using the built-in command-logger:show command. This is perfect for quickly checking the status of recent jobs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;View the latest 10 logs:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;bin/console command-logger:show&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Filter by command name:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;bin/console command-logger:show app:example-command&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quickly find failed commands (the primary use case!):&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;bin/console command-logger:show --error&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Use — success to show commands that run successfully.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Find a specific log entry by its ID:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;bin/console command-logger:show --id=123&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The command also supports interactive pagination; simply press Enter to load more entries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keeping Your Logs Tidy
&lt;/h2&gt;

&lt;p&gt;A log table can grow quickly. The Command Logger Bundle provides tools to prevent it from getting out of control.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automatic Purging
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;purge_threshold&lt;/code&gt; option in your configuration file automatically deletes logs older than the specified number of days. And of course, do not forgot to put this command in a cron job that runs periodically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Manual Purging
&lt;/h3&gt;

&lt;p&gt;If you need to clean up logs manually, you can run the &lt;code&gt;command-logger:purge&lt;/code&gt; command.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Purge logs using the configured threshold&lt;br&gt;
&lt;code&gt;bin/console command-logger:purge&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Purge logs older than 30 days, overriding the config&lt;br&gt;
&lt;code&gt;bin/console command-logger:purge --threshold=30&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The Command Logger Bundle offers a focused and powerful solution for auditing your Symfony console commands, especially in environments where direct log file access is limited. By providing a persistent, queryable database log with built-in tools for viewing and maintenance, it dramatically improves your ability to debug and monitor your application’s command-line activity.&lt;/p&gt;

&lt;p&gt;This bundle is distributed under the MIT Licence. For more information, please visit the &lt;a href="https://github.com/ayaou/command-logger-bundle" rel="noopener noreferrer"&gt;official repository&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>symfony</category>
      <category>logging</category>
      <category>monitoring</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
