В настоящее время мы испытываем некоторые проблемы с подключением при попытке войти в Google Stackdriver через наше приложение Laravel 6.
Мы используем официальный пакет google/cloud-logging
в настраиваемом канале Laravel для регистрации ведение журнала со следующей настройкой, которая позволяет нам использовать собственные методы ведения журнала Laravel (Log::info('...')
):
// Within the `channels` array in `logging.php`
'googlelog' => [
'driver' => 'custom',
'via' => CreateStackdriverLogger::class,
'logName' => 'api',
'loggingClientOptions' => [
'keyFilePath' => resource_path('google-service-account-prod.json'),
],
'level' => env('LOG_LEVEL', 'info'),
'username' => 'Logger'
],
use Monolog\Logger;
class CreateStackdriverLogger {
/**
* Create a custom Monolog instance.
*
* @param array $config
* @return Logger
*/
public function __invoke(array $config) {
$projectId = $config['logName'] ?? '';
$loggingClientOptions = $config['loggingClientOptions'] ?? [];
$loggerOptions = $config['loggerOptions'] ?? [];
$entryOptionsWrapper = $config['entryOptionsWrapper'] ?? 'stackdriver';
$lineFormat = $config['lineFormat'] ?? '%message%';
$level = $config['level'] ?? Logger::DEBUG;
$bubble = $config['bubble'] ?? true;
$stackdriverHandler = new StackdriverLogger($projectId, $loggingClientOptions, $loggerOptions, $entryOptionsWrapper, $lineFormat, $level, $bubble);
return new Logger('stackdriver', [$stackdriverHandler]);
}
}
use Google\Cloud\Logging\LoggingClient;
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\AbstractProcessingHandler;
use Monolog\Logger;
class StackdriverLogger extends AbstractProcessingHandler {
/**
* The Stackdriver logger
*
* @var \Google\Cloud\Logging\Logger
*/
private $logger;
/**
* A context array key used to take log entry options from
*
* @var string
*/
private $entryOptionsWrapper;
/**
* Log entry options (all but severity) as supported by Google\Cloud\Logging\Logger::entry
*
* @var array Entry options.
*/
private $entryOptions = [
'resource',
'httpRequest',
'labels',
'operation',
'insertId',
'timestamp',
];
/**
* @param string $logName Name of your log
* @param array $loggingClientOptions Google\Cloud\Logging\LoggingClient valid options
* @param array $loggerOptions Google\Cloud\Logging\LoggingClient::logger valid options
* @param string $entryOptionsWrapper Array key used in the context array to take Google\Cloud\Logging\Entry options from
* @param string $lineFormat Monolog\Formatter\LineFormatter format
* @param int $level The minimum logging level at which this handler will be triggered
* @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
*/
public function __construct($logName, $loggingClientOptions, $loggerOptions = [], $entryOptionsWrapper = 'stackdriver', $lineFormat = '%message%', $level = Logger::DEBUG,
$bubble = true) {
parent::__construct($level, $bubble);
$this->logger = (new LoggingClient($loggingClientOptions))->logger($logName, $loggerOptions);
$this->formatter = new LineFormatter($lineFormat);
$this->entryOptionsWrapper = $entryOptionsWrapper;
}
/**
* Writes the record down to the log
*
* @param array $record
* @return void
*/
protected function write(array $record): void {
$options = $this->getOptionsFromRecord($record);
$data = [
'message' => $record['formatted'],
'data' => $record['context']
];
$entry = $this->logger->entry($data, $options);
$this->logger->write($entry);
}
/**
* Get the Google\Cloud\Logging\Entry options
*
* @param array $record by reference
* @return array $options
*/
private function getOptionsFromRecord(array &$record) {
$options = [
'severity' => $record['level_name']
];
if (isset($record['context'][$this->entryOptionsWrapper])) {
foreach ($this->entryOptions as $entryOption) {
if ($record['context'][$this->entryOptionsWrapper][$entryOption] ?? false) {
$options[$entryOption] = $record['context'][$this->entryOptionsWrapper][$entryOption];
}
}
unset($record['context'][$this->entryOptionsWrapper]);
}
return $options;
}
}
Таким образом, регистрация через эту настройку, кажется, работает в большинстве случаев, но иногда мы получаем следующие различные ошибки с нерегулярными интервалами, все в контексте процесса ведения журнала:
Ошибка cURL 7: Не удалось подключиться к порту 443 logging.googleapis.com: Тайм-аут соединения (см. http://curl.haxx.se/libcurl/c/libcurl-errors.html)
Ошибка cURL 7. Не удалось подключиться к порту oauth2.googleapis.com 443: Тайм-аут соединения (см. http://curl.haxx.se/libcurl/c/libcurl-errors.html)
cURL ошибка 35: неизвестная ошибка протокола SSL при подключении к oauth2.googleapis.com:443 (см. http://curl.haxx.se/libcurl/c/libcurl-errors.html)
Вот пример для полной трассировки стека: https://sentry.io/share/issue/7a25c0a3575e4e2684ad5220cd89b86a/
Мы уже проверили, работаем ли мы с какими-либо ограничениями скорости Google, но, похоже, это не так. Есть ли что-нибудь еще, что может вызвать такие проблемы с подключением?