PluginProbe
DecaLog / 4.4.0
DecaLog v4.4.0
3.0.2 3.1.0 3.10.0 3.2.0 3.3.0 3.4.0 3.4.1 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.6.3 3.7.0 3.7.1 3.8.0 3.9.0 3.9.1 4.0.0 4.1.0 4.2.0 4.3.0 4.3.1 4.4.0 4.5.0 All 75 releases
decalog / includes / features / class-loggers.php

class-loggers.php in DecaLog 4.4.0, at includes/features/class-loggers.php

370 lines 12.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Loggers list
4 *
5 * Lists all available loggers.
6 *
7 * @package Features
8 * @author Pierre Lannoy <https://pierre.lannoy.fr/>.
9 * @since 1.0.0
10 */
11
12 namespace Decalog\Plugin\Feature;
13
14 use Decalog\System\Environment;
15 use Decalog\System\Option;
16 use Decalog\Plugin\Feature\Log;
17 use Decalog\Plugin\Feature\PrivacyOptions;
18 use Feather\Icons;
19
20 if ( ! class_exists( 'WP_List_Table' ) ) {
21 require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
22 }
23
24 /**
25 * Define the loggers list functionality.
26 *
27 * Lists all available loggers.
28 *
29 * @package Features
30 * @author Pierre Lannoy <https://pierre.lannoy.fr/>.
31 * @since 1.0.0
32 */
33 class Loggers extends \WP_List_Table {
34
35 /**
36 * The loggers options handler.
37 *
38 * @since 1.0.0
39 * @var array $loggers The loggers list.
40 */
41 private $loggers = [];
42
43 /**
44 * The HandlerTypes instance.
45 *
46 * @since 1.0.0
47 * @var HandlerTypes $handler_types The handlers types.
48 */
49 private $handler_types;
50
51 /**
52 * The ProcessorTypes instance.
53 *
54 * @since 1.0.0
55 * @var HandlerTypes $processor_types The processors types.
56 */
57 private $processor_types;
58
59 /**
60 * Initialize the class and set its properties.
61 *
62 * @since 1.0.0
63 */
64 public function __construct() {
65 parent::__construct(
66 [
67 'singular' => 'logger',
68 'plural' => 'loggers',
69 'ajax' => true,
70 ]
71 );
72 global $wp_version;
73 if ( version_compare( $wp_version, '4.2-z', '>=' ) && $this->compat_fields && is_array( $this->compat_fields ) ) {
74 array_push( $this->compat_fields, 'all_items' );
75 }
76 $this->loggers = [];
77 foreach ( Option::network_get( 'loggers' ) as $key => $logger ) {
78 $logger['uuid'] = $key;
79 $this->loggers[] = $logger;
80 }
81 $this->handler_types = new HandlerTypes();
82 $this->processor_types = new ProcessorTypes();
83 }
84
85 /**
86 * Default column formatter.
87 *
88 * @param array $item The current item.
89 * @param string $column_name The current column name.
90 * @return string The cell formatted, ready to print.
91 * @since 1.0.0
92 */
93 protected function column_default( $item, $column_name ) {
94 return $item[ $column_name ];
95 }
96
97 /**
98 * "name" column formatter.
99 *
100 * @param array $item The current item.
101 * @return string The cell formatted, ready to print.
102 * @since 1.0.0
103 */
104 protected function column_name( $item ) {
105 $actions = [];
106 $edit = esc_url(
107 add_query_arg(
108 [
109 'page' => 'decalog-settings',
110 'action' => 'form-edit',
111 'tab' => 'loggers',
112 'uuid' => $item['uuid'],
113 ],
114 admin_url( 'admin.php' )
115 )
116 );
117 $delete = esc_url(
118 add_query_arg(
119 [
120 'page' => 'decalog-settings',
121 'action' => 'form-delete',
122 'tab' => 'loggers',
123 'uuid' => $item['uuid'],
124 ],
125 admin_url( 'admin.php' )
126 )
127 );
128 $pause = esc_url(
129 add_query_arg(
130 [
131 'page' => 'decalog-settings',
132 'action' => 'pause',
133 'tab' => 'loggers',
134 'uuid' => $item['uuid'],
135 'nonce' => wp_create_nonce( 'decalog-logger-pause-' . $item['uuid'] ),
136 ],
137 admin_url( 'admin.php' )
138 )
139 );
140 $test = esc_url(
141 add_query_arg(
142 [
143 'page' => 'decalog-settings',
144 'action' => 'test',
145 'tab' => 'loggers',
146 'uuid' => $item['uuid'],
147 'nonce' => wp_create_nonce( 'decalog-logger-test-' . $item['uuid'] ),
148 ],
149 admin_url( 'admin.php' )
150 )
151 );
152 $start = esc_url(
153 add_query_arg(
154 [
155 'page' => 'decalog-settings',
156 'action' => 'start',
157 'tab' => 'loggers',
158 'uuid' => $item['uuid'],
159 'nonce' => wp_create_nonce( 'decalog-logger-start-' . $item['uuid'] ),
160 ],
161 admin_url( 'admin.php' )
162 )
163 );
164 $view = esc_url(
165 add_query_arg(
166 [
167 'page' => 'decalog-viewer',
168 'logger_id' => $item['uuid'],
169 ],
170 admin_url( 'admin.php' )
171 )
172 );
173 $tview = esc_url(
174 add_query_arg(
175 [
176 'page' => 'decalog-tviewer',
177 'logger_id' => $item['uuid'],
178 ],
179 admin_url( 'admin.php' )
180 )
181 );
182 $epview = esc_url(
183 add_query_arg(
184 [
185 'uuid' => $item['uuid'],
186 ],
187 site_url( '/wp-json/' . DECALOG_REST_NAMESPACE . '/metrics' )
188 )
189 );
190 $handler = $this->handler_types->get( $item['handler'] );
191 $icon = '<img style="width:38px;float:left;padding-right:6px;" src="' . $handler['icon'] . '" />';
192 if ( 'system' !== $handler['class'] ) {
193 $actions['edit'] = sprintf( '<a href="%s">' . decalog_esc_html__( 'Edit', 'decalog' ) . '</a>', $edit );
194 $actions['delete'] = sprintf( '<a href="%s">' . decalog_esc_html__( 'Remove', 'decalog' ) . '</a>', $delete );
195 if ( $item['running'] ) {
196 $actions['pause'] = sprintf( '<a href="%s">' . decalog_esc_html__( 'Pause', 'decalog' ) . '</a>', $pause );
197 } else {
198 $actions['start'] = sprintf( '<a href="%s">' . decalog_esc_html__( 'Start', 'decalog' ) . '</a>', $start );
199 }
200 if ( 'WordpressHandler' === $handler['id'] ) {
201 $actions['view'] = sprintf( '<a href="%s">' . decalog_esc_html__( 'View', 'decalog' ) . '</a>', $view );
202 }
203 if ( 'WordpressTracingHandler' === $handler['id'] ) {
204 $actions['view'] = sprintf( '<a href="%s">' . decalog_esc_html__( 'View', 'decalog' ) . '</a>', $tview );
205 }
206 if ( 'PrometheusMetricsEPHandler' === $handler['id'] ) {
207 $actions['epview'] = sprintf( '<a href="%s" target="_blank">' . decalog_esc_html__( 'View', 'decalog' ) . '</a>', $epview );
208 }
209 }
210 if ( $item['running'] && 'metrics' !== ( $this->handler_types->get( $item['handler'] ) )['class'] && 'tracing' !== ( $this->handler_types->get( $item['handler'] ) )['class'] ) {
211 $actions['test'] = sprintf( '<a href="%s">' . decalog_esc_html__( 'Send Test', 'decalog' ) . '</a>', $test );
212 }
213 return $icon . '&nbsp;' . sprintf( '<a href="%1$s">%2$s</a><br /><span style="color:silver">&nbsp;%3$s</span>%4$s', $edit, $item['name'], $handler['name'], $this->row_actions( $actions ) );
214 }
215
216 /**
217 * "status" column formatter.
218 *
219 * @param array $item The current item.
220 * @return string The cell formatted, ready to print.
221 * @since 1.0.0
222 */
223 protected function column_status( $item ) {
224 $running = '<span style="vertical-align: middle;font-size:10px;padding:2px 6px;display: inline-block;text-transform:uppercase;font-weight: bold;background-color:#4AA03E;color:#F9F9F9;border-radius:2px;cursor: default;word-break: break-word;">▶&nbsp;' . decalog_esc_html__( 'Running', 'decalog' ) . '</span>';
225 $paused = '<span style="vertical-align: middle;font-size:10px;padding:2px 6px;display: inline-block;text-transform:uppercase;font-weight: bold;background-color:#E0E0E0;color:#AAAAAA;border-radius:2px;cursor: default;word-break: break-word;">❙❙&nbsp;' . decalog_esc_html__( 'Paused', 'decalog' ) . '</span>';
226 return ( $item['running'] ? $running : $paused );
227 }
228
229 /**
230 * "details" column formatter.
231 *
232 * @param array $item The current item.
233 * @return string The cell formatted, ready to print.
234 * @since 1.0.0
235 */
236 protected function column_details( $item ) {
237 $result = '';
238 $class = ( $this->handler_types->get( $item['handler'] ) )['class'];
239 $list[] = '<span style="vertical-align: middle;font-size:9px;padding:2px 6px;text-transform:uppercase;font-weight: bold;background-color:#9999BB;color:#F9F9F9;border-radius:2px;cursor: default;word-break: break-word;">' . decalog_esc_html__( 'Standard', 'decalog' ) . '</span>';
240 foreach ( $item['processors'] as $processor ) {
241 $list[] = '<span style="vertical-align: middle;font-size:9px;padding:2px 6px;text-transform:uppercase;font-weight: bold;background-color:#9999BB;color:#F9F9F9;border-radius:2px;cursor: default;word-break: break-word;">' . str_replace( ' ', '&nbsp;', $this->processor_types->get( $processor )['name'] ) . '</span>';
242 }
243 if ( in_array( $class, [ 'metrics', 'tracing' ], true ) ) {
244 if ( isset( $item['configuration']['sampling'] ) ) {
245 $sampling = (float) ( ( (int) $item['configuration']['sampling'] ) / 10 );
246 if ( 1.0 <= $sampling ) {
247 $sampling = (string) ( ( (int) round( $sampling, 0 ) ) ) . '%';
248 } else {
249 $sampling = (string) ( ( (int) round( $sampling * 10, 0 ) ) ) . '';
250 }
251 $result .= '<span style="margin-bottom: 6px;vertical-align: middle;font-size:10px;display: inline-block;text-transform:uppercase;font-weight: 900;background-color:#FFFFFF;color:#5F656A;border-radius:2px;border: 1px solid #9999BB;border-radius:2px;cursor: default;word-break: break-word;">&nbsp;&nbsp;&nbsp;' . $sampling . '&nbsp;&nbsp;&nbsp;</span>';
252 }
253 if ( isset( $item['configuration']['profile'] ) ) {
254 switch ( $item['configuration']['profile'] ) {
255 case 550:
256 $level = decalog_esc_html__( 'Forced', 'decalog' ) . ' / ' . decalog_esc_html__( 'Development', 'decalog' );
257 break;
258 case 600:
259 $level = decalog_esc_html__( 'Forced', 'decalog' ) . ' / ' . decalog_esc_html__( 'Production', 'decalog' );
260 break;
261 default:
262 if ( 'production' === Environment::stage() ) {
263 $level = decalog_esc_html__( 'Automatic', 'decalog' ) . ' / ' . decalog_esc_html__( 'Production', 'decalog' );
264 } else {
265 $level = decalog_esc_html__( 'Automatic', 'decalog' ) . ' / ' . decalog_esc_html__( 'Development', 'decalog' );
266 }
267 }
268 $result .= '<br/><span style="vertical-align: middle;font-size:9px;padding:2px 6px;text-transform:uppercase;font-weight: bold;background-color:#9999BB;color:#F9F9F9;border-radius:2px;cursor: default;word-break: break-word;">' . str_replace( ' ', '&nbsp;', $level ) . '</span>';
269 }
270 }
271 if ( in_array( $class, [ 'alerting', 'logging', 'debugging', 'analytics' ], true ) ) {
272 $level = strtolower( Log::level_name( $item['level'] ) );
273 $result .= '<span style="margin-bottom: 6px;vertical-align: middle;font-size:10px;display: inline-block;text-transform:uppercase;font-weight: 900;background-color:' . EventTypes::$levels_colors[ $level ][0] . ';color:' . EventTypes::$levels_colors[ $level ][1] . ';border-radius:2px;border: 1px solid ' . EventTypes::$levels_colors[ $level ][1] . ';cursor: default;word-break: break-word;">&nbsp;&nbsp;&nbsp;' . $level . '&nbsp;&nbsp;&nbsp;</span>';
274 }
275 if ( in_array( $class, [ 'alerting', 'logging', 'debugging', 'analytics', 'tracing' ], true ) ) {
276 foreach ( PrivacyOptions::$options as $option ) {
277 if ( $item['privacy'][$option] ) {
278 $result .= '<img alt="' . PrivacyOptions::$options_names[ $option ] . '" title="' . PrivacyOptions::$options_names[ $option ] . '" style="width:16px;padding-left:6px;padding-top:6px;" src="' . Icons::get_base64( PrivacyOptions::$options_icons[ $option ], 'none', '#9999BB' ) . '" />';
279 }
280 }
281 $result .= '<br/>' . implode( ' ', $list );
282 }
283 return $result;
284 }
285
286 /**
287 * "minimal level" column formatter.
288 *
289 * @param array $item The current item.
290 * @return string The cell formatted, ready to print.
291 * @since 1.0.0
292 */
293 protected function column_type( $item ) {
294 return $this->handler_types->get_class_name( ( $this->handler_types->get( $item['handler'] ) )['class'] );
295 }
296
297 /**
298 * Enumerates columns.
299 *
300 * @return array The columns.
301 * @since 1.0.0
302 */
303 public function get_columns() {
304 $columns = [
305 'name' => decalog_esc_html__( 'Logger', 'decalog' ),
306 'status' => decalog_esc_html__( 'Status', 'decalog' ),
307 'type' => decalog_esc_html__( 'Type', 'decalog' ),
308 'details' => decalog_esc_html__( 'Settings', 'decalog' ),
309 ];
310 return $columns;
311 }
312
313 /**
314 * Enumerates hidden columns.
315 *
316 * @return array The hidden columns.
317 * @since 1.0.0
318 */
319 protected function get_hidden_columns() {
320 return [];
321 }
322
323 /**
324 * Enumerates sortable columns.
325 *
326 * @return array The sortable columns.
327 * @since 1.0.0
328 */
329 protected function get_sortable_columns() {
330 $sortable_columns = [
331 'name' => [ 'name', true ],
332 ];
333 return $sortable_columns;
334 }
335
336 /**
337 * Enumerates bulk actions.
338 *
339 * @return array The bulk actions.
340 * @since 1.0.0
341 */
342 public function get_bulk_actions() {
343 return [];
344 }
345
346 /**
347 * Prepares the list to be displayed.
348 *
349 * @since 1.0.0
350 */
351 public function prepare_items() {
352 $columns = $this->get_columns();
353 $hidden = $this->get_hidden_columns();
354 $sortable = $this->get_sortable_columns();
355 $this->_column_headers = [ $columns, $hidden, $sortable ];
356 $data = $this->loggers;
357 usort(
358 $data,
359 function ( $a, $b ) {
360 $orderby = ( ! is_null( filter_input( INPUT_GET, 'orderby', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) ) ) ? filter_input( INPUT_GET, 'orderby', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) : 'name';
361 $order = ( ! is_null( filter_input( INPUT_GET, 'order', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) ) ) ? filter_input( INPUT_GET, 'order', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) : 'desc';
362 $result = strcmp( strtolower( $a[ $orderby ] ), strtolower( $b[ $orderby ] ) );
363 return ( 'asc' === $order ) ? -$result : $result;
364 }
365 );
366 $this->items = $data;
367 }
368
369 }
370