# 版本
# 前言
我喜歡使用 Laravel 開發的感覺, 除了開發快速, 程式碼簡潔且優雅之外, Laravel 框架本身也是一個很好的學習參照物。 本篇主要將官方文件重點整理成 Q&A 的形式呈現, 原子化的概念, 這方式並不適用於每個人, 但若對你有幫助, 我會很開心。
# 目錄
# Configuration
# Configuring The Channel Name
Laravel 中, 預設的 channel name 是?
當前的 environment, 像是 production
或 local
以下的 Laravel example code 的意思是?
- Example:
<?php
'stack' => [
'driver' => 'stack',
'name' => 'foo',
'channels' => ['single', 'slack'],
],
- Answer: 定義 stack channel 的資訊 driver 為 stack name 為 foo, 會出現在 log 開頭, 如下圖, 預設為當前 environment 當 stack channel 被使用時, 定義於 channels 裡頭的 channel 都會被使用
# Available Channel Drivers
Laravel 中, 預設的 channel driver 是?
stack
# Configuring The Single and Daily Channels
Laravel logging 中, single 及 daily channel 有哪三個配置選項?
- bubble
- permission
- locking
Laravel logging 中, single 及 daily channel 的配置選項中, bubble 的意思是?
在這個 channel 處理完後, 是否流到別的 channel 去
Laravel logging 中, single 及 daily channel 的配置選項中, bubble 的預設值是?
true
Laravel logging 中, single 及 daily channel 的配置選項中, permission 的預設值是?
0644
Laravel logging 中, single 及 daily channel 的配置選項中, permission 的意思是?
log 的預設權限
Laravel logging 中, single 及 daily channel 的配置選項中, locking 的預設值是?
false
Laravel logging 中, single 及 daily channel 的配置選項中, locking 的用途是?
在寫 log 進去之前, 先把它鎖住
# Configuring The Papertrail Channel
Laravel logging 中, 是否有支援 PaperTrail 服務?
有
# Configuring The Slack Channel
Laravel logging 中, 是否有支援 Slack 服務?
有
# Building Log Stacks
Laravel logging 中, 如果我想要結合多個 channel, 我可以使用哪一個 channel driver?
stack
以下的 Laravel example code 的意思是?
- Example:
<?php
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['syslog', 'slack'],
],
'syslog' => [
'driver' => 'syslog',
'level' => 'debug',
],
'slack' => [
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'),
'username' => 'Laravel Log',
'emoji' => ':boom:',
'level' => 'critical',
],
],
- Answer:
<?php
'channels' => [
'stack' => [
// driver 為預設的 stack
'driver' => 'stack',
// 當 stack 被呼叫時, channels 裡頭的 channel 都會被使用
'channels' => ['syslog', 'slack'],
],
// syslog channel
'syslog' => [
// driver 為預設的 syslog
'driver' => 'syslog',
'level' => 'debug',
],
// slack channel
'slack' => [
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'),
'username' => 'Laravel Log',
'emoji' => ':boom:',
'level' => 'critical',
],
],
# Log Levels
Laravel logging 中, level
option 的用途是?
定義 channel level, 這樣當我們使用 Log::debug
或 Log::info
時, 所有 level 在 Log level 層級以下的 channel 都會被使用
以下的 Laravel logging example 中, 如果我的 log 等級是 critical, 共會 log 到哪些 channel?
- Example:
<?php
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['syslog', 'slack'],
],
'syslog' => [
'driver' => 'syslog',
'level' => 'debug',
],
'slack' => [
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'),
'username' => 'Laravel Log',
'emoji' => ':boom:',
'level' => 'critical',
],
],
- Answer: syslog, slack 因為 critical 這個 log level 是高於 syslog channel 的 level debug, 所有 level 低於或等於 log level 的 channel 都會被使用
# Writing Log Messages
# Writing To Specific Channels
以下的 Laravel example code 的意思是?
- Example:
<?php
Log::channel('slack')->info('Something happened!');
- Answer: log ‘something happened!’ 到 channel slack, 並指定等級為 info
# Advanced Monolog Channel Customization
解釋以下 Laravel example
- Example:
<?php
namespace App\Components;
use Monolog\Formatter\JsonFormatter as BaseJsonFormatter;
class JsonFormatter extends BaseJsonFormatter
{
public function format(array $record)
{
$newRecord = [
'time' => $record['datetime']->format('Y-m-d H:i:s'),
'result' => json_decode($record['message'], true),
];
if (!empty($record['context'])) {
$newRecord = array_merge($newRecord, $record['context']);
}
$json = $this->toJson($newRecord) . ($this->appendNewline ? "\n" : '');
return $json;
}
}
- Answer:
<?php
namespace App\Components;
// 繼承 Monolog 的 JsonFormatter 來達到我們的需求
use Monolog\Formatter\JsonFormatter as BaseJsonFormatter;
class JsonFormatter extends BaseJsonFormatter
{
public function format(array $record)
{
// 加入我們需要的資料
$newRecord = [
'time' => $record['datetime']->format('Y-m-d H:i:s'),
// message 就是我們原本的 log
// 注意:這邊的 log 已經被轉換成字串了,並不會是 array,因此建議直接以 JSON 傳遞資料
'result' => json_decode($record['message'], true),
];
// Contextual Information
if (!empty($record['context'])) {
$newRecord = array_merge($newRecord, $record['context']);
}
// 轉換成 JSON 並換行
$json = $this->toJson($newRecord) . ($this->appendNewline ? "\n" : '');
return $json;
}
}
Laravel logging 中, 我可以自定義 log 的 format 嗎?
可以哦
以下的 Laravel example code 的意思是?
- Example:
<?php
'single' => [
'driver' => 'single',
'tap' => [App\Logging\CustomizeFormatter::class],
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
],
- Answer: 使用 tap, 指定 CustomizeFormatter 為 formatter
Laravel logging 中, 如果我想要自定義一個 formatter, 可以放在哪一個資料夾內?
app/Logging
# Customizing Monolog For Channels
Laravel logging 中, 如果我想要建立自訂義的 channel, 我可以使用哪一個 driver?
monolog
以下的 Laravel example code 的意思是?
- Example:
<?php
'logentries' => [
'driver' => 'monolog',
'handler' => Monolog\Handler\SyslogUdpHandler::class,
'with' => [
'host' => 'my.logentries.internal.datahubhost.company.com',
'port' => '10000',
],
],
- Answer: 自定義 channel, 並使用 monolog 底下的 SyslogUdpHandler, 使用 with(), 將 ‘host’ 及 ‘port’ 作為 args 帶入 handler
以下的 Laravel example code 的意思是?
- Example:
<?php
'logentries' => [
'driver' => 'monolog',
'handler' => Monolog\Handler\SyslogUdpHandler::class,
'with' => [
'host' => 'example.com',
'port' => '8883',
],
],
- Answer: 使用 SyslogUdpHandler, 並帶入 parameter
['host' => 'example.com', 'port' => '8883']
# Creating Monolog Handler Channels
# Monolog Formatters
Laravel logging 中, 當我使用 Monolog 時, 預設的 formatter 是?
LineFormatter
以下的 Laravel example code 的意思是?
- Example:
<?php
'newrelic' => [
'driver' => 'monolog',
'handler' => Monolog\Handler\NewRelicHandler::class,
'formatter' => 'default',
],
- Answer: 使用 driver 為 monolog, 且使用的 handler 中已有自己的 formatter
# Creating Channels Via Factories
以下的 Laravel example code 的意思是?
- Example:
<?php
'channels' => [
'custom' => [
'driver' => 'custom',
'via' => App\Logging\CreateCustomLogger::class,
],
],
- Answer: 不使用預設的 Monolog, 要完全的客制 Monolog, 將 driver 設為 custom, 而 ‘via’ 則是客制 Monolog 的 class
以下的 Laravel example code 的意思是?
- Example:
<?php
namespace App\Logging;
use Monolog\Logger;
class CreateCustomLogger
{
public function __invoke(array $config)
{
return new Logger(...);
}
}
- Answer: 建立一個客製化的 logger