Logger.php 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. <?php
  2. namespace Libs;
  3. /**
  4. * Logger simples da aplicação.
  5. *
  6. * - Escreve no terminal (STDERR) para visibilidade imediata em desenvolvimento.
  7. * - Escreve também em arquivo (log.txt por padrão) para histórico persistente.
  8. *
  9. * Ativado/desativado pela variável de ambiente LOG_ENABLED (true/false).
  10. * O caminho do arquivo pode ser customizado por LOG_FILE.
  11. */
  12. final class Logger
  13. {
  14. public const LEVEL_DEBUG = 'debug';
  15. public const LEVEL_INFO = 'info';
  16. public const LEVEL_WARNING = 'warning';
  17. public const LEVEL_ERROR = 'error';
  18. /**
  19. * Verifica se o log está habilitado. Default: habilitado.
  20. */
  21. public static function isEnabled(): bool
  22. {
  23. $flag = $_ENV['LOG_ENABLED'] ?? 'true';
  24. return filter_var($flag, FILTER_VALIDATE_BOOLEAN);
  25. }
  26. public static function debug(string $message, array $context = []): void
  27. {
  28. self::log(self::LEVEL_DEBUG, $message, $context);
  29. }
  30. public static function info(string $message, array $context = []): void
  31. {
  32. self::log(self::LEVEL_INFO, $message, $context);
  33. }
  34. public static function warning(string $message, array $context = []): void
  35. {
  36. self::log(self::LEVEL_WARNING, $message, $context);
  37. }
  38. public static function error(string $message, array $context = []): void
  39. {
  40. self::log(self::LEVEL_ERROR, $message, $context);
  41. }
  42. /**
  43. * Registra uma entrada de log no terminal e no arquivo.
  44. */
  45. public static function log(string $level, string $message, array $context = []): void
  46. {
  47. if (!self::isEnabled()) {
  48. return;
  49. }
  50. $line = self::format($level, $message, $context);
  51. self::writeToTerminal($line);
  52. self::writeToFile($line);
  53. }
  54. private static function format(string $level, string $message, array $context): string
  55. {
  56. $timestamp = date('Y-m-d H:i:s');
  57. $levelLabel = strtoupper($level);
  58. $suffix = '';
  59. if (!empty($context)) {
  60. $encoded = json_encode($context, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
  61. $suffix = ' ' . ($encoded !== false ? $encoded : '[context not serializable]');
  62. }
  63. return sprintf('[%s] %s: %s%s', $timestamp, $levelLabel, $message, $suffix);
  64. }
  65. private static function writeToTerminal(string $line): void
  66. {
  67. if (defined('STDERR')) {
  68. fwrite(STDERR, $line . PHP_EOL);
  69. return;
  70. }
  71. error_log($line);
  72. }
  73. private static function writeToFile(string $line): void
  74. {
  75. $file = $_ENV['LOG_FILE'] ?? (dirname(__DIR__) . '/log.txt');
  76. // Falha de escrita em log não deve derrubar a aplicação.
  77. @file_put_contents($file, $line . PHP_EOL, FILE_APPEND | LOCK_EX);
  78. }
  79. }