Skip to content

Commit 4a80d07

Browse files
authored
🧐 Add hafas insights to prometheus (#3040)
1 parent 9d131a1 commit 4a80d07

File tree

7 files changed

+162
-21
lines changed

7 files changed

+162
-21
lines changed

app/Helpers/CacheKey.php

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,27 @@
55

66
use App\Models\User;
77
use Carbon\Carbon;
8+
use Illuminate\Support\Facades\Cache;
89

910
class CacheKey
1011
{
1112
// static keys
12-
public const string STATUS_CREATED = 'monitoring-counter-StatusCreated';
13-
public const string STATUS_DELETED = 'monitoring-counter-StatusDeleted';
14-
public const string USER_CREATED = 'monitoring-counter-UserCreated';
15-
public const string USER_DELETED = 'monitoring-counter-UserDeleted';
13+
public const string STATUS_CREATED = 'monitoring-counter-StatusCreated';
14+
public const string STATUS_DELETED = 'monitoring-counter-StatusDeleted';
15+
public const string USER_CREATED = 'monitoring-counter-UserCreated';
16+
public const string USER_DELETED = 'monitoring-counter-UserDeleted';
1617
public const string WEBHOOK_ABSENT = 'monitoring-counter-WebhookAbsent';
1718
public const string LEADERBOARD_GLOBAL_POINTS = 'LeaderboardGlobalPoints';
1819
public const string LEADERBOARD_GLOBAL_DISTANCE = 'LeaderboardGlobalDistance';
1920

2021
// dynamic keys
2122
private const string LEADERBOARD_FRIENDS = 'LeaderboardFriends';
2223
private const string LEADERBOARD_MONTH = 'LeaderboardMonth';
23-
private const string STATISTICS_GLOBAL = 'StatisticsGlobal';
24+
private const string STATISTICS_GLOBAL = 'StatisticsGlobal';
2425

2526
// formatting keys
26-
private const string FOR = '%s-for-%s';
27-
private const string FROM_TO = '%s-from-%s-to-%s';
27+
private const string FOR = '%s-for-%s';
28+
private const string FROM_TO = '%s-from-%s-to-%s';
2829

2930
public static function getFriendsLeaderboardKey(int $userId): string {
3031
return sprintf(self::FOR, self::LEADERBOARD_FRIENDS, $userId);
@@ -54,4 +55,12 @@ public static function getYearInReviewKey(User $user, int $year): string {
5455
public static function getAccountDeletionNotificationTwoWeeksBeforeKey(User $user): string {
5556
return sprintf("account-deletion-notification-two-weeks-before-%s", $user->id);
5657
}
58+
59+
public static function increment(string $key): void {
60+
if (Cache::has($key)) {
61+
Cache::increment($key);
62+
} else {
63+
Cache::put($key, 1);
64+
}
65+
}
5766
}

app/Helpers/HCK.php

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Helpers;
6+
7+
enum HCK
8+
{
9+
public const string DEPARTURES_SUCCESS = 'monitoring-counter-HafasDeparturesSuccess';
10+
public const string DEPARTURES_FAILURE = 'monitoring-counter-HafasDeparturesFailure';
11+
public const string DEPARTURES_NOT_OK = 'monitoring-counter-HafasDeparturesNotOk';
12+
public const string TRIPS_SUCCESS = 'monitoring-counter-HafasTripsSuccess';
13+
public const string TRIPS_FAILURE = 'monitoring-counter-HafasTripsFailure';
14+
public const string TRIPS_NOT_OK = 'monitoring-counter-HafasTripsNotOk';
15+
public const string TRIPS_502 = 'monitoring-counter-HafasTrips502';
16+
public const string STOPS_SUCCESS = 'monitoring-counter-HafasStopsSuccess';
17+
public const string STOPS_FAILURE = 'monitoring-counter-HafasStopsFailure';
18+
public const string STOPS_NOT_OK = 'monitoring-counter-HafasStopsNotOk';
19+
public const string STATIONS_SUCCESS = 'monitoring-counter-HafasStationsSuccess';
20+
public const string STATIONS_FAILURE = 'monitoring-counter-HafasStationsFailure';
21+
public const string STATIONS_NOT_OK = 'monitoring-counter-HafasStationsNotOk';
22+
public const string LOCATIONS_SUCCESS = 'monitoring-counter-HafasLocationsSuccess';
23+
public const string LOCATIONS_FAILURE = 'monitoring-counter-HafasLocationsFailure';
24+
public const string LOCATIONS_NOT_OK = 'monitoring-counter-HafasLocationsNotOk';
25+
public const string NEARBY_SUCCESS = 'monitoring-counter-HafasNearbySuccess';
26+
public const string NEARBY_FAILURE = 'monitoring-counter-HafasNearbyFailure';
27+
public const string NEARBY_NOT_OK = 'monitoring-counter-HafasNearbyNotOk';
28+
29+
/**
30+
* @return array {string: string}
31+
*/
32+
public static function getFailures(): array {
33+
return [
34+
self::DEPARTURES_FAILURE => 'Departures',
35+
self::TRIPS_FAILURE => 'Trips',
36+
self::STOPS_FAILURE => 'Stops',
37+
self::STATIONS_FAILURE => 'Stations',
38+
self::LOCATIONS_FAILURE => 'Locations',
39+
self::NEARBY_FAILURE => 'Nearby',
40+
];
41+
}
42+
43+
/**
44+
* @return array {string: string}
45+
*/
46+
public static function getNotOks(): array {
47+
return [
48+
self::DEPARTURES_NOT_OK => 'Departures',
49+
self::TRIPS_NOT_OK => 'Trips',
50+
self::STOPS_NOT_OK => 'Stops',
51+
self::STATIONS_NOT_OK => 'Stations',
52+
self::LOCATIONS_NOT_OK => 'Locations',
53+
self::NEARBY_NOT_OK => 'Nearby',
54+
];
55+
}
56+
57+
/**
58+
* @return array {string: string}
59+
*/
60+
public static function getSuccesses(): array {
61+
return [
62+
self::DEPARTURES_SUCCESS => 'Departures',
63+
self::TRIPS_SUCCESS => 'Trips',
64+
self::STOPS_SUCCESS => 'Stops',
65+
self::STATIONS_SUCCESS => 'Stations',
66+
self::LOCATIONS_SUCCESS => 'Locations',
67+
self::NEARBY_SUCCESS => 'Nearby',
68+
];
69+
}
70+
}

app/Http/Controllers/HafasController.php

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
use App\Enum\TravelType;
77
use App\Enum\TripSource;
88
use App\Exceptions\HafasException;
9+
use App\Helpers\CacheKey;
10+
use App\Helpers\HCK;
911
use App\Models\HafasOperator;
1012
use App\Models\Station;
1113
use App\Models\Stopover;
@@ -37,9 +39,11 @@ public static function getStationByRilIdentifier(string $rilIdentifier): ?Statio
3739
$response = self::getHttpClient()
3840
->get("/stations/$rilIdentifier");
3941
if (!$response->ok()) {
42+
CacheKey::increment(HCK::STATIONS_NOT_OK);
4043
return null;
4144
}
4245
$data = json_decode($response->body(), false, 512, JSON_THROW_ON_ERROR);
46+
CacheKey::increment(HCK::STATIONS_SUCCESS);
4347
return Station::updateOrCreate([
4448
'ibnr' => $data->id
4549
], [
@@ -49,6 +53,7 @@ public static function getStationByRilIdentifier(string $rilIdentifier): ?Statio
4953
'longitude' => $data->location->longitude
5054
]);
5155
} catch (Exception $exception) {
56+
CacheKey::increment(HCK::STATIONS_FAILURE);
5257
report($exception);
5358
}
5459
return null;
@@ -79,13 +84,21 @@ public static function getStations(string $query, int $results = 10): Collection
7984
]);
8085

