調整程式碼風格(Coding Style)
雖然程式碼風格跟設計沒有關係,但是程式碼風格不一致,對理解程式是一個很大的阻礙。調整程式碼風格,是不會影響功能的,因此很適合拿來當重構的暖身。
雖然程式碼風格跟設計沒有關係,但是程式碼風格不一致,對理解程式是一個很大的阻礙。調整程式碼風格,是不會影響功能的,因此很適合拿來當重構的暖身。
打開 Monolog 的資料夾,會發現除了昨天提到的 Logger 與 Handler 之外,還有幾個沒提到的角色,如 Formatter
或是 Processor
。
今天我們就來看看 Formatter
裡面做了什麼事。
首先當然先看看它如何使用!我們可以從先從 Handler\HandlerInterface
找到相關的實作:
interface HandlerInterface |
這裡可以注意到,它的設計是「抽象依賴抽象」,這符合依賴反轉原則;並且它的行為設計上,是做成抽象與抽象之間的一對一關係(因為它用 set
,而不是 push
),所以它實際上是實作了 Bridge Pattern。關係圖如下:
@startuml |
它們的實作之間並沒有直接耦合,而是透過抽象介面耦合;換句話說,只要物件有實作抽象介面的話,它就能正常的介接使用。
我們先來看昨天使用的 Handler\StreamHandler
裡面是使用了哪種 Formatter。追一下程式碼,會發現在 Handler\AbstractHandler
裡面:
abstract class AbstractHandler implements HandlerInterface |
因此預設會是 LineFormatter
,當然不是發 Log 到 Line,而是指單行的 log。
再來我們來寫一個測試程式如下:
$logger = new \Monolog\Logger('name'); |
這樣輸出的結果應該會如下:
[2018-01-15 18:10:12] name.WARNING: test [] [] |
剛有提到,我們應該能自由地抽換 Formatter 才對,我們來換成 JsonFormatter
試看看:
$handler->setFormatter(new \Monolog\Formatter\JsonFormatter()); |
輸出就會變成 JSON 了:
{"message":"test","context":[],"level":300,"level_name":"WARNING","channel":"name","datetime":{"date":"2018-01-15 18:16:28.438148","timezone_type":3,"timezone":"UTC"},"extra":[]} |
相信大家都去過黃色拱門,Formatter 與 Handler 之間的關係事實上就跟銅板輕鬆點很像,可以依需求任意搭配兩區的餐點,而店員都可以接受並結帳。
我們也可以使用 Slack 配 Json 或是 Mail 配 Html 等等,完全自由配。
在拿到程式碼的時候,我們並不是立刻把程式碼砍掉重練,而是先做一連串的準備工作:
在開始拆解前,首先我們先了解該如何使用它,官方提供的 Basic Usage 如下:
use Monolog\Logger; |
以下為方便說明,皆把 Monolog namespace 省略
通常好的函式庫,從範例就能快速了解函式庫的基本架構。這段程式碼可以發現主要的核心物件是 Logger
,而另外一個依附在 Logger 上的物件 Handler\StreamHandler
。Handler\StreamHandler
實作了 Handler\HandlerInterface
,這也是 pushHandler
方法所限制的物件型別。
而後面兩行新增 log 的方法,翻一下原始碼,會發現是由 Logger
轉接到 Handler\StreamHandler
和其他被加入的 Handler 上。
通常兩個物件如果是抽象層依賴的話,有可能會是 Bridge Pattern 或是 Observer Pattern;而 Bridge Pattern 又通常會是建構時期決定依賴的物件為何,因此 Logger
與 Handler\HandlerInterface
的關係基本上比較像是 Observer Pattern。關係圖如下:
@startuml |
Logger 有些行為也正好是 Observer Pattern 的特色:
使用 Observer Pattern 的好處很明確,實作儲存 log 的方法有千百種,加上寫 log 行為並不會太複雜(info
、error
等),自從 PHP 有 PSR-3 後,行為又更加明確了。這樣的情境下使用 Observer Pattern 更能看出套用 Pattern 的好處。
因為參加的是 Modern Web 主題,不管怎樣,還是跟 Web 掛勾一下好了。
身為一個開發者,有時會需要知道維運的過程中發生了什麼意外錯誤訊息。現在 Slack 很紅,只要開個 channel 設定一下,就會生出一個 webhook url。然後只要透過 HTTP 協定,就能把訊息往 channel 送。
但有些人是 Atlassian 派,覺得 HipChat 才是王道;又有人說,我想用線上服務 Rollbar 來記錄;甚至還有人習慣收 Email 呢。
這麼多種服務,每次都要看文件串接,真的有點麻煩。
串接還是小事,我們再往下看:
身為一個 PHP 開發者,開發或測試階段會想知道某段程式發生了什麼事,最常用的招數相信大家都知道--echo
放在程式裡面就能看得到內容啦!但有時不是單純某一段程式,而是需要記錄很多位置的內容;又或是記錄的內容不是要印出來,而是要存在其他地方。
基於種種因素,echo
雖然是個 debug 最簡單也最常用的工具,但在這多變的需求下,就顯得太簡陋了。
又或是上述有提到串接很多種提醒機制,而有種需求是同個訊息內容,要分派到不同的提醒。比方說 DB 連線失敗要同時通知 Slack 給開發團隊、寄簡訊給 DBA、發 mail 給老闆。這樣 DB 連線豈不要寫三行程式才能做這三件事?
這還不打緊,要是哪天寄簡訊的 SDK 改版了,程式的所有角落都得掃過一次,不然 DBA 收不到簡訊,服務就完蛋了!
Monolog 正是解決上述問題的好夥伴。
後面我們來一起看看 Monolog 是如何解決這些問題吧。
昨天把網頁載好,不過裡面的資料似乎很難處理。後來有找到另一個 API: