Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions src/CheckIn.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<?php

declare(strict_types=1);

namespace Sentry;

use Sentry\Util\SentryUid;

final class CheckIn
{
/**
* @var string The check-in ID
*/
private $id;

/**
* @var string The monitor slug
*/
private $monitorSlug;

/**
* @var \Sentry\CheckInStatus The status of the check-in
*/
private $status;

/**
* @var string|null The release
*/
private $release;

/**
* @var string|null The environment
*/
private $environment;

/**
* @var int|null The duration of the check in seconds
*/
private $duration;

public function __construct(
string $monitorSlug,
CheckInStatus $status,
string $id = null,
?string $release = null,
?string $environment = null,
?int $duration = null
) {
$this->setMonitorSlug($monitorSlug);
$this->setStatus($status);

$this->setId($id ?? SentryUid::generate());
$this->setRelease($release ?? '');
$this->setEnvironment($environment ?? Event::DEFAULT_ENVIRONMENT);
$this->setDuration($duration);
}

public function getId(): string
{
return $this->id;
}

public function setId(string $id): void
{
$this->id = $id;
}

public function getMonitorSlug(): string
{
return $this->monitorSlug;
}

public function setMonitorSlug(string $monitorSlug): void
{
$this->monitorSlug = $monitorSlug;
}

public function getStatus(): CheckInStatus
{
return $this->status;
}

public function setStatus(CheckInStatus $status): void
{
$this->status = $status;
}

public function getRelease(): ?string
{
return $this->release;
}

public function setRelease(string $release): void
{
$this->release = $release;
}

public function getEnvironment(): ?string
{
return $this->environment;
}

public function setEnvironment(string $environment): void
{
$this->environment = $environment;
}

public function getDuration(): ?int
{
return $this->duration;
}

public function setDuration(?int $duration): void
{
$this->duration = $duration;
}
}
55 changes: 55 additions & 0 deletions src/CheckInStatus.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

declare(strict_types=1);

namespace Sentry;

/**
* This enum represents all the possible status of a check in.
*/
final class CheckInStatus implements \Stringable
{
/**
* @var string The value of the enum instance
*/
private $value;

/**
* @var array<string, self> A list of cached enum instances
*/
private static $instances = [];

private function __construct(string $value)
{
$this->value = $value;
}

public static function ok(): self
{
return self::getInstance('ok');
}

public static function error(): self
{
return self::getInstance('error');
}

public static function inProgress(): self
{
return self::getInstance('in_progress');
}

public function __toString(): string
{
return $this->value;
}

private static function getInstance(string $value): self
{
if (!isset(self::$instances[$value])) {
self::$instances[$value] = new self($value);
}

return self::$instances[$value];
}
}
20 changes: 20 additions & 0 deletions src/Event.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ final class Event
*/
private $transaction;

/**
* @var CheckIn|null The check in data
*/
private $checkIn;

/**
* @var string|null The name of the server (e.g. the host name)
*/
Expand Down Expand Up @@ -200,6 +205,11 @@ public static function createTransaction(EventId $eventId = null): self
return new self($eventId, EventType::transaction());
}

public static function createCheckIn(?EventId $eventId = null): self
{
return new self($eventId, EventType::checkIn());
}

/**
* Gets the ID of this event.
*/
Expand Down Expand Up @@ -322,6 +332,16 @@ public function setTransaction(?string $transaction): void
$this->transaction = $transaction;
}

public function setCheckIn(?CheckIn $checkIn): void
{
$this->checkIn = $checkIn;
}

public function getCheckIn(): ?CheckIn
{
return $this->checkIn;
}

/**
* Gets the name of the server.
*/
Expand Down
5 changes: 5 additions & 0 deletions src/EventType.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ public static function transaction(): self
return self::getInstance('transaction');
}

public static function checkIn(): self
{
return self::getInstance('check_in');
}

public function __toString(): string
{
return $this->value;
Expand Down
33 changes: 32 additions & 1 deletion src/Serializer/PayloadSerializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ public function serialize(Event $event): string
return $transactionEnvelope;
}

