ๆฆ‚่ฆ

PHP ใƒญใ‚ฐใ‚’ Datadog ใซ้€ไฟกใ™ใ‚‹ๅ ดๅˆใฏใ€ใƒ•ใ‚กใ‚คใƒซใซใƒญใ‚ฐใ‚’่จ˜้Œฒใ—ใ€Datadog Agent ใ‚’ไฝฟ็”จใ—ใฆใใฎใƒ•ใ‚กใ‚คใƒซใ‚’ใƒ†ใƒผใƒซใ—ใพใ™ใ€‚ใ“ใฎใƒšใƒผใ‚ธใงใฏใ€Monologใ€Zend-Log ใŠใ‚ˆใณ Symfony ใƒญใ‚ฐใƒฉใ‚คใƒ–ใƒฉใƒชใ‚’ใ‚ปใƒƒใƒˆใ‚ขใƒƒใƒ—ใ™ใ‚‹ไพ‹ใ‚’่ฉณใ—ใ่ชฌๆ˜Žใ—ใพใ™ใ€‚

ใ‚ปใƒƒใƒˆใ‚ขใƒƒใƒ—

ใ‚คใƒณใ‚นใƒˆใƒผใƒซ

ใ“ใฎใ‚ณใƒžใƒณใƒ‰ใ‚’ๅฎŸ่กŒใ™ใ‚‹ใจใ€Composer ใ‚’ไฝฟ็”จใ—ใฆ Monolog ใ‚’ไพๅญ˜้–ขไฟ‚ใจใ—ใฆ่ฟฝๅŠ ใ™ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚

composer require "monolog/monolog"

ใพใŸใฏใ€ไปฅไธ‹ใฎๆ–นๆณ•ใง Monolog ใ‚’ๆ‰‹ๅ‹•ใงใ‚คใƒณใ‚นใƒˆใƒผใƒซใ—ใพใ™ใ€‚

  1. ใƒชใƒใ‚ธใƒˆใƒชใ‹ใ‚‰ Monolog ใ‚’ใƒ€ใ‚ฆใƒณใƒญใƒผใƒ‰ใ—ใ€ใƒฉใ‚คใƒ–ใƒฉใƒชใซ่ฟฝๅŠ ใ—ใพใ™ใ€‚

  2. ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใฎใƒ–ใƒผใƒˆใ‚นใƒˆใƒฉใƒƒใƒ—ๅ†…ใซไปฅไธ‹ใ‚’่ฟฝๅŠ ใ—ใ€ใ‚คใƒณใ‚นใ‚ฟใƒณใ‚นใ‚’ๅˆๆœŸๅŒ–ใ—ใพใ™ใ€‚

    <?php
      require __DIR__ . '/vendor/autoload.php';
    
      // load Monolog library
      use Monolog\Logger;
      use Monolog\Handler\StreamHandler;
      use Monolog\Formatter\JsonFormatter;
    

Zend-Log ใฏใ€Zend ใƒ•ใƒฌใƒผใƒ ใƒฏใƒผใ‚ฏใฎไธ€้ƒจใงใ™ใ€‚ใ“ใฎใ‚ณใƒžใƒณใƒ‰ใ‚’ๅฎŸ่กŒใ™ใ‚‹ใจใ€Composer ใ‚’ไฝฟใฃใฆ Zend-Log ใ‚’่ฟฝๅŠ ใ™ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚

composer require "zendframework/zend-log"

ใพใŸใฏใ€ไปฅไธ‹ใฎๆ–นๆณ•ใง Zend-Log ใ‚’ๆ‰‹ๅ‹•ใงใ‚คใƒณใ‚นใƒˆใƒผใƒซใ—ใพใ™ใ€‚

  1. ใƒชใƒใ‚ธใƒˆใƒชใ‹ใ‚‰ใ‚ฝใƒผใ‚นใ‚’ใƒ€ใ‚ฆใƒณใƒญใƒผใƒ‰ใ—ใ€ใƒฉใ‚คใƒ–ใƒฉใƒชใซ่ฟฝๅŠ ใ—ใพใ™ใ€‚
  2. ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใฎใƒ–ใƒผใƒˆใ‚นใƒˆใƒฉใƒƒใƒ—ๅ†…ใซไปฅไธ‹ใ‚’่ฟฝๅŠ ใ—ใ€ใ‚คใƒณใ‚นใ‚ฟใƒณใ‚นใ‚’ๅˆๆœŸๅŒ–ใ—ใพใ™ใ€‚
