PluginProbe ʕ •ᴥ•ʔ
NitroPack – Performance, Page Speed & Cache Plugin for Core Web Vitals, CDN & Image Optimization / 1.18.9
NitroPack – Performance, Page Speed & Cache Plugin for Core Web Vitals, CDN & Image Optimization v1.18.9
1.19.8 1.19.7 1.19.6 1.19.5 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.11.0 1.12.0 1.13.0 1.14.0 1.15.0 1.15.1 1.15.2 1.15.3 1.16.0 1.16.1 1.16.2 1.16.3 1.16.4 1.16.5 1.16.6 1.16.7 1.16.8 1.17.0 1.17.6 1.17.7 1.17.8 1.17.9 1.18.0 1.18.1 1.18.2 1.18.3 1.18.4 1.18.5 1.18.6 1.18.7 1.18.8 1.18.9 1.19.0 1.19.1 1.19.2 1.19.3 1.19.4 1.3.19 1.3.20 1.4.0 1.4.1 1.5.0 1.5.1 1.5.10 1.5.11 1.5.12 1.5.13 1.5.14 1.5.15 1.5.16 1.5.17 1.5.18 1.5.19 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.7.0 1.7.1 1.8.0 1.8.1 1.8.3 1.9.0 1.9.1 1.9.2
nitropack / classes / Feature / Logger / Logger.php
nitropack / classes / Feature / Logger Last commit date
Logger.php 7 months ago LoggingEvents.php 1 year ago
Logger.php
223 lines
1 <?php
2
3 namespace NitroPack\Feature\Logger;
4
5 class Logger {
6 private $nitro;
7 public $separator;
8 const ERROR = 3;
9 const NOTICE = 2;
10 const INFO = 1;
11
12 /** Mapping of log levels to their string representations */
13 private $level_value;
14
15 /**
16 * Logger constructor.
17 *
18 * @param int $level The logging level (default: ERROR)
19 */
20 public function __construct( $nitro ) {
21 $this->nitro = $nitro;
22 $this->separator = ';';
23 $this->level_value = [
24 self::ERROR => 'ERROR',
25 self::NOTICE => 'NOTICE',
26 self::INFO => 'INFO'
27 ];
28 }
29
30 /**
31 * Determines if the current execution environment is CLI (Command Line Interface).
32 *
33 * This function checks various indicators to determine if the script is being run from the command line.
34 * It returns true if any of the following conditions are met:
35 * - The STDIN constant is defined.
36 * - The PHP SAPI name is 'cli'.
37 * - The 'SHELL' key exists in the $_ENV array.
38 * - The $_SERVER array lacks 'REMOTE_ADDR' and 'HTTP_USER_AGENT', and has arguments in 'argv'.
39 * - The 'REQUEST_METHOD' key does not exist in the $_SERVER array.
40 *
41 * @return bool True if the script is running in CLI mode, false otherwise.
42 */
43 private function is_cli() {
44 if ( defined( 'STDIN' ) ) {
45 return true;
46 }
47
48 if ( php_sapi_name() === 'cli' ) {
49 return true;
50 }
51
52 if ( array_key_exists( 'SHELL', $_ENV ) ) {
53 return true;
54 }
55
56 if ( empty( $_SERVER['REMOTE_ADDR'] ) and ! isset( $_SERVER['HTTP_USER_AGENT'] ) and count( $_SERVER['argv'] ) > 0 ) {
57 return true;
58 }
59
60 if ( ! array_key_exists( 'REQUEST_METHOD', $_SERVER ) ) {
61 return true;
62 }
63
64 return false;
65 }
66 /**
67 * Log a message with the specified level.
68 * The message will be logged only if the current log level meets the minimum log level requirement.
69 * The log level is first fetched from the config.json if the value is not found then it is fetched from the database.
70 * The reason is that when connecting or disconnecting NitroPack, the config.json is empty.
71 *
72 * @param int $level The log level of the message
73 * @param string $message The message to log
74 * @return void
75 */
76 private function log( $level, $message ) {
77 $siteConfig = $this->nitro->getSiteConfig();
78 $configLevel = ! empty( $siteConfig['minimumLogLevel'] ) ? $siteConfig['minimumLogLevel'] : null;
79
80 if ( ! $configLevel ) {
81 if ( ! function_exists( 'get_option' ) ) {
82 return;
83 }
84
85 $configLevel = (int) get_option( 'nitropack-minimumLogLevel', null );
86 }
87
88 // Check if the log level is set and if the current log level meets the minimum log level requirement
89 if ( $configLevel === null || $level < $configLevel ) {
90 return;
91 }
92
93 if ( ! $this->init_logs_dir() )
94 return;
95
96 $log_file = $this->get_log_file_path();
97 $max_size = $this->get_max_log_filesize();
98
99 if ( file_exists( $log_file ) && filesize( $log_file ) > $max_size ) {
100 error_log( "NitroPack log file has reached maximum size. Logging stopped." );
101 return;
102 }
103
104 $prepend = '';
105 if ( $this->is_cli() )
106 $prepend = '[CLI] ';
107 $level = $this->level_value[ $level ];
108 $content = [
109 'Date' => date( 'Y-m-d H:i:s' ),
110 'Level' => $level,
111 'Message' => $prepend . $message,
112 ];
113
114 $this->write_to_log_file( $log_file, $content );
115 }
116 public function error( $message ) {
117 $this->log( self::ERROR, $message );
118 }
119 public function notice( $message ) {
120 $this->log( self::NOTICE, $message );
121 }
122 public function info( $message ) {
123 $this->log( self::INFO, $message );
124 }
125 /**
126 * Initialize the logs directory.
127 *
128 * @return bool True if the directory exists or was created successfully, false otherwise
129 */
130 private function init_logs_dir() {
131 if ( $this->data_logs_dir_exists() )
132 return true;
133
134 $create_dir = mkdir( NITROPACK_LOGS_DATA_DIR );
135
136 if ( $create_dir ) {
137 // Create .htaccess file with deny from all
138 $htaccess_path = NITROPACK_LOGS_DATA_DIR . '/.htaccess';
139 file_put_contents( $htaccess_path, "Order Allow,Deny\nAllow from all\n<FilesMatch \"\.(csv|zip)$\">\nOrder Deny,Allow\nAllow from all\n</FilesMatch>" );
140
141 // Create empty index.html file
142 $index_path = NITROPACK_LOGS_DATA_DIR . '/index.html';
143 file_put_contents( $index_path, "" );
144 return true;
145 } else {
146 error_log( "Failed to create nitroopack logs directory: " . NITROPACK_LOGS_DATA_DIR );
147 }
148 return false;
149 }
150
151 /**
152 * Check if the data logs directory exists.
153 *
154 * @return bool True if the directory exists, false otherwise
155 */
156 private function data_logs_dir_exists() {
157 return defined( "NITROPACK_LOGS_DATA_DIR" ) && is_dir( NITROPACK_LOGS_DATA_DIR );
158 }
159
160 /**
161 * Get the full path of the log file.
162 *
163 * @return string The log file path
164 */
165 private function get_log_file_path() {
166 return nitropack_trailingslashit( NITROPACK_LOGS_DATA_DIR ) . $this->get_log_filename();
167 }
168
169 /**
170 * Get the log filename based on the current date.
171 *
172 * @return string The log filename
173 */
174 private function get_log_filename() {
175 return date( 'Y-m-d' ) . '_nitropack_log.csv';
176 }
177
178 /**
179 * Get the maximum log file size.
180 *
181 * @return int The maximum log file size in bytes
182 */
183 private function get_max_log_filesize() {
184 return apply_filters( 'nitropack_max_log_filesize', 20 * 1024 * 1024 ); // 20MB
185 }
186
187 /**
188 * Rotate the log file by renaming it with a timestamp.
189 *
190 * @param string $log_file The path to the log file
191 * @return bool True if rotation was successful, false otherwise
192 */
193 private function rotate_log_file( $log_file ) {
194 $rotated_file = $log_file . '.' . date( 'Y-m-d-H-i-s' );
195 return rename( $log_file, $rotated_file );
196 }
197
198 /**
199 * Write content to the log file.
200 *
201 * @param string $log_file The path to the log file
202 * @param array $content The content to write to the log file
203 * @return void
204 */
205 private function write_to_log_file( $log_file, $content ) {
206 $file_exists = file_exists( $log_file );
207 $file_handle = fopen( $log_file, 'a' );
208
209 if ( $file_handle === false ) {
210 error_log( "Failed to open nitropack log file: $log_file" );
211 return;
212 }
213
214 //chmod($log_file, $this->get_chmod());
215
216 if ( ! $file_exists ) {
217 fputcsv( $file_handle, array_keys( $content ), $this->separator );
218 }
219
220 fputcsv( $file_handle, $content, $this->separator );
221 fclose( $file_handle );
222 }
223 }