API MIKROTIK – Graficar trafico de interfaces en tiempo real con Highcharts y PHP


Te voy a enseñar como graficar en vivo una interfaz en particular de tu RouterOS. El ejemplo que arme en esta ocasión con las fabulosas, increíbles gráficas highcharts.com. (tal como lo pidio Cesar Maffini).

Si te interesa podes continuar leyendo una actualizacion de este post con bastantes mejoras: Graficar Interfaces y Queues con Highcharts version mejorada

Actualización: un fiel lector de nombre Alejandro Mogollon nos armo un video tutorial para demostrar que es muy muy facil la puesta en marcha.

El codigo tiene 3 archivos:

1) api_mt_include2.php: API RouterOS.
2) data.php: Conecta a RouterOS, trae TX, RX y los imprime en formato JSON.
3) index.html: Utiliza Ajax para llamar data.php cada 1 segundo y graficar puntos en tiempo real usando highcharts.
highchart_tech-nico.com_API_MIKROTIK

El codigo esta muy muy facil. Vamos a resumirlo:

index.html

           chart = new Highcharts.Chart({
			   chart: {
				renderTo: 'container',
				animation: Highcharts.svg,
				type: 'spline',
				events: {
					load: function () {
						setInterval(function () {
							requestDatta(document.getElementById("interface").value);
						}, 1000);
					}
			}
		 },

Sin duda esta es la parte mas importante del codigo En la linea donde comienza el setInterval lo que hace es llamar a la funcion requestDatta() y pasarle como parametro el nombre de la interfaz de red de nuestro Mikrotik que queremos graficar en tiempo real, cada 1 segundo. Esto funciona con cualquier interfaz. Bridge, Vlan, pppoe, Wlan, etc. En este caso, el parametro con el nombre de la interfaz que le vamos a pasar a la funcion requestDatta lo asigne a un campo de texto editable para hacerlo un poco mas interesante.

	function requestDatta(interface) {
		$.ajax({
			url: 'data.php?interface='+interface,
			datatype: "json",
			success: function(data) {
				var midata = JSON.parse(data);
				if( midata.length > 0 ) {
					var TX=parseInt(midata[0].data);
					var RX=parseInt(midata[1].data);
					var x = (new Date()).getTime();
					shift=chart.series[0].data.length > 19;
					chart.series[0].addPoint([x, TX], true, shift);
					chart.series[1].addPoint([x, RX], true, shift);
					document.getElementById("trafico").innerHTML=TX + " / " + RX;
				}else{
					document.getElementById("trafico").innerHTML="- / -";
				}
			}

Aqui, como explicábamos mas arriba, tenemos la función que se conecta al RouterOS y nos trae el dato de TX / RX de la interfaz que nosotros le pidamos.
Los datos que traemos de data.php estan en formato JSON, por lo tanto los tenemos que parsear para poner cada dato en una variable y luego graficar el punto en el Highchart. Si se fijan, es muy importante convertir el valor que viene en JSON a numero «parseINT».

La linea, shift=chart.series[0].data.length > 19; la usamos para que, cada vez que agregamos un punto nuevo, guardemos un indice con la cantidad de puntos, que le va a decir al chart cuando comenzar a pisar los valores antiguos de la serie.

Aqui pego las lineas con comentario:

	var TX=parseInt(midata[0].data);   // UPLOAD
	var RX=parseInt(midata[1].data);   // DOWNLOAD
	var x = (new Date()).getTime();    // tooltip cuando hacemos hover en el punto
	shift=chart.series[0].data.length > 19;  // indice de cantidad de puntos
	chart.series[0].addPoint([x, TX], true, shift);  // agrego TX en SERIE 0
	chart.series[1].addPoint([x, RX], true, shift);  // agrego RX en SERIE 1

Podemos agregar la cantidad de series que queramos; solo que mas abajo tenemos que definirlas asi:

            series: [{
                name: 'TX',
                data: []
            }, {
                name: 'RX',
                data: []
            }]

Con esto de arriba, tendriamos serie0 y serie1 (siempre contamos de arriba hacia abajo).
Presten atencion que «data» esta vacio, ya que nosotros le agregamos los puntos en tiempo de ejecución.
Si se nos ocurre graficar un tercer valor a la par de TX y RX lo haríamos definiendo otra serie, de esta manera:

series: [{
name: ‘TX’,
data: []
}, {
name: ‘RX’,
data: []
}, {
name: ‘RX’,
data: []
}]

Aca tendriamos, serie0, serie1 y serie2.
Espero que se entienda.

data.php
Este archivo como dijimos mas arriba es el que se conecta al routerOS y hace su trabajito. Editen las primeras lineas con los datos de su servidor Mikrotik.

Usaremos el comando /interfaces/monitor-traffic
Este nos pide el nombre de la interfaz, que ya la traemos desde el otro archivo.

		   $API->write("/interface/monitor-traffic",false);
		   $API->write("=interface=".$interface,false);
		   $API->write("=once=",true);

Esto ya lo hemos explicado en los posts anteriores, así que solo quiero detallar que la ultima linea dice =once= para que el trafic monitor, ejecute el comando 1 vez y pare. Si no ponemos este comando, se queda trabado, trayendo y trayendo el trafico en tiempo real, pero de manera infinita, con esto nos aseguramos que lo haga 1 vez.

Espero que les guste tanto como a mi. Investiguen un poco las graficas lindas que tiene higcharts porque son fantasticas y por supuesto si tienen modificaciones, mejoras, etc no duden en pasar un mail que las posteamos!!

Estoy pensando en usar github para control de versiones 😀

Descargar el codigo fuente completo

Se escribió primero en Tech-nico.com por Nicolas Daistch

65 comentarios en “API MIKROTIK – Graficar trafico de interfaces en tiempo real con Highcharts y PHP

  1. hola tus tutoriales me han ayudado bastante, hay alguna manera de que podamos comunicarnos, podrias hacer algun tutorial para chequear el ping de una direccion ?

  2. Hola Giovanni, me alegro que te sirva, de donde sos?. Si como no!! todo lo que hago para mi es un nuevo desafió. Manda un mensaje en el formulario de contacto de mi sitio y detallame lo que queres hacer y lo publico. Saludos. Nico.!!

  3. Grácias por los tutoriales, muy buenos!!!!
    Perdona mi falta de conocimientos, pero algo debo de hacer mal, porque no me funciona, he cambiado los siguientes parametros:
    $ipRouteros = «151.xxx.xxx.xxx»;
    $Username=»admin»;
    $Pass=»xxxxxxxx»;
    $interface = $_GET[«WAN»]
    Y no me hace las gráficas, he de cambiar algun parámetro mas?
    Gracias por la ayuda!!! 😉

  4. $interface «No deberias modificarlo» a no ser que tambien hayas modificado el nombre e id de

    <input name="interface" id="interface" type="text" value="NOMBRE_INTERFACE" />

    // LO UNICO QUE NECESITAS EDITAR PARA QUE FUNCIONE ES:

    $ipRouteros = "192.168.0.1";
    $Username="tu_usuario";
    $Pass="tu_contrasena";
    $api_puerto=8728;
    

    Si ves que no conecta puedes poner la linea $API->debug = false; en $API->debug = true; y asi va a darte mas info de lo que pasa.

    saludos.

  5. Hola, te comento que me parece muy bueno y util el post…pero no logro hacerlo funcionar…pruebo del data.php solo y funciona…pero parecería que el script no lo llama…algna sugerencia de debug para saber donde se «muere»? Gracias desde ya,

  6. Hola Eduardo, como sugerencia te pido que elimines los archivos temporales de internet. Tambien, que lo testees con distintos navegadores, porque a veces IE hace cosas raras.

    Si no se resuelve con lo anterior; otras sugerencias que podrian ayudar:
    Primero.. asegurate que esten todos los archivos que descargaste del sitio. Tanto las librerias de Highchart como las de Jquery.
    Segundo… Asegurate de no haber movido ninguna carpeta o archivo de lugar… Tercero: el codigo que pase «Esta Funcionando» !!. Asi que, si modificaste algo.. trata de recordar que era. Si no estas seguro que es lo que modificaste, te recomiendo que vuelvas a descargar el archivo comprimido y solo edites data.php. Solo para ver si funciona!!. Si ves que no anda tampoco, ahi podemos ponernos a debugear!!!. Avisame que resultado tuviste.

    Slds.

    Nicolas

  7. Tremendo aporte nicolas! Lo puse a andar y perfecto, lo unico que me gustaria seria que se pudiera notar de mejor forma el download, ya que cuando pasa a 1MBps el indicador de tx baja y por ende el rx sube obviamente xq esta identificado en kbps. y es mas alto que 1 ó 2. (800kbps por ejemplo) Seria bueno colocar tambien en decimales y que predominara el download contra el upload. Otra cosa me gustaria que descifraras alguna manera de ver el consumo real de cada cliente, me parece que se pudiera hacer via queue simple o hotspot, no lo tengo muy claro aun, seria perfecto algun tuto de tu parte, vi por ahi un sistema de administración que tiene una especie de barra de progreso y se ve el consumo real del cliente, llegando a su tope segun su plan. De esta manera el cliente ingresando al servidor web pueda ver su consumo real. Gracias por tu dedicación.! Saludos desde Barinas, Venezuela.

  8. Hola, te comento, no me muestra el trafico de la interface, q en mi caso se llama bridge, ya modifique el index.html, data.php y ya habilite el puerto 8728, y no me da, si me puedes ayudar muchas gracias.

  9. // LO UNICO QUE NECESITAS EDITAR PARA QUE FUNCIONE ES:

    $ipRouteros = "192.168.0.1";
    $Username="tu_usuario";
    $Pass="tu_contrasena";
    $api_puerto=8728;
    

    Si ves que no conecta puedes poner la linea $API->debug = false; en $API->debug = true; y asi va a darte mas info de lo que pasa.

    saludos.

  10. manya, Fijate que abajo hay un campo de texto que dice «rb_inalambricos». Es el nombre de la interfaz o puerto ethernet que queres graficar en tiempo real. Ahi mismo podes modificarlo por «ether1» o «wlan1» o el nombre que uses para la interfaz en tu interfaz. Saludos.

  11. Estimados, a mi tampoco me funcionaba, pero vi con la herramienta de desarrollo de Chrome que me estaba dando problemas cuando recibía el JSON. entonces, cambie en el archivo data.php:
    print json_encode($result);
    por
    echo json_encode($result);

    Y funciona de maravilla.

    Saludos.

  12. Hola, me gustaria saber en que escala estan representado los datos, bien sea kbps o mbps, quiero especificar eso en mis graficos pero no doy con la solucion.. saludos!

  13. Creo que estan en kbps por que a mi la grafica me va hasta 1000 y mi wan es de 12Mbps, seria bueno lograr que represente los datos especificos

  14. Antes de tudo quero agradecer a valiosa contribuição. muito obrigado!

    É possível no índex.html observar 2 ou mais gráficos de outras interfaces?

    Abraço é obrigado por sua atenção

  15. Sergio, lo intente pero no me funciono. Por supuesto que higchart lo permite!. Cuando logre tener los 2 gráficos en la misma pagina, se freno la gráfica en vivo. Seguro es cuestión de dedicarle tiempo. Deberías intentarlo y por ahí lo conseguís.

  16. Consulta. Estoy laburando con Web Service. Y quiero hacer lecturas de forma remota a un servidor, específicamente a la base que se encuentra en el. Tu código es adaptable a este tipo de tarea? Desde ya muchas gracias.

  17. Delfor, Si. Esto en realidad esta aplicado a leer el trafico de un router. Pero podes usarlo para lo que quiereas.
    Dentro del archivo data.php deberias hacer la conexion a la base de datos e imprimir el ultimo dato que seleccionas de tu tabla de datos. Si el dato sigue siendo el mismo.. va a seguir graficando el mismo valor. Con pocas modificaciones va a funcionar bien.

  18. buenas muy interesantestus trabajos consulta tendras algun programilla sencillo en donde ponga una ip y le haga ping cuando se corte me salte alguna alerta desde ya gracias y saludos sigue asi.

  19. Ing Pedroza, al parecer el archivo data.php, (que es el que se comunica con tu mikrotik) no esta devolviendo la informacion que necesita la grafica.
    fijate: http://www.mikronet.com.ve/graph/data.php?interface=ether1
    Lo que podes hacer para debugear es poner la linea…

    $API->debug = false;
    

    en true.

    $API->debug = true;
    

    Y asi ver si te esta devolviendo un error de comunicacion tu RouterOS.
    Saludos.

  20. Connection attempt #1 to 47b9041199fe.sn.mynetname.net:8728… <<>> [5/5] bytes read. >>> [5, 39]!done >>> [37/37] bytes read. >>> [37, 1]=ret=42c39109e9c932ff595120ce391f88d9 <<< [6] /login <<< [11] =name=admin <<>> [5/5] bytes read. >>> [5, 1]!done Connected… <<< [26] /interface/monitor-traffic <<< [14] =interface=LAN <<>> [3/3] bytes read. >>> [3, 221]!re >>> [9/9] bytes read. >>> [9, 211]=name=LAN >>> [26/26] bytes read. >>> [26, 184]=rx-packets-per-second=439 >>> [22/22] bytes read. >>> [22, 161]=rx-drops-per-second=0 >>> [23/23] bytes read. >>> [23, 137]=rx-errors-per-second=0 >>> [26/26] bytes read. >>> [26, 110]=rx-bits-per-second=426600 >>> [26/26] bytes read. >>> [26, 83]=tx-packets-per-second=795 >>> [22/22] bytes read. >>> [22, 60]=tx-drops-per-second=0 >>> [23/23] bytes read. >>> [23, 36]=tx-errors-per-second=0 >>> [27/27] bytes read. >>> [27, 8]=tx-bits-per-second=9212688 >>> [5/5] bytes read. >>> [5, 1]!done Disconnected…

  21. Saludos! excelente aporte te felicito. pero me esta pasando lo que ya he visto en varios de los post que te han dejado acá. Solo modifique el archivo data.php con los datos requeridos por el API y en la interface (index.html) en la caja de texto he colocado LAN pero no me gráfica. Active el Debug y no me genera errores, entro en el LOG de la RB y veo que se generan las dos peticiones por seg (tx,rx) he probado en diferentes navegadores y nada, descargue nuevamente el archivo y modifique los datos necesarios y nada, solo me aparece la imagen sin graficar. De verdad me gustaría que me ayudaras con este detalle. Saludos!

  22. Alejandro, Excelente video!!. esta perfecto lo que estas haciendo!!. Yo segui exactamente tus pasos para verificar que no este fallando mi codigo y realmente salio andando de una!!. Fijate que en la URL http://localhost/api_routeros_chart/data.php?interface=LAN te este trayendo el TX y RX como a continuacion:

    [{«name»:»Tx»,»data»:[233.8]},{«name»:»Rx»,»data»:[«3,902.5»]}]

    Si haces refresh en el navegador deberia mostrarte en tiempo real digamos el trafico de esa interfaz.

    Tambien proba cambiar el nombre de la interfaz LAN por el de la WAN (por si esa interfaz no tiene trafico)

    Yo lo probe en Firefox y en Chrome.! en ambos anduvo perfecto!!.

    Para eliminar margen de error sacale las IP que tenes puestas en IP – Services – API. Aunque creo que eso esta funcionando bien.

    Finalmente… no se.. actualiza tu version de java por si acaso este jodiendo algo del javascript cosa que tambien seria muy extraño.

    Luego contame como te fue que me interesa saber el resultado.

    Saludos.

  23. Saludos yo nuevamente por aca, al ejecutar lo siguiente «http://localhost/graficar-mk/data.php?interface=LAN» me esta generando este error «Warning: json_encode() expects exactly 1 parameter, 2 given in C:\AppServ\www\graficar-mk\data.php on line 43» y en la linea 43 lo que tengo es lo siguiente: «print json_encode($result, JSON_NUMERIC_CHECK);» cambie el print por el echo pero me sigue apareciendo lo mismo, muchas gracias por la paciencia jejeje saludos!

  24. Es por la version de tu PHP. El parametro JSON_NUMERIC_CHECK se añadio en la version de PHP 5.3.3. Usa una version de PHP mayor y tiene que salir andando.

  25. en teoria si instalo el appserv 2.6.0 que viene con Apache 2.2.8, PHP 6.0.0-dev, MySQL 6.0.4-alpha, phpMyAdmin-2.10.3 deberia funcionar? ya actualice la maquina de java, Saludos!

  26. Alejandro, Lo que mas me interesaria saber es si en la url «http://localhost/graficar-mk/data.php?interface=LAN» te dejo de tirar el error sobre el parametro JSON_NUMERIC_CHECK.

  27. «Fatal error: Call to undefined function print_encode() in C:\AppServ\www\graficar-mk\data.php on line 35» y la linea 35 contiene «print_encode($result, JSON_NUMERIC_CHECK);»

  28. En el codigo original la linea no es esa. Es esta:

    print json_encode($result, JSON_NUMERIC_CHECK);

    Si queres podes probar cambiarla por esta otra:

    echo json_encode($result, JSON_NUMERIC_CHECK);

  29. Bueh hermano en definitiva no quiso correr! probé con echo, con print y nada… de verdad un millon de gracias por tu valiosa colaboración y de verdad disculpa tanta molesta, un abrazo desde Venezuela!

  30. Alejandro, el problema es que tu servidor no acepta JSON. Json tiene que venir compilado dentro de PHP. Por alguna razón no lo esta tomando. Si quieres probar algo mas, instala WAMP Server (que es el que estoy usando yo y me anda todo bien). http://www.wampserver.com/en/. No te des por vencido. El script funciona!! Eso te lo aseguro!.

  31. le diste al clavo hermano! un millón de gracias! un abrazo grande y bendiciones!

  32. Muchas gracias ! me fue muy útil.
    Dejo un dato de algo que me pasó por si a alguien le sirve, al representar el tráfico por encima de 1mb en lugar de mostrar 1000 mostraba 1 como si el tráfico cayera, lo solucioné agregando la especificación de los separadores decimales de number_format en «data.php» a: $tx = number_format($ARRAY[0][«tx-bits-per-second»]/1024,1,’.’,»);
    Saludos y muchas gracias por el código y los otros tutoriales !!!

  33. No te conviene porque RouterOS ya las guarda. De todos modos, si te interesa guardar tus propias graficas podes hacerlo con php y mysql. Vas a tener que buscar la mejor manera de hacerlo. Slds.

  34. Para que me funcione, luego de modificar «data.php»
    $ipRouteros = «tu IP»;
    $Username=»tu usuario»;
    $Pass=»tu contraseña»;
    $api_puerto=8728; //NO SE TOCO
    $interface = $_GET[«interface»]; //NO TE TOCO

    A la vez, algo que tienes que modificar es el «index.html», linea 96…, el campo value=»tu interfaz», el valor por defecto es «rb_inalambricos» por ejemplo

    Otro detalle es que tienes que limpiar el cache o historial de tu navegador, porque de lo contrario va a seguir cargando tu primera interface «rb_inalambricos».

    Gracias por el codigo!

  35. Hola, muchas gracias y enhorabuena por tu blog, nos ayuda bastante, a los que empezamos a estudiar php para Mikrotik. he logrado que funcione tu ejemplo, pero hay un cosa que no entiendo, cuando pongo el index.html y empieza a conectar, mi log na RB se queda logando el tiempo todo mi usuario, como hago para que sea solamente una conexion? gracias

  36. Hermeson: En la versión 6.30 agregaron un timeout para que el API mantenga la conexión por 30 segundos. Por lo que estimo, que por mas que veas que entra y sale el usuario, Mikrotik mantiene su sesión activa. (Me puedo estar equivocando, pero asi es como lo interpreto)

    What’s new in 6.30 (2015-Jul-08 09:07):
    *) api – reduce api tcp connection keepalive delay to 30 seconds,
    will timeout idle connections in about 5 minutes;

  37. Funciona con servidor web apache y s.o. win. No muestra la gráfica con apache y s.o. Linux fedora. ¿Alguna pista para solucionar este problema? Gracias.

  38. @Plico Deberia andar .. te debe estar faltando habilitar algun modulo de apache.. como las librerias GD.
    Revisa los logs del apache que seguro te tiran algun indicio. Slds.

  39. Gracias por responder y aprovecho la oportunidad para agradecer la gentiliza de compartir esa herramienta con la comunidad. Desde luego que debería andar; pero te comento que revisé los GD’s y están todo ok, PHP corriendo, JavaScript ok; sin embargo, esta aplicación no levanta en Fedora Apache, no muestra error, se ejecuta y no muestra gráfico alguno, solo la línea final de ETHER1. Aclaro que se ejecuta sin problemas en WIN C/ APACHE.

  40. Hola Nico,soy nuevo en MK, el video esta claro y la explicacion tambien, pero me falta algo, los arcivo data, api e index, se suben al MK? o hay q instalar un verdidor para esto? me falta eso, no se que hacer con esos archivos para q ande, gracias!

  41. yo denuevo, instale el servidor en mi pc el WAMPSERVER, copie los archivo al directorio www, pero cuando tipeo localhost/monitor aparece el grafico pero ningun dato, pregunto, la direccion del servidor que hay q editar, es la del mikrotik o hay q poner la ip de la pc donde corre el wamp? gracias!

  42. Subimos a la versión 6.47.3 de RouterOS y dejó de funcionar…. :-d

    Habilité el debug y ahora me da este error y no hemos cambiado el usuario, ni la clave.

    Connection attempt #1 to 192.168.1.254:8787… <<>> [5/5] bytes read. >>> [5, 39]!done >>> [37/37] bytes read. >>> [37, 1]=ret=a4a8253cbe8e0de4363538993907bac9 <<< [6] /login <<< [13] =name=monitor <<>> [5/5] bytes read. >>> [5, 51]!trap >>> [42/42] bytes read. >>> [42, 8]=message=invalid user name or password (6) >>> [5/5] bytes read. >>> [5, 1]!done

Deja un comentario