Skip to content

Commit 778664b

Browse files
committed
Added new Beacon handling code
1 parent dd2e77d commit 778664b

File tree

14 files changed

+446
-0
lines changed

14 files changed

+446
-0
lines changed

.env.example

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ DB_PREFIX=null
1414
CACHE_DRIVER=file
1515
SESSION_DRIVER=file
1616
QUEUE_DRIVER=sync
17+
18+
CACHET_BEACON=true
1719
CACHET_EMOJI=false
1820

1921
MAIL_DRIVER=smtp
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
/*
4+
* This file is part of Cachet.
5+
*
6+
* (c) Alt Three Services Limited
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace CachetHQ\Cachet\Bus\Handlers\Jobs\System;
13+
14+
use CachetHQ\Cachet\Integrations\Contracts\Beacon;
15+
use CachetHQ\Cachet\Bus\Jobs\System\SendBeaconJob;
16+
use Exception;
17+
18+
/**
19+
* This is the send beacon job handler.
20+
*
21+
* @author James Brooks <james@alt-three.com>
22+
*/
23+
class SendBeaconJobHandler
24+
{
25+
/**
26+
* The beacon instance.
27+
*
28+
* @var \CachetHQ\Cachet\Integrations\Contracts\Beacon
29+
*/
30+
protected $beacon;
31+
32+
/**
33+
* Create a new send beacon job handler instance.
34+
*
35+
* @param \CachetHQ\Cachet\Integrations\Contracts\Beacon $beacon
36+
*
37+
* @return void
38+
*/
39+
public function __construct(Beacon $beacon)
40+
{
41+
$this->beacon = $beacon;
42+
}
43+
44+
/**
45+
* Handle the send beacon job.
46+
*
47+
* @param \CachetHQ\Cachet\Bus\Jobs\SendBeaconJob $job
48+
*
49+
* @return void
50+
*/
51+
public function handle(SendBeaconJob $job)
52+
{
53+
// Don't send anything if the installation explicitly prevents us.
54+
if (!$this->beacon->enabled()) {
55+
return;
56+
}
57+
58+
try {
59+
$this->beacon->send();
60+
} catch (Exception $e) {
61+
//
62+
}
63+
}
64+
}

app/Bus/Jobs/System/SendBeaconJob.php

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
/*
4+
* This file is part of Cachet.
5+
*
6+
* (c) Alt Three Services Limited
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace CachetHQ\Cachet\Bus\Jobs\System;
13+
14+
use Illuminate\Contracts\Queue\ShouldQueue;
15+
16+
/**
17+
* This is the send beacon job.
18+
*
19+
* @author James Brooks <james@alt-three.com>
20+
*/
21+
final class SendBeaconJob implements ShouldQueue
22+
{
23+
//
24+
}
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
/*
4+
* This file is part of Cachet.
5+
*
6+
* (c) Alt Three Services Limited
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace CachetHQ\Cachet\Console\Commands;
13+
14+
use CachetHQ\Cachet\Bus\Jobs\System\SendBeaconJob;
15+
use Illuminate\Console\Command;
16+
17+
/**
18+
* This is the beacon command class.
19+
*
20+
* @author James Brooks <james@alt-three.com>
21+
*/
22+
class BeaconCommand extends Command
23+
{
24+
/**
25+
* The console command name.
26+
*
27+
* @var string
28+
*/
29+
protected $name = 'cachet:beacon';
30+
31+
/**
32+
* The console command description.
33+
*
34+
* @var string
35+
*/
36+
protected $description = 'Send a beacon to the Cachet server.';
37+
38+
/**
39+
* Execute the console command.
40+
*
41+
* @return void
42+
*/
43+
public function fire()
44+
{
45+
dispatch(new SendBeaconJob());
46+
}
47+
}

app/Console/Kernel.php

+4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace CachetHQ\Cachet\Console;
1313

14+
use CachetHQ\Cachet\Console\Commands\BeaconCommand;
1415
use CachetHQ\Cachet\Console\Commands\DemoMetricPointSeederCommand;
1516
use CachetHQ\Cachet\Console\Commands\DemoSeederCommand;
1617
use Illuminate\Console\Scheduling\Schedule;
@@ -24,6 +25,7 @@ class Kernel extends ConsoleKernel
2425
* @var array
2526
*/
2627
protected $commands = [
28+
BeaconCommand::class,
2729
DemoMetricPointSeederCommand::class,
2830
DemoSeederCommand::class,
2931
];
@@ -38,5 +40,7 @@ class Kernel extends ConsoleKernel
3840
protected function schedule(Schedule $schedule)
3941
{
4042
$schedule->command('queue:work --sleep=3 --tries=3')->everyMinute();
43+
44+
$schedule->command('cachet:beacon')->twiceDaily('00:00', '12:00');
4145
}
4246
}

app/Foundation/Providers/IntegrationServiceProvider.php

+17
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@
1111

1212
namespace CachetHQ\Cachet\Foundation\Providers;
1313

