Files
appwrite/app/init/span.php
T
2026-04-30 10:18:54 +05:30

93 lines
3.2 KiB
PHP

<?php
use Appwrite\Extend\Exception;
use Utopia\Console;
use Utopia\DSN\DSN;
use Utopia\Span\Exporter;
use Utopia\Span\Exporter\SentryField;
use Utopia\Span\Span;
use Utopia\Span\Storage;
use Utopia\System\System;
Span::setStorage(new Storage\Coroutine());
$loggingConfig = System::getEnv('_APP_LOGGING_CONFIG', '');
if (\str_ends_with($_SERVER['SCRIPT_NAME'] ?? '', 'realtime.php')) {
$loggingConfig = System::getEnv('_APP_LOGGING_CONFIG_REALTIME', '') ?: $loggingConfig;
}
$addSentryExporter = function (string $loggingConfig, ?callable $sampler = null): void {
try {
$loggingProvider = new DSN($loggingConfig);
$providerName = $loggingProvider->getScheme();
if ($providerName !== 'sentry') {
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Logging provider not supported. Logging is disabled');
}
$dsn = 'https://' . $loggingProvider->getPassword() . '@' . $loggingProvider->getHost() . '/' . ($loggingProvider->getUser() ?? '');
Span::addExporter(
new Exporter\Sentry(
dsn: $dsn,
environment: System::getEnv('_APP_ENV', 'development') === 'production' ? 'production' : 'staging',
release: System::getEnv('_APP_VERSION', 'UNKNOWN'),
serverName: System::getEnv('_APP_LOGGING_SERVICE_IDENTIFIER', \gethostname()),
classifier: fn (string $key): SentryField => match ($key) {
'appwrite.error.action',
'appwrite.error.publish',
'code',
'database',
'dnsDomain',
'embeddingModel',
'error.code',
'error.type',
'hostname',
'locale',
'method',
'projectId',
'service',
'type',
'url',
'userId',
'verboseType' => SentryField::Tag,
default => SentryField::Context,
},
),
sampler: $sampler ?? fn (Span $span): bool => $span->getError() !== null
&& $span->get('appwrite.error.publish') === true
&& $span->get('appwrite.error.experimental') !== true,
);
} catch (Throwable $th) {
Console::warning('Failed to initialize logging provider: ' . $th->getMessage());
}
};
if (!empty($loggingConfig)) {
$addSentryExporter($loggingConfig);
}
$experimentalLoggingConfig = System::getEnv('_APP_EXPERIMENT_LOGGING_CONFIG', '');
if (!empty($experimentalLoggingConfig)) {
$sampleRate = 0.01;
try {
$sampleRate = (float) (new DSN($experimentalLoggingConfig))->getParam('sample', $sampleRate);
} catch (Throwable) {
}
$addSentryExporter(
$experimentalLoggingConfig,
fn (Span $span): bool => $span->getError() !== null
&& $span->get('appwrite.error.experimental') === true
&& \mt_rand() / \mt_getrandmax() <= $sampleRate,
);
}
Span::addExporter(new Exporter\Pretty(), function (Span $span): bool {
if (\str_starts_with($span->getAction(), 'listener.')) {
return $span->getError() !== null;
}
return true;
});