Configuring Monolog Logging for AWS Cloudwatch Logs

So that the logs are beautifully formatted from a Symfony 4 Arrive application in AWS Cloudwatch, must be Monologue configure as follows:

# config/services.yaml
        - [includeStacktraces]


# config/packages/prod/monolog.yaml
      type:  stream
      level: error
      path:  '%kernel.logs_dir%/error.log'
      formatter: Monolog\Formatter\JsonFormatter

After that, you have to Cloudwatch Daemon to configure:

# /etc/awslogs/awslogs.conf
# Path to the CloudWatch Logs agent's state file. The agent uses this file to maintain
# client side state across its executions.
state_file = /var/lib/awslogs/agent-state

datetime_format = [%Y-%m-%d H:%M:%S]
file = /var/www/html/var/log/error.log
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name = test_group_name/error_log

and you get wonderful (Aggregated) ErrorLog Information in Cloudwatch Logs Insight:



Symfony Switftmailer Mail is not sent

With the following command a test mail can be sent with Swiftmailer. If the email does not arrive, the Switftmailer parameters are inconfig/packages/swiftmailer.yaml probably wrong:

php bin/console swiftmailer:email:send --help

Since the email is sent with a queue, should nevertheless be Error_log be examined under var/log/, in it found with me the reason for my shipping problem:

app.ERROR: Exception occurred while flushing email queue: Expected response code 250 but got code "554", with message "554 Message rejected: 
Email address is not verified. The following identities failed the check in region EU-WEST-1: email1, email2


Tutorial: Administration backend create symfony

In this post, I'm going with Symfony 4 an Administartionsoberfläche with the help of Sonata create and describe the steps.

1. Create a new symfony project

With composer can be quickly skeleton project creating a new symfony:

composer create-project symfony/website-skeleton my-admin-demo

The skeleton project contains the main symfony components for a Web application and doctrine.

Now is a good time to check in the Porjket in a Versionierungsystem like GIT and to commit for the first time.

Optionally, symfony PHPUnit bridge can now be installed, When tests should be written:

composer require phpunit --dev

The database can now be configured in the .env file:


And are created with the following command:

php bin/console doctrine:database:create

2. Installation of the SonataAdmin bundle more…

Recursively delete directories Gau Frette FTP adapter

To with FTP recursively delete files and directories adapter Gau Frette, you can apply following trick to avoid the error message:

ftp_rmdir(): Directory not empty.

1. just delete all files

2. then delete the lowest directories up to the top:

 * @param Filesystem $fileSystem
function deleteAllFilesInDirectory(Filesystem $fileSystem)
    // delete files first, than directories
    foreach ($fileSystem->keys() as $key) {
        if (!$fileSystem->isDirectory($key)) {
    $keys = $fileSystem->keys();
    usort($keys, function (string $a, string $b){
        $aCount = substr_count($a, '/');
        $bCount = substr_count($b, '/');
        return $bCount <=> $aCount;
    foreach ($keys as $key) {

Symfony FosUser bundle to apply their own password policy

In the SonataAdmin with FosUser bundle your own rules to define module for the strength of the passwords, can you overwrite the validation.xml, by one in the folder src/application/Sonata/UserBundle/resources/config /. its own validation.XML creates:

<?xml version="1.0" ?>
<constraint-mapping xmlns=""

    <class name="FOS\UserBundle\Model\User">

        <property name="plainPassword">
            <constraint name="NotBlank">
                <option name="message">fos_user.password.blank</option>
                <option name="groups">
            <constraint name="Length">
                <option name="min">8</option>
                <option name="max">50</option>
                <option name="minMessage">fos_user.password.short</option>
                <option name="groups">
            <constraint name="Regex">
                <option name="pattern">/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}$/</option>
                <option name="message">Das Passwort muss mindestens 8 Zeichen haben, eine Zahl, Groß und Kleinschreibung enthalten.</option>
                <option name="groups">

Create symfony brute-force guard for SonataAdmin

For the SonataAdmin bundle There is the possibility of Symofny guards own logic in the login process to incorporate, such as:

  • Defense against brute force attacks by a maximum number of login attempts

In the following example, I have configured a guard for the administration area, It will count, How many times a user incorrectly logged.

The UserManager must then contain the logic, to counting the number of logins for each user, and it formed. also to ban for a period of time. more…

Working Gau Frette with file streams

To with Gau Frette (Symfony extension) to be able to perform also stream operations on files, can you get the little scrawny documented Stream wrapper use.

This is configured in the gaufrette.yaml:

    stream_wrapper: ~
            adapter: backup

And can then be z.B. the following mass is a csv. Write file:

$stream = fopen('gaufrette://backup1/datei.csv', 'w+');

fputcsv($stream, [1,2,3]);

Dynamically configure symfony service ID using parameters

If you like in his Depnedency configuration of injection (services.yml) the service injections make dynamically configurable wants about the parameters.yml,

    my_class: 'App\MyClass'

can you do this using the Symfony expression language component do:

composer require symfony/expression-language

Then you can define in the services.yml:

        - '@=service(parameter("my_class"))'