@@ -319,6 +319,10 @@ public function log($level, $message, array $context = []): bool
319
319
* {session_vars}
320
320
* {post_vars}
321
321
* {get_vars}
322
+ * {env}
323
+ * {env:foo}
324
+ * {file}
325
+ * {line}
322
326
*
323
327
* @param $message
324
328
* @param array $context
@@ -336,7 +340,7 @@ protected function interpolate($message, array $context = [])
336
340
// or error, both of which implement the 'Throwable' interface.
337
341
if ($ key == 'exception ' && $ val instanceof \Throwable)
338
342
{
339
- $ val = $ val ->getMessage ().' ' .$ val ->getFile ().': ' . $ val ->getLine ();
343
+ $ val = $ val ->getMessage ().' ' .$ this -> cleanFileNames ( $ val ->getFile () ).': ' . $ val ->getLine ();
340
344
}
341
345
342
346
// todo - sanitize input before writing to file?
@@ -346,6 +350,31 @@ protected function interpolate($message, array $context = [])
346
350
// Add special placeholders
347
351
$ replace ['{post_vars} ' ] = '$_POST: ' .print_r ($ _POST , true );
348
352
$ replace ['{get_vars} ' ] = '$_GET: ' .print_r ($ _GET , true );
353
+ $ replace ['{env} ' ] = ENVIRONMENT ;
354
+
355
+ // Allow us to log the file/line that we are logging from
356
+ if (strpos ($ message , '{file} ' ) !== false )
357
+ {
358
+ list ($ file , $ line ) = $ this ->determineFile ();
359
+
360
+ $ replace ['{file} ' ] = $ file ;
361
+ $ replace ['{line} ' ] = $ line ;
362
+ }
363
+
364
+ // Match up environment variables in {env:foo} tags.
365
+ if (strpos ($ message , 'env: ' ) !== false )
366
+ {
367
+ preg_match ('/env:[^}]+/ ' , $ message , $ matches );
368
+
369
+ if (count ($ matches ))
370
+ {
371
+ foreach ($ matches as $ str )
372
+ {
373
+ $ key = str_replace ('env: ' , '' , $ str );
374
+ $ replace ["{ {$ str }} " ] = $ _ENV [$ key ] ?? 'n/a ' ;
375
+ }
376
+ }
377
+ }
349
378
350
379
if (isset ($ _SESSION ))
351
380
{
@@ -358,4 +387,63 @@ protected function interpolate($message, array $context = [])
358
387
359
388
//--------------------------------------------------------------------
360
389
390
+ /**
391
+ * Determines the current file/line that the log method was called from.
392
+ * by analyzing the backtrace.
393
+ *
394
+ * @return array
395
+ */
396
+ public function determineFile ()
397
+ {
398
+ // Determine the file and line by finding the first
399
+ // backtrace that is not part of our logging system.
400
+ $ trace = debug_backtrace ();
401
+ $ file = null ;
402
+ $ line = null ;
403
+
404
+ foreach ($ trace as $ row )
405
+ {
406
+ if (in_array ($ row ['function ' ], ['interpolate ' , 'determineFile ' , 'log ' , 'log_message ' ]))
407
+ {
408
+ continue ;
409
+ }
410
+
411
+ $ file = $ row ['file ' ] ?? isset ($ row ['object ' ]) ? get_class ($ row ['object ' ]) : 'unknown ' ;
412
+ $ line = $ row ['line ' ] ?? $ row ['function ' ] ?? 'unknown ' ;
413
+ break ;
414
+ }
415
+
416
+ return [
417
+ $ file ,
418
+ $ line
419
+ ];
420
+ }
421
+
422
+ //--------------------------------------------------------------------
423
+
424
+
425
+ /**
426
+ * Cleans the paths of filenames by replacing APPPATH, BASEPATH, FCPATH
427
+ * with the actual var. i.e.
428
+ *
429
+ * /var/www/site/application/controllers/Home.php
430
+ * becomes:
431
+ * APPPATH/controllers/Home.php
432
+ *
433
+ * @param $file
434
+ *
435
+ * @return mixed
436
+ */
437
+ protected function cleanFileNames ($ file )
438
+ {
439
+ $ file = str_replace (APPPATH , 'APPPATH/ ' , $ file );
440
+ $ file = str_replace (BASEPATH , 'BASEPATH/ ' , $ file );
441
+ $ file = str_replace (FCPATH , 'FCPATH/ ' , $ file );
442
+
443
+ return $ file ;
444
+ }
445
+
446
+ //--------------------------------------------------------------------
447
+
448
+
361
449
}
0 commit comments