public function logMessage(Message $message): void
    {
        if (in_array($message->getLevel(), $this->config['log'])) {
            // If script is running for very long time (e.g. CRON), then date might change if time passes midnight.
            // In that case, log will continue to write messages to new file.

            $fpFile = $this->getFileName();
            if ($fpFile !== $this->fpFile) {
                //date has changed? or we need to init?
                if ($this->fp) {
                    // close pointer to old file
                    @fclose($this->fp);
                }

                if ($this->config['path'] === null) {
                    $path = Application::getStoragePath('log' . DS . $fpFile);
                } else {
                    $path = str_replace(DS . DS, DS, $this->config['path'] . DS . $fpFile);
                }

                $this->fpFile = $fpFile;

                if (!($this->fp = @fopen($path, 'a'))) {
                    // file failed to open, maybe directory doesn't exists?
                    $dir = dirname($path);
                    if (!is_dir($dir)) {
                        Directory::mkdir($dir, $this->mode);
                    }

                    if (!($this->fp = @fopen($path, 'a'))) {
                        // now the directory should exists, so try to open file again
                        throw new Exception('Can not write to log file on path=' . $path);
                    }
                }
            }

            if (!$this->fp || $this->fp === null) {
                if ($this->config['path'] === null) {
                    $path = Application::getStoragePath('log' . DS . $fpFile);
                } else {
                    $path = str_replace(DS . DS, DS, $this->config['path'] . DS . $fpFile);
                }

                throw new Exception("Can not write to log file path={$path}");
            }

            if ($this->getMessageFunction !== null) {
                $line = call_user_func($this->getMessageFunction, $message);
            } else {
                $time = $message->getTime()->format('y-m-d H:i:s.v');
                $level = strtoupper($message->getLevel());
                $space = str_repeat(' ', 10 - strlen($level));
                $who = $message->getWho() ?? Log::getWho();
                $line = "{$time} {$level}{$space}{$who}\t{$message->getMessage()}\n";
            }

            if (!@fwrite($this->fp, $line)) { // actually write it in file
                throw new Exception('Unable to write to log file');
            }
        }
    }