1<?php declare(strict_types=1); 2 3/* 4 * This file is part of the Monolog package. 5 * 6 * (c) Jordi Boggiano <j.boggiano@seld.be> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Monolog\Processor; 13 14use Monolog\Logger; 15use Psr\Log\LogLevel; 16 17/** 18 * Injects Git branch and Git commit SHA in all records 19 * 20 * @author Nick Otter 21 * @author Jordi Boggiano <j.boggiano@seld.be> 22 * 23 * @phpstan-import-type Level from \Monolog\Logger 24 * @phpstan-import-type LevelName from \Monolog\Logger 25 */ 26class GitProcessor implements ProcessorInterface 27{ 28 /** @var int */ 29 private $level; 30 /** @var array{branch: string, commit: string}|array<never>|null */ 31 private static $cache = null; 32 33 /** 34 * @param string|int $level The minimum logging level at which this Processor will be triggered 35 * 36 * @phpstan-param Level|LevelName|LogLevel::* $level 37 */ 38 public function __construct($level = Logger::DEBUG) 39 { 40 $this->level = Logger::toMonologLevel($level); 41 } 42 43 /** 44 * {@inheritDoc} 45 */ 46 public function __invoke(array $record): array 47 { 48 // return if the level is not high enough 49 if ($record['level'] < $this->level) { 50 return $record; 51 } 52 53 $record['extra']['git'] = self::getGitInfo(); 54 55 return $record; 56 } 57 58 /** 59 * @return array{branch: string, commit: string}|array<never> 60 */ 61 private static function getGitInfo(): array 62 { 63 if (self::$cache) { 64 return self::$cache; 65 } 66 67 $branches = `git branch -v --no-abbrev`; 68 if ($branches && preg_match('{^\* (.+?)\s+([a-f0-9]{40})(?:\s|$)}m', $branches, $matches)) { 69 return self::$cache = [ 70 'branch' => $matches[1], 71 'commit' => $matches[2], 72 ]; 73 } 74 75 return self::$cache = []; 76 } 77} 78