Я вернулся с более проблем с Laravel, так как у меня проблемы с пониманием.
Опять же, я пытаюсь создать пакет для собственного ведения журнала. Сделав некоторое дополнительное чтение и просматривая основной код и пробую другие подходы, я пришел к выводу, что все, что мне нужно сделать, это расширить основные функции ведения журнала laravel, чтобы он регистрировался на другом пути с помощью пользовательский форматтер.
Я создал свой пакет. Вот мой класс поставщика услуг:
use Illuminate\Log\LogServiceProvider; class VmlogServiceProvider extends LogServiceProvider { /** * Bootstrap the application events. * * @return void */ public function boot() { App::bind('log', function() { return new Vm\Vmlog\Vmlog; }); parent::boot(); } } ?>
Вот класс VmLog
<?php namespace Vm\Vmlog; use App; use Illuminate\Support\ServiceProvider; use Log; use Monolog\Formatter\LineFormatter; use Monolog\Handler\StreamHandler; use Monolog\Handler\RotatingFileHandler; class Vmlog extends \Illuminate\Log\Writer { protected $path; protected $formatter; protected $stream; protected $rotatingStream; public function __construct() { $output = APP_HOST."|%datetime%|%level%|%level_name%|".__METHOD__."|%message%|%context%".PHP_EOL; $this->path = VM_LOGPATH.APP_VLCODE."/".APP_VLCODE."_".APP_INSTANCE.".log"; $this->formatter = new LineFormatter($output, $dateFormat); parent::__construct(); } /** * Register a file log handler. * * @param string $path * @param string $level * @return void */ public function useFiles($path, $level = 'debug') { $level = $this->parseLevel($level); $this->stream = new StreamHandler($this->path, $level); $this->stream->setFormatter($this->formatter); $this->monolog->pushHandler($this->stream); } /** * Register a daily file log handler. * * @param string $path * @param int $days * @param string $level * @return void */ public function useDailyFiles($path, $days = 0, $level = 'debug') { $level = $this->parseLevel($level); $this->rotatingStream = new RotatingFileHandler($this->path, $days, $level); $this->rotatingStream->setFormatter($this->formatter); $this->monolog->pushHandler($this->rotatingStream); } } ?>
Я прокомментировал LogServiceProvider в app.php и добавил его в свой VmlogServiceProvider на своем месте.
Тем не менее, когда я пытаюсь запустить что-то, я получаю следующую ошибку.
Вызов неопределенного метода Illuminate \ Support \ Facades \ Log :: useDailyFiles ()
Я не понимаю, почему это происходит. Я удалил основной LogServiceProvider, я добавил свой собственный в его место и привязал его правильно, согласно документации (я думаю). Что я здесь делаю неправильно?
Почему вы используете метод загрузки в поставщике услуг?
Возможно, вы использовали метод register
вместо метода boot
этого поставщика услуг?
Похоже, ваша реализация этого приведет к переопределению регистратора по умолчанию, а не к созданию дополнительного журнала. Это ваше намерение? В этом случае обратите внимание на то, что вы использовали метод boot
для регистрации экземпляра «log», но затем метод register
выполняет повторную работу. (возможно, заменив его по умолчанию? Я не уверен, какое поведение приведет).
Если вы хотите добавить дополнительный журнал, вы можете сделать это без необходимости продления срока службы поставщика услуг Laravel.
В новом файле и вашем собственном пространстве имен создайте LogServiceProvider
:
<?php namespace Fideloper\Log; use Illuminate\Support\ServiceProvider; class LogServiceProvider extends ServiceProvider { /** * Indicates if loading of the provider is deferred. * * @var bool */ protected $defer = false; /** * Register the service provider. * * @return void */ public function register() { $logger = new Writer(new \Monolog\Logger('my-custom-log'), $this->app['events']); $logFile = 'my-custom-log.txt'; $logger->useDailyFiles(storage_path().'/logs/'.$logFile); $this->app->instance('fideloper.log', $logger); $this->app->bind('Fideloper\Log\Writer', function($app) { return $app->make('fideloper.log'); }); } /** * Get the services provided by the provider. * * @return array */ public function provides() { return array('fideloper.log'); } }
Затем создайте новую запись журнала (аналогично тому, как вы это сделали):
<?php namespace Fideloper\Log; use Illuminate\Log\Writer as BaseWriter; class Writer extends BaseWriter {}
Обратите внимание, что я не добавлял никаких дополнительных функций в мой расширенный класс писателя, но мог.
Консоль этой установки заключается в том, что я не создал или переписан фасад Log
для использования моего нового регистратора. Любой вызов Log::whatever()
прежнему будет использоваться по умолчанию для Laravel. Я создаю новый Fideloper\Log\Writer
и он работает из-за способности Laravel автоматически устанавливать зависимости классов.
$log = App::make('fideloper.log'); // Or get auto-created by laravel by making it a dependency // in a controller, for example: <?php use Fideloper\Log\Writer class SomeController extends BaseController { public function __construct(Writer $log) { $this->log = $log; //Later $this->log->error('SOME CUSTOM ERROR'); } }
Мне удалось все отсортировать, поэтому он предоставит ответ за полноту.
Мы в основном имитируем класс LogServiceProvider, но вместо вызова класса Laravel Writer мы вызываем собственный класс Vmlog, который просто расширяет класс записи. Таким образом, вся функциональность исходного ведения журнала сохраняется на месте, и мы просто переопределяем функции, которые нам нужны. Вам также необходимо прокомментировать регистрацию поставщика услуг Laravel Log и поместить свой собственный файл app.php.
Вот класс ServiceProvider.
<?php namespace vm\Vmlog; use Monolog\Logger; use Illuminate\Log\LogServiceProvider; use Illuminate\Support\ServiceProvider; class VmlogServiceProvider extends LogServiceProvider { /** * Bootstrap the application events. * * @return void */ public function boot() { $this->package('vm/vmlog'); } /** * Register the service provider. * * @return void */ public function register() { $logger = new Vmlog(new Logger('log'), $this->app['events']); $this->app->instance('log', $logger); if (isset($this->app['log.setup'])) { call_user_func($this->app['log.setup'], $logger); } } } ?>
Вот класс Vmlog, который расширяет класс Writer.
<?php namespace vm\Vmlog; use Illuminate\Support\ServiceProvider; use Monolog\Formatter\LineFormatter; use Monolog\Handler\StreamHandler; use Monolog\Handler\RotatingFileHandler; use Illuminate\Events\Dispatcher; use Monolog\Logger as MonologLogger; class Vmlog extends \Illuminate\Log\Writer { protected $path; protected $dateFormat; protected $output; public function __construct(MonologLogger $monolog, Dispatcher $dispatcher = null) { // Do stuff $this->dateFormat = 'Ymd\TH:i:s'; $this->output = "|%datetime%|%level%|%level_name%|%message%|%context%".PHP_EOL; parent::__construct($monolog, $dispatcher); } /** * Register a file log handler. * * @param string $path * @param string $level * @return void */ public function useFiles($path, $level = 'debug') { $level = $this->parseLevel($level); $this->path = VM_LOGPATH.APP_VLCODE."/".APP_VLCODE."_".APP_INSTANCE.".log"; $formatter = new LineFormatter(APP_HOST.$this->output, $this->dateFormat); $stream = new StreamHandler($this->path, $level); $stream->setFormatter($formatter); $this->monolog->pushHandler($stream); } /** * Register a daily file log handler. * * @param string $path * @param int $days * @param string $level * @return void */ public function useDailyFiles($path, $days = 0, $level = 'debug') { $level = $this->parseLevel($level); $this->path = VM_LOGPATH.APP_VLCODE."/".APP_VLCODE."_".APP_INSTANCE.".log"; $formatter = new LineFormatter(APP_HOST.$this->output, $this->dateFormat); $stream = new RotatingFileHandler($this->path, $days, $level); $stream->setFormatter($formatter); $this->monolog->pushHandler($stream); } } ?>
Мне все равно нужно сделать так, чтобы путь к журналу был настроен в файлах конфигурации для пакета, но это будет сделано сейчас и для этого ответа.