Completed
Push — master ( 04bd65...4036d4 )
by Fran
09:06
created

Logger::addDefaultStreamHandler()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 7
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 12
ccs 7
cts 7
cp 1
crap 2
rs 9.4285
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 20 and the first side effect is on line 19.

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\GitProcessor;
10
    use Monolog\Processor\MemoryUsageProcessor;
11
    use Monolog\Processor\UidProcessor;
12
    use Monolog\Processor\WebProcessor;
13
    use PSFS\base\config\Config;
14
    use PSFS\base\types\SingletonTrait;
15
16
17 1
    if (!defined("LOG_DIR"))
18 1
    {
19
        Config::createDir(BASE_DIR.DIRECTORY_SEPARATOR.'logs');
20
        define("LOG_DIR", BASE_DIR.DIRECTORY_SEPARATOR.'logs');
21
    }
22
23
    /**
24
     * Class Logger
25
     * @package PSFS\base
26
     * Servicio de log
27
     */
28
    class Logger {
29
        use SingletonTrait;
30
        /**
31
         * @var \Monolog\Logger
32
         */
33
        protected $logger;
34
        /**
35
         * @var resource
36
         */
37
        private $stream;
38
39
        /**
40
         * @internal param string $path
41
         */
42 1
        public function __construct() {
43 1
            $config = Config::getInstance();
44 1
            $args = func_get_args();
45 1
            list($logger, $debug, $path) = $this->setup($config, $args);
46 1
            $this->stream = fopen($path.DIRECTORY_SEPARATOR.date("Ymd").".log", "a+");
47 1
            $this->addPushLogger($logger, $debug, $config);
48 1
        }
49
50
        /**
51
         * Destruye el recurso
52
         */
53
        public function __destroy() {
54
            fclose($this->stream);
55
        }
56
57
        /**
58
         * Método que escribe un log de información
59
         * @param string $msg
60
         * @param array $context
61
         *
62
         * @return bool
63
         */
64
        public function infoLog($msg = '', $context = []) {
65
            return $this->logger->addInfo($msg, $this->addMinimalContext($context));
66
        }
67
68
        /**
69
         * Método que escribe un log de Debug
70
         * @param string $msg
71
         * @param array $context
72
         *
73
         * @return bool
74
         */
75 9
        public function debugLog($msg = '', $context = []) {
76 9
            return $this->logger->addDebug($msg, $this->addMinimalContext($context));
77
        }
78
79
        /**
80
         * Método que escribe un log de Error
81
         * @param $msg
82
         * @param array $context
83
         *
84
         * @return bool
85
         */
86 3
        public function errorLog($msg, $context = []) {
87 3
            return $this->logger->addError($msg, $this->addMinimalContext($context));
88
        }
89
90
        /**
91
         * Método que escribe un log de Warning
92
         * @param $msg
93
         * @param array $context
94
         * @return bool
95
         */
96
        public function warningLog($msg, $context = []) {
97
            return $this->logger->addWarning($msg, $this->addMinimalContext($context));
98
        }
99
100
        /**
101
         * Método que añade los push processors
102
         * @param string $logger
103
         * @param boolean $debug
104
         * @param Config $config
105
         */
106 1
        private function addPushLogger($logger, $debug, Config $config) {
107 1
            $this->logger = new Monolog(strtoupper($logger));
108 1
            $this->logger->pushHandler($this->addDefaultStreamHandler($debug));
109 1
            if ($debug) {
110 1
                $phpFireLog = $config->get("logger.phpFire");
111 1
                if (!empty($phpFireLog)) {
112
                    $this->logger->pushHandler(new FirePHPHandler());
113
                }
114 1
                $memoryLog = $config->get("logger.memory");
115 1
                if (!empty($memoryLog)) {
116
                    $this->logger->pushProcessor(new MemoryUsageProcessor());
117
                }
118 1
            }
119 1
            $this->logger->pushProcessor(new UidProcessor());
120 1
        }
121
122
        /**
123
         * Método que inicializa el Logger
124
         * @param Config $config
125
         * @param array $args
126
         *
127
         * @return array
128
         */
129 1
        private function setup(Config $config, array $args = array()) {
130 1
            $debug = $config->getDebugMode();
131 1
            $namespace = "PSFS";
132 1
            if (0 !== count($args)) {
133 1
                if (array_key_exists(0, $args) && array_key_exists(0, $args[0])) {
134
                    $namespace = $args[0][0];
135
                }
136 1
                if (array_key_exists(0, $args) && array_key_exists(1, $args[0])) {
137
                    $debug = $args[0][1];
138
                }
139 1
            }
140 1
            $path = $this->createLoggerPath($config);
141 1
            return array($this->cleanLoggerName($namespace), $debug, $path);
142
        }
143
144
        /**
145
         * Método que construye el nombre del logger
146
         * @param Config $config
147
         *
148
         * @return string
149
         */
150 1
        private function setLoggerName(Config $config) {
151 1
            $logger = $config->get("platform_name") ?: "PSFS";
152 1
            $logger = $this->cleanLoggerName($logger);
153
154 1
            return $logger;
155
        }
156
157
        /**
158
         * Método para limpiar el nombre del logger
159
         * @param $logger
160
         *
161
         * @return mixed
162
         */
163 1
        private function cleanLoggerName($logger)
164
        {
165 1
            $logger = str_replace(' ', '', $logger);
166 1
            $logger = preg_replace('/\\\/', ".", $logger);
167
168 1
            return $logger;
169
        }
170
171
        /**
172
         * Método que crea el path del logger
173
         * @param Config $config
174
         *
175
         * @return string
176
         */
177 1
        private function createLoggerPath(Config $config)
178
        {
179 1
            $logger = $this->setLoggerName($config);
180 1
            $path = LOG_DIR.DIRECTORY_SEPARATOR.$logger.DIRECTORY_SEPARATOR.date('Y').DIRECTORY_SEPARATOR.date('m');
181 1
            Config::createDir($path);
182
183 1
            return $path;
184
        }
185
186
        /**
187
         * Static method to trace logs
188
         * @param string $msg
189
         * @param int $type
190
         * @param array $context
191
         */
192 9
        public static function log($msg, $type = LOG_DEBUG, $context = []) {
193
            switch($type) {
194 9
                case LOG_DEBUG:
195 9
                    Logger::getInstance()->debugLog($msg, $context);
196 9
                    break;
197 3
                case LOG_WARNING:
198
                    Logger::getInstance()->warningLog($msg, $context);
199
                    break;
200 3
                case LOG_CRIT:
201 3
                case LOG_ERR:
202 3
                Logger::getInstance()->errorLog($msg, $context);
203 3
                    break;
204
                case LOG_INFO:
205
                    Logger::getInstance()->infoLog($msg, $context);
206
                    break;
207
                default:
208
                    Logger::getInstance()->log($msg, $context);
0 ignored issues
show
Documentation introduced by
$context is of type array, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
209
                    break;
210
            }
211 9
        }
212
213
        /**
214
         * Add the default stream handler
215
         * @param bool $debug
216
         * @return StreamHandler
217
         */
218 1
        private function addDefaultStreamHandler($debug = false)
219
        {
220
            // the default date format is "Y-m-d H:i:s"
221 1
            $dateFormat = "Y-m-d H:i:s.u";
222
            // the default output format is "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n"
223 1
            $output = "[%datetime%] [%channel%:%level_name%]\t%message%\t%context%\t%extra%\n";
224
            // finally, create a formatter
225 1
            $formatter = new LineFormatter($output, $dateFormat);
226 1
            $stream = new StreamHandler($this->stream, $debug ? Monolog::DEBUG : Monolog::WARNING);
227 1
            $stream->setFormatter($formatter);
228 1
            return $stream;
229
        }
230
231
        /**
232
         * Add a minimum context to the log
233
         * @param array $context
234
         * @return array
235
         */
236 9
        private function addMinimalContext(array $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...
237
        {
238 9
            $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 130 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...
239 9
            $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 139 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...
240 9
            return $context;
241
        }
242
    }
243