if (EventType::checkIn() === $event->getType()) {
return $this->serializeAsEnvelope($event);
}

return $this->serializeAsEvent($event);
}

Expand All @@ -63,6 +67,25 @@ private function serializeAsEvent(Event $event): string
return JSON::encode($result);
}

private function serializeAsCheckInEvent(Event $event): string
{
$result = [];

$checkIn = $event->getCheckIn();
if (null !== $checkIn) {
$result = [
'check_in_id' => $checkIn->getId(),
'monitor_slug' => $checkIn->getMonitorSlug(),
'status' => (string) $checkIn->getStatus(),
'duration' => $checkIn->getDuration(),
'release' => $checkIn->getRelease(),
'environment' => $checkIn->getEnvironment(),
];
}

return JSON::encode($result);
}

/**
* @return array<string, mixed>
*/
Expand Down Expand Up @@ -231,7 +254,15 @@ private function serializeAsEnvelope(Event $event): string
'content_type' => 'application/json',
];

return sprintf("%s\n%s\n%s", JSON::encode($envelopeHeader), JSON::encode($itemHeader), $this->serializeAsEvent($event));
$seralizedEvent = '';
if (EventType::transaction() === $event->getType()) {
$seralizedEvent = $this->serializeAsEvent($event);
}
if (EventType::checkIn() === $event->getType()) {
$seralizedEvent = $this->serializeAsCheckInEvent($event);
}

return sprintf("%s\n%s\n%s", JSON::encode($envelopeHeader), JSON::encode($itemHeader), $seralizedEvent);
}

private function seralizeProfileAsEnvelope(Event $event): ?string
Expand Down
5 changes: 4 additions & 1 deletion src/Transport/HttpTransport.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,10 @@ public function send(Event $event): PromiseInterface
return new RejectedPromise(new Response(ResponseStatus::rateLimit(), $event));
}

if (EventType::transaction() === $eventType) {
if (
EventType::transaction() === $eventType ||
EventType::checkIn() === $eventType
) {
$request = $this->requestFactory->createRequest('POST', $dsn->getEnvelopeApiEndpointUrl())
->withHeader('Content-Type', 'application/x-sentry-envelope')
->withBody($this->streamFactory->createStream($this->payloadSerializer->serialize($event)));
Expand Down
59 changes: 59 additions & 0 deletions tests/CheckInTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

declare(strict_types=1);

namespace Sentry\Tests;

use PHPUnit\Framework\TestCase;
use Sentry\CheckIn;
use Sentry\CheckInStatus;
use Sentry\Util\SentryUid;

final class CheckInTest extends TestCase
{
public function testConstructor(): void
{
$checkInId = SentryUid::generate();
$checkIn = new CheckIn(
'my-monitor',
CheckInStatus::ok(),
$checkInId,
'1.0.0',
'dev',
10
);

$this->assertEquals($checkInId, $checkIn->getId());
$this->assertEquals('my-monitor', $checkIn->getMonitorSlug());
$this->assertEquals('ok', $checkIn->getStatus());
$this->assertEquals('1.0.0', $checkIn->getRelease());
$this->assertEquals('dev', $checkIn->getEnvironment());
$this->assertEquals(10, $checkIn->getDuration());
}

/**
* @dataProvider gettersAndSettersDataProvider
*/
public function testGettersAndSetters(string $getterMethod, string $setterMethod, $expectedData): void
{
$checkIn = new CheckIn(
'my-monitor',
CheckInStatus::ok()
);
$checkIn->$setterMethod($expectedData);

$this->assertEquals($expectedData, $checkIn->$getterMethod());
}

public function gettersAndSettersDataProvider(): array
{
return [
['getId', 'setId', SentryUid::generate()],
['getMonitorSlug', 'setMonitorSlug', 'my-monitor'],
['getStatus', 'setStatus', CheckInStatus::ok()],
['getRelease', 'setRelease', '1.0.0'],
['getEnvironment', 'setEnvironment', 'dev'],
['getDuration', 'setDuration', 10],
];
}
}
Loading