8186
$data = json_decode($response->body(), false, 512, JSON_THROW_ON_ERROR);
87+
if (!$response->ok()) {
88+
CacheKey::increment(HCK::LOCATIONS_NOT_OK);
89+
}
90+
8291
if (empty($data) || !$response->ok()) {
8392
return Collection::empty();
8493
}
8594

95+
CacheKey::increment(HCK::LOCATIONS_SUCCESS);
8696
return self::parseHafasStops($data);
8797
} catch (JsonException $exception) {
8898
throw new HafasException($exception->getMessage());
99+
} catch (Exception $exception) {
100+
CacheKey::increment(HCK::LOCATIONS_FAILURE);
101+
throw new HafasException($exception->getMessage());
89102
}
90103
}
91104

@@ -143,6 +156,7 @@ public static function getNearbyStations(float $latitude, float $longitude, int
143156
]);
144157

145158
if (!$response->ok()) {
159+
CacheKey::increment(HCK::NEARBY_NOT_OK);
146160
throw new HafasException(__('messages.exception.generalHafas'));
147161
}
148162

@@ -154,8 +168,10 @@ public static function getNearbyStations(float $latitude, float $longitude, int
154168
$station->distance = $hafasStation->distance;
155169
}
156170

171+
CacheKey::increment(HCK::NEARBY_SUCCESS);
157172
return $stations;
158173
} catch (JsonException $exception) {
174+
CacheKey::increment(HCK::NEARBY_FAILURE);
159175
throw new HafasException($exception->getMessage());
160176
}
161177
}
@@ -190,13 +206,16 @@ public static function fetchDepartures(
190206
try {
191207
$response = $client->get('/stops/' . $station->ibnr . '/departures', $query);
192208
} catch (Exception $exception) {
209+
CacheKey::increment(HCK::DEPARTURES_FAILURE);
193210
throw new HafasException($exception->getMessage());
194211
}
195212

196213
if (!$response->ok()) {
214+
CacheKey::increment(HCK::DEPARTURES_NOT_OK);
197215
throw new HafasException(__('messages.exception.generalHafas'));
198216
}
199217

218+
CacheKey::increment(HCK::DEPARTURES_SUCCESS);
200219
return json_decode($response->body(), false, 512, JSON_THROW_ON_ERROR);
201220
}
202221

