fjffk简�的咖啡店科开�2方法2
环æ»�皆山也。其西å�—诸峰,林壑尤美,望之蔚然而深秀者,ç�…ç�Šä¹Ÿã€‚山行å…七里,æ¸�闻水声潺潺,而泻出于两峰之间者,酿泉也
???????????????????????????????
??????????????/?????????????????
............/...................
.........................../...
???????????????????????????????
>>>>>>>>>>>>>/>>>>>>>>>>>>>>>>>
ÿØÿà JFIF ÿÛ „ ( %!1!%)+//.383,7(-.+
-%%-////---/-.+/--+------/------/--0+--/-/-----.-----ÿÀ ¥2" ÿÄ ÿÄ J ! 1AQ"aq�2‘#BR‚¡�Ñ3br’¢±Âð$CSƒ²á4c“%DsÓñÿÄ ÿÄ * !1AQa‘"2q3�±ð#b¡ÿÚ ? ¼QxJQa�uò¸Zö Úü8,�Úú
"SSn<rçù–´âE—^ªBÖ9À\†¸Â�ÔÂ�Ã�TÂÃÛ5
ëd´³Ã�#Ã�;Þ38ϔÂ� ¶H£M:wÃŽ3…³…âpÔF&‚FK¸9„â4à GEõªfÂ�ÿ ‘ñ(ßwÂpŽF|È¥ù®häðÃ�Ѷ¹‘[Ã’inÙW¶ùñYËœQ{›K"išÒ[Ú8žë\F¹@-?v"ÔUâ€�,ìöžkÿ {I‡£šÃ�?e
rÂ�ÃV
?>
.........................................
.............................................................................
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>/>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
dsdfPK î%W],Á†D D sentry/LICENSEnu „[µü¤ MIT License
Copyright (c) 2012 Functional Software, Inc. dba Sentry
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.PK î%W]FoÐ?® ® sentry/UPGRADE-4.0.mdnu „[µü¤ # Upgrade 3.x to 4.0
- This version exclusively uses the [envelope endpoint](https://develop.sentry.dev/sdk/envelopes/) to send event data to Sentry.
If you are using [sentry.io](https://sentry.io), no action is needed.
If you are using an on-premise/self-hosted installation of Sentry, the minimum requirement is now version `>= v20.6.0`.
- Added `ext-curl` as a composer requirement.
- The `IgnoreErrorsIntegration` integration was removed. Use the `ignore_exceptions` option instead.
```php
Sentry\init([
'ignore_exceptions' => [BadThingsHappenedException::class],
]);
```
This option performs an [`is_a`](https://www.php.net/manual/en/function.is-a.php) check, so you can also ignore more generic exceptions.
- Removed support for `symfony/options-resolver: ^3.4.43`.
- The `RequestFetcher` now relies on `guzzlehttp/psr7: ^1.8.4|^2.1.1`.
- Added new methods to `ClientInterface`
```php
public function getCspReportUrl(): ?string;
public function getStacktraceBuilder(): StacktraceBuilder;
```
- Added new methods to `HubInterface`
```php
public function captureCheckIn(string $slug, CheckInStatus $status, $duration = null, ?MonitorConfig $monitorConfig = null, ?string $checkInId = null): ?string;
```
- The new default value for the `trace_propagation_targets` option is now `null`. To not attach any headers to outgoing requests, using the `GuzzleTracingMiddleware`, set this option to `[]`.
- The `ignore_exceptions` option now performs a `is_a` check on the provided class strings.
- The `send_attempts` option was removed. You may implement a custom transport if you rely on this behaviour.
- The `enable_compression` option was removed. Use `http_compression` instead.
- The `logger` option now accepts a `Psr\Log\LoggerInterface` instance instead of `string`.
- Removed `Options::getSendAttempts/setSendAttempts()`.
- Removed `Options::isCompressionEnabled/setEnableCompression()`. Use `Options::isHttpCompressionEnabled/setEnableHttpCompression()` instead.
- Removed `SpanContext::fromTraceparent()`. Use `Sentry\continueTrace()` instead.
- Removed `TransactionContext::fromSentryTrace()`. Use `Sentry\continueTrace()` instead.
- Removed `Sentry\Exception\InvalidArgumentException`. Use `\InvalidArgumentException` instead.
- Removed `Sentry\Exception/ExceptionInterface`.
- Removed `ClientBuilderInterface()`.
- Removed `ClientBuilder::setSerializer()`.
- Removed `ClientBuilder::setTransportFactory()`. You can set a custom transport via the `transport` option.
- Removed `Client::__construct()` parameter `SerializerInterface $serializer`.
- Removed `TransportFactoryInterface`.
- Removed `DefaultTransportFactory`.
- Removed `HttpClientFactoryInterface`.
- Removed `HttpClientFactory`.
- Removed `NullTransport`.
- Removed `Dsn::getSecretKey()`.
- Removed `Dsn::setSecretKey()`.
- Removed `Dsn::getStoreApiEndpointUrl()`.
- Removed `EventType::default()`.
- Removed adding the value of the `logger` option as a tag on the event. If you rely on this behaviour, add the tag manually.
- Added return type to `Dsn::getProjectId(): string`.
- Changed return type to `Options::getLogger(): ?LoggerInterface`.
- Changed parameter type of `Options::setLogger(LoggerInterface $logger)`.
PK î%W]Æ™Zö® ® sentry/README.mdnu „[µü¤
_Bad software is everywhere, and we're tired of it. Sentry is on a mission to help developers write better software faster, so we can get back to enjoying technology. If you want to join us [**Check out our open positions**](https://sentry.io/careers/)_
# Official Sentry SDK for PHP
[](https://github.com/getsentry/sentry-php/actions?query=workflow%3ACI+branch%3Amaster)
[](https://codecov.io/gh/getsentry/sentry-php/branch/master)
[](https://packagist.org/packages/sentry/sentry)
[](https://packagist.org/packages/sentry/sentry)
[](https://packagist.org/packages/sentry/sentry)
[](https://packagist.org/packages/sentry/sentry)
[](https://discord.gg/cWnMQeA)
The Sentry PHP error reporter tracks errors and exceptions that happen during the
execution of your application and provides instant notification with detailed
information needed to prioritize, identify, reproduce and fix each issue.
## Getting started
### Install
Install the SDK using [Composer](https://getcomposer.org/).
```bash
composer require sentry/sentry
```
### Configuration
Initialize the SDK as early as possible in your application.
```php
\Sentry\init(['dsn' => '___PUBLIC_DSN___' ]);
```
### Usage
```php
try {
thisFunctionThrows(); // -> throw new \Exception('foo bar');
} catch (\Exception $exception) {
\Sentry\captureException($exception);
}
```
## Official integrations
The following integrations are fully supported and maintained by the Sentry team.
- [Symfony](https://github.com/getsentry/sentry-symfony)
- [Laravel](https://github.com/getsentry/sentry-laravel)
## 3rd party integrations using SDK 4.x
The following integrations are available and maintained by members of the Sentry community.
- [Drupal](https://www.drupal.org/project/raven)
- [WordPress](https://wordpress.org/plugins/wp-sentry-integration/)
- Magento 2 by [JustBetter](https://github.com/justbetter/magento2-sentry) or by [Mygento](https://github.com/mygento/module-sentry)
- [Joomla!](https://github.com/AlterBrains/sentry-joomla)
- ... feel free to be famous, create a port to your favourite platform!
## 3rd party integrations using the old SDK 3.x
- [Neos Flow](https://github.com/flownative/flow-sentry)
- [ZendFramework](https://github.com/facile-it/sentry-module)
- [Yii2](https://github.com/notamedia/yii2-sentry)
- [Silverstripe](https://github.com/phptek/silverstripe-sentry)
- [CakePHP 3.0 - 4.3](https://github.com/Connehito/cake-sentry)
- [CakePHP 4.4+](https://github.com/lordsimal/cakephp-sentry)
- [October CMS](https://github.com/OFFLINE-GmbH/oc-sentry-plugin)
## 3rd party integrations using the old SDK 2.x
- [Neos Flow](https://github.com/networkteam/Networkteam.SentryClient)
- [OXID eShop](https://github.com/OXIDprojects/sentry)
- [TYPO3](https://github.com/networkteam/sentry_client)
- [CakePHP](https://github.com/Connehito/cake-sentry/tree/3.x)
## 3rd party integrations using the old SDK 1.x
- [Neos CMS](https://github.com/networkteam/Netwokteam.Neos.SentryClient)
- [OpenCart](https://github.com/BurdaPraha/oc_sentry)
- [TYPO3](https://github.com/networkteam/sentry_client/tree/2.1.1)
## Community
- [Documentation](https://docs.sentry.io/error-reporting/quickstart/?platform=php)
- [Bug Tracker](http://github.com/getsentry/sentry-php/issues)
- [Code](http://github.com/getsentry/sentry-php)
## Contributing to the SDK
Please make sure to read the [CONTRIBUTING.md](CONTRIBUTING.md) before making a pull request.
Thanks to everyone who has contributed to this project so far.
## Getting help/support
If you need help setting up or configuring the PHP SDK (or anything else in the Sentry universe) please head over to the [Sentry Community on Discord](https://discord.com/invite/sentry). There is a ton of great people in our Discord community ready to help you!
## Resources
- [](https://docs.sentry.io/quickstart/)
- [](https://discord.gg/Ww9hbqr)
- [](http://stackoverflow.com/questions/tagged/sentry)
- [](https://twitter.com/intent/follow?screen_name=getsentry)
## License
Licensed under the MIT license, see [`LICENSE`](LICENSE)
PK î%W]U>-ãž ž sentry/AUTHORSnu „[µü¤ The Sentry PHP SDK was originally written by Michael van Tellingen
and is maintained by the Sentry Team.
http://github.com/getsentry/sentry-php/contributors
PK î%W]{>…öî î sentry/scripts/bump-version.shnu „[µü¤ #!/bin/bash
set -eux
if [ "$(uname -s)" != "Linux" ]; then
echo "Please use the GitHub Action."
exit 1
fi
SCRIPT_DIR="$( dirname "$0" )"
cd $SCRIPT_DIR/..
OLD_VERSION="${1}"
NEW_VERSION="${2}"
echo "Current version: $OLD_VERSION"
echo "Bumping version: $NEW_VERSION"
function replace() {
! grep "$2" $3
perl -i -pe "s/$1/$2/g" $3
grep "$2" $3 # verify that replacement was successful
}
replace "SDK_VERSION = '[0-9.]+'" "SDK_VERSION = '$NEW_VERSION'" ./src/Client.phpPK î%W]!-Ôrù ù sentry/src/SentrySdk.phpnu „[µü¤
*/
final class SentrySdk
{
/**
* @var HubInterface|null The current hub
*/
private static $currentHub;
/**
* Constructor.
*/
private function __construct()
{
}
/**
* Initializes the SDK by creating a new hub instance each time this method
* gets called.
*/
public static function init(): HubInterface
{
self::$currentHub = new Hub();
return self::$currentHub;
}
/**
* Gets the current hub. If it's not initialized then creates a new instance
* and sets it as current hub.
*/
public static function getCurrentHub(): HubInterface
{
if (self::$currentHub === null) {
self::$currentHub = new Hub();
}
return self::$currentHub;
}
/**
* Sets the current hub.
*
* @param HubInterface $hub The hub to set
*/
public static function setCurrentHub(HubInterface $hub): HubInterface
{
self::$currentHub = $hub;
return $hub;
}
}
PK î%W]?8¢´Ì Ì 4 sentry/src/Serializer/PayloadSerializerInterface.phpnu „[µü¤ maxDepth = $maxDepth;
if ($mbDetectOrder != null) {
$this->mbDetectOrder = $mbDetectOrder;
}
$this->options = $options;
}
/**
* Serialize an object (recursively) into something safe for data
* sanitization and encoding.
*
* @param mixed $value
*
* @return string|bool|float|int|mixed[]|null
*/
protected function serializeRecursively($value, int $_depth = 0)
{
try {
if ($_depth >= $this->maxDepth) {
return $this->serializeValue($value);
}
try {
if (@\is_callable($value)) {
return $this->serializeCallable($value);
}
} catch (\Throwable $exception) {
// Do nothing on purpose
}
if (\is_array($value)) {
$serializedArray = [];
foreach ($value as $k => $v) {
$serializedArray[$k] = $this->serializeRecursively($v, $_depth + 1);
}
return $serializedArray;
}
if (\is_object($value)) {
$classSerializers = $this->resolveClassSerializers($value);
// Try each serializer until there is none left or the serializer returned data
foreach ($classSerializers as $classSerializer) {
try {
$serializedObjectData = $classSerializer($value);
if (\is_array($serializedObjectData)) {
return [
'class' => \get_class($value),
'data' => $this->serializeRecursively($serializedObjectData, $_depth + 1),
];
}
} catch (\Throwable $e) {
// Ignore any exceptions generated by a class serializer
}
}
if ($value instanceof \DateTimeInterface) {
return $this->formatDate($value);
}
if ($this->serializeAllObjects || ($value instanceof \stdClass)) {
return $this->serializeObject($value, $_depth);
}
}
return $this->serializeValue($value);
} catch (\Throwable $error) {
if (\is_string($value)) {
return $value . ' {serialization error}';
}
return '{serialization error}';
}
}
/**
* Find class serializers for a object.
*
* Registered serializers with the `class_serializers` option take precedence over
* objects implementing the `SerializableInterface`.
*
* @param object $object
*
* @return array
*/
protected function resolveClassSerializers($object): array
{
$serializers = [];
foreach ($this->options->getClassSerializers() as $type => $serializer) {
if ($object instanceof $type) {
$serializers[] = $serializer;
}
}
if ($object instanceof SerializableInterface) {
$serializers[] = static function (SerializableInterface $object): ?array {
return $object->toSentry();
};
}
return $serializers;
}
/**
* @param object $object
* @param string[] $hashes
*
* @return mixed[]|string|bool|float|int|null
*/
protected function serializeObject($object, int $_depth = 0, array $hashes = [])
{
if ($_depth >= $this->maxDepth || \in_array(spl_object_hash($object), $hashes, true)) {
return $this->serializeValue($object);
}
$hashes[] = spl_object_hash($object);
$serializedObject = [];
foreach ($object as $key => &$value) {
if (\is_object($value)) {
$serializedObject[$key] = $this->serializeObject($value, $_depth + 1, $hashes);
} else {
$serializedObject[$key] = $this->serializeRecursively($value, $_depth + 1);
}
}
return $serializedObject;
}
/**
* Serializes the given value to a string.
*
* @param string $value The value to serialize
*/
protected function serializeString(string $value): string
{
if ($value === '') {
return '';
}
// we always guarantee this is coerced, even if we can't detect encoding
if ($currentEncoding = mb_detect_encoding($value, $this->mbDetectOrder)) {
$encoded = mb_convert_encoding($value, 'UTF-8', $currentEncoding) ?: '';
} else {
$encoded = mb_convert_encoding($value, 'UTF-8') ?: '';
}
if (mb_strlen($encoded) > $this->options->getMaxValueLength()) {
$encoded = mb_substr($encoded, 0, $this->options->getMaxValueLength() - 10, 'UTF-8') . ' {clipped}';
}
return $encoded;
}
/**
* @param mixed $value
*
* @return string|bool|float|int|null
*/
protected function serializeValue($value)
{
if (($value === null) || \is_bool($value) || is_numeric($value)) {
return $value;
}
if ($value instanceof \UnitEnum) {
$reflection = new \ReflectionObject($value);
return 'Enum ' . $reflection->getName() . '::' . $value->name;
}
if (\is_object($value)) {
$reflection = new \ReflectionObject($value);
$objectId = null;
if ($reflection->hasProperty('id') && ($idProperty = $reflection->getProperty('id'))->isPublic()) {
$objectId = $idProperty->getValue($value);
} elseif ($reflection->hasMethod('getId') && ($getIdMethod = $reflection->getMethod('getId'))->isPublic()) {
try {
$objectId = $getIdMethod->invoke($value);
} catch (\Throwable $e) {
// Do nothing on purpose
}
}
return 'Object ' . $reflection->getName() . (\is_scalar($objectId) ? '(#' . $objectId . ')' : '');
}
if (\is_resource($value)) {
return 'Resource ' . get_resource_type($value);
}
try {
if (@\is_callable($value)) {
return $this->serializeCallable($value);
}
} catch (\Throwable $exception) {
// Do nothing on purpose
}
if (\is_array($value)) {
return 'Array of length ' . \count($value);
}
if (\is_string($value) || (\is_object($value) && method_exists($value, '__toString'))) {
return $this->serializeString((string) $value);
}
return null;
}
private function formatDate(\DateTimeInterface $date): string
{
$hasMicroseconds = $date->format('u') !== '000000';
$formatted = $hasMicroseconds ? $date->format('Y-m-d H:i:s.u') : $date->format('Y-m-d H:i:s');
$className = \get_class($date);
$timezone = $date->getTimezone();
if ($timezone && $timezone->getName() !== 'UTC') {
$formatted .= ' ' . $date->format('eP');
}
return "$className($formatted)";
}
/**
* @param callable|mixed $callable
*/
protected function serializeCallable($callable): string
{
if (\is_string($callable)) {
return $callable;
}
if (!\is_callable($callable)) {
throw new \InvalidArgumentException(\sprintf('Expecting callable, got %s', \is_object($callable) ? \get_class($callable) : \gettype($callable)));
}
try {
if (\is_array($callable)) {
$reflection = new \ReflectionMethod($callable[0], $callable[1]);
$class = $reflection->getDeclaringClass();
} elseif ($callable instanceof \Closure) {
$reflection = new \ReflectionFunction($callable);
$class = null;
} elseif (\is_object($callable) && method_exists($callable, '__invoke')) {
$reflection = new \ReflectionMethod($callable, '__invoke');
$class = $reflection->getDeclaringClass();
} else {
throw new \InvalidArgumentException('Unrecognized type of callable');
}
} catch (\ReflectionException $exception) {
return '{unserializable callable, reflection error}';
}
$callableType = $reflection->isClosure() ? 'Lambda ' : 'Callable ';
$callableReturnType = $reflection->getReturnType();
if ($callableReturnType instanceof \ReflectionNamedType) {
$callableType .= $callableReturnType->getName() . ' ';
}
if ($class) {
$callableType .= $class->getName() . '::';
}
return $callableType . $reflection->getName() . ' ' . $this->serializeCallableParameters($reflection);
}
private function serializeCallableParameters(\ReflectionFunctionAbstract $reflection): string
{
$params = [];
foreach ($reflection->getParameters() as &$param) {
$reflectionType = $param->getType();
if ($reflectionType instanceof \ReflectionNamedType) {
$paramType = $reflectionType->getName();
} else {
$paramType = 'mixed';
}
if ($param->allowsNull()) {
$paramType .= '|null';
}
$paramName = ($param->isPassedByReference() ? '&' : '') . $param->getName();
if ($param->isOptional()) {
$paramName = '[' . $paramName . ']';
}
$params[] = $paramType . ' ' . $paramName;
}
return '[' . implode('; ', $params) . ']';
}
public function getMbDetectOrder(): string
{
return $this->mbDetectOrder;
}
/**
* @return $this
*/
public function setMbDetectOrder(string $mbDetectOrder): self
{
$this->mbDetectOrder = $mbDetectOrder;
return $this;
}
public function setSerializeAllObjects(bool $value): void
{
$this->serializeAllObjects = $value;
}
public function getSerializeAllObjects(): bool
{
return $this->serializeAllObjects;
}
}
PK î%W])øó™ ™ > sentry/src/Serializer/Traits/StacktraceFrameSeralizerTrait.phpnu „[µü¤
*
* @psalm-return array{
* filename: string,
* lineno: int,
* in_app: bool,
* abs_path?: string,
* function?: string,
* raw_function?: string,
* pre_context?: string[],
* context_line?: string,
* post_context?: string[],
* vars?: array
* }
*/
protected static function serializeStacktraceFrame(Frame $frame): array
{
$result = [
'filename' => $frame->getFile(),
'lineno' => $frame->getLine(),
'in_app' => $frame->isInApp(),
];
if ($frame->getAbsoluteFilePath() !== null) {
$result['abs_path'] = $frame->getAbsoluteFilePath();
}
if ($frame->getFunctionName() !== null) {
$result['function'] = $frame->getFunctionName();
}
if ($frame->getRawFunctionName() !== null) {
$result['raw_function'] = $frame->getRawFunctionName();
}
if (!empty($frame->getPreContext())) {
$result['pre_context'] = $frame->getPreContext();
}
if ($frame->getContextLine() !== null) {
$result['context_line'] = $frame->getContextLine();
}
if (!empty($frame->getPostContext())) {
$result['post_context'] = $frame->getPostContext();
}
if (!empty($frame->getVars())) {
$result['vars'] = $frame->getVars();
}
return $result;
}
}
PK î%W]€j?ó ó 9 sentry/src/Serializer/Traits/BreadcrumbSeralizerTrait.phpnu „[µü¤
*
* @psalm-return array{
* type: string,
* category: string,
* level: string,
* timestamp: float,
* message?: string,
* data?: object
* }
*/
protected static function serializeBreadcrumb(Breadcrumb $breadcrumb): array
{
$result = [
'type' => $breadcrumb->getType(),
'category' => $breadcrumb->getCategory(),
'level' => $breadcrumb->getLevel(),
'timestamp' => $breadcrumb->getTimestamp(),
];
if ($breadcrumb->getMessage() !== null) {
$result['message'] = $breadcrumb->getMessage();
}
if (!empty($breadcrumb->getMetadata())) {
$result['data'] = (object) $breadcrumb->getMetadata();
}
return $result;
}
}
PK î%W]kŸÆbO O 2 sentry/src/Serializer/RepresentationSerializer.phpnu „[µü¤ serializeRecursively($value);
if (is_numeric($value)) {
return (string) $value;
}
if (\is_bool($value)) {
return $value ? 'true' : 'false';
}
return $value;
}
/**
* This method is overridden to return even basic types as strings.
*
* @param mixed $value The value that needs to be serialized
*
* @return string
*/
protected function serializeValue($value)
{
if ($value === null) {
return 'null';
}
if ($value === false) {
return 'false';
}
if ($value === true) {
return 'true';
}
if (\is_float($value) && (int) $value == $value) {
return $value . '.0';
}
if (is_numeric($value)) {
return (string) $value;
}
return (string) parent::serializeValue($value);
}
}
PK î%W]”ñSÅ Å ; sentry/src/Serializer/RepresentationSerializerInterface.phpnu „[µü¤ 'profile',
'content_type' => 'application/json',
];
$profile = $event->getSdkMetadata('profile');
if (!$profile instanceof Profile) {
return null;
}
$payload = $profile->getFormattedData($event);
if ($payload === null) {
return null;
}
return \sprintf("%s\n%s", JSON::encode($header), JSON::encode($payload));
}
}
PK î%W]íi‡ÙE E 6 sentry/src/Serializer/EnvelopItems/TransactionItem.phpnu „[µü¤ ,
* }
*/
class TransactionItem implements EnvelopeItemInterface
{
use BreadcrumbSeralizerTrait;
public static function toEnvelopeItem(Event $event): string
{
$header = [
'type' => (string) EventType::transaction(),
'content_type' => 'application/json',
];
$payload = [
'timestamp' => $event->getTimestamp(),
'platform' => 'php',
'sdk' => $event->getSdkPayload(),
];
if ($event->getStartTimestamp() !== null) {
$payload['start_timestamp'] = $event->getStartTimestamp();
}
if ($event->getLevel() !== null) {
$payload['level'] = (string) $event->getLevel();
}
if ($event->getTransaction() !== null) {
$payload['transaction'] = $event->getTransaction();
}
if ($event->getServerName() !== null) {
$payload['server_name'] = $event->getServerName();
}
if ($event->getRelease() !== null) {
$payload['release'] = $event->getRelease();
}
if ($event->getEnvironment() !== null) {
$payload['environment'] = $event->getEnvironment();
}
if (!empty($event->getFingerprint())) {
$payload['fingerprint'] = $event->getFingerprint();
}
if (!empty($event->getModules())) {
$payload['modules'] = $event->getModules();
}
if (!empty($event->getExtra())) {
$payload['extra'] = $event->getExtra();
}
if (!empty($event->getTags())) {
$payload['tags'] = $event->getTags();
}
$user = $event->getUser();
if ($user !== null) {
$payload['user'] = array_merge($user->getMetadata(), [
'id' => $user->getId(),
'username' => $user->getUsername(),
'email' => $user->getEmail(),
'ip_address' => $user->getIpAddress(),
'segment' => $user->getSegment(),
]);
}
$osContext = $event->getOsContext();
if ($osContext !== null) {
$payload['contexts']['os'] = [
'name' => $osContext->getName(),
'version' => $osContext->getVersion(),
'build' => $osContext->getBuild(),
'kernel_version' => $osContext->getKernelVersion(),
];
}
$runtimeContext = $event->getRuntimeContext();
if ($runtimeContext !== null) {
$payload['contexts']['runtime'] = [
'name' => $runtimeContext->getName(),
'sapi' => $runtimeContext->getSAPI(),
'version' => $runtimeContext->getVersion(),
];
}
if (!empty($event->getContexts())) {
$payload['contexts'] = array_merge($payload['contexts'] ?? [], $event->getContexts());
}
if (!empty($event->getBreadcrumbs())) {
$payload['breadcrumbs']['values'] = array_map([self::class, 'serializeBreadcrumb'], $event->getBreadcrumbs());
}
if (!empty($event->getRequest())) {
$payload['request'] = $event->getRequest();
}
$payload['spans'] = array_values(array_map([self::class, 'serializeSpan'], $event->getSpans()));
$transactionMetadata = $event->getSdkMetadata('transaction_metadata');
if ($transactionMetadata instanceof TransactionMetadata) {
$payload['transaction_info']['source'] = (string) $transactionMetadata->getSource();
}
return \sprintf("%s\n%s", JSON::encode($header), JSON::encode($payload));
}
/**
* @return array
*
* @psalm-return array{
* span_id: string,
* trace_id: string,
* parent_span_id?: string,
* start_timestamp: float,
* timestamp?: float,
* status?: string,
* description?: string,
* op?: string,
* data?: array,
* tags?: array
* _metrics_summary?: array
* }
*/
protected static function serializeSpan(Span $span): array
{
$result = [
'span_id' => (string) $span->getSpanId(),
'trace_id' => (string) $span->getTraceId(),
'start_timestamp' => $span->getStartTimestamp(),
'origin' => $span->getOrigin() ?? 'manual',
];
if ($span->getParentSpanId() !== null) {
$result['parent_span_id'] = (string) $span->getParentSpanId();
}
if ($span->getEndTimestamp() !== null) {
$result['timestamp'] = $span->getEndTimestamp();
}
if ($span->getStatus() !== null) {
$result['status'] = (string) $span->getStatus();
}
if ($span->getDescription() !== null) {
$result['description'] = $span->getDescription();
}
if ($span->getOp() !== null) {
$result['op'] = $span->getOp();
}
if (!empty($span->getData())) {
$result['data'] = $span->getData();
}
if (!empty($span->getTags())) {
$result['tags'] = $span->getTags();
}
return $result;
}
}
PK î%W]™'ýâÚ Ú <