14+
use CachetHQ\Cachet\Integrations\Contracts\Beacon as BeaconContract;
1415
use CachetHQ\Cachet\Integrations\Contracts\Credits as CreditsContract;
1516
use CachetHQ\Cachet\Integrations\Contracts\Feed as FeedContract;
1617
use CachetHQ\Cachet\Integrations\Contracts\Releases as ReleasesContract;
1718
use CachetHQ\Cachet\Integrations\Contracts\System as SystemContract;
19+
use CachetHQ\Cachet\Integrations\Core\Beacon;
1820
use CachetHQ\Cachet\Integrations\Core\Credits;
1921
use CachetHQ\Cachet\Integrations\Core\Feed;
2022
use CachetHQ\Cachet\Integrations\Core\System;
@@ -36,13 +38,28 @@ class IntegrationServiceProvider extends ServiceProvider
3638
*/
3739
public function register()
3840
{
41+
$this->registerBeacon();
3942
$this->registerCredits();
4043
$this->registerFeed();
4144
$this->registerSystem();
4245

4346
$this->registerReleases();
4447
}
4548

49+
/**
50+
* Register the beacon class.
51+
*
52+
* @return void
53+
*/
54+
protected function registerBeacon()
55+
{
56+
$this->app->singleton(BeaconContract::class, function ($app) {
57+
$config = $app['config'];
58+
59+
return new Beacon($config);
60+
});
61+
}
62+
4663
/**
4764
* Register the credits class.
4865
*

app/Integrations/Contracts/Beacon.php

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
/*
4+
* This file is part of Cachet.
5+
*
6+
* (c) Alt Three Services Limited
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace CachetHQ\Cachet\Integrations\Contracts;
13+
14+
/**
15+
* This is the beacon interface.
16+
*
17+
* @author James Brooks <james@alt-three.com>
18+
*/
19+
interface Beacon
20+
{
21+
/**
22+
* Has the install enabled Cachet beacon?
23+
*
24+
* @return bool
25+
*/
26+
public function enabled();
27+
28+
/**
29+
* Send a beacon to our server.
30+
*
31+
* @return void
32+
*/
33+
public function send();
34+
}

app/Integrations/Core/Beacon.php

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<?php
2+
3+
/*
4+
* This file is part of Cachet.
5+
*
6+
* (c) Alt Three Services Limited
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace CachetHQ\Cachet\Integrations\Core;
13+
14+
use CachetHQ\Cachet\Integrations\Contracts\Beacon as BeaconContract;
15+
use CachetHQ\Cachet\Models\Component;
16+
use CachetHQ\Cachet\Models\Incident;
17+
use CachetHQ\Cachet\Models\Metric;
18+
use CachetHQ\Cachet\Models\User;
19+
use CachetHQ\Cachet\Settings\Repository as Setting;
20+
use Exception;
21+
use GuzzleHttp\Client;
22+
use Illuminate\Contracts\Config\Repository;
23+
24+
/**
25+
* This is the beacon class.
26+
*
27+
* @author James Brooks <james@alt-three.com>
28+
*/
29+
class Beacon implements BeaconContract
30+
{
31+
/**
32+
* The beacon url.
33+
*
34+
* @var string
35+
*/
36+
const URL = 'https://cachethq.io/beacon';
37+
38+
/**
39+
* The illuminate config instance.
40+
*
41+
* @var \Illuminate\Contracts\Config\Repository
42+
*/
43+
protected $config;
44+
45+
/**
46+
* Create a new beacon instance.
47+
*
48+
* @param \Illuminate\Contracts\Config\Repository $config
49+
*
50+
* @return void
51+
*/
52+
public function __construct(Repository $config)
53+
{
54+
$this->config = $config;
55+
}
56+
57+
/**
58+
* Has the install enabled Cachet beacon?
59+
*
60+
* @return bool
61+
*/
62+
public function enabled()
63+
{
64+
return $this->config->get('cachet.beacon');
65+
}
66+
67+
/**
68+
* Send a beacon to our server.
69+
*
70+
* @return void
71+
*/
72+
public function send()
73+
{
74+
// We don't want any accidental sending of beacons if the installation has explicitly said no.
75+
if (!$this->enabled()) {
76+
return;
77+
}
78+
79+
if (!($contactEmail = User::admins()->active()->first()->email)) {
80+
$contactEmail = null;
81+
}
82+
83+
$setting = app(Setting::class);
84+
85+
if (!$installId = $setting->get('install_id', null)) {
86+
$installId = sha1(str_random(20));
87+
88+
$setting->set('install_id', $installId);
89+
}
90+
91+
$payload = [
92+
'install_id' => $installId,
93+
'version' => CACHET_VERSION,
94+
'docker' => $this->config->get('cachet.is_docker'),
95+
'database' => $this->config->get('database.default'),
96+
'contact_email' => $contactEmail,
97+
'data' => [
98+
'components' => Component::all()->count(),
99+
'incidents' => Incident::all()->count(),
100+
'metrics' => Metric::all()->count(),
101+
'users' => User::all()->count(),
102+
],
103+
];
104+
105+
try {
106+
$client = new Client();
107+
$client->post(self::URL, [
108+
'headers' => ['Accept' => 'application/json', 'User-Agent' => defined('CACHET_VERSION') ? 'cachet/'.constant('CACHET_VERSION') : 'cachet'],
109+
'json' => $payload,
110+
]);
111+
} catch (Exception $e) {
112+
// TODO: Log a warning that the beacon could not be sent.
113+
}
114+
}
115+
}

0 commit comments

Comments
 (0)