<?php
  require __DIR__ . '/vendor/autoload.php';

  use Zend\Log\Logger;
  use Zend\Log\Writer\Stream;
  use Zend\Log\Formatter\JsonFormatter;

ไปฅไธ‹ใ‚’่ฟฝๅŠ ใ—ใฆใ€Monolog JSON Formatter ใ‚’ใ‚ตใƒผใƒ“ใ‚นใจใ—ใฆๅฎฃ่จ€ใ—ใพใ™ใ€‚

services:
    monolog.json_formatter:
        class: Monolog\Formatter\JsonFormatter

ใƒญใ‚ฌใƒผใฎๆง‹ๆˆ

ไปฅไธ‹ใฎๆง‹ๆˆใงใฏใ€JSON ใƒ•ใ‚ฉใƒผใƒžใƒƒใƒˆใ‚’ๆœ‰ๅŠนใซใ—ใ€ใƒญใ‚ฐใจใ‚คใƒ™ใƒณใƒˆใ‚’ application-json.log ใƒ•ใ‚กใ‚คใƒซใซๆ›ธใ่พผใ‚“ใงใ„ใพใ™ใ€‚ใ‚ณใƒผใƒ‰ใงใ€Monolog ใ‚คใƒณใ‚นใ‚ฟใƒณใ‚นใฎๅˆๆœŸๅŒ–ๅพŒใซๆ–ฐใ—ใ„ใƒใƒณใƒ‰ใƒฉใƒผใ‚’่ฟฝๅŠ ใ—ใพใ™ใ€‚

 <?php
  require __DIR__ . '/vendor/autoload.php';

  // Monolog ใƒฉใ‚คใƒ–ใƒฉใƒชใ‚’ใƒญใƒผใƒ‰
  use Monolog\Logger;
  use Monolog\Handler\StreamHandler;
  use Monolog\Formatter\JsonFormatter;

  // ใƒญใ‚ฐใƒใƒฃใƒใƒซใ‚’ไฝœๆˆ
  $log = new Logger('channel_name');

  // Json ใƒ•ใ‚ฉใƒผใƒžใƒƒใ‚ฟใ‚’ไฝœๆˆ
  $formatter = new JsonFormatter();

  // ใƒใƒณใƒ‰ใƒฉใƒผใ‚’ไฝœๆˆ
  $stream = new StreamHandler(__DIR__.'/application-json.log', Logger::DEBUG);
  $stream->setFormatter($formatter);

  // ใƒใ‚คใƒณใƒ‰
  $log->pushHandler($stream);

  // ไพ‹
  $log->info('Adding a new user', array('username' => 'Seldaek'));```
 
 

 

ไปฅไธ‹ใฎๆง‹ๆˆใงใฏใ€JSON ใƒ•ใ‚ฉใƒผใƒžใƒƒใƒˆใ‚’ๆœ‰ๅŠนใซใ—ใ€ใƒญใ‚ฐใจใ‚คใƒ™ใƒณใƒˆใ‚’ application-json.log ใƒ•ใ‚กใ‚คใƒซใซๆ›ธใ่พผใ‚“ใงใ„ใพใ™ใ€‚ใ‚ณใƒผใƒ‰ใงใ€Zend-Log ใ‚คใƒณใ‚นใ‚ฟใƒณใ‚นใฎๅˆๆœŸๅŒ–ๅพŒใซๆ–ฐใ—ใ„ใƒใƒณใƒ‰ใƒฉใƒผใ‚’่ฟฝๅŠ ใ—ใพใ™ใ€‚

<?php
  use Zend\Log\Logger;
  use Zend\Log\Writer\Stream;
  use Zend\Log\Formatter\JsonFormatter;

  // ใƒญใ‚ฌใƒผใ‚’ไฝœๆˆ
  $logger = new Logger();

  // ใƒฉใ‚คใ‚ฟใƒผใ‚’ไฝœๆˆ
  $writer = new Stream('file://' . __DIR__ . '/application-json.log');

  // Json ใƒ•ใ‚ฉใƒผใƒžใƒƒใ‚ฟใ‚’ไฝœๆˆ
  $formatter = new JsonFormatter();
  $writer->setFormatter($formatter);

  // ใƒใ‚คใƒณใƒ‰
  $logger->addWriter($writer); Zend\Log\Logger::registerErrorHandler($logger);```

