We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

download an example of a log

Where can I download an example of a log with Phalcon. I was reading https://docs.phalcon.io/en/latest/api/Phalcon_Logger_Adapter_File.html

How I can create a log when data is inserted into a table? Is there an example?

with Phalcon:

$di->setShared('db', function () {
    $settings = $this->getSettings();

    $dbConfig = $settings->databases->default->toArray();
    $adapter = $dbConfig['adapter'];
    unset($dbConfig['adapter']);

    $class = 'Phalcon\Db\Adapter\Pdo\\' . $adapter;

    /**
     * @var \Phalcon\Db\Adapter\Pdo\Postgresql $connection
     */
    $connection = new $class($dbConfig);

    if (ENVIRONMENT == 'development') {
        $logDir = $settings->directories->logDir;
        $eventsManager = new EventsManager();
        if (!is_dir($logDir)) {
            mkdir($logDir, 755, true);
        }
        $logger = new FileLogger($logDir . "db.log");
        // Listen all the database events
        $eventsManager->attach('db', function ($event, $connection) use ($logger) {
            /**
             * @var \Phalcon\Events\Event $event
             * @var \Phalcon\Db\Adapter\Pdo\Postgresql $connection
             */
            if ($event->getType() == 'beforeQuery') {
                // Here! filter INSERT statements
                $logger->log($connection->getSQLStatement(), Logger::INFO);
            }
        });
        // Assign the eventsManager to the db adapter instance
        $connection->setEventsManager($eventsManager);
    }

    return $connection;
});

Well i wouldn't do writes during request time :P Better add queue job to log certain message and in cli task just write it to file :)



81.1k

Interestingly, I use the translator Unfortunately my English is not very good and perhaps they did not understand correcetamente. If you stop me an example of what you just told me

Well i wouldn't do writes during request time :P Better add queue job to log certain message and in cli task just write it to file :)



81.1k

hello you can tell me how you have created the directory in the config file logdir

with Phalcon:

$di->setShared('db', function () {
   $settings = $this->getSettings();

   $dbConfig = $settings->databases->default->toArray();
   $adapter = $dbConfig['adapter'];
   unset($dbConfig['adapter']);

   $class = 'Phalcon\Db\Adapter\Pdo\\' . $adapter;

   /**
    * @var \Phalcon\Db\Adapter\Pdo\Postgresql $connection
    */
   $connection = new $class($dbConfig);

   if (ENVIRONMENT == 'development') {
       $logDir = $settings->directories->logDir;
       $eventsManager = new EventsManager();
       if (!is_dir($logDir)) {
           mkdir($logDir, 755, true);
       }
       $logger = new FileLogger($logDir . "db.log");
       // Listen all the database events
       $eventsManager->attach('db', function ($event, $connection) use ($logger) {
           /**
            * @var \Phalcon\Events\Event $event
            * @var \Phalcon\Db\Adapter\Pdo\Postgresql $connection
            */
           if ($event->getType() == 'beforeQuery') {
              // Here! filter INSERT statements
               $logger->log($connection->getSQLStatement(), Logger::INFO);
           }
       });
       // Assign the eventsManager to the db adapter instance
       $connection->setEventsManager($eventsManager);
   }

   return $connection;
});

settings.php file:

<?php

