热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Laravel5.7log的custom驱动写入报错

我的目的是希望日志按照日期+小时+等级来分割比如2019-04-10/11/info.log,2019-04-10/11/error.log

我的目的是希望日志按照日期+小时+等级来分割
比如2019-04-10/11/info.log, 2019-04-10/11/error.log ...



报错

1
laravel.EMERGENCY: Unable to create configured logger. Using emergency logger. {"exception":"[object] (Illuminate\\Contracts\\Container\\BindingResolutionException(code: 0): Unresolvable dependency resolving [Parameter #0 [ $name ]] in class Monolog\\Logger at D:\\phpStudy\\PHPTutorial\\WWW\\wdt_crm\\wdt_platform\\branch\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\Container.php:960)

找不到错在哪里,求大神相助




1
logging.php

如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
'stack' => [

    'driver' => 'stack',

    'channels' => ['sliceLevels'],

],



....



'sliceLevels' => [

    'driver' => 'custom',

    'via' =>  App\Logging\Custom\LoggingByLevelLogger::class,

    'path' => storage_path('logs/level.log'),

    'level' => 'debug',

    'days' => 7,

],

新的

1
logger

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
namespace App\Logging\Custom;



use Monolog\Logger;

use App\Logging\Handler\LoggingByLevelHandler;



class LoggingByLevelLogger extends Logger

{

    // 当前记录日志的等级

    protected $level = 'info';



    public function __invoke(array $config)

    {

        // file_put_contents(storage_path('logs/test.txt'), print_r($config));



        $logger = new static('local');



        $logger->pushHandler(new LoggingByLevelHandler(

            $config['path'],

            $this->level,

            $config['days'],

            $config['level']

        ));



        return $logger;

    }



    /**

     * set record level

     *

     * @param int $level

     * @return void

     */

    public function setRecordLevel($level)

    {

        $this->level = strtolower(self::getLevelName($level));

    }



    /**

     * Adds a log record at the INFO level.

     *

     * This method allows for compatibility with common interfaces.

     *

     * @param  string $message The log message

     * @param  array  $context The log context

     * @return bool   Whether the record has been processed

     */

    public function info($message, array $cOntext= array())

    {

        $this->setRecordLevel(static::INFO);



        return $this->addRecord(static::INFO, $message, $context);

    }



   ...

}


1
LoggingByLevelHandler

类是对daily默认的handler进行了修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/*

 * This file is part of the Monolog package.

 *

 * (c) Jordi Boggiano

 *

 * For the full copyright and license information, please view the LICENSE

 * file that was distributed with this source code.

 */



namespace App\Logging\Handler;



use Monolog\Logger;

use Monolog\Handler\StreamHandler;



/**

 * Stores logs to files that are rotated every day and a limited number of files are kept.

 *

 * This rotation is only intended to be used as a workaround. Using logrotate to

 * handle the rotation is strongly encouraged when you can use it.

 *

 * @author Christophe Coevoet

 * @author Jordi Boggiano

 */

class LoggingByLevelHandler extends StreamHandler

{

    const FILE_PER_DAY = 'Y-m-d';

    const FILE_PER_MOnTH= 'Y-m';

    const FILE_PER_YEAR = 'Y';



    protected $filename;

    protected $maxFiles;

    protected $mustRotate;

    protected $nextRotation;

    protected $filenameFormat;

    protected $dateFormat;

    protected $recordLevel;



    /**

     * @param string   $filename

     * @param int      $maxFiles       The maximal amount of files to keep (0 means unlimited)

     * @param int      $level          The minimum logging level at which this handler will be triggered

     * @param bool     $bubble         Whether the messages that are handled can bubble up the stack or not

     * @param int|null $filePermission Optional file permissions (default (0644) are only for owner read/write)

     * @param bool     $useLocking     Try to lock log file before doing any writes

     */

    public function __construct($filename, $recordLevel, $maxFiles = 0, $level = Logger::DEBUG, $bubble = true, $filePermission = null, $useLocking = false)

    {

        $this->filename = $filename;

        $this->recordLevel = $recordLevel;

        $this->maxFiles = (int) $maxFiles;

        $this->nextRotation = new \DateTime('tomorrow');

        $this->filenameFormat = '{date}/{hour}/{filename}';

        $this->dateFormat = 'Y-m-d';



        parent::__construct($this->getTimedFilename(), $level, $bubble, $filePermission, $useLocking);

    }



    /**

     * {@inheritdoc}

     */

    public function close()

    {

        parent::close();



        if (true === $this->mustRotate) {

            $this->rotate();

        }

    }



    /**

     * {@inheritdoc}

     */

    public function reset()

    {

        parent::reset();



        if (true === $this->mustRotate) {

            $this->rotate();

        }

    }



    public function setFilenameFormat($filenameFormat, $dateFormat)

    {

        if (!preg_match('{^Y(([/_.-]?m)([/_.-]?d)?)?$}', $dateFormat)) {

            trigger_error(

                'Invalid date format - format must be one of '.

                'RotatingFileHandler::FILE_PER_DAY ("Y-m-d"), RotatingFileHandler::FILE_PER_MONTH ("Y-m") '.

                'or RotatingFileHandler::FILE_PER_YEAR ("Y"), or you can set one of the '.

                'date formats using slashes, underscores and/or dots instead of dashes.',

                E_USER_DEPRECATED

            );

        }

        if (substr_count($filenameFormat, '{date}') === 0) {

            trigger_error(

                'Invalid filename format - format should contain at least `{date}`, because otherwise rotating is impossible.',

                E_USER_DEPRECATED

            );

        }

        $this->filenameFormat = $filenameFormat;

        $this->dateFormat = $dateFormat;

        $this->url = $this->getTimedFilename();

        $this->close();

    }



    /**

     * {@inheritdoc}

     */

    protected function write(array $record)

    {

        // on the first record written, if the log is new, we should rotate (once per day)

        if (null === $this->mustRotate) {

            $this->mustRotate = !file_exists($this->url);

        }



        if ($this->nextRotation <$record['datetime']) {

            $this->mustRotate = true;

            $this->close();

        }



        parent::write($record);

    }



    /**

     * Rotates the files.

     */

    protected function rotate()

    {

        // update filename

        $this->url = $this->getTimedFilename();

        $this->nextRotation = new \DateTime('tomorrow');



        // skip GC of old logs if files are unlimited

        if (0 === $this->maxFiles) {

            return;

        }



        $logFiles = glob($this->getGlobPattern());

        if ($this->maxFiles >= count($logFiles)) {

            // no files to remove

            return;

        }



        // Sorting the files by name to remove the older ones

        usort($logFiles, function ($a, $b) {

            return strcmp($b, $a);

        });



        foreach (array_slice($logFiles, $this->maxFiles) as $file) {

            if (is_writable($file)) {

                // suppress errors here as unlink() might fail if two processes

                // are cleaning up/rotating at the same time

                set_error_handler(function ($errno, $errstr, $errfile, $errline) {});

                unlink($file);

                restore_error_handler();

            }

        }



        $this->mustRotate = false;

    }



    protected function getTimedFilename()

    {

        $fileInfo = pathinfo($this->filename);

        $timedFilename = str_replace(

            array('{filename}', '{date}', '{hour}'),

            array($this->recordLevel, date($this->dateFormat), date('H')),

            $fileInfo['dirname'] . '/' . $this->filenameFormat

        );



        if (!empty($fileInfo['extension'])) {

            $timedFilename .= '.'.$fileInfo['extension'];

        }



        return $timedFilename;

    }



    protected function getGlobPattern()

    {

        $fileInfo = pathinfo($this->filename);

        $glob = str_replace(

            array('{filename}', '{date}', '{hour}'),

            array($this->recordLevel, '[0-9][0-9][0-9][0-9]*', '(1|0)[0-9]|2[0-3]'),

            $fileInfo['dirname'] . '/' . $this->filenameFormat

        );



        if (!empty($fileInfo['extension'])) {

            $glob .= '.'.$fileInfo['extension'];

        }



        return $glob;

    }

}



   



推荐阅读
  • 版本控制工具——Git常用操作(下)
    本文由云+社区发表作者:工程师小熊摘要:上一集我们一起入门学习了git的基本概念和git常用的操作,包括提交和同步代码、使用分支、出现代码冲突的解决办法、紧急保存现场和恢复 ... [详细]
  • 深入解析Spring启动过程
    本文详细介绍了Spring框架的启动流程,帮助开发者理解其内部机制。通过具体示例和代码片段,解释了Bean定义、工厂类、读取器以及条件评估等关键概念,使读者能够更全面地掌握Spring的初始化过程。 ... [详细]
  • 最近同事提了一个需求过来,他觉得项目对于第三方日志记录的太多了,只想记录一些业务相关的日志减少对于框架日志的显示。具体要求就是对于框架日志只显示warn等级以上的,而业务日志显示info等级以上 ... [详细]
  • Git支持通过自定义钩子来扩展其功能,这些钩子根据触发条件的不同,可以分为客户端和服务器端两种类型。客户端钩子通常与本地操作相关联,如提交代码或合并分支;而服务器端钩子则与远程仓库的交互有关。 ... [详细]
  • 本文档介绍了在使用GitLab进行数据仓库项目开发时,如何管理和维护代码版本,包括非标准gitflow工作流下的分支结构及其权限设置,以及git commit message的规范。 ... [详细]
  • Hadoop发行版本选择指南:技术解析与应用实践
    本文详细介绍了Hadoop的不同发行版本及其特点,帮助读者根据实际需求选择最合适的Hadoop版本。内容涵盖Apache Hadoop、Cloudera CDH等主流版本的特性及应用场景。 ... [详细]
  • 深入理解 .NET 中的中间件
    中间件是插入到应用程序请求处理管道中的组件,用于处理传入的HTTP请求和响应。它在ASP.NET Core中扮演着至关重要的角色,能够灵活地扩展和自定义应用程序的行为。 ... [详细]
  • Spring Boot单元测试中Redis连接失败的解决方案
    本文探讨了在Spring Boot项目中进行单元测试时遇到Redis连接问题的原因及解决方法,详细分析了配置文件加载路径不当导致的问题,并提供了有效的解决方案。 ... [详细]
  • 本文详细介绍了如何在Kendo UI for jQuery的数据管理组件中,将行标题字段呈现为锚点(即可点击链接),帮助开发人员更高效地实现这一功能。通过具体的代码示例和解释,即使是新手也能轻松掌握。 ... [详细]
  • SpringMVC RestTemplate的几种请求调用(转)
    SpringMVCRestTemplate的几种请求调用(转),Go语言社区,Golang程序员人脉社 ... [详细]
  • 本文详细介绍了如何解压并安装MySQL集群压缩包,创建用户和组,初始化数据库,配置环境变量,并启动相关服务。此外,还提供了详细的命令行操作步骤和常见问题的解决方案。 ... [详细]
  • 本文探讨了在QT框架中如何有效遍历文件内容,并解决了一个常见的错误,即文件内容读取为空时弹窗无法正常显示的问题。 ... [详细]
  • Webpack中实现环境与代码的有效分离
    本文探讨了如何在Webpack中有效地区分开发与生产环境,并实现代码的合理分离,以提高项目的可维护性和加载性能。 ... [详细]
  • 本文详细介绍了 Java 中 freemarker.ext.dom.NodeModel 类的 removeComments 方法,并提供了多个实际使用的代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • 本文提供了关于如何在 Java 中使用 `com.amazonaws.services.kinesis.model.StreamDescription.getRetentionPeriodHours()` 方法的详细说明,并附带了多个实际代码示例。 ... [详细]
author-avatar
钞绚舞亨利
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有