Monolog ๆง‹ๆˆใงใƒ•ใ‚ฉใƒผใƒžใƒƒใ‚ฟใ‚’ๆง‹ๆˆใ™ใ‚‹ใซใฏใ€ไปฅไธ‹ใฎใƒ•ใ‚ฉใƒผใƒžใƒƒใ‚ฟใƒ•ใ‚ฃใƒผใƒซใƒ‰ใ‚’ๅฎฃ่จ€ใ—ใพใ™ใ€‚

 monolog:
    handlers:
        main:
            type:   stream
            path:   "%kernel.logs_dir%/%kernel.environment%.log"
            level:  debug
            formatter: monolog.json_formatter

Datadog Agent ใฎๆง‹ๆˆ

ใƒญใ‚ฐๅŽ้›†ใŒๆœ‰ๅŠนใซใชใฃใŸใ‚‰ใ€ไปฅไธ‹ใ‚’่กŒใฃใฆใƒญใ‚ฐใƒ•ใ‚กใ‚คใƒซใ‚’่ฟฝ่ทกใ—ใฆๆ–ฐใ—ใ„ใƒญใ‚ฐใ‚’ Datadog ใซ้€ไฟกใ™ใ‚‹ใ‚ซใ‚นใ‚ฟใƒ ใƒญใ‚ฐๅŽ้›†ใ‚’่จญๅฎšใ—ใพใ™ใ€‚

  1. php.d/ ใƒ•ใ‚ฉใƒซใƒ€ใƒผใ‚’ conf.d/ Agent ๆง‹ๆˆใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒชใซไฝœๆˆใ—ใพใ™ใ€‚
  2. php.d/ ใซไปฅไธ‹ใฎๅ†…ๅฎนใง conf.yaml ใƒ•ใ‚กใ‚คใƒซใ‚’ไฝœๆˆใ—ใพใ™ใ€‚
init_config:

instances:

## Log ใ‚ปใ‚ฏใ‚ทใƒงใƒณ
logs:

  - type: file
    path: "<path_to_your_php_application_json>.log"
    service: "<service_name>"
    source: php
    sourcecategory: sourcecode

ใƒญใ‚ฐใจใƒˆใƒฌใƒผใ‚นใซใŠใ‘ใ‚‹ใ‚ตใƒผใƒ“ใ‚นใ‚’ๆŽฅ็ถš

ใ“ใฎใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใง APM ใŒๆœ‰ๅŠนใซใชใฃใฆใ„ใ‚‹ๅ ดๅˆใ€APM PHP ใƒญใ‚ฎใƒณใ‚ฐใฎๆŒ‡็คบใซๅพ“ใฃใฆใƒญใ‚ฐใซใƒˆใƒฌใƒผใ‚น ID ใจใ‚นใƒ‘ใƒณ ID ใ‚’่‡ชๅ‹•็š„ใซ่ฟฝๅŠ ใ™ใ‚‹ใ“ใจใงใ€ใ‚ขใƒ—ใƒชใ‚ฑใƒผใ‚ทใƒงใƒณใƒญใ‚ฐใจใƒˆใƒฌใƒผใ‚น้–“ใฎ็›ธ้–ข้–ขไฟ‚ใ‚’ๆ”นๅ–„ใงใใพใ™ใ€‚

ใƒญใ‚ฐใซใ‚ณใƒณใƒ†ใ‚ญใ‚นใƒˆใ‚’่ฟฝๅŠ ใ™ใ‚‹

ใƒญใ‚ฐใ‚„ใ‚คใƒ™ใƒณใƒˆใซ่ฟฝๅŠ ใฎใ‚ณใƒณใƒ†ใ‚ญใ‚นใƒˆใ‚’่ฟฝๅŠ ใ™ใ‚‹ใจไพฟๅˆฉใชใ“ใจใŒใ‚ใ‚Šใพใ™ใ€‚Monolog ใฏใ€ใ‚นใƒฌใƒƒใƒ‰ใƒญใƒผใ‚ซใƒซใ‚ณใƒณใƒ†ใ‚ญใ‚นใƒˆใ‚’่จญๅฎšใ™ใ‚‹ใƒกใ‚ฝใƒƒใƒ‰ใ‚’ๆไพ›ใ—ใ€ใ™ในใฆใฎใ‚คใƒ™ใƒณใƒˆใจๅ…ฑใซ่‡ชๅ‹•็š„ใซ้€ไฟกใ•ใ‚Œใพใ™ใ€‚ไพ‹ใˆใฐใ€ใ‚ณใƒณใƒ†ใ‚ญใ‚นใƒˆใƒ‡ใƒผใ‚ฟใ‚’ๅซใ‚€ใ‚คใƒ™ใƒณใƒˆใ‚’ใƒญใ‚ฐใซ่จ˜้Œฒใ™ใ‚‹ใซใฏ

