yii2从日志中排除变量

Nic*_*lay 0 logging yii2

我需要为yii2记录创建路径。此路径应避免记录诸如密码等的变量。根据文档(yii \ log \ Target),要排除变量,我需要配置logVars。

在配置中:

 'targets' => [
            [
                'class' => yii\log\FileTarget::className(),
                'levels' => ['error', 'warning'],
                'maxLogFiles' => 1000,
                'maxFileSize' => 102400,
                'logVars' => '!_POST[LoginForm[password]]',
            ],
Run Code Online (Sandbox Code Playgroud)

但是LoginForm密码仍然出现在日志文件中。如何正确配置logVars。

PS我已经尝试过!LoginForm.password,!_POST.LoginForm.password

Biz*_*ley 5

我出于相同的目的准备了代码-也许您会发现它很有用。

覆盖getContextMessage()选定的目标类,例如:

<?php

namespace your\namespace\here;

use yii\helpers\ArrayHelper;

class FileTarget extends \yii\log\FileTarget
{
    protected function getContextMessage()
    {
        $context = ArrayHelper::filter($GLOBALS, $this->logVars);
        $result = [];
        foreach ($context as $key => $value) {
            if (\is_string($value) && stripos($key, 'password') !== false) {
                $result[] = "\${$key} = '** PASSWORD HIDDEN **'";
            } else {
                $result[] = "\${$key} = " . \your\namespace\here\LogVarDumper::dumpAsString($value);
            }
        }
        return implode("\n\n", $result);
    }
}
Run Code Online (Sandbox Code Playgroud)

覆盖VarDumperLogVarDumper(用于上面):

<?php

namespace your\namespace\here;

use yii\base\InvalidValueException;

/**
 * Class LogVarDumper
 * Extended to handle logs password fields darkening.
 */
class LogVarDumper extends \yii\helpers\VarDumper
{
    private static $_objects;
    private static $_output;
    private static $_depth;

    public static function dumpAsString($var, $depth = 10, $highlight = false)
    {
        self::$_output = '';
        self::$_objects = [];
        self::$_depth = $depth;
        self::dumpInternal($var, 0);
        if ($highlight) {
            $result = highlight_string("<?php\n" . self::$_output, true);
            self::$_output = preg_replace('/&lt;\\?php<br \\/>/', '', $result, 1);
        }

        return self::$_output;
    }

    /**
     * @param mixed $var variable to be dumped
     * @param int $level depth level
     * @param bool $passwordKey whether password related key was present in previous iteration
     */
    private static function dumpInternal($var, $level, $passwordKey = false)
    {
        switch (gettype($var)) {
            case 'boolean':
                self::$_output .= $var ? 'true' : 'false';
                break;
            case 'integer':
                self::$_output .= "$var";
                break;
            case 'double':
                self::$_output .= "$var";
                break;
            case 'string':
                if ($passwordKey) {
                    self::$_output .= "'** PASSWORD HIDDEN **'";
                } else {
                    self::$_output .= "'" . addslashes($var) . "'";
                }
                break;
            case 'resource':
                self::$_output .= '{resource}';
                break;
            case 'NULL':
                self::$_output .= 'null';
                break;
            case 'unknown type':
                self::$_output .= '{unknown}';
                break;
            case 'array':
                if (self::$_depth <= $level) {
                    self::$_output .= '[...]';
                } elseif (empty($var)) {
                    self::$_output .= '[]';
                } else {
                    $keys = array_keys($var);
                    $spaces = str_repeat(' ', $level * 4);
                    self::$_output .= '[';
                    foreach ($keys as $key) {
                        self::$_output .= "\n" . $spaces . '    ';
                        self::dumpInternal($key, 0);
                        self::$_output .= ' => ';
                        self::dumpInternal($var[$key], $level + 1, strpos(strtolower($key), 'password') !== false);
                    }
                    self::$_output .= "\n" . $spaces . ']';
                }
                break;
            case 'object':
                if (($id = array_search($var, self::$_objects, true)) !== false) {
                    self::$_output .= get_class($var) . '#' . ($id + 1) . '(...)';
                } elseif (self::$_depth <= $level) {
                    self::$_output .= get_class($var) . '(...)';
                } else {
                    $id = array_push(self::$_objects, $var);
                    $className = get_class($var);
                    $spaces = str_repeat(' ', $level * 4);
                    self::$_output .= "$className#$id\n" . $spaces . '(';
                    if ('__PHP_Incomplete_Class' !== get_class($var) && method_exists($var, '__debugInfo')) {
                        $dumpValues = $var->__debugInfo();
                        if (!is_array($dumpValues)) {
                            throw new InvalidValueException('__debuginfo() must return an array');
                        }
                    } else {
                        $dumpValues = (array) $var;
                    }
                    foreach ($dumpValues as $key => $value) {
                        $keyDisplay = strtr(trim($key), "\0", ':');
                        self::$_output .= "\n" . $spaces . "    [$keyDisplay] => ";
                        self::dumpInternal($value, $level + 1);
                    }
                    self::$_output .= "\n" . $spaces . ')';
                }
                break;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

your\namespace\here\FileTarget在配置中用于日志。您可以使用可用于所选目标的所有属性,现在password,名称中包含字段值为字符串的所有字段都将记录,** PASSWORD HIDDEN **而不是实际密码。