# 前言
學習一個框架, Ray 的想法是, 在深入理解底層實作的原理之前, 應該先知道這個框架的 使用方法
; 先學習怎麼使用這個前人造的輪子, 再學習怎麼樣造一個輪子。
所以本篇文章重點在於細讀官方文件, 並將內容理解後以 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
留言