【メモ】Laravel10 Logに関してドキュメントさっくりまとめ

## 概要
- さっくりとLogに関する情報をまとめる
- わからない部分は、ドキュメントコピペ

## 公式ドキュメント
https://laravel.com/docs/10.x/logging

多少省略もしているため、すべてを見たい場合は直接参照のこと、、
## Configuration

>All of the configuration options for your application's logging behavior are housed in the config/logging.php configuration file. This file allows you to configure your application's log channels, so be sure to review each of the available channels and their options. We'll review a few common options below.
By default, Laravel will use the stack channel when logging messages. The stack channel is used to aggregate multiple log channels into a single channel. For more information on building stacks, check out the documentation below.

>アプリケーションのロギング動作に関するすべての設定オプションは config/logging.php 設定ファイルに格納されます。このファイルでアプリケーションのログチャンネルを設定できるので、利用可能なチャンネルとそのオプションを確認してください。以下に、いくつかの一般的なオプションについて説明します。
デフォルトでは、Laravelはメッセージをログするときにスタックチャンネルを使用します。スタックチャンネルは、複数のログチャンネルを1つのチャンネルに集約するために使用されます。スタックの構築に関する詳細は、以下のドキュメントを参照してください。

- Logの設定を確認するには**config/logging.php**をすればよい
- このドキュメントでは、一般的なオプションについての説明がある
### チャンネル名はオプションで変更が可能
>By default, Monolog is instantiated with a "channel name" that matches the current environment, such as production or local. To change this value, add a name option to your channel's configuration:

>デフォルトでは、Monolog は現在の環境（production や local など）にマッチする「チャンネル名」でインスタンス化されます。この値を変更するには、チャンネルの設定に name オプションを追加します：

```php
'stack' => [
    'driver' => 'stack',
    'name' => 'channel-name',
    'channels' => ['single', 'slack'],
],
```
## Available Channel Drivers
>Each log channel is powered by a "driver". The driver determines how and where the log message is actually recorded. The following log channel drivers are available in every Laravel application. An entry for most of these drivers is already present in your application's config/logging.php configuration file, so be sure to review this file to become familiar with its contents:

>各ログチャンネルは「ドライバ」によって駆動される。ドライバは、ログメッセージが実際に記録される方法と場所を決定します。以下のログチャンネルドライバは、全てのLaravelアプリケーションで利用可能です。これらのドライバのほとんどは、アプリケーションのconfig/logging.php設定ファイルに既にエントリが存在しますので、このファイルの内容をよく確認してください：

- config/logging.phpに設定があるよ

| Name     | Description                                                     |
|----------|-----------------------------------------------------------------|
| custom   | 指定されたファクトリーを呼び出してチャンネルを作成するドライバ   |
| daily    | 毎日ローテーションする RotatingFileHandler ベースの Monolog ドライバ |
| errorlog | ErrorLogHandler ベースの Monolog ドライバ                       |
| monolog  | サポートされているMonologハンドラーを使用するMonologファクトリードライバー |
| papertrail | SyslogUdpHandler ベースの Monolog ドライバ                    |
| single   | 単一のファイルまたはパスベースのロガーチャンネル（StreamHandler） |
| slack    | SlackWebhookHandler ベースの Monolog ドライバ                  |
| stack    | マルチチャンネル」チャンネルを作成するためのラッパー             |
| syslog   | SyslogHandler ベースの Monolog ドライバ                         |


ここに、より詳細なドキュメントがあるよ

https://laravel.com/docs/10.x/logging#monolog-channel-customization

