-
Notifications
You must be signed in to change notification settings - Fork 23
/
RaygunClientFactory.php
176 lines (155 loc) · 5.64 KB
/
RaygunClientFactory.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
<?php
namespace SilverStripe\Raygun;
use GuzzleHttp\Client;
use LogicException;
use Psr\SimpleCache\CacheInterface;
use Raygun4php\RaygunClient;
use Raygun4php\Transports\GuzzleAsync;
use SilverStripe\Control\Director;
use SilverStripe\Core\Config\Config;
use SilverStripe\Core\Environment;
use SilverStripe\Core\Flushable;
use SilverStripe\Core\Injector\Factory;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Core\Path;
class RaygunClientFactory implements Factory, Flushable
{
use CustomAppKeyProvider;
/**
* The environment variable used to assign the Raygun api key
*
* @var string
*/
const RAYGUN_APP_KEY_NAME = 'SS_RAYGUN_APP_KEY';
/**
* @var Raygun4php\RaygunClient
*/
protected $client;
/**
* Wrapper to get the Raygun API key from the .env file to pass through to
* the Raygun client.
*
* {@inheritdoc}
*/
public function create($service, array $params = [])
{
// extract api key from .env file
$apiKey = $this->getCustomRaygunAppKey() ?? (string) Environment::getEnv(self::RAYGUN_APP_KEY_NAME);
// log error to warn user that exceptions will not be logged to Raygun
if (empty($apiKey) && !Director::isDev()) {
$name = self::RAYGUN_APP_KEY_NAME;
user_error("You need to set the {$name} environment variable in order to log to Raygun.", E_USER_WARNING);
}
// check if user tracking is enabled
$disableTracking = Config::inst()->get(
RaygunClient::class,
'disable_user_tracking'
);
$disableTracking = is_bool($disableTracking) ? $disableTracking : false;
// Setup new client in the way that is best for the current SDK version.
if (substr(ltrim(static::getSdkVersion(), 'v'), 0, 2) === '1.') {
$this->createForV1($apiKey, $disableTracking, $params);
} else {
$this->createForV2($apiKey, $disableTracking, $params);
}
$this->filterSensitiveData();
return $this->client;
}
protected function createForV1($apiKey, $disableTracking, $params)
{
// Instantiate actual client
$this->client = new RaygunClient(
$apiKey,
true,
false,
$disableTracking
);
// Set proxy
if (!empty($params['proxyHost'])) {
$proxy = $params['proxyHost'];
if (!empty($params['proxyPort'])) {
$proxy .= ':' . $params['proxyPort'];
}
$this->client->setProxy($proxy);
}
}
protected function createForV2($apiKey, $disableTracking, $params)
{
// Prepare transport config.
$transportConfig = [
'base_uri' => 'https://api.raygun.com',
'timeout' => 2.0,
'headers' => [
'X-ApiKey' => $apiKey,
],
];
// Set proxy
if (!empty($params['proxyHost'])) {
$proxy = $params['proxyHost'];
if (!empty($params['proxyPort'])) {
$proxy .= ':' . $params['proxyPort'];
}
$transportConfig['proxy'] = $proxy;
}
// Create raygun client using async transport.
$transport = new GuzzleAsync(
new Client($transportConfig)
);
$this->client = new RaygunClient($transport, $disableTracking);
// Ensure asynchronous requests are given time to finish.
register_shutdown_function([$transport, 'wait']);
}
protected function filterSensitiveData()
{
// Filter sensitive data out of server variables
$this->client->setFilterParams([
'/SS_DATABASE_USERNAME/' => true,
'/SS_DEFAULT_ADMIN_USERNAME/' => true,
'/KEY/i' => true,
'/TOKEN/i' => true,
'/PASSWORD/i' => true,
'/SECRET/i' => true,
sprintf('/%s/', self::RAYGUN_APP_KEY_NAME) => true,
'/HTTP_AUTHORIZATION/' => true,
'/PHP_AUTH_PW/' => true,
'/HTTP_COOKIE/' => true,
'Authorization' => true,
'Cookie' => true,
]);
}
/**
* Get the currently installed version of the raygun4php package according to composer.lock
*
* @return string
*/
public static function getSdkVersion()
{
$cache = Injector::inst()->get(CacheInterface::class . '.raygunCache');
// If the SDK version isn't cached, get it from the composer.lock file.
// Note that this is called before flushing has occurred - if we're flushing, bypass the cache for now.
if (Director::isManifestFlushed() || !$version = $cache->get('raygun4phpVersion')) {
$composerLockRaw = file_get_contents(Path::join(Director::baseFolder(), 'composer.lock'));
if (!$composerLockRaw) {
throw new LogicException('composer.lock file is missing.');
}
$packageList = json_decode($composerLockRaw, true)['packages'];
foreach ($packageList as $package) {
if ($package['name'] === 'mindscape/raygun4php') {
$version = $package['version'];
break;
}
}
if (!$version) {
throw new LogicException('mindscape/raygun4php not found in composer.lock');
}
// Cache the SDK version so we don't have to do this every request.
$cache->set('raygun4phpVersion', $version);
}
return $version;
}
public static function flush()
{
$cache = Injector::inst()->get(CacheInterface::class . '.raygunCache');
$cache->clear();
}
}