PsrLoggerAdapter.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace OC\Log;
  8. use OC\Log;
  9. use OCP\EventDispatcher\IEventDispatcher;
  10. use OCP\ILogger;
  11. use OCP\Log\IDataLogger;
  12. use Psr\Log\InvalidArgumentException;
  13. use Psr\Log\LoggerInterface;
  14. use Throwable;
  15. use function array_key_exists;
  16. use function array_merge;
  17. final class PsrLoggerAdapter implements LoggerInterface, IDataLogger {
  18. public function __construct(
  19. private Log $logger,
  20. ) {
  21. }
  22. public function setEventDispatcher(IEventDispatcher $eventDispatcher): void {
  23. $this->logger->setEventDispatcher($eventDispatcher);
  24. }
  25. private function containsThrowable(array $context): bool {
  26. return array_key_exists('exception', $context) && $context['exception'] instanceof Throwable;
  27. }
  28. /**
  29. * System is unusable.
  30. *
  31. * @param $message
  32. * @param mixed[] $context
  33. */
  34. public function emergency($message, array $context = []): void {
  35. if ($this->containsThrowable($context)) {
  36. $this->logger->logException($context['exception'], array_merge(
  37. [
  38. 'message' => (string)$message,
  39. 'level' => ILogger::FATAL,
  40. ],
  41. $context
  42. ));
  43. } else {
  44. $this->logger->emergency((string)$message, $context);
  45. }
  46. }
  47. /**
  48. * Action must be taken immediately.
  49. *
  50. * Example: Entire website down, database unavailable, etc. This should
  51. * trigger the SMS alerts and wake you up.
  52. *
  53. * @param $message
  54. * @param mixed[] $context
  55. */
  56. public function alert($message, array $context = []): void {
  57. if ($this->containsThrowable($context)) {
  58. $this->logger->logException($context['exception'], array_merge(
  59. [
  60. 'message' => (string)$message,
  61. 'level' => ILogger::ERROR,
  62. ],
  63. $context
  64. ));
  65. } else {
  66. $this->logger->alert((string)$message, $context);
  67. }
  68. }
  69. /**
  70. * Critical conditions.
  71. *
  72. * Example: Application component unavailable, unexpected exception.
  73. *
  74. * @param $message
  75. * @param mixed[] $context
  76. */
  77. public function critical($message, array $context = []): void {
  78. if ($this->containsThrowable($context)) {
  79. $this->logger->logException($context['exception'], array_merge(
  80. [
  81. 'message' => (string)$message,
  82. 'level' => ILogger::ERROR,
  83. ],
  84. $context
  85. ));
  86. } else {
  87. $this->logger->critical((string)$message, $context);
  88. }
  89. }
  90. /**
  91. * Runtime errors that do not require immediate action but should typically
  92. * be logged and monitored.
  93. *
  94. * @param $message
  95. * @param mixed[] $context
  96. */
  97. public function error($message, array $context = []): void {
  98. if ($this->containsThrowable($context)) {
  99. $this->logger->logException($context['exception'], array_merge(
  100. [
  101. 'message' => (string)$message,
  102. 'level' => ILogger::ERROR,
  103. ],
  104. $context
  105. ));
  106. } else {
  107. $this->logger->error((string)$message, $context);
  108. }
  109. }
  110. /**
  111. * Exceptional occurrences that are not errors.
  112. *
  113. * Example: Use of deprecated APIs, poor use of an API, undesirable things
  114. * that are not necessarily wrong.
  115. *
  116. * @param $message
  117. * @param mixed[] $context
  118. */
  119. public function warning($message, array $context = []): void {
  120. if ($this->containsThrowable($context)) {
  121. $this->logger->logException($context['exception'], array_merge(
  122. [
  123. 'message' => (string)$message,
  124. 'level' => ILogger::WARN,
  125. ],
  126. $context
  127. ));
  128. } else {
  129. $this->logger->warning((string)$message, $context);
  130. }
  131. }
  132. /**
  133. * Normal but significant events.
  134. *
  135. * @param $message
  136. * @param mixed[] $context
  137. */
  138. public function notice($message, array $context = []): void {
  139. if ($this->containsThrowable($context)) {
  140. $this->logger->logException($context['exception'], array_merge(
  141. [
  142. 'message' => (string)$message,
  143. 'level' => ILogger::INFO,
  144. ],
  145. $context
  146. ));
  147. } else {
  148. $this->logger->notice((string)$message, $context);
  149. }
  150. }
  151. /**
  152. * Interesting events.
  153. *
  154. * Example: User logs in, SQL logs.
  155. *
  156. * @param $message
  157. * @param mixed[] $context
  158. */
  159. public function info($message, array $context = []): void {
  160. if ($this->containsThrowable($context)) {
  161. $this->logger->logException($context['exception'], array_merge(
  162. [
  163. 'message' => (string)$message,
  164. 'level' => ILogger::INFO,
  165. ],
  166. $context
  167. ));
  168. } else {
  169. $this->logger->info((string)$message, $context);
  170. }
  171. }
  172. /**
  173. * Detailed debug information.
  174. *
  175. * @param $message
  176. * @param mixed[] $context
  177. */
  178. public function debug($message, array $context = []): void {
  179. if ($this->containsThrowable($context)) {
  180. $this->logger->logException($context['exception'], array_merge(
  181. [
  182. 'message' => (string)$message,
  183. 'level' => ILogger::DEBUG,
  184. ],
  185. $context
  186. ));
  187. } else {
  188. $this->logger->debug((string)$message, $context);
  189. }
  190. }
  191. /**
  192. * Logs with an arbitrary level.
  193. *
  194. * @param mixed $level
  195. * @param $message
  196. * @param mixed[] $context
  197. *
  198. * @throws InvalidArgumentException
  199. */
  200. public function log($level, $message, array $context = []): void {
  201. if (!is_int($level) || $level < ILogger::DEBUG || $level > ILogger::FATAL) {
  202. throw new InvalidArgumentException('Nextcloud allows only integer log levels');
  203. }
  204. if ($this->containsThrowable($context)) {
  205. $this->logger->logException($context['exception'], array_merge(
  206. [
  207. 'message' => (string)$message,
  208. 'level' => $level,
  209. ],
  210. $context
  211. ));
  212. } else {
  213. $this->logger->log($level, (string)$message, $context);
  214. }
  215. }
  216. public function logData(string $message, array $data, array $context = []): void {
  217. $this->logger->logData($message, $data, $context);
  218. }
  219. }