En esta guía aprenderemos a obtener información de l os recursos sistema en Java, usando la librería Sigar. Los datos que podremos extraer son los siguientes: y
Información de la CPU.
y
Esp acio en di sco di sp sp onible.
y
Cantidad de e sp acio que con sume un directorio en e specífico.
y
Cantidad de memoria RAM di sp sp onible y en u so.
y
Información de red (dirección IP, nombre de la NIC, puerto s abiertos, tablas de enrutamiento, etc.)
y
Información de lo s procesos que se están ejecutando en el s i stema. As ignación de variables de entorno. entorno.
y
y
U ptime, o cantidad de tiem po que el equi po ha e stado encendido.
y
Nombre y ver sión del s i stema o perativo.
y
U suario s logueado s actualmente.
Resaltadas en negrita está la información en la que nos concentraremos en el ejemplo. Pero antes aclaremos un poco que es Sigar: el API de Sigar nos proporciona una serie de métodos
que
nos permiten obtener información
del sistema operativo; consta de una librería de Java (.jar) y otras librerías nativas específicas para cada sistema operativo soportado (libsigar-amd64-linux.so , para Linux de 64 bits o sigar-x86-winnt.dll para Windows de 32 bits, por poner un ejemplo). Teniendo esto en cuenta, para hacer
funcionar dicha dicha API en una
de
nuestras aplicaciones, bastaría con tener el archivo .jar y la librería específica de nuestro sistema operativo. operativo. En el desarrollo del ejemplo se usará Eclipse y, aunque se explicará cómo añadir las librerías en el proyecto, se da por conoci conocido do el funcionamiento del flag --classpath de los comandos javac y java (obligatorio si no se usa ningún IDE).
E l resultado« Siempre pongo primero el resultado ya que nos aclara la visión de hacia donde vamos, y de paso saber si lo que está aquí es lo que buscamos. Esta es la salida del programa en mi Gentoo Linux: ? 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
nformacion del sistema ==== escripcion del SO Gentoo 2.1.6 Nombre del SO Linux Arquitectura del SO x86_64 Version del SO 2.6.31-gentoo Nivel de parches unknown Fabricante Gentoo Version SO 2.1.6 Encendido durante: 6:15 ====I D
nformacion de la CPU ==== Fabricante: Intel Modelo Core(TM)2 Duo CPU Mhz 1994 Total CPUs 2 CPUs fisiscas fisiscas 1 Nucleos Nucleos por CPU 2 Tamanio cache 2048 ==== I
T5750 T5750
@ 2.00GHz 2.00GHz
16 17 18 19 20 21 22
Consumo de CPU 0 22.0% Consumo de CPU 1 2.0% Consumo total de CPU 6.0% nformacion del sistema de archivos ====
====I
dispos.|total|usado|disponible|%uso|dir|tipo
23 24 25
/dev/root|24042944|10698228|12123376|47%|/|ext4 /dev/sda1|175457764|155825380|10719932|94%|/home|ext3
26 27 28 29 30 31 32 33
nformacion de la memoria ==== Cantidad de memoria RAM: 3968MB Total: 4056984 Usada: 2307076 Disponible: 1749908 Memoria SWAP total: 1052248 Memoria SWAP usada: 0 Memoria SWAP libre: 1052248 ====I
34 35 36 37 38
Descargar
Sigar
Puedes descargar Sigar
de
la
página
oficial: http://support.hyperic.com/display/SIGAR/Home que además ejemplos para
Java,
Perl,
C,
Python,
Ruby,
incluye y
más.
Puedes
además descargar el código fuente que se encuentra licenciado bajo la GPL2.
Creación del proyecto en E cli pse Voy
a usar este ejemplo para además enseñar a manipular librerías externas
en Eclipse; si lo que te interesa es conocer el código, puedes saltarte a dicha sección directamente. Creamos un proyecto en Eclipse ll amado InfoSistema:
A
¡
£
¤
¥
¢
£
¡
¢
£
£
¨
¨
l £
£
¥
§
¤
¡
¢
li
§
¥
§
¦
i
¤
¨
§
¦
¡
¢
©
¡
¢
£
¥
¢
£
§
¦
A
t
t
¡
§
¥
¢
§
¥
¡
¡
¢
¥
¤
í
i i ¦
¡
¥
¤
t .E ¡
©
t
¥
¨
¦
©
i
¤
£
§
©
l
¥
§
¦
¥
Si
¥
§
t
£
£
¢
¢
©
¥
£
¢
¥
¨
¢
¤
©
¢
i
£
¤
¢
£
£
¤
¡
¥
t
ll
¡
¤
¢
¥
§
¤
£
£
¡
£
£
Si
¥
§
¦
t sigar-bin/lib
¥
i l £
¡
¡
¥
©
©
¤
¢
¢
¥
¥
£
£
¥
¤
£
¦
¨
l
li ,
£
, . ll, t . :
¡
©
l
§
¢
£
©
¡
.j , .
¡
¥
¢
¥
£
£
l
¡
¢
i ¤
¥
¤
¡
¥
©
§
t ¥
£
¡
¦
¡
©
¢
l
£
¤
,
£
£
¤
¤
¥
£
¢
i £
¡
¡
t lib £
:
cp sigar-bin/lib/* /home/compartido/workspace/InfoSistema/lib/
l
§
¡
¦
¥
§
Cabe resaltar que bastaría con copiar el archivo llamado sigar.jar y la librería del sistema donde
vamos
a
correr
nuestro
programa
(libsigar-amd64-
linux.so en mi caso).
Una vez hecha la copia, hacemos clic en l a raiz del proyecto en Eclipse y presionamos F5 para actualizar el árbol de ficheros; de esta maneraEclipse sabrá de los nuevos archivos que hemos copiado. Y lo que haremos a continuación será enlazar la librería sigar.jar a nuestro proyecto, para lo cual hacemos clic derecho en el mismo, Build Path -> Configure Build Path«
En la ventana que aparece, seleccionaremos la pestaña Libraries y hacemos clic en el botón Add JARs«Seleccionamos el archivo sigar.jar y hacemos clic en OK :
A
#
%
)
"
. ¡P
%
"
@
8
i
A
%
$
ll
i
5
,
%
3
&
!
'
%
&
%
í "
!
!
'
t
%
'
3
t %
(
)
(
l "
l "
'
%
"
3
"
)
i
'
!
InfoSO
D
(
G
E
F
(
l
"
'
i
1
"
"
0
i
6 1
5
,
1
"
!
)
it
%
%
2
6
%
%
t
%
$
"
tili
1
%
2
'
"
4
3
$
l API
%
!
#
Si
%
5
$
"
!
'
(
!
« '
(
B
)
(
7
1
"
%
%
(
n del sistem
9
7
'
(
"
$
!
Infor m
l li
%
!
f
"
!
,
3
l "
l i H
%
&
"
i
G
P
t G
%
F
$
Q
D
i f
%
R
!
t
)
i I
E
(
"
$
!
,
i 6
(
it
#
!
I
t
"
!
)
3
%
t .
l i t
1
%
'
(
)
%
C
'
"
!
%
3
"
%
3
2
ti
"
B
!
"
'
$
(
%
(
$
,
B
)
l
%
3
"
)
l "
'
%
:
?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23
import org.hyperic.sigar.OperatingSystem; import org.hyperic.sigar.Sigar; import org.hyperic.sigar.SigarException; public class InfoSO { private Sigar sigar = newSigar(); public void imprimirInfo() { OperatingSystem sys = OperatingSystem.getInstance(); System.out.p rintln("Descr ipcion del SO \t" + sys.getDescription()); System.out.p rintln("Nombr e del SO\t\t" + sys.getName()); System.out.p rintln("Arqui tectura del SO \t" + sys.getArch()); System.out.p rintln("Versi on del SO\t\t" + sys.getVersion()); System.out.p rintln("Nivel de parches\t" + sys.getPatchLevel()); System.out.p rintln("Fabricante\t\t" + sys.getVendor()); System.out.p rintln("Versi on SO\t\t" + sys.getVendorVersion()); try { imprimirUptime(); } catch (SigarException e) { e.printStackTrace(); } } public void imprimirUptime() throwsSigarException { double uptime = sigar.getUptime().getUptime(); String resultado = ""; int dias = (int) uptime / (60* 60 * 24); int minutos, horas; if (dias != 0) resultado += dias + " " + ((dias > 1) ? "dias": "dia") + ", ";
minutos = (int) uptime / 60; horas = minutos / 60; horas %= 24; minutos % = 60; if (horas ! = 0) resultado + = horas + ":" + (minutos < 10 ? "0" + minutos : minutos); else resultado + = minutos + " min"; System.out.println("Encendido durante: \t" + resultado);
24 25 26 27 28 29 30 31 32
} }
33 34 35 36 37 38 39
Aspectos importantes: La
y
clase
que
no s
pro porciona
lo s
método s
para
recu perar
información
del s i stema o perativo es OperatingSystem . Con lo s método s getName y getDescription obtenemo s el nombre del si stema o perativo y
y
de scri pción ( por ejem p lo: nombre = Linux; de scri pción = Gentoo 2.1.6). E l método getUptime de la cla se Sigar no s permite conocer cuanto tiem po ha e stado prendido el
y
equi po analizado.
Información de la CPU« La siguiente clase nos permitirá conocer el modelo del procesador, sus capacidades, la cantidad de núcleos y el uso de los mismos, etc. Creamos una nueva clase llamada InfoCPU con el siguiente código: ? 01 02 03
import import import import
org.hyperic.sigar.Cpu Info; org.hyperic.sigar.CpuPerc; org.hyperic.sigar.Sigar; org.hyperic.sigar.SigarException;
04 05 06
public class InfoCPU { private Sigar sigar;
07 08 09 10 11 12 13 14 15
public void imprimirInfoCPU() { sigar = new Sigar(); CpuInfo[] infos = null; CpuPerc[] cpus = null; try { infos = sigar.getCpuInfoList(); cpus = sigar.getCpuPercList(); } catch (SigarException e) { e.printStackTrace(); }
16 17 18 19
CpuInfo info = infos[0]; long tamanioCache = info.getCacheSize(); System.out.println("Fabricante: \t\t" + info.getVendor()); System.out.println("Modelo \t\t\t" + info.getModel());
System.out.println("Mhz \t\t\t" + info.getMhz()); System.out.println("Total CPUs \t\t" + info.getTotalCores()); if ((info.getTotalCores() ! = info.getTotalSockets()) || (info.getCoresPerSocket() > info.getTotalCores())) { System.out.println("CPUs fisiscas\t\t" + info.getTotalSockets()); System.out .println("Nucleos por CPU \t\t" + info.getCoresPerSocket()); }
20 21 22 23 24 25 26 27
if (tamanioCache ! = Sigar.FIELD_NOTIMPL) System.out.println("Tamanio cache \t\t" + tamanioCache); System.out.println("");
28 29 30
for (int i = 0; i < cpus.length; i++) System.out.println("Consumo de CPU " + i + "\t" + CpuPerc.format(cpus[i].getUser()));
31 32 33 34
try { System.out.println("Consumo total de CPU \t" + CpuPerc.format(sigar.getCpuPerc().getUser())); } catch (SigarException e) { e.printStackTrace(); }
35 36 37 38 39 40
} }
41 42 43 44 45 46 47 48
Aspectos importantes: Se deben u sar objetos de CpuInfo y CpuPerc que pro porcionan lo s método s para recu perar
y
información del procesador. Dichos objetos se crean a partir de un objeto princi pal de ti po Sigar . Para extraer información acerca del procesador u samo s los método s de la cla se C puInfo ( por
y
ejem p lo getVendor o getModel ). L os
y
dato s esp ecíficos de cada núcleo de nue stro procesador se extraen con lo s método s de la
clase CpuPerc (getU ser para obtener el u so de un núcleo, por ejem p lo).
Información del si s tema de archivos« La siguiente clase nos permite obtener información del sistema de archivos: unidades montadas, espacio en disco, tipo de sistema de archivos, etc. Creamos una nueva clase llamada InfoSistemaArchivos con el siguiente código: ? 01 02 03 04 05 06
import import import import import import import
org.hyperic.sigar.Sigar; org.hyperic.sigar.SigarException; org.hyperic.sigar.FileSystem; org.hyperic.sigar.FileSystemUsage; org.hyperic.sigar.NfsFileSystem; org.hyperic.sigar.SigarProxy; org.hyperic.sigar.SigarProx yCache;
07 08 09
public class InfoSistemaArchivos { private SigarProxy proxy; private Sigar sigar;
10
public InfoSistemaArchivos() { sigar = new Sigar(); proxy = SigarProxyCache.new Instance(sigar); }
11 12 13 14
public void imprimirInfo() throws SigarException { FileSystem[] listaSistemaArchivos = proxy.getFileSystemList(); System.out.println(" \ndispos.|total|usado|disponible|%uso|dir|tipo \n"); for (int i = 0; i < listaSistemaArchivos.length; i++) imprimirSistemaArchivos(listaSistemaArchivos[i]); }
15 16 17 18 19 20
public void imprimirSistemaArchivos(FileSystem sistemaArchivos) throws SigarException { long usado, disponible, total, porcentaje;
21 22 23 24
try { FileSystemUsage uso; if (sistemaArchivos instanceof NfsFileSystem) { NfsFileSystem nfs = (NfsFileSystem) sistemaArchivos; if (!nfs.ping()) { System.out.println(nfs.getUnreachableMessage()); return; } } uso = sigar.getFileSystemUsage(sistemaArchivos.get DirName());
25 26 27 28 29 30 31 32 33
usado = uso.getTotal() - uso.getFree(); disponible = uso.getAvail(); total = uso.getTotal();
34 35 36
porcentaje = (long) (uso.getUsePercent() * 100); } catch (SigarException e) { // por ejemplo, si en al procesar D: \ en windows falla // con "Device not ready" usado = disponible = total = porcentaje = 0; }
37 38 39 40 41 42
String porcentajeUso; if (porcentaje == 0) porcentajeUso = " -"; else porcentajeUso = porcentaje + "%";
43 44 45 46 47
System.out.print(sistemaArchivos.get DevName()); System.out.print("|" + total); System.out.print("|" + usado); System.out.print("|" + disponible); System.out.print("|" + porcentajeUso); System.out.print("|" + sistemaArchivos.get DirName()); System.out.println("|" + sistemaArchivos.getSysTypeName());
48 49 50 51 52 53 54 55 56
} }
57 58 59 60 61 62 63 64 65
Aspectos importantes: La
y
clase que no s pro porciona lo s método s para obtener información de una unidad en e sp ecífico
es FileSystem . E l método getDevName no s devuelve el nombre del di sp ositivo referenciado por e l objeto de la
y
clase FileSystem . L os
y
método s getTotal y getAvail devuelven un long que re presenta el esp acio total del
di sp os itivo y espacio di sponible, re sp ectivamente. Para conocer el ti po de s i stema de archivo s (ext4, ntf s, fat, btrf s, etc.) utilizamos el
y
método getSysTypeName .
Información de la memoria« La siguiente clase nos permite conocer la cantidad de memoria RAM que tiene el equipo, así como la que se está usando actualmente (tanto memoria física como virtual, aka, swap). Creamos una nueva clase llamada InfoMemoria con el siguiente código: ? 01 02 03 04 05 06 07 08 09
import import import import
org.hyperic.sigar.Mem; org.hyperic.sigar.Sigar; org.hyperic.sigar.Swap; org.hyperic.sigar.SigarException;
public class InfoMemoria { private Sigar sigar = new Sigar(); public void imprimirInfo() throws SigarException { Mem memoria = sigar.getMem() ; Swap intercambio = sigar.getSwap();
10
System.out.println("Cantidad de memoria RAM: "+ memoria.getRam() + "MB");
11 12
System.out.println("Total: "+enBytes(memoria.getTotal())); System.out.println("Usada: "+enBytes(memoria.getUsed())); System.out.println("Disponible: "+enBytes(memoria.getFree()));
13 14 15
System.out.println("Memoria SWAP total: "+enBytes(intercambio.getTotal())); System.out.println("Memoria SWAP usada: "+enBytes(intercambi o.getUsed())); System.out.println("Memoria SWAP libre: "+enBytes(intercambio.getFree()));
16 17 18 19
} private Long enBytes(long valor) { return new Long(valor / 1024); }
20 21 22 23
}
24 25 26
Aspectos importantes: y
La
clase Mem no s pro porciona método s para obtener información de la memoria del s i stema.
y
La
clase Swap hace lo mi smo que Mem, pero para la memoria virtual.
y
L os
método s getTotal y getUsed no s devuelven un long que re presenta (en bit s ) la cantidad de
memoria del equi po y lo que e stá u sando, re spectivamente. La
clase main« El main de nuestro proyecto estará contenido en la cl ase InfoSistema :
? 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16
import org.hyperic.sigar.SigarException; public class InfoSistema { public static void main(String[] args) { try { System.out.println(" ====Informacion del sistema ===="); new InfoSO().imprimirInfo(); System.out.println(" \n ==== Informacion de la CPU ===="); new InfoCPU().imprimirInfoCPU(); System.out.println(" \n ====Informacion del sistema de archivos ===="); new InfoSistemaArchivos().imprimir Info(); System.out.println(" \n ====Informacion de la memoria ===="); new InfoMemoria().imprimir Info(); } catch (SigarException e) { e.printStackTrace(); } } }
17
Eso es todo, solo nos queda ejecutar el proyecto y, opcionalmente, crear un archivo .jar para ejecutar en cualquier lado.