La gente a menudo se queja de que WordPress es lento. Si esto es cierto o no, depende de muchos factores, pero si podemos ver los recursos del servidor dentro del panel de WordPress, entonces podemos dar una idea de qué tan bien está funcionando nuestra instalación de WordPress..
En este tutorial, crearemos un complemento para mostrar el estado del servidor, incluido el espacio en disco, los consumos de memoria, el uso de la CPU y el uso del proceso..
También aprenderemos sobre el caché de WordPress para evitar consultar estas métricas una y otra vez y también cubriremos los trabajos cron de WordPress para generar estos datos automáticamente.
El panel del administrador, de forma predeterminada, nos presenta un par de bloques llamados widgets. Éstos incluyen:
Los widgets se pueden reordenar por preferencia y se pueden mostrar u ocultar. En general, el panel de control es personalizable..
Como los widgets son muy flexibles y están disponibles en la primera pantalla de la pantalla del administrador, podemos usarlos para mostrar los recursos del servidor: estado del disco, uso de RAM, uso de la CPU e información del sistema operativo. Llamaremos a estos recursos "métricas" para abreviar.
A lo largo de todo esto, aprenderemos la API de Widgets de Dashboard y los roles y capacidades para que estos widgets estén disponibles para algunos usuarios, ya que los datos podrían ser confidenciales..
Para hacerlo, también aprenderemos algunos comandos básicos de Linux para extraer información del servidor y colocarlos en nuestro panel de control de widgets. Utilizaremos Transients API para almacenar en caché estos datos. Cronjobs se aprovechará para extraer automáticamente estos datos en lugar de obtenerlos a pedido en cada solicitud.
El trabajo de nuestro plugin está inspirado en Linux Dash..
Nuestro plugin soporta nueve tipos de métricas. Como resultado, tendremos nueve widgets de tablero.
Vamos a crear un plugin simple y lo llamamos Tablero del servidor. Comenzaremos con algunas cosas básicas. Un tradicional Hola Mundo te ayudará a tener la oportunidad de agregar un widget al panel.
Es facil, en realidad.
Creando una llamada de carpeta Tablero del servidor dentro wp-content / plugins
, y un archivo serverdashboard.php
. El diseño de la carpeta se ve así. Solo enfóquese en el archivo principal e ignore la ubicación, las pruebas, los widgets, etc..
Usa este código para serverdashboard.php
correr(); ?>Utilicé espacio de nombres
AX \ StatBoard
para evitar la colisión de nombres con diferentes complementos de clase, nombre de la función de los temas y otros complementos. correr
para registrar gancho o filtro con WordPress.wp_dashboard_setup
. Estos enlaces nos permiten acceder a la opción de personalización relacionada con Dashboard. Nos permite agregar o eliminar el widget del panel de WordPress. wp_add_dashboard_widget
para registrar un widget. Requiere argumentos en este orden:La mayoría de las veces, nos encontraremos con devoluciones de llamada como una sola función, una función anónima, una matriz de objetos y métodos, o una matriz de clases y métodos estáticos..Actualiza tu panel de control. Nuestro plugin muestra su widget. Observe la
carné de identidad
del elemento div widget.Vamos a avanzar en esto. Mostraremos un gráfico circular con algunos datos ficticios. Para mantenerlo simple, usaré la API de Google Chart. Lo usaremos extensivamente más adelante para las métricas del servidor porque es mejor visualizar este tipo de datos.
Si no te gusta Google Chart, puedes deshacerte de él y poner tu biblioteca de gráficos favorita. Recuerde que este es un tutorial, así que no se limite, use lo que le resulte más cómodo.!
Necesitamos cargar el script de Google Chart. Cambia tu correr()
Método para registrar un gancho más.
función pública ejecutar () add_action ('wp_dashboard_setup', array ($ this, 'add_dashboard_widgets')); add_action ('admin_enqueue_scripts', array ($ this, 'add_asset'));
admin_enqueue_scripts
es la acción que necesita conectar para agregar su propio script en el panel de administración. Agregaremos un método más llamado add_asset
en nuestra clase para manejar la carga de scripts. El implemento de add_asset
.
/ ** * Agregar javascript * / function add_asset () wp_enqueue_script ('google-chart', 'https://www.google.com/jsapi');Tenemos la biblioteca de cartas. Ahora tenemos que renderizarlo dentro de nuestro panel de control. Puedes jugar con Google Chart. Solo reutilizaremos su ejemplo ahora.
función add_dashboard_widgets () syslog (LOG_DEBUG, "Run"); wp_add_dashboard_widget ('hello_world_dashboard_widget', // Un Slug para identificar este widget 'Hello World', // función de título del widget () echo <<<'EOD' Hey, I'm the body of widget. Thanks for bring me to the life.Simplemente agregamos un elemento div más con id hello_piechart y renderizar el gráfico en ese elemento. A ver que tenemos ahora:Observe el ID del elemento widget.EOD; // función para mostrar el contenido del widget, estoy usando un cierre aquí);
Ahora que sabemos cómo agregar nuestro propio bloque de widgets al panel de control, y ahora que sabemos cómo obtener Google Chart para generar información, podemos combinar los dos para mostrar más información..
En la siguiente sección, aprenderemos cómo capturar las métricas del servidor y renderizar el contenido para cada tipo de métrica del servidor que hemos analizado anteriormente..
Al extraer las métricas del servidor, usaremos el comando de Linux para obtener esta información. En PHP, podemos usar backtick "o shell_exec para invocar un comando de shell, y recuperar la salida.
Podemos analizar la salida para obtener datos del servidor. Por ejemplo, para obtener el estado de uso del disco podemos usar el comando. df -h
. Conocemos el formato de salida, por lo que podemos analizarlo para obtener lo que queremos.
$ df = 'df -h'; $ df = explode ("\ n", $ df); if (is_array ($ df) && count ($ df)> = 2) array_shift ($ df); // Deshágase de la primera línea $ df = array_map (function ($ line) if (empty ($ line)) return NULL; $ segment = preg_split ('/ \ s + /', $ line); return array ( 'sistema de archivos' => $ segmento [0], 'tamaño' => $ segmento [1], 'usado' => $ segmento [2], 'disponible' => $ segmento [3], 'use_percent' => $ segmento [4],);, $ df); var_dump ($ df);
[command_we_run] | awk 'imprimir $ 1, $ 3,…'
. Dash Server Dashboard [master] ls -lh total 32 -rw-r - r-- 1 kureikain staff 2.6K 11 de abril 00:46 Server Dashboard.php drwxr-x-x 3 kureikain staff 102B Mar 29 01:27 bin - rw-r - r-- 1 personal de kureikain 98B 5 de abril 18:53 loader.js -rw-r - r-- 1 personal de kureikain 321B 29 de marzo de 01:27 phpunit.xml drwxr-xr-x 4 personal de kureikain 136B Mar 29 01:27 pruebas drwxr-xr-x 12 personal de kureikain 408B 13 de abril 17:37 widget -rw-r - r-- 1 personal de kureikain 1.1K 6 de abril 01:04 widget.php ☁ Server Dashboard [master] ls -lh | awk 'imprimir $ 3, $ 4, $ 5, $ 9' kureikain staff 2.6K Servidor kureikain staff 102B bin kureikain staff 98B loader.js kureikain staff 321B phpunit.xml kureikain staff 136B tests kureikain staff 408B widget kureikain staff 1.1K widget.phpComo puedes ver cada linea de
ls -la
contiene nueve campos:drwxr-xr-x 4 personal de kureikain 136B Mar 29 01:27 pruebasSeparando por espacios, estos 9 campos son:
awk 'imprimir $ 3, $ 4, $ 5, $ 9'
y verékureikain staff 136B tests
Por lo tanto, al utilizar awk podemos limpiar un poco más la salida antes de utilizar nuestra función de procesamiento de PHP.
Algunos comandos generan datos adicionales que no necesitamos; por lo tanto, requiere un poco de esfuerzo adicional con PHP para limpiarlo.
Por ejemplo:
[vagrant @ vagrant-centos64 ~] $ free -m total de buffers compartidos gratuitos utilizados en caché Mem: 589 537 51 0 8 271 - / + buffers / cache: 258 330 Swap: 255 0 255
libre -m
Nos muestra el uso de la memoria RAM con la memoria y el archivo de intercambio; sin embargo, incluye otras dos líneas con total / used / free y - / + buffers / cache que no necesitamos. -mi
cambiar. Ese interruptor permite usar el expreso regular para la búsqueda. Porque queremos encontrar la línea con las palabras Mem y Swap, vamos a combinar con grep -E "Mem | Swap"
. [vagrant @ vagrant-centos64 ~] $ free -m | grep -E "Mem | Swap" Mem: 589 536 52 0 8 271 Swap: 255 0 255Así que es mucho más limpio. Combina ambos
grep
y awk
Podemos limpiar los datos y obtener solo lo que necesitamos.[vagrant @ vagrant-centos64 ~] $ free -m | grep -E "Mem | Swap" | awk 'imprimir $ 1, $ 2, $ 3, $ 4' Mem: 589 537 52 Swap: 255 0 255
Tenemos que aprender algunos comandos para obtener las métricas del servidor, por lo que abriremos nuestro shell de servidor e intentaremos escribir debajo del comando para tener una idea rápida.
$ netstat-en Kernel Tabla de interfaz Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg eth0 1500 0 5538339494 0 0 0 6216082004 0 0 0 BMRU eth0: 1 1500 0 - no hay estadísticas disponibles - BMRU eth1 1500 0 96707328840 0 0 0 102776317608 0 0 0 BMRU eth2 1500 0 33 0 0 0 7 0 0 0 BMRU lo 16436 0 29461422 0 0 0 29461422 0 0 0 LRU
df -h Tamaño del sistema de archivos usado Avail Use% Montado en / dev / sda7 2.0G 660M 1.3G 35% / / dev / sda8 1.0T 632G 340G 66% / home / dev / sda6 2.0G 68M 1.9G 4% / tmp / dev / sda5 20G 1.5G 18G 8% / var / dev / sda2 20G 2.1G 17G 12% / usr / dev / sda1 194M 25M 160M 14% / boot / dev / hdb1 459G 277G 159G 64% / backup tmpfs 16G 0 16G 0% / dev / shm
libre -m total utilizado libre compartido buffers en caché Mem: 32189 32129 59 0 419 9052 - / + buffers / cache: 22656 9532 Swap: 32767 4 3276Usaremos más comandos más adelante, pero los anteriores le dan un comando fundamental para ver qué podemos obtener del servidor directamente en la línea de comandos.
Vamos a refactorizar nuestra clase original en la sección anterior un poco. Tenga en cuenta que, a menos que se indique claramente lo contrario, estaremos creando todos los archivos y carpetas. dentro nuestro directorio de plugins.
Primero, no querremos incluir archivos manualmente. Escribiremos un cargador automático de clases para ese propósito. Cuando se inicializa una clase faltante, verificaremos el nombre de la clase e intentaremos incluir el archivo fuente que contiene la definición de la clase.
Usaremos los espacios de nombres como la ruta y el nombre de la clase como el nombre del archivo. Por ejemplo, una clase. foo
en espacio de nombres AX \ StatBoard
Debería estar en la raíz de la carpeta del complemento. Una clase zumbido
en espacio de nombres AX \ StatBoard \ Bar
debería estar en Bar \ buzz.php
Con eso en mente, sigamos adelante y comencemos a diseñar nuestro método de cargador automático:
_plugin_dir. strtolower (str_replace ('\\', '/', $ classname). '.php'); if (! file_exists ($ filepath)) return false; incluye $ filepath;Entonces, ¿qué pasa aquí? Nuestro plugin utiliza el espacio de nombres.
/ **
* Variable de configuración y proveedor de widget de inicialización.
* /
función __construir ()
$ this -> _ plugin_dir = plugin_dir_path (__FILE__);
spl_autoload_register (array ($ this, 'load_class'));
//…
AX \ StatBoard
. Por lo tanto, nos aseguramos de que la clase solicitada bajo este espacio de nombres sea manejada por nuestro complemento, de lo contrario, nuestro cargador automático no es capaz de cargarlos. Luego despojamos el AX \ StatBoard en el nombre de la clase y reemplazarlo con la ruta de la carpeta del complemento. La barra invertida \ en espacio de nombres se sustituye por / separador de ruta, y anexar php
extensión. Eso significa que el espacio de nombres se utilizará como la ruta a la carpeta que contiene el archivo de clase, y el nombre de la clase es el nombre del archivo. La inclusión solo ocurre si el archivo existe. Ahora, tenemos el cargador automático, aún debemos informarle a PHP que tenemos un cargador automático y queremos usarlo. PHP incluye spl_autoload_register para este propósito. Lo ponemos en nuestra clase constructor..wp_add_dashboard_widget
, Tenemos que darle el título y el contenido. En función de cada widget, tendremos una clase para representar el título y el contenido. A estas clases las llamamos widgets. Proveedor
. Todo proveedor de widgets debe definir get_title ()
y obtener el contenido()
para representar contenido.Proveedor
interfaz, y que nuestra clase de proveedor de widgets implemente esta interfaz. También necesitamos crear un método más llamado get_metric ()
para extraer datos del servidor.widget / provider.php
con este contenido:Esta es una interfaz. Requerimos que cada proveedor de widgets tenga que implementar esta interfaz y, por lo tanto, nos aseguramos de que la clase de proveedor de widgets siempre tenga estos tres métodos.
Crearemos una clase más.Widget
para gestionar estos proveedores. Creamos clases de proveedores, luego las entregamos aWidget
clase y vistaWidget
clase como un punto único para que solicitemos un proveedor cuando lo necesitemos. Simplemente podemos poner todo en nuestro archivo de complemento principal, y simplemente crear una instancia de clase connuevo
Operador cuando lo necesitamos pero es difícil de mantener más tarde..
Cuando dividimos la cosa en muchas capas, es más fácil de probar y extender. Una vez que hacemos que todos los proveedores sean administrados por una sola clase, podemos usar esa clase para hacer lo mismo en el conjunto de proveedores. Podemos agregar fácilmente más proveedores en cualquier momento, simplemente creando un objeto que implemente una clase de proveedor y aliméntelos aWidget
clase
Componer un archivowidget.php
en el directorio raíz de la carpeta de plugin.Nuevamente, estamos usando el patrón Singleton para nuestra clase de widgets. Un breve resumen de nuestro método aquí..
espacio de nombres AX \ StatBoard;
use AX \ StatBoard \ Widget \ Provider;
Widget de clase
const WIDGET_SLUG_PREFIX = 'AX';
protegido $ _providers = array ();
$ _instancia estática protegida;
instancia de función estática ()
return self :: $ _ instance = self :: $ _ instance?: new self ();
función __construir ()
/ **
* Añadir un proveedor de widget
* @param string nombre del widget
* @param proveedor objeto para manejar la representación del contenido del widget
* /
función pública add_provider ($ name, Provider $ handler)
$ esto -> _ proveedores [$ nombre] = $ manejador;
devuelve $ esto;
/ **
* Obtener todos los proveedores o un proveedor en particular
* /
función pública get_provider ($ name = NULL)
si (! $ nombre)
devuelve $ esto -> _ proveedores;
devuelve $ esto -> _ proveedores [$ nombre];
/ **
* Registrar un widget para renderizarlo..
* /
registro de función pública ($ nombre)
$ slugid = self :: WIDGET_SLUG_PREFIX. $ nombre;
$ widget_provider = $ this-> get_provider ($ name);
if (vacío ($ widget_provider))
falso retorno;
wp_add_dashboard_widget (
$ slugid,
$ widget_provider-> get_title (),
array ($ widget_provider, 'get_content'));
devuelve verdadero
- los
añadir_proveedor
El método agregará un objeto de proveedor de widgets a la lista de proveedores de widgets. También utilizamos sugerencias de tipo para asegurarnos de que el paso de objeto a add_provider debe ser un Proveedor implementando nuestroProveedor
interfaz.- los
obtener_proveedor
El método puede devolver una lista de todos los proveedores, o un proveedor en particular.- los
registro
El método en realidad registrará nuestro objeto proveedor con WordPress para generar un widget de panel conwp_add_dashboard_widget
. El ID del widget se genera según el prefijo, una constante predefinida y el nombre de la clase del widget. El título y el contenido serán tirados víaobtener_título
y get_content
del proveedor. Nos aseguramos de que implementen nuestra interfaz de proveedor. Con este método de registro, abstraemos la implementación de agregar el widget al panel de control. Todo lo que tenemos que hacer ahora es llamarregistro
con el nombre del proveedor que agregamos antes conañadir_proveedor
. Con esto en mente, cuando la API de WordPress cambia, no necesitamos ir a todos los lugares dewp_add_dashboard_widget
, acabamos de actualizar en un solo lugar.
Volviendo a nuestro archivo de plugin principal originalserverdashboard.php
, Inicializaremos todos los proveedores y los agregaremos a la lista de proveedores del objeto Widget.._plugin_dir = plugin_dir_path (__FILE__); spl_autoload_register (array ($ this, 'load_class')); $ this -> _ dashboard_widget = array ('server', 'cpu_load', 'ram', 'disk', 'diskio', 'software', 'ethernet', 'internetspeed', 'networkio', 'process')); foreach ($ this -> _ dashboard_widget as $ item) if (! file_exists ($ this -> _ plugin_dir. '/ widget /'. $ item. '.php')) continue; $ classname = 'AX \\ StatBoard \\ Widget \\'. ucwords ($ item); Widget :: instance () -> add_provider ($ item, new $ classname ());Pondremos todas las clases de proveedores de widgets bajo el espacio de nombresAX \ StatBoard \ Widget
y por lo tanto se sentarán dentro de la carpetawidget
. Apoyamos nueve tipos de métricas y nombramos la clase correspondiente a la matriz_dashboard_widgets
encima.
Para cada uno de los widgets, creamos una nueva instancia de su proveedor y la agregamos aWidget
clase. Esto es lo que obtendremos más adelante con esta estructura:
Recuerda que nos enganchamos enwp_dashboard_setup
, Y dentro de ella llamamos a la función.wp_add_dashboard_widget
para agregar nuevo widget al panel de control. A continuación, tenemos nuestroregistro
Método para este fin. Iremos a todos los proveedores agregados y los registraremos. Actualizar el contenido deadd_dashboard_widgets
deserverdashboard.php
volverse:
/ ** * Registrar el proider del widget del panel de control para que aparezca en el panel de control * / function add_dashboard_widgets () $ widget = Widget :: instance (); foreach ($ widget-> get_provider () como $ name => $ provider) $ widget-> register ($ name);
A continuación, nos conectaremos a admin_footer para generar JavaScript en línea en la parte inferior de la página de administración para inicializar el paquete de clase de Google Chart. Nuestrocorrer()
Método también se actualiza para nuevo gancho./ ** * Comenzar a configurar el gancho * / public function run () add_action ('wp_dashboard_setup', array ($ this, 'add_dashboard_widgets')); add_action ('admin_enqueue_scripts', array ($ this, 'add_asset')); add_action ('admin_footer', array ($ this, 'footer')); / ** * JavaScript en línea para el gráfico * / función pie de página () echo ' ';
En este momento, completamos el archivo básico, y el archivo del complemento principal debería tener este aspecto._plugin_dir. strtolower (str_replace ('\\', '/', $ classname). '.php'); if (! file_exists ($ filepath)) return false; incluye $ filepath; / ** * Variable de configuración e intializar proveedor de widgets * / function __construct () $ this -> _ plugin_dir = plugin_dir_path (__FILE__); spl_autoload_register (array ($ this, 'load_class')); $ this -> _ dashboard_widget = array ('server', 'cpuload', 'ram', 'disk', 'software', 'process', 'ethernet', 'networkio', 'iostat',); foreach ($ this -> _ dashboard_widget as $ item) if (! file_exists ($ this -> _ plugin_dir. '/ widget /'. $ item. '.php')) continue; $ classname = 'AX \\ StatBoard \\ Widget \\'. ucwords ($ item); Widget :: instance () -> add_provider ($ item, new $ classname ()); / ** * Crear una instancia única a través de la aplicación * / public static function instance () return self :: $ _ instance = self :: $ _ instance?: New self (); / ** * Comenzar a configurar hook * / public function run () add_action ('wp_dashboard_setup', array ($ this, 'add_dashboard_widgets')); add_action ('admin_enqueue_scripts', array ($ this, 'add_asset')); add_action ('admin_footer', array ($ this, 'footer')); / ** * Registrar el proider del widget del panel de control para que aparezca en el panel de control * / function add_dashboard_widgets () $ widget = Widget :: instance (); foreach ($ widget-> get_provider () como $ name => $ provider) $ widget-> register ($ name); / ** * Carga de activos: hoja de estilo, JS. * / function add_asset () syslog (LOG_DEBUG, "Loaded"); wp_enqueue_script ('google-chart', 'https://www.google.com/jsapi'); // wp_enqueue_script ('plugin_dir_url', plugin_dir_url (__ FILE__). '/loader.js'); / ** * JavaScript en línea para el gráfico * / función pie de página () echo ' '; Dashboard :: instance () -> run ();Básicamente creamos una instancia de la clase del complemento principal y llamamos al método de ejecución. Que a su vez acaba de configurar una lista de gancho. Cada gancho es otro método dentro de la clase. También creamos y registramos nuestro objeto proveedor conWidget
objeto.Que sigue?
En este punto, todavía no mostramos nada; sin embargo, establecimos una estructura para nuestro anuncio de complemento que comenzó a conectarse a Google Charts.
Puede descargar el script completo de los enlaces de descarga en la parte superior de este artículo. Iremos al detalle de implementación de cada proveedor de widgets en el próximo artículo, así que asegúrate de seguir la siguiente parte.
Espero que hayan disfrutado este artículo. Deja comentarios con cualquiera de tus pensamientos y me aseguraré de responderlos..