return [

    // ... code ...
    'directories' => [
        'modulesDir' => APP_PATH . '/core/modules/',
        'themesDir' => APP_PATH . '/core/views/',
        'languagesDir' => APP_PATH . '/app/default/lang/',
        'modelsDir' => APP_PATH . '/core/models/',
        'migrationsDir' => APP_PATH . '/core/migrations/',
        'partialsDir' => APP_PATH . '/core/views/sui/partials/',
        'layoutsDir' => APP_PATH . '/core/views/sui/layouts/',
        'viewsDir' => APP_PATH . '/core/views/sui/',

        'logDir' => APP_PATH . '/var/log/default/',
        'backupDir' => APP_PATH . '/var/backup/default/',
        'dbDir' => APP_PATH . '/var/db/default/',
        'sessionDir' => APP_PATH . '/var/session/default/',
    ],

    //.., code....

services.php

/* Settings */
$di->setShared('settings', function () {
    \Druphal\Core\Site\Settings::initialize(SITE_PATH);
    return \Druphal\Core\Site\Settings::getAll();
});

Settings Class

<?php

namespace Druphal\Core\Site;

use Phalcon\Config;

/**
 * Read only settings that are initialized with the class.
 *
 * @ingroup utility
 */
final class Settings
{
    /**
     * Array with the settings.
     *
     * @var Config
     */
    private $storage = array();

    /**
     * Singleton instance.
     *
     * @var \Druphal\Core\Site\Settings
     */
    private static $instance;

    /**
     * Constructor.
     *
     * @param array $settings
     *   Array with the settings.
     */
    public function __construct(array $settings)
    {
        $this->storage = new Config($settings);
        self::$instance = $this;
    }

    /**
     * Returns the settings instance.
     *
     * A singleton is used because this class is used before the container is
     * available.
     *
     * @return \Druphal\Core\Site\Settings
     */
    public static function getInstance()
    {
        return self::$instance;
    }

    /**
     * Protects creating with clone.
     */
    private function __clone()
    {
    }

    /**
     * Prevents settings from being serialized.
     */
    public function __sleep()
    {
        throw new \LogicException(
            'Settings can not be serialized. This probably means you are serializing an object that has an indirect reference to the Settings object. Adjust your code so that is not necessary.'
        );
    }

    /**
     * Returns a setting.
     *
     * Settings can be set in settings.php in the $settings array and requested
     * by this function. Settings should be used over configuration for read-only,
     * possibly low bootstrap configuration that is environment specific.
     *
     * @param string $name
     *   The name of the setting to return.
     * @param mixed $default
     *   (optional) The default value to use if this setting is not set.
     *
     * @return mixed
     *   The value of the setting, the provided default if not set.
     */
    public static function get($name, $default = null)
    {
        return self::$instance->storage->get($name) ?? $default;
    }

    /**
     * Returns all the settings. This is only used for testing purposes.
     *
     * @return Config
     *   All the settings.
     */
    public static function getAll()
    {
        return self::$instance->storage;
    }

    /**
     * Bootstraps settings.php and the Settings singleton.
     *
     * @param string $sitePath
     *   The current site path.
     *
     * @see default.settings.php
     */
    public static function initialize($sitePath)
    {
        if (!is_readable($sitePath . '/settings.php')) {
            throw new \RuntimeException(sprintf('Create a settings.php file in %s directory', $sitePath));
        }

        $settings = include $sitePath . '/settings.php';

        // Initialize Settings.
        new Settings($settings);
    }

    /**
     * Gets a salt useful for hardening against SQL injection.
     *
     * @return string
     *   A salt based on information in settings.php, not in the database.
     *
     * @throws \RuntimeException
     */
    public static function getHashSalt()
    {
        $hash_salt = self::$instance->get('hash_salt');
        // This should never happen, as it breaks user logins and many other
        // services. Therefore, explicitly notify the user (developer) by throwing
        // an exception.
        if (empty($hash_salt)) {
            throw new \RuntimeException('Missing $settings[\'hash_salt\'] in settings.php.');
        }

        return $hash_salt;
    }

}

This is very useful to do this:

<?php

namespace Druphal\Core\PhpStorage;

use Druphal\Core\Site\Settings;
use Druphal\Core\StreamWrapper\PublicStream;

/**
 * Creates a php storage object
 */
class PhpStorageFactory
{

    /**
     * Instantiates a storage for generated PHP code.
     *
     * By default, this returns an instance of the
     * \Druphal\Component\PhpStorage\MTimeProtectedFileStorage class.
     *
     * Classes implementing
     * \Druphal\Component\PhpStorage\PhpStorageInterface can be registered for a
     * specific bin or as a default implementation.
     *
     * @param string $name
     *   The name for which the storage should be returned. Defaults to 'default'
     *   The name is also used as the storage bin if one is not specified in the
     *   configuration.
     *
     * @return \Druphal\Component\PhpStorage\PhpStorageInterface
     *   An instantiated storage for the specified name.
     */
    static function get($name)
    {
        $configuration = array();
        $overrides = Settings::get('php_storage');
        if (isset($overrides[$name])) {
            $configuration = $overrides[$name];
        } elseif (isset($overrides['default'])) {
            $configuration = $overrides['default'];
        }
        // Make sure all the necessary configuration values are set.
        $class = isset($configuration['class']) ? $configuration['class'] : 'Druphal\Component\PhpStorage\MTimeProtectedFileStorage';
        if (!isset($configuration['secret'])) {
            $configuration['secret'] = Settings::getHashSalt();
        }
        if (!isset($configuration['bin'])) {
            $configuration['bin'] = $name;
        }
        if (!isset($configuration['directory'])) {
            $configuration['directory'] = PublicStream::basePath() . '/php';
        }
        return new $class($configuration);
    }

}