@@ -328,13 +347,20 @@ public static function getStation(
328347
* @throws HafasException
329348
*/
330349
private static function fetchStation(int $ibnr): Station {
331-
$response = self::getHttpClient()->get("/stops/$ibnr");
350+
try {
351+
$response = self::getHttpClient()->get("/stops/$ibnr");
352+
} catch (Exception $exception) {
353+
CacheKey::increment(HCK::STOPS_FAILURE);
354+
throw new HafasException($exception->getMessage());
355+
}
332356

333357
if (!$response->ok()) {
358+
CacheKey::increment(HCK::STOPS_NOT_OK);
334359
throw new HafasException($response->reason());
335360
}
336361

337362
$data = json_decode($response->body());
363+
CacheKey::increment(HCK::STOPS_SUCCESS);
338364
return Station::updateOrCreate([
339365
'ibnr' => $data->id
340366
], [
@@ -349,20 +375,28 @@ private static function fetchStation(int $ibnr): Station {
349375
* @throws HafasException|JsonException
350376
*/
351377
public static function fetchRawHafasTrip(string $tripId, string $lineName) {
352-
$tripResponse = self::getHttpClient()->get("trips/" . rawurlencode($tripId), [
353-
'lineName' => $lineName,
354-
'polyline' => 'true',
355-
'stopovers' => 'true'
356-
]);
378+
try {
379+
$tripResponse = self::getHttpClient()->get("trips/" . rawurlencode($tripId), [
380+
'lineName' => $lineName,
381+
'polyline' => 'true',
382+
'stopovers' => 'true'
383+
]);
384+
} catch (Exception $exception) {
385+
CacheKey::increment(HCK::TRIPS_FAILURE);
386+
throw new HafasException(__('messages.exception.generalHafas'));
387+
}
357388

358389
if ($tripResponse->ok()) {
390+
CacheKey::increment(HCK::TRIPS_SUCCESS);
359391
return json_decode($tripResponse->body(), false, 512, JSON_THROW_ON_ERROR);
360392
}
361393
//sometimes HAFAS returnes 502 Bad Gateway
362394
if ($tripResponse->status() === 502) {
395+
CacheKey::increment(HCK::TRIPS_502);
363396
Log::error('Cannot fetch trip with id: ' . $tripId);
364397
throw new HafasException(__('messages.exception.hafas.502'));
365398
}
399+
CacheKey::increment(HCK::TRIPS_NOT_OK);
366400
Log::error('Unknown HAFAS Error (fetchRawHafasTrip)', [
367401
'status' => $tripResponse->status(),
368402
'body' => $tripResponse->body()

app/Listeners/RemoveAbsentWebhooksListener.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
use App\Helpers\CacheKey;
66
use App\Models\Webhook;
7-
use Illuminate\Support\Facades\Cache;
87
use Illuminate\Support\Facades\Log;
98
use Spatie\WebhookServer\Events\WebhookCallFailedEvent;
109

@@ -21,6 +20,6 @@ public function handle(WebhookCallFailedEvent $event) {
2120
"webhookId" => $webhookId,
2221
"userId" => $event->headers["X-Trwl-User-Id"]
2322
]);
24-
Cache::increment(CacheKey::WEBHOOK_ABSENT);
23+
CacheKey::increment(CacheKey::WEBHOOK_ABSENT);
2524
}
2625
}

app/Observers/StatusObserver.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,11 @@
1010
use App\Notifications\StatusLiked;
1111
use App\Notifications\UserJoinedConnection;
1212
use Illuminate\Notifications\DatabaseNotification;
13-
use Illuminate\Support\Facades\Cache;
1413

1514
class StatusObserver
1615
{
1716
public function created(Status $status): void {
18-
Cache::increment(CacheKey::STATUS_CREATED);
17+
CacheKey::increment(CacheKey::STATUS_CREATED);
1918
MentionHelper::createMentions($status);
2019
}
2120

@@ -24,7 +23,7 @@ public function updated(Status $status): void {
2423
}
2524

2625
public function deleted(Status $status): void {
27-
Cache::increment(CacheKey::STATUS_DELETED);
26+
CacheKey::increment(CacheKey::STATUS_DELETED);
2827

2928
WebhookController::sendStatusWebhook(
3029
status: $status,

app/Observers/UserObserver.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,15 @@
66
use App\Models\User;
77
use App\Notifications\StatusLiked;
88
use Illuminate\Notifications\DatabaseNotification;
9-
use Illuminate\Support\Facades\Cache;
109

1110
class UserObserver
1211
{
1312
public function created(User $user): void {
14-
Cache::increment(CacheKey::USER_CREATED);
13+
CacheKey::increment(CacheKey::USER_CREATED);
1514
}
1615

1716
public function deleted(User $user): void {
18-
Cache::increment(CacheKey::USER_DELETED);
17+
CacheKey::increment(CacheKey::USER_DELETED);
1918

2019
//delete all notifications for this user (there is no cascade delete)
2120
DatabaseNotification::where('notifiable_id', $user->id)

app/Providers/PrometheusServiceProvider.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace App\Providers;
44

55
use App\Helpers\CacheKey;
6+
use App\Helpers\HCK;
67
use App\Models\PolyLine;
78
use App\Models\Trip;
89
use Illuminate\Support\Facades\Cache;
@@ -93,6 +94,27 @@ public function register() {
9394
return $this->getJobsByDisplayName("failed_jobs");
9495
});
9596

97+
Prometheus::addGauge("failed_hafas_requests_count")
98+
->helpText("How many hafas requests have failed?")
99+
->labels(["request_name"])
100+
->value(function() {
101+
return $this->getHafasByType(HCK::getFailures());
102+
});
103+
104+
Prometheus::addGauge("not_ok_hafas_requests_count")
105+
->helpText("How many hafas requests are not ok?")
106+
->labels(["request_name"])
107+
->value(function() {
108+
return $this->getHafasByType(HCK::getNotOks());
109+
});
110+
111+
Prometheus::addGauge("succeeded_hafas_requests_count")
112+
->helpText("How many hafas requests have succeeded?")
113+
->labels(["request_name"])
114+
->value(function() {
115+
return $this->getHafasByType(HCK::getSuccesses());
116+
});
117+
96118
Prometheus::addGauge("completed_jobs_count")
97119
->helpText("How many jobs are done? Old items from queue monitor table are deleted after 7 days.")
98120
->labels(["job_name", "status", "queue"])
@@ -192,4 +214,13 @@ public static function getJobsByDisplayName(string $tableName): array {
192214
array_values($counts)
193215
);
194216
}
217+
218+
private function getHafasByType(array $getFailures): array {
219+
$values = [];
220+
foreach ($getFailures as $key => $name) {
221+
$values[$name] = Cache::get($key, 0);
222+
}
223+
224+
return array_map(fn($value, $key) => [$value, [$key]], $values, array_keys($values));
225+
}
195226
}

0 commit comments

Comments
 (0)