PluginProbe
Search Atlas SEO – OTTO AI SEO Automation for WordPress / trunk
Search Atlas SEO – OTTO AI SEO Automation for WordPress vtrunk
2.6.26 2.6.25 2.6.24 2.6.23 2.6.22 2.6.21 2.6.20 2.6.19 2.6.18 2.6.17 2.6.16 2.6.15 2.6.14 2.6.13 2.6.12 2.6.11 2.6.10 2.6.9 2.6.8 2.6.7 2.6.6 2.6.5 2.6.4 2.6.3 2.5.23 All 138 releases
metasync / telemetry / class-request_monitor.php

class-request_monitor.php in Search Atlas SEO – OTTO AI SEO Automation for WordPress trunk, at telemetry/class-request_monitor.php

306 lines 8.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // If this file is called directly, abort.
3 if (!defined('ABSPATH')) {
4 exit;
5 }
6
7 require_once __DIR__ . '/privacy.php';
8
9 /**
10 * Request monitoring
11 *
12 * */
13
14 class Metasync_Telemetry_Request_Monitor {
15
16 # telemetry manager
17 private $telemetry_manager;
18
19 # construct
20 function __construct(){
21 $this->telemetry_manager = Metasync_Telemetry_Manager::get_instance();
22 }
23
24 /**
25 * Get current timestamp for logging
26 */
27 private function log_timestamp() {
28 return current_time('mysql');
29 }
30
31 # uri strings
32
33 # These are sections of the uri to look for in a request
34 # prevents logging unauthorized requests
35 protected $loggable_uri_strings = [
36 'metasync', 'searchatlas'
37 ];
38
39
40 /**
41 * Check Loggable URI
42 * This method helps us check that the uri is permitted
43 * Otherwise it returns fals
44 *
45 */
46 function log_uri_permitted($uri) {
47
48 # Get permitted URI strings
49 $permitted_strings = $this->loggable_uri_strings;
50
51 # If an asterisk is used, allow all
52 if ($permitted_strings === '*') {
53 return true;
54 }
55
56 # Check if any string is in the URI
57 foreach ($permitted_strings as $string) {
58 if (strpos($uri, $string) !== false) {
59 return true; # Found a match
60 }
61 }
62
63 # Return false for no matches
64 return false;
65 }
66
67 # @section
68 # Monitors Incoming and Outgoing Request Data
69
70 # let's monitor outgoing logs
71 function api_monitor_outgoing($preempt, $args, $url){
72
73 if (metasync_telemetry_is_disabled()) {
74 return $preempt;
75 }
76
77 # ignore wp chron requests
78 if(strpos($url, 'wp-cron.php') !== false){
79 return $preempt;
80 }
81
82 # check that the route is permitted for logging
83 if ( empty($url) || $this->log_uri_permitted($url) == False ){
84 return $preempt;
85 }
86
87 # prepare the request object
88 $request = [
89 'timestamp' => $this->log_timestamp(),
90 'type' => 'outgoing_request',
91 'method' => $args['method'] ?? 'undefined',
92 'request_url' => metasync_telemetry_request_path($url),
93 'args' => $this->sanitize_args($args)
94 ];
95
96 # send the request with telemetry manager
97 $this->telemetry_manager->send_message('Outgoing Request', 'info', $request);
98
99
100 # Return preempt to allow the request to continue
101 return $preempt;
102
103 }
104
105 # monitor incoming
106 function api_monitor_incoming($result, $server, $request){
107
108 if (metasync_telemetry_is_disabled()) {
109 return $result;
110 }
111
112 # check that the route is permitted for logging
113 if ( empty($request->get_route()) || $this->log_uri_permitted($request->get_route()) == False ){
114 return $result;
115 }
116
117 # prepare the reuqest
118
119 $request_data = [
120 'timestamp' => $this->log_timestamp(),
121 'type' => 'incoming_request',
122 'method' => $request->get_method(),
123 'uri' => metasync_telemetry_request_path($request->get_route())
124 ];
125
126 $this->telemetry_manager->send_message('Incoming Request', 'info', $request_data);
127
128
129 # Return result to allow the request to continue
130 return $result;
131 }
132
133 # @section
134 # Monitors the Request Responses
135 # Helps checking for errors
136
137 # monitor the response to an outgoing API call
138 # function monitor_outgoing_response($response, $context, $url, $parsed_args){
139 function monitor_outgoing_response($response, $parsed_args, $url){
140 if (metasync_telemetry_is_disabled()) {
141 return $response;
142 }
143
144 # Skip logging for wp-cron requests
145 if (strpos($url, 'wp-cron.php') !== false) {
146 return $response;
147 }
148
149 # check that the route is permitted for logging
150 if ( empty($url) || $this->log_uri_permitted($url) == False ){
151 return $response;
152 }
153
154 # request data
155 $response_data = [
156 'timestamp' => $this->log_timestamp(),
157 'type' => 'outgoing_response',
158 'status_code' => $response['response']['code'] ?? '',
159 'url' => metasync_telemetry_request_path($url),
160 'response_data' => $this->sanitize_outgoing_response($response),
161 'args' => $this->sanitize_args($parsed_args)
162 ];
163
164 #return the response
165 $this->telemetry_manager->send_message('Outgoing Response', 'info', $response_data);
166
167
168 # Return response to allow it to continue
169 return $response;
170 }
171
172 # monitor the response to an incoming api call
173 function monitor_incoming_response($response, $server, $request){
174 if (metasync_telemetry_is_disabled()) {
175 return $response;
176 }
177
178 # check that the route is permitted for logging
179 if ( empty($request->get_route()) || $this->log_uri_permitted($request->get_route()) == False ){
180 return $response;
181 }
182
183 # prepare the response object
184 $response_object = array(
185 'timestamp' => $this->log_timestamp(),
186 'type' => 'incoming_response',
187 'status_code' => $response->get_status() ?? '',
188 'url' => metasync_telemetry_request_path($request->get_route()),
189 'method' => $request->get_method(),
190 'response_data' => $this->sanitize_response_data($response),
191 'request_data' => $this->sanitize_request_data($request)
192 );
193
194 # let record the response
195
196 $this->telemetry_manager->send_message('Incoming Response', 'info', $response_object);
197
198 # Return response to allow it to continue
199 return $response;
200
201 }
202
203 /**
204 * Sanitize WP_REST_Response object for serialization
205 *
206 * @param mixed $response The response object
207 * @return array Sanitized response data
208 */
209 private function sanitize_response_data($response) {
210 if (!is_object($response)) {
211 return is_array($response) ? $response : array();
212 }
213
214 return array(
215 'status' => method_exists($response, 'get_status') ? $response->get_status() : null
216 );
217 }
218
219 /**
220 * Sanitize WP_REST_Request object for serialization
221 *
222 * @param mixed $request The request object
223 * @return array Sanitized request data
224 */
225 private function sanitize_request_data($request) {
226 if (!is_object($request)) {
227 return is_array($request) ? $request : array();
228 }
229
230 return array(
231 'method' => method_exists($request, 'get_method') ? $request->get_method() : null,
232 'route' => method_exists($request, 'get_route')
233 ? metasync_telemetry_request_path($request->get_route())
234 : null
235 );
236 }
237
238 /**
239 * Sanitize outgoing HTTP response for serialization
240 *
241 * @param array $response The HTTP response array
242 * @return array Sanitized response data
243 */
244 private function sanitize_outgoing_response($response) {
245 if (!is_array($response)) {
246 return $response;
247 }
248
249 $sanitized = array();
250
251 // Safely extract response data
252 if (isset($response['response'])) {
253 $sanitized['response'] = array(
254 'code' => $response['response']['code'] ?? null,
255 'message' => $response['response']['message'] ?? null
256 );
257 }
258
259 return $sanitized;
260 }
261
262 /**
263 * Sanitize HTTP request arguments for serialization
264 *
265 * @param array $args The HTTP request arguments
266 * @return array Sanitized arguments
267 */
268 private function sanitize_args($args) {
269 if (!is_array($args)) {
270 return $args;
271 }
272
273 $sanitized = array();
274
275 // Only include safe, serializable data
276 $safe_keys = array('method', 'timeout', 'redirection', 'httpversion', 'user-agent', 'reject_unsafe_urls', 'blocking', 'sslverify', 'stream', 'filename', 'decompress');
277
278 foreach ($safe_keys as $key) {
279 if (isset($args[$key])) {
280 $sanitized[$key] = $args[$key];
281 }
282 }
283
284 return $sanitized;
285 }
286
287 /**
288 * @see monitor_api_calls
289 *
290 */
291 function monitor_api_calls(){
292 # log incoming requests
293 add_filter('rest_pre_dispatch', [$this, 'api_monitor_incoming'],10, 3);
294
295 # add hook to monitor outgoing api requests
296 add_filter('pre_http_request', [$this, 'api_monitor_outgoing'], 1, 3);
297
298 # Hook to monitor outgoing API responses
299 add_action('http_response', [$this, 'monitor_outgoing_response'], 10, 4);
300
301 # Monitor incoming request responses
302 add_filter('rest_post_dispatch', [$this, 'monitor_incoming_response'], 10, 3);
303
304 }
305 }
306