<?php
  $logger->info('Adding a new user', array('username' => 'Seldaek'));

Monolog ใฎใƒ—ใƒชใƒ—ใƒญใ‚ปใƒƒใ‚ตใƒผใซใฏใ€ๅ˜็ด”ใชใ‚ณใƒผใƒซใƒใƒƒใ‚ฏใงใ€่จญๅฎšใงใใ‚‹ใƒกใ‚ฟใƒ‡ใƒผใ‚ฟ (ไพ‹ใˆใฐใ€ใ‚ปใƒƒใ‚ทใƒงใƒณ ID ใ‚„ใƒชใ‚ฏใ‚จใ‚นใƒˆ ID ใชใฉ) ใงใ‚คใƒ™ใƒณใƒˆใ‚’ใƒชใƒƒใƒๅŒ–ใ™ใ‚‹ๆฉŸ่ƒฝใŒใ‚ใ‚Šใพใ™ใ€‚

 <?php
  $log->pushProcessor(function ($record) {

      // ็พๅœจใฎใƒฆใƒผใ‚ถใƒผใ‚’่จ˜้Œฒ
      $user = Acme::getCurrentUser();
      $record['context']['user'] = array(
          'name' => $user->getName(),
          'username' => $user->getUsername(),
          'email' => $user->getEmail(),
      );

      // ใ•ใพใ–ใพใชใ‚ฟใ‚ฐใ‚’่ฟฝๅŠ 
      $record['ddtags'] = array('key' => 'value');

      // ใ•ใพใ–ใพใชๆฑŽ็”จใ‚ณใƒณใƒ†ใ‚ญใ‚นใƒˆใ‚’่ฟฝๅŠ 
      $record['extra']['key'] = 'value';

      return $record; });```

ใƒญใ‚ฐใ‚„ใ‚คใƒ™ใƒณใƒˆใซ่ฟฝๅŠ ใฎใ‚ณใƒณใƒ†ใ‚ญใ‚นใƒˆใ‚’่ฟฝๅŠ ใ™ใ‚‹ใจไพฟๅˆฉใชใ“ใจใŒใ‚ใ‚Šใพใ™ใ€‚Zend-Log ใฏใ€ใ‚นใƒฌใƒƒใƒ‰ใƒญใƒผใ‚ซใƒซใ‚ณใƒณใƒ†ใ‚ญใ‚นใƒˆใ‚’่จญๅฎšใ™ใ‚‹ใƒกใ‚ฝใƒƒใƒ‰ใ‚’ๆไพ›ใ—ใ€ใ™ในใฆใฎใ‚คใƒ™ใƒณใƒˆใจๅ…ฑใซ่‡ชๅ‹•็š„ใซ้€ไฟกใ•ใ‚Œใพใ™ใ€‚ไพ‹ใˆใฐใ€ใ‚ณใƒณใƒ†ใ‚ญใ‚นใƒˆใƒ‡ใƒผใ‚ฟใ‚’ๅซใ‚€ใ‚คใƒ™ใƒณใƒˆใ‚’ใƒญใ‚ฐใซ่จ˜้Œฒใ™ใ‚‹ใซใฏ

<?php
  $logger->info('Adding a new user', array('username' => 'Seldaek'));

ใƒญใ‚ฐใซ่ฟฝๅŠ ๆƒ…ๅ ฑใ‚’ไธŽใˆใ‚‹ๆ–นๆณ•ใซใคใ„ใฆใฏใ€ Zend ใฎใƒ—ใƒญใ‚ปใƒƒใ‚ตใƒผใฎใƒ‰ใ‚ญใƒฅใƒกใƒณใƒˆใ‚’ๅ‚็…งใ—ใฆใใ ใ•ใ„ใ€‚

ใ‚ปใƒƒใ‚ทใƒงใƒณใƒ—ใƒญใ‚ปใƒƒใ‚ตใƒผใ‚’ไฝฟ็”จใ—ใฆใƒญใ‚ฐใซๅค‰ๆ•ฐใ‚ณใƒณใƒ†ใ‚ญใ‚นใƒˆใ‚’่ฟฝๅŠ ใ™ใ‚‹ใซใฏใ€ไปฅไธ‹ใฎๆ‰‹้ †ใซๅพ“ใ„ใพใ™ใ€‚

  1. ใ‚ปใƒƒใ‚ทใƒงใƒณใƒ—ใƒญใ‚ปใƒƒใ‚ตใƒผใ‚’ๅฎŸ่ฃ…ใ—ใพใ™ใ€‚ ๆฌกใฎไพ‹ใงใฏใ€ใƒ—ใƒญใ‚ปใƒƒใ‚ตใƒผใฏ็พๅœจใฎใ‚ปใƒƒใ‚ทใƒงใƒณใ‚’็ŸฅใฃใฆใŠใ‚Šใ€requestIdใ€sessionId ใชใฉใฎๆƒ…ๅ ฑใงใƒญใ‚ฐใƒฌใ‚ณใƒผใƒ‰ใฎๅ†…ๅฎนใ‚’ใƒชใƒƒใƒๅŒ–ใ—ใฆใ„ใพใ™ใ€‚

    <?php
      namespace Acme\Bundle\MonologBundle\Log;
    
      use Symfony\Component\HttpFoundation\Session\Session;
    
      class SessionRequestProcessor {
        private $session;
        private $sessionId;
        private $requestId;
        private $_server;
        private $_get;
        private $_post;
    
        public function __construct(Session $session) {
          $this->session = $session;
        }
    
        public function processRecord(array $record) {
          if (null === $this->requestId) {
            if ('cli' === php_sapi_name()) {
              $this->sessionId = getmypid();
            } else {
              try {
                $this->session->start();
                $this->sessionId = $this->session->getId();
              } catch (\RuntimeException $e) {
                $this->sessionId = '????????';
              }
            }
            $this->requestId = substr(uniqid(), -8);
            $this->_server = array(
              'http.url' => (@$_SERVER['HTTP_HOST']).'/'.(@$_SERVER['REQUEST_URI']),
              'http.method' => @$_SERVER['REQUEST_METHOD'],
              'http.useragent' => @$_SERVER['HTTP_USER_AGENT'],
              'http.referer' => @$_SERVER['HTTP_REFERER'],
              'http.x_forwarded_for' => @$_SERVER['HTTP_X_FORWARDED_FOR']
            );
            $this->_post = $this->clean($_POST);
            $this->_get = $this->clean($_GET);
          }
          $record['http.request_id'] = $this->requestId;
          $record['http.session_id'] = $this->sessionId;
          $record['http.url'] = $this->_server['http.url'];
          $record['http.method'] = $this->_server['http.method'];
          $record['http.useragent'] = $this->_server['http.useragent'];
          $record['http.referer'] = $this->_server['http.referer'];
          $record['http.x_forwarded_for'] = $this->_server['http.x_forwarded_for'];
    
          return $record;
        }
    
        protected function clean($array) {
          $toReturn = array();
          foreach(array_keys($array) as $key) {
            if (false !== strpos($key, 'password')) {
              // Do not add
            } else if (false !== strpos($key, 'csrf_token')) {
              // Do not add
            } else {
              $toReturn[$key] = $array[$key];
            }
          }
    
          return $toReturn;
        }
      }
    
  2. ไปฅไธ‹ใ‚’่ฟฝๅŠ ใ—ใฆใ€ใƒ—ใƒญใ‚ปใƒƒใ‚ตใƒผใ‚’ Symfony ใจใ‚คใƒณใƒ†ใ‚ฐใƒฌใƒผใ‚ทใƒงใƒณใ—ใพใ™ใ€‚

      services:
          monolog.processor.session_request:
              class: Acme\Bundle\MonologBundle\Log\SessionRequestProcessor
              arguments:  [ @session ]
              tags:
                  - { name: monolog.processor, method: processRecord }
    
  3. ็”Ÿๆˆใ•ใ‚ŒใŸ JSON ใƒ•ใ‚กใ‚คใƒซใ‚’ Datadog ใซใ‚นใƒˆใƒชใƒผใƒŸใƒณใ‚ฐใ—ใพใ™ใ€‚

Monolog ใƒ•ใƒฌใƒผใƒ ใƒฏใƒผใ‚ฏใฎใ‚คใƒณใƒ†ใ‚ฐใƒฌใƒผใ‚ทใƒงใƒณ

Monolog ใฏใ€ไปฅไธ‹ใฎใƒ•ใƒฌใƒผใƒ ใƒฏใƒผใ‚ฏใงไฝฟ็”จใ™ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚

Monolog ใ‚’ใƒ•ใƒฌใƒผใƒ ใƒฏใƒผใ‚ฏใจใ‚คใƒณใƒ†ใ‚ฐใƒฌใƒผใ‚ทใƒงใƒณใ™ใ‚‹ใŸใ‚ใซใ€ไปฅไธ‹ใ‚’่ฟฝๅŠ ใ—ใพใ™ใ€‚

 <?php
  // Monolog ใƒฉใ‚คใƒ–ใƒฉใƒชใฎใƒญใƒผใƒ‰ใŒๆญฃๅธธใ‹็ขบ่ช
  //use Monolog\Logger;
  //use Monolog\Handler\StreamHandler;
  //use Monolog\Formatter\JsonFormatter;

  // monolog ใ‚คใƒณใ‚นใ‚ฟใƒณใ‚นใ‚’ๅซใ‚€
  $monolog = ...

  ///// Log shipper configuration

  $formatter = new JsonFormatter();
  $stream = new StreamHandler(__DIR__.'/application-json.log', Logger::DEBUG);
  $stream->setFormatter($formatter);

  $monolog->pushHandler($stream);
  return $r;

ๆฌกใซใ€Monolog ็”จใฎใƒญใ‚ฌใƒผใ‚’ๆง‹ๆˆใ—ใพใ™ใ€‚

ๆง‹ๆˆใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒช /path/to/config/directory/ ใซใ‚ใ‚‹ config_dev.yml ใจ config_prod.yml ใซไปฅไธ‹ใ‚’่ฟฝๅŠ ใ—ใฆใใ ใ•ใ„ใ€‚้–‹็™บ็’ฐๅขƒใจๆœฌ็•ช็’ฐๅขƒใซๅˆใ‚ใ›ใŸๆง‹ๆˆใซใชใ‚‹ใ‚ˆใ†ใซใ€ใ‚ตใƒณใƒ—ใƒซใ‚’ไฟฎๆญฃใ—ใพใ™ใ€‚

# app/config/config.yml
monolog:

# ใƒ—ใƒญใ‚ปใƒƒใ‚ตใƒผใ‚’ไฝฟ็”จใ™ใ‚‹ๅ ดๅˆใฏใ“ใฎใ‚ปใ‚ฏใ‚ทใƒงใƒณใฎใ‚ณใƒกใƒณใƒˆใ‚’่งฃ้™ค
#       Processor :
#           session_processor:
#               class: Acme\Bundle\MonologBundle\Log\SessionRequestProcessor
#            arguments:  [ @session ]
#            tags:
#               - { name: monolog.processor, method: processRecord }

    json_formatter:
        class: Monolog\Formatter\JsonFormatter

    handlers:

        # ใƒญใ‚ฐใ‚ทใƒƒใƒ‘ใƒผใฎใ‚ณใƒณใƒ•ใ‚ฃใ‚ฎใƒฅใƒฌใƒผใ‚ทใƒงใƒณ
        to_json_files:
            # lvar/logs/(environment).log ใซ่จ˜้Œฒ
            type: stream
            path: "%kernel.logs_dir%/%kernel.environment%.log"
            # ๅ…จใƒใƒฃใƒใƒซ (ใƒ‰ใ‚ฏใƒˆใƒชใƒณใ€ใ‚จใƒฉใƒผใชใฉ) ใ‚’ๅซใ‚€
            channels: ~
            # json ใƒ•ใ‚ฉใƒผใƒžใƒƒใ‚ฟใ‚’ไฝฟ็”จ
            formatter: monolog.json_formatter
            # ใƒญใ‚ฐใƒฌใƒ™ใƒซใ‚’่จญๅฎšใ—ใพใ™ (ไพ‹: debugใ€errorใ€alert)
            level: debug

ๆง‹ๆˆใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒช /path/to/config/directory/ ใซใ‚ใ‚‹ config_dev.yml ใจ config_prod.yml ใซไปฅไธ‹ใ‚’่ฟฝๅŠ ใ—ใฆใใ ใ•ใ„ใ€‚้–‹็™บ็’ฐๅขƒใจๆœฌ็•ช็’ฐๅขƒใซๅˆใ‚ใ›ใŸๆง‹ๆˆใซใชใ‚‹ใ‚ˆใ†ใซใ€ใ‚ตใƒณใƒ—ใƒซใ‚’ไฟฎๆญฃใ—ใพใ™ใ€‚

monolog:
    handlers:

        # ใƒญใ‚ฐใ‚ทใƒƒใƒ‘ใƒผๆง‹ๆˆ
        to_json_files:
            # var/logs/(environment).log ใซใƒญใ‚ฐใ‚’่จ˜้Œฒใ—ใพใ™
            type: stream
            path: "%kernel.logs_dir%/%kernel.environment%.log"
            # JSON ใƒ•ใ‚ฉใƒผใƒžใƒƒใ‚ฟใ‚’ไฝฟ็”จใ—ใพใ™
            formatter: monolog.json_formatter
            # ใƒญใ‚ฐใƒฌใƒ™ใƒซใ‚’่จญๅฎšใ—ใพใ™ (ไพ‹: debugใ€errorใ€alert)
            level: debug
้–ขๆ•ฐ \DDTrace\current_context() ใฏใ€ใƒใƒผใ‚ธใƒงใƒณ 0.61.0 ใงๅฐŽๅ…ฅใ•ใ‚Œใฆใ„ใพใ™ใ€‚

ไปฅไธ‹ใ‚’่ฟฝๅŠ ใ—ใพใ™ใ€‚

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        // Monolog ใ‚คใƒณใ‚นใ‚ฟใƒณใ‚นใ‚’ๅ–ๅพ—
        $monolog = logger()->getLogger();
        if (!$monolog instanceof \Monolog\Logger) {
            return;
        }

        // ใ‚ชใƒ—ใ‚ทใƒงใƒณ: JSON ๅฝขๅผใ‚’ไฝฟ็”จ
        $useJson = false;
        foreach ($monolog->getHandlers() as $handler) {
            if (method_exists($handler, 'setFormatter')) {
                $handler->setFormatter(new \Monolog\Formatter\JsonFormatter());
                $useJson = true;
            }
        }

        // ใƒˆใƒฌใƒผใ‚นใŠใ‚ˆใณใ‚นใƒ‘ใƒณ ID ใ‚’ๆŒฟๅ…ฅใ—ใฆใƒญใ‚ฐใ‚จใƒณใƒˆใƒชใ‚’ APM ใƒˆใƒฌใƒผใ‚นใจๆŽฅ็ถš
        $monolog->pushProcessor(function ($record) use ($useJson) {
            $context = \DDTrace\current_context();
            if ($useJson === true) {
                $record['extra']['dd'] = [
                    'trace_id' => $context['trace_id'],
                    'span_id'  => $context['span_id'],
                ];
            } else {
                $record['message'] .= sprintf(
                    ' [dd.trace_id=%d dd.span_id=%d]',
                    $context['trace_id'],
                    $context['span_id']
                );
            }
            return $record;
        });
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}

ไปฅไธ‹ใ‚’่ฟฝๅŠ ใ—ใพใ™ใ€‚

<?php
  // file: bootstrap
  $app->extend('monolog', function($monolog, $app) {
      $monolog->pushHandler(...);
      // ไธ‹่จ˜ใซใƒญใ‚ฌใƒผใ‚’ๆง‹ๆˆ
      return $monolog;
  });

ไปฅไธ‹ใ‚’่ฟฝๅŠ ใ—ใพใ™ใ€‚

<?php
  //file: bootstrap/app.php
  $app->configureMonologUsing(function($monolog) {
      $monolog->pushHandler(...);
      // ไธ‹่จ˜ใซใƒญใ‚ฌใƒผใ‚’ๆง‹ๆˆ
  });

  return $app;

ใใฎไป–ใฎๅ‚่€ƒ่ณ‡ๆ–™