他にも、設定に関する話があるが詳細は割愛
- [slack](https://laravel.com/docs/10.x/logging#configuring-the-slack-channel)にログ出しをするやつ

## Logging Deprecation Warnings
- config/logging.php設定ファイルをいじることで、ライブラリなどの非推奨の警告を残すことができる。
>PHP, Laravel, and other libraries often notify their users that some of their features have been deprecated and will be removed in a future version. If you would like to log these deprecation warnings, you may specify your preferred deprecations log channel in your application's config/logging.php configuration file:

>PHP、Laravel、その他のライブラリは、機能の一部が非推奨となり、将来のバージョンで削除されることをユーザーに通知することがよくあります。これらの非推奨の警告をログに記録したい場合は、アプリケーションのconfig/logging.php設定ファイルで好みの非推奨ログチャンネルを指定することができます：

```php:方法１
// ログに非推奨の警告を出力する
'deprecations' => env('LOG_DEPRECATIONS_CHANNEL', 'null'),
 
'channels' => [
    ...
]
```
```php:方法２
// 非推奨用のログチャンネルを作成することで、常にそちらが利用される
// 2023-12-08 通常のログとの切り分けが可能かは未確認
'channels' => [
    'deprecations' => [
        'driver' => 'single',
        'path' => storage_path('logs/php-deprecation-warnings.log'),
    ],
],
```
## Building Log Stacks
>As mentioned previously, the stack driver allows you to combine multiple channels into a single log channel for convenience. To illustrate how to use log stacks, let's take a look at an example configuration that you might see in a production application:

>前述したように、スタックドライバは、利便性のために、複数のチャンネルを一つのログ チャンネルにまとめることを可能にする。ログスタックの使い方を説明するために、本番アプリケーションで見かけるかもしれない 設定例を見てみましょう：

```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',
    ],
],
```
- channelsオプションで2つのstackチャンネルをまとめている。
- syslogとslackの2つ
- ログレベルによって出力は制御される
### Log Levels
- RFC 5424仕様で定義されている全てのログレベルを提供する
- 具体的には、**emergency, alert, critical, error, warning, notice, info, debug.**
```php:例
Log::debug('An informational message.');
Log::emergency('The system is down!');
```
ほかの言語でもあるように、debugレベルでは、emergencyは記述されないがemergencyの場合は両方の閾値を超えているため、どちらにも（syslog, slack）反映される。

## Writing Log Messages
Log ファサードを使用してログに情報を書き込むことが可能である。

```php:例
use Illuminate\Support\Facades\Log;
 
Log::emergency($message);
Log::alert($message);
Log::critical($message);
Log::error($message);
Log::warning($message);
Log::notice($message);
Log::info($message);
Log::debug($message);
```
- これらのメソッドを呼び出すことで、対応するレベルのログメッセージを記述可能
- 規定では、ロギング構成ファイルで競って利されたログチャンネルに書き込まれる

```php:使用例
<?php
 
namespace App\Http\Controllers;
 
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Support\Facades\Log; // ログのインポート
use Illuminate\View\View;
 
class UserController extends Controller
{
    /**
     * Show the profile for the given user.
     */
    public function show(string $id): View
    {   // 利用
        Log::info('Showing the user profile for user: {id}', ['id' => $id]);
 
        return view('user.profile', [
            'user' => User::findOrFail($id)
        ]);
    }
}
```
## Contextual Information
- 配列のデータをログに渡すことも可能
- 成形されてログに表示される
```php
use Illuminate\Support\Facades\Log;
 
Log::info('User {id} failed to login.', ['id' => $user->id]);
```
>Occasionally, you may wish to specify some contextual information that should be included with all subsequent log entries in a particular channel. For example, you may wish to log a request ID that is associated with each incoming request to your application. To accomplish this, you may call the Log facade's withContext method:

>時折、特定のチャネルの後続のすべてのログエントリーに含まれるべき、いくつかの コンテキスト情報を指定したいと思うかもしれません。例えば、アプリケーションに送られてくるリクエストに関連付けられた リクエストIDをログに記録したい場合などです。これを実現するには、Log ファサードの withContext メソッドをコールします：

```php:IDの記録の例（withContextの利用例）
<?php
 
namespace App\Http\Middleware;
 
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\Response;
 
class AssignRequestId
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        $requestId = (string) Str::uuid();
 
        Log::withContext([
            'request-id' => $requestId
        ]);
 
        $response = $next($request);
 
        $response->headers->set('Request-Id', $requestId);
 
        return $response;
    }
}
```
>If you would like to share contextual information across all logging channels, you may call the Log::shareContext() method. This method will provide the contextual information to all created channels and any channels that are created subsequently. Typically, the shareContext method should be called from the boot method of an application service provider:

>すべてのロギング・チャンネルでコンテキスト情報を共有したい場合は、 Log::shareContext() メソッドを呼び出します。このメソッドは、作成されたすべてのチャンネルと、その後に作成されたすべてのチャンネルにコンテキスト情報を提供します。通常、shareContext メソッドは、アプリケーションサービスプロバイダのブートメソッドから呼び出す必要があります：

```php
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
 
class AppServiceProvider
{
    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        Log::shareContext([
            'invocation-id' => (string) Str::uuid(),
        ]);
    }
}
```

## Writing To Specific Channels
>Sometimes you may wish to log a message to a channel other than your application's default channel. You may use the channel method on the Log facade to retrieve and log to any channel defined in your configuration file:

>アプリケーションのデフォルト・チャネル以外のチャネルにメッセージを記録したい場合があります。Log ファサードの channel メソッドを使用すると、 設定ファイルで定義されている任意のチャネルを取得し、そこにログを記録することができます：

- channelメソッドを利用することで、チャンネルを指定することが可能である。
```php
use Illuminate\Support\Facades\Log;
 
Log::channel('slack')->info('Something happened!');
```
>If you would like to create an on-demand logging stack consisting of multiple channels, you may use the stack method:

>複数のチャンネルからなるオンデマンド・ロギング・スタックを作成したい場合は、スタック・メソッドを使用することができる：

- オンデマンド・ロギングなるものがある、、らしい
```php
Log::stack(['single', 'slack'])->info('Something happened!');
```
### On-Demand Channels
>It is also possible to create an on-demand channel by providing the configuration at runtime without that configuration being present in your application's logging configuration file. To accomplish this, you may pass a configuration array to the Log facade's build method:

>また、アプリケーションのロギング設定ファイルに設定が存在しなくても、 実行時に設定を提供することでオンデマンド・チャンネルを作成することも可能です。これを実現するには、Logファサードのビルドメソッドに設定配列を渡します：

```php
use Illuminate\Support\Facades\Log;
 
Log::build([
  'driver' => 'single',
  'path' => storage_path('logs/custom.log'),
])->info('Something happened!');
```
>You may also wish to include an on-demand channel in an on-demand logging stack. This can be achieved by including your on-demand channel instance in the array passed to the stack method:

>また、オンデマンドチャネルをオンデマンドロギングスタックに含めたい場合もあります。これは、スタックメソッドに渡される配列にオンデマンドチャネルのインスタンスを含めることで実現できます：

```php
use Illuminate\Support\Facades\Log;
 
$channel = Log::build([
  'driver' => 'single',
  'path' => storage_path('logs/custom.log'),
]);
 
Log::stack(['slack', $channel])->info('Something happened!');
```

## Monolog Channel Customization
### Customizing Monolog For Channels
```php
'single' => [
    'driver' => 'single',
    // このtap配列を作る必要がある
    'tap' => [App\Logging\CustomizeFormatter::class],
    'path' => storage_path('logs/laravel.log'),
    'level' => 'debug',
],
```
tapオプションを設定した後は、Monologインスタンスをカスタマイズするクラスを定義する。
ここでは、invokeで、IlluminateLogLoggerインスタンスを受け取ります。
そうすることで、基礎となるMonologインスタンスへの全てのメソッド呼び出しをプロキシできるようになります。
```php
<?php
 
namespace App\Logging;
 
use Illuminate\Log\Logger;
use Monolog\Formatter\LineFormatter;
 
class CustomizeFormatter
{
    /**
     * Customize the given logger instance.
     */
    public function __invoke(Logger $logger): void
    {
        foreach ($logger->getHandlers() as $handler) {
            $handler->setFormatter(new LineFormatter(
                '[%datetime%] %channel%.%level_name%: %message% %context% %extra%'
            ));
        }
    }
}
```
## Creating Monolog Handler Channels
>Monolog has a variety of available handlers and Laravel does not include a built-in channel for each one. In some cases, you may wish to create a custom channel that is merely an instance of a specific Monolog handler that does not have a corresponding Laravel log driver. These channels can be easily created using the monolog driver.
When using the monolog driver, the handler configuration option is used to specify which handler will be instantiated. Optionally, any constructor parameters the handler needs may be specified using the with configuration option:

>Monologには様々なハンドラがあり、Laravelにはそれぞれのハンドラに対応するビルトインチャンネルは含まれていません。場合によっては、対応するLaravelログドライバを持たない特定のMonologハンドラのインスタンスだけのカスタムチャンネルを作成したいこともあるでしょう。このようなチャンネルは、モノログドライバを使用して簡単に作成できます。
モノログドライバを使用する場合、どのハンドラをインスタンス化するかを指定するために、ハンドラ設定オプションを使用します。オプションで、ハンドラが必要とするコンストラクタのパラメータを with 設定オプションで指定することもできます：

```php
'logentries' => [
    'driver'  => 'monolog',
    'handler' => Monolog\Handler\SyslogUdpHandler::class,
    'with' => [
        'host' => 'my.logentries.internal.datahubhost.company.com',
        'port' => '10000',
    ],
],
```
### Monolog Formatters
```php
'browser' => [
    'driver' => 'monolog',
    'handler' => Monolog\Handler\BrowserConsoleHandler::class,
    // フォーマットの設定が可能
    'formatter' => Monolog\Formatter\HtmlFormatter::class,
    'formatter_with' => [
        'dateFormat' => 'Y-m-d',
    ],
],
```
```php
'newrelic' => [
    'driver' => 'monolog',
    // 独自のフォーマッタを提供できるMonologハンドラを利用している場合は、defaultで設定できる。
    'handler' => Monolog\Handler\NewRelicHandler::class,
    'formatter' => 'default',
],
```

### Monolog Processors
monologドライバの設定が可能である

以下詳細↓↓

https://github.com/Seldaek/monolog/tree/main/src/Monolog/Processor

```php
'memory' => [
    'driver' => 'monolog',
    'handler' => Monolog\Handler\StreamHandler::class,
    'with' => [
        'stream' => 'php://stderr',
    ],
    'processors' => [
        // Simple syntax...
        Monolog\Processor\MemoryUsageProcessor::class,
 
        // With options...
        [
           'processor' => Monolog\Processor\PsrLogMessageProcessor::class,
           'with' => ['removeUsedContextFields' => true],
       ],
    ],
],
```

## Creating Custom Channels Via Factories
>If you would like to define an entirely custom channel in which you have full control over Monolog's instantiation and configuration, you may specify a custom driver type in your config/logging.php configuration file. Your configuration should include a via option that contains the name of the factory class which will be invoked to create the Monolog instance:

>Monologのインスタンス生成と設定を完全に制御できる、完全にカスタムなチャネルを定義したい場合は、config/logging.php設定ファイルでカスタムなドライバタイプを指定することができます。設定には、Monolog のインスタンスを作成するために呼び出されるファクトリクラスの名前を含む via オプションを含める必要があります：

```php
'channels' => [
    'example-custom-channel' => [
        'driver' => 'custom',
        'via' => App\Logging\CreateCustomLogger::class,
    ],
],
```
>Once you have configured the custom driver channel, you're ready to define the class that will create your Monolog instance. This class only needs a single __invoke method which should return the Monolog logger instance. The method will receive the channels configuration array as its only argument:

>カスタムドライバーチャンネルを設定したら、Monolog インスタンスを作成するクラスを定義します。このクラスは、Monolog ロガーのインスタンスを返す __invoke メソッドだけが必要です。このメソッドは、唯一の引数としてチャンネル設定配列を受け取ります：

- 前のcustomドライバーを利用してCustomizeFormatterを作成するのと一緒

```php
<?php
 
namespace App\Logging;
 
use Monolog\Logger;
 
class CreateCustomLogger
{
    /**
     * Create a custom Monolog instance.
     */
    public function __invoke(array $config): Logger
    {
        return new Logger(/* ... */);
    }
}
```

## Tailing Log Messages Using Pail
- コマンドラインからリアルタイム監視をするためのコマンド

```sh
composer require laravel/pail
php artisan pail
# 切り捨てを避けるためのオプション
php artisan pail -v
# 例外やスタックトレースを表示させるオプション
php artisan pail -vv
# -filterオプションを使うと、ログのタイプ、ファイル、メッセージ、スタックトレースの内容でログをフィルターすることができる：
php artisan pail --filter="QueryException"
# メッセージのみでログをフィルターするには、-messageオプションを使う：
php artisan pail --message="User created"
# levelオプションを使用すると、ログをログレベルでフィルターすることができる：
php artisan pail --level=error
# 指定したユーザーが認証されている間に書き込まれたログだけを表示するには、--userオプションにそのユーザーのIDを指定する：
php artisan pail --user=1
```

## まとめ
最低限の知識レベルの人間がまとめたため、ドキュメント以上に深めることはできていないが、今後Logに関して扱うなかで、振り返りが容易なように簡単にまとめた。
使っていく中で、学んだことや分かったことがあれば追記していきたいと思う。