Test Failed
Push — master ( 0d14a6...e876c1 )
by Fran
09:15
created

Logger::log()   C

Complexity

Conditions 7
Paths 12

Size

Total Lines 24
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 7

Importance

Changes 0
Metric Value
cc 7
eloc 20
nc 12
nop 3
dl 0
loc 24
ccs 16
cts 16
cp 1
crap 7
rs 6.7272
c 0
b 0
f 0
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 19 and the first side effect is on line 18.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
3
namespace PSFS\base;
4
5
use Monolog\Formatter\LineFormatter;
6
use Monolog\Handler\FirePHPHandler;
7
use Monolog\Handler\StreamHandler;
8
use Monolog\Logger as Monolog;
9
use Monolog\Processor\MemoryUsageProcessor;
10
use Monolog\Processor\UidProcessor;
11
use PSFS\base\config\Config;
12
use PSFS\base\types\helpers\GeneratorHelper;
13
use PSFS\base\types\helpers\Inspector;
14
use PSFS\base\types\traits\SingletonTrait;
15
16
17
if (!defined("LOG_DIR")) {
18
    GeneratorHelper::createDir(BASE_DIR . DIRECTORY_SEPARATOR . 'logs');
19
    define("LOG_DIR", BASE_DIR . DIRECTORY_SEPARATOR . 'logs');
20
}
21
22
/**
23
 * Class Logger
24
 * @package PSFS\base
25
 * Servicio de log
26
 */
27
class Logger
28
{
29
    const DEFAULT_NAMESPACE = 'PSFS';
30
    use SingletonTrait;
31
    /**
32
     * @var \Monolog\Logger
33
     */
34
    protected $logger;
35
    /**
36
     * @var resource
37
     */
38
    private $stream;
39
    /**
40
     * @var string
41
     */
42
    protected $log_level;
43
44
    /**
45
     * @internal param string $path
46 2
     */
47
    public function __construct()
48 2
    {
49 2
        $config = Config::getInstance();
50 2
        $args = func_get_args();
51 2
        list($logger, $debug, $path) = $this->setup($config, $args);
52 2
        $this->stream = fopen($path . DIRECTORY_SEPARATOR . date("Ymd") . ".log", "a+");
53 2
        $this->addPushLogger($logger, $debug, $config);
54 2
        $this->log_level = Config::getParam('log.level', 'info');
55
    }
56
57
    /**
58
     * Destruye el recurso
59 1
     */
60
    public function __destruct()
61 1
    {
62 1
        fclose($this->stream);
63
    }
64
65
    /**
66
     * Default log method
67
     * @param string $msg
68
     * @param array $context
69
     * @return bool
70 1
     */
71
    public function defaultLog($msg = '', $context = [])
72 1
    {
73
        return $this->logger->addNotice($msg, $this->addMinimalContext($context));
74
    }
75
76
    /**
77
     * Método que escribe un log de información
78
     * @param string $msg
79
     * @param array $context
80
     *
81
     * @return bool
82 3
     */
83
    public function infoLog($msg = '', $context = [])
84 3
    {
85
        return $this->logger->addInfo($msg, $this->addMinimalContext($context));
86
    }
87
88
    /**
89
     * Método que escribe un log de Debug
90
     * @param string $msg
91
     * @param array $context
92
     *
93
     * @return bool
94 15
     */
95
    public function debugLog($msg = '', $context = [])
96 15
    {
97
        return ($this->log_level === 'debug') ? $this->logger->addDebug($msg, $this->addMinimalContext($context)) : null;
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 121 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
98
    }
99
100
    /**
101
     * Método que escribe un log de Error
102
     * @param $msg
103
     * @param array $context
104
     *
105
     * @return bool
106 3
     */
107
    public function errorLog($msg, $context = [])
108 3
    {
109
        return $this->logger->addError($msg, $this->addMinimalContext($context));
110
    }
111
112
    /**
113
     * Método que escribe un log de Warning
114
     * @param $msg
115
     * @param array $context
116
     * @return bool
117 2
     */
118
    public function warningLog($msg, $context = [])
119 2
    {
120
        return $this->logger->addWarning($msg, $this->addMinimalContext($context));
121
    }
122
123
    /**
124
     * Método que añade los push processors
125
     * @param string $logger
126
     * @param boolean $debug
127
     * @param Config $config
128 2
     */
129
    private function addPushLogger($logger, $debug, Config $config)
130 2
    {
131 2
        $this->logger = new Monolog(strtoupper($logger));
132 2
        $this->logger->pushHandler($this->addDefaultStreamHandler($debug));
133 1
        if ($debug) {
134 1
            $phpFireLog = $config->get("logger.phpFire");
135 1
            if (!empty($phpFireLog)) {
136
                $this->logger->pushHandler(new FirePHPHandler());
137 1
            }
138 1
            $memoryLog = $config->get("logger.memory");
139 1
            if (!empty($memoryLog)) {
140
                $this->logger->pushProcessor(new MemoryUsageProcessor());
141
            }
142 2
        }
143 2
        $this->logger->pushProcessor(new UidProcessor());
144
    }
145
146
    /**
147
     * Método que inicializa el Logger
148
     * @param Config $config
149
     * @param array $args
150
     *
151
     * @return array
152 2
     */
153
    private function setup(Config $config, array $args = array())
154 2
    {
155 2
        $debug = $config->getDebugMode();
156 2
        $namespace = self::DEFAULT_NAMESPACE;
157 2
        if (0 !== count($args)) {
158 1
            if (array_key_exists(0, $args) && array_key_exists(0, $args[0])) {
159
                $namespace = $args[0][0];
160 2
            }
161 1
            if (array_key_exists(0, $args) && array_key_exists(1, $args[0])) {
162
                $debug = $args[0][1];
163
            }
164 2
        }
165 2
        $path = $this->createLoggerPath($config);
166
        return array($this->cleanLoggerName($namespace), $debug, $path);
167
    }
168
169
    /**
170
     * Método que construye el nombre del logger
171
     * @param Config $config
172
     *
173
     * @return string
174 2
     */
175
    private function setLoggerName(Config $config)
176 2
    {
177 2
        $logger = $config->get("platform_name") ?: self::DEFAULT_NAMESPACE;
178
        $logger = $this->cleanLoggerName($logger);
179 2
180
        return $logger;
181
    }
182
183
    /**
184
     * Método para limpiar el nombre del logger
185
     * @param $logger
186
     *
187
     * @return mixed
188 2
     */
189
    private function cleanLoggerName($logger)
190 2
    {
191 2
        $logger = str_replace(' ', '', $logger);
192
        $logger = preg_replace('/\\\/', ".", $logger);
193 2
194
        return $logger;
195
    }
196
197
    /**
198
     * Método que crea el path del logger
199
     * @param Config $config
200
     *
201
     * @return string
202 2
     */
203
    private function createLoggerPath(Config $config)
204 2
    {
205 2
        $logger = $this->setLoggerName($config);
206 2
        $path = LOG_DIR . DIRECTORY_SEPARATOR . $logger . DIRECTORY_SEPARATOR . date('Y') . DIRECTORY_SEPARATOR . date('m');
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 124 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
207
        GeneratorHelper::createDir($path);
208 2
209
        return $path;
210
    }
211
212
    /**
213
     * Static method to trace logs
214
     * @param string $msg
215
     * @param int $type
216
     * @param array $context
217 16
     */
218
    public static function log($msg, $type = LOG_DEBUG, $context = [])
219
    {
220 16
        if(Config::getParam('profiling.enable')) {
221 15
            Inspector::stats($msg);
222 15
        }
223 5
        switch ($type) {
224 2
            case LOG_DEBUG:
225 2
                Logger::getInstance()->debugLog($msg, $context);
226 5
                break;
227 5
            case LOG_WARNING:
228 3
                Logger::getInstance()->warningLog($msg, $context);
229 3
                break;
230 3
            case LOG_CRIT:
231 3
            case LOG_ERR:
232 3
                Logger::getInstance()->errorLog($msg, $context);
233
                break;
234 1
            case LOG_INFO:
235 1
                Logger::getInstance()->infoLog($msg, $context);
236
                break;
237 16
            default:
238
                Logger::getInstance()->defaultLog($msg, $context);
239
                break;
240
        }
241
    }
242
243
    /**
244 2
     * Add the default stream handler
245
     * @param bool $debug
246
     * @return StreamHandler
247 2
     */
248
    private function addDefaultStreamHandler($debug = false)
249 2
    {
250
        // the default date format is "Y-m-d H:i:s"
251 2
        $dateFormat = "Y-m-d H:i:s.u";
252 2
        // the default output format is "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n"
253 2
        $output = "[%datetime%] [%channel%:%level_name%]\t%message%\t%context%\t%extra%\n";
254 2
        // finally, create a formatter
255
        $formatter = new LineFormatter($output, $dateFormat);
256
        $stream = new StreamHandler($this->stream, $debug ? Monolog::DEBUG : Monolog::WARNING);
257
        $stream->setFormatter($formatter);
258
        return $stream;
259
    }
260
261
    /**
262 5
     * Add a minimum context to the log
263
     * @param array $context
264 5
     * @return array
265
     */
266
    private function addMinimalContext($context = [])
0 ignored issues
show
Coding Style introduced by
addMinimalContext uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
267 5
    {
268 5
        if(!is_array($context)) {
269 5
            $context = [];
270
        }
271
        $context['uri'] = null !== $_SERVER && array_key_exists('REQUEST_URI', $_SERVER) ? $_SERVER['REQUEST_URI'] : 'Unknow';
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 126 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
272
        $context['method'] = null !== $_SERVER && array_key_exists('REQUEST_METHOD', $_SERVER) ? $_SERVER['REQUEST_METHOD'] : 'Unknow';
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 135 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
273
        return $context;
274
    }
275
}
276