Log.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006~2023 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. declare(strict_types=1);
  12. namespace think;
  13. use InvalidArgumentException;
  14. use Psr\Log\LoggerInterface;
  15. use Psr\Log\LoggerTrait;
  16. use Stringable;
  17. use think\event\LogWrite;
  18. use think\helper\Arr;
  19. use think\log\Channel;
  20. use think\log\ChannelSet;
  21. /**
  22. * 日志管理类
  23. * @package think
  24. * @mixin Channel
  25. */
  26. class Log extends Manager implements LoggerInterface
  27. {
  28. use LoggerTrait;
  29. const EMERGENCY = 'emergency';
  30. const ALERT = 'alert';
  31. const CRITICAL = 'critical';
  32. const ERROR = 'error';
  33. const WARNING = 'warning';
  34. const NOTICE = 'notice';
  35. const INFO = 'info';
  36. const DEBUG = 'debug';
  37. const SQL = 'sql';
  38. protected $namespace = '\\think\\log\\driver\\';
  39. /**
  40. * 默认驱动
  41. * @return string|null
  42. */
  43. public function getDefaultDriver(): ?string
  44. {
  45. return $this->getConfig('default');
  46. }
  47. /**
  48. * 获取日志配置
  49. * @access public
  50. * @param null|string $name 名称
  51. * @param mixed $default 默认值
  52. * @return mixed
  53. */
  54. public function getConfig(string $name = null, $default = null)
  55. {
  56. if (!is_null($name)) {
  57. return $this->app->config->get('log.' . $name, $default);
  58. }
  59. return $this->app->config->get('log');
  60. }
  61. /**
  62. * 获取渠道配置
  63. * @param string $channel
  64. * @param string $name
  65. * @param mixed $default
  66. * @return array
  67. */
  68. public function getChannelConfig(string $channel, string $name = null, $default = null)
  69. {
  70. if ($config = $this->getConfig("channels.{$channel}")) {
  71. return Arr::get($config, $name, $default);
  72. }
  73. throw new InvalidArgumentException("Channel [$channel] not found.");
  74. }
  75. /**
  76. * driver()的别名
  77. * @param string|array $name 渠道名
  78. * @return Channel|ChannelSet
  79. */
  80. public function channel(string|array $name = null)
  81. {
  82. if (is_array($name)) {
  83. return new ChannelSet($this, $name);
  84. }
  85. return $this->driver($name);
  86. }
  87. protected function resolveType(string $name)
  88. {
  89. return $this->getChannelConfig($name, 'type', 'file');
  90. }
  91. public function createDriver(string $name)
  92. {
  93. $driver = parent::createDriver($name);
  94. $lazy = !$this->getChannelConfig($name, "realtime_write", false) && !$this->app->runningInConsole();
  95. $allow = array_merge($this->getConfig("level", []), $this->getChannelConfig($name, "level", []));
  96. return new Channel($name, $driver, $allow, $lazy, $this->app->event);
  97. }
  98. protected function resolveConfig(string $name)
  99. {
  100. return $this->getChannelConfig($name);
  101. }
  102. /**
  103. * 清空日志信息
  104. * @access public
  105. * @param string|array $channel 日志通道名
  106. * @return $this
  107. */
  108. public function clear(string|array $channel = '*')
  109. {
  110. if ('*' == $channel) {
  111. $channel = array_keys($this->drivers);
  112. }
  113. $this->channel($channel)->clear();
  114. return $this;
  115. }
  116. /**
  117. * 关闭本次请求日志写入
  118. * @access public
  119. * @param string|array $channel 日志通道名
  120. * @return $this
  121. */
  122. public function close(string|array $channel = '*')
  123. {
  124. if ('*' == $channel) {
  125. $channel = array_keys($this->drivers);
  126. }
  127. $this->channel($channel)->close();
  128. return $this;
  129. }
  130. /**
  131. * 获取日志信息
  132. * @access public
  133. * @param string $channel 日志通道名
  134. * @return array
  135. */
  136. public function getLog(string $channel = null): array
  137. {
  138. return $this->channel($channel)->getLog();
  139. }
  140. /**
  141. * 保存日志信息
  142. * @access public
  143. * @return bool
  144. */
  145. public function save(): bool
  146. {
  147. /** @var Channel $channel */
  148. foreach ($this->drivers as $channel) {
  149. $channel->save();
  150. }
  151. return true;
  152. }
  153. /**
  154. * 记录日志信息
  155. * @access public
  156. * @param mixed $msg 日志信息
  157. * @param string $type 日志级别
  158. * @param array $context 替换内容
  159. * @param bool $lazy
  160. * @return $this
  161. */
  162. public function record($msg, string $type = 'info', array $context = [], bool $lazy = true)
  163. {
  164. $channel = $this->getConfig('type_channel.' . $type);
  165. $this->channel($channel)->record($msg, $type, $context, $lazy);
  166. return $this;
  167. }
  168. /**
  169. * 实时写入日志信息
  170. * @access public
  171. * @param mixed $msg 调试信息
  172. * @param string $type 日志级别
  173. * @param array $context 替换内容
  174. * @return $this
  175. */
  176. public function write($msg, string $type = 'info', array $context = [])
  177. {
  178. return $this->record($msg, $type, $context, false);
  179. }
  180. /**
  181. * 注册日志写入事件监听
  182. * @param $listener
  183. * @return Event
  184. */
  185. public function listen($listener)
  186. {
  187. return $this->app->event->listen(LogWrite::class, $listener);
  188. }
  189. /**
  190. * 记录日志信息
  191. * @access public
  192. * @param mixed $level 日志级别
  193. * @param string|Stringable $message 日志信息
  194. * @param array $context 替换内容
  195. * @return void
  196. */
  197. public function log($level, $message, array $context = []): void
  198. {
  199. $this->record($message, $level, $context);
  200. }
  201. /**
  202. * 记录sql信息
  203. * @access public
  204. * @param string|Stringable $message 日志信息
  205. * @param array $context 替换内容
  206. * @return void
  207. */
  208. public function sql($message, array $context = []): void
  209. {
  210. $this->log(__FUNCTION__, $message, $context);
  211. }
  212. public function __call($method, $parameters)
  213. {
  214. $this->log($method, ...$parameters);
  215. }
  216. }