.\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" Set up some character translations and predefined strings. \*(-- will
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
.\" nothing in troff, for use with C<>.
.tr \(*W-
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.ie n \{\
. ds -- \(*W-
. ds PI pi
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
. ds L" ""
. ds R" ""
. ds C` ""
. ds C' ""
'br\}
.el\{\
. ds -- \|\(em\|
. ds PI \(*p
. ds L" ``
. ds R" ''
. ds C`
. ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{\
. if \nF \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. if !\nF==2 \{\
. nr % 0
. nr F 2
. \}
. \}
.\}
.rr rF
.\"
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
.\" Fear. Run. Save yourself. No user-serviceable parts.
. \" fudge factors for nroff and troff
.if n \{\
. ds #H 0
. ds #V .8m
. ds #F .3m
. ds #[ \f1
. ds #] \fP
.\}
.if t \{\
. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
. ds #V .6m
. ds #F 0
. ds #[ \&
. ds #] \&
.\}
. \" simple accents for nroff and troff
.if n \{\
. ds ' \&
. ds ` \&
. ds ^ \&
. ds , \&
. ds ~ ~
. ds /
.\}
.if t \{\
. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
.\}
. \" troff and (daisy-wheel) nroff accents
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
.ds ae a\h'-(\w'a'u*4/10)'e
.ds Ae A\h'-(\w'A'u*4/10)'E
. \" corrections for vroff
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
. \" for low resolution devices (crt and lpr)
.if \n(.H>23 .if \n(.V>19 \
\{\
. ds : e
. ds 8 ss
. ds o a
. ds d- d\h'-1'\(ga
. ds D- D\h'-1'\(hy
. ds th \o'bp'
. ds Th \o'LP'
. ds ae ae
. ds Ae AE
.\}
.rm #[ #] #H #V #F C
.\" ========================================================================
.\"
.IX Title "RRDTUTORIAL.ES 1"
.TH RRDTUTORIAL.ES 1 "2022-04-14" "1.0.50" "RRDtool"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH "NAME"
rrdtutorial \- Tutorial sobre RRDtool por Alex van den Bogaerdt
(Traducido al castellano por Jesu\*'s Couto Fandin\*~o)
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
RRDtool es un programa escrito por Tobias Oetiker con la
colaboracio\*'n de muchas personas en diversas partes del mundo. Alex van
den Bogaerdt escribio\*' este documento para ayudarte a entender que es
RRDtool y que es lo que puede hacer por ti.
.PP
La documentacio\*'n que viene con RRDtool puede ser demasiado te\*'cnica
para algunos. Este tutorial existe para ayudarte a entender las
funciones ba\*'sicas de RRdtool. Debe servirte de preparacio\*'n para leer la
documentacio\*'n, y adema\*'s explica algunas ideas generales sobre
estadi\*'stica, con un enfoque particular hacia las redes.
.SH "TUTORIAL"
.IX Header "TUTORIAL"
.SS "Importante"
.IX Subsection "Importante"
XPor favor, no te adelantes en la lectura de este documento! Esta
primera parte explica los fundamentos ba\*'sicos. Puede ser aburrida,
pero si te saltas los fundamentos, los ejemplos no te van a tener
mucho sentido.
.SS "XQue\*' es RRDtool?"
.IX Subsection "XQue' es RRDtool?"
RRDtool significa \*(L"herramienta de bases de datos en round robin\*(R".
\&\*(L"Round robin\*(R" es una te\*'cnica que implica un nu\*'mero fijo de datos, y un
apuntador al elemento ma\*'s reciente. Piensa en un circulo con unos
cuantos puntos dibujados alrededor del borde; estos puntos son los
lugares donde se pueden guardar los datos. Dibuja ahora una flecha
desde el centro del ci\*'rculo a uno de los puntos; este es el apuntador.
Cuando se lee o escribe el dato actualmente apuntado, la flecha se
mueve al pro\*'ximo elemento. Como estamos en un ci\*'rculo, no hay ni
principio ni fin; siempre puedes seguir, eternamente. Al cabo de un
tiempo ya se habra\*'n usado todas las posiciones disponibles y el
proceso empieza a reutilizar las antiguas. De esta forma, la base de datos
no crece en taman\*~o y, por lo tanto, no requiere ningu\*'n mantenimiento.
RRDtool trabaja con estas bases de datos en \*(L"round-robin\*(R", guardando y
recuperando datos de ellas.
.SS "XQue\*' datos pueden guardarse en una \s-1RRD\s0?"
.IX Subsection "XQue' datos pueden guardarse en una RRD?"
Lo que se te ocurra. Debes poder medir algu\*'n valor dado en distintos
momentos en el tiempo y proveer a RRDtool de estos valores. Si puedes
hacer esto, RRDtool puede guardar los datos. Los valores tienen que
ser nume\*'ricos, pero no necesariamente enteros, como en \s-1MRTG.\s0
.PP
Muchos ejemplos mencionan \s-1SNMP,\s0 que es el acro\*'nimo de
\&\*(L"Simple Network Management Protocol\*(R" (Protocolo Simple de
Administracio\*'n de Redes). Lo de \*(L"simple\*(R" se refiere al protocolo \- no
se supone que sea fa\*'cil administrar o monitorizar una red. Cuando
hayas terminado con este documento, debera\*'s saber lo suficiente para
entender cuando oigas a otros hablar sobre
\&\s-1SNMP.\s0 Por ahora, simplemente considera a
\&\s-1SNMP\s0 como una forma de preguntarle a los dispositivos
por los valores de ciertos contadores que mantienen. Son estos valores
de estos contadores los que vamos a almacenar en la \s-1RRD.\s0
.SS "XQue\*' puedo hacer con esta herramienta?"
.IX Subsection "XQue' puedo hacer con esta herramienta?"
RRDtool se deriva de \s-1MRTG\s0 (Multi Router
Traffic Grapher, Graficador De Tra\*'fico de Mu\*'ltiples Enrutadores).
\&\s-1MRTG\s0 empezo\*' como un pequen\*~o script para poder
graficar el uso de una conexio\*'n a la Internet. Luego evoluciono\*',
permitiendo graficar otras fuentes de datos, como temperatura,
velocidad, voltajes, cantidad de pa\*'ginas impresas, etc... Lo ma\*'s
probable es que empieces a usar RRDtool para guardar y procesar datos
conseguidos a trave\*'s de \s-1SNMP,\s0 y que los datos
sean el nu\*'mero de bytes (o bits) transferidos desde y hacia una red u
ordenador. RRDtool te permite crear una base de datos, guardar los
datos en ellas, recuperarlos y crear gra\*'ficos en formato \s-1GIF\s0 o \s-1PNG,\s0
para mostrarlos en un navegador web. Esas ima\*'genes dependen de los
datos que hayas guardado y pueden, por ejemplo, ser un sumario del
promedio de uso de la red, o los picos de tra\*'fico que ocurrieron.
Tambie\*'n lo puedes usar para mostrar el nivel de las mareas, la
radiacio\*'n solar, el consumo de electricidad, el nu\*'mero de visitantes
en una exposicio\*'n en un momento dado, los niveles de ruido cerca del
aeropuerto, la temperatura en tu lugar de vacaciones favorito, o en
la nevera, o cualquier otra cosa que te puedas imaginar, mientras
tengas algu\*'n sensor con el cual medir los datos y seas capaz de
pasarle los nu\*'meros a RRDtool.
.SS "\s-1XY\s0 si au\*'n tengo problemas despue\*'s de leer este documento?"
.IX Subsection "XY si au'n tengo problemas despue's de leer este documento?"
Lo primero, Xle\*'elo otra vez!. Puede que te hayas perdido de algo.
Si no puedes compilar el co\*'digo fuente y usas un sistema operativo
bastante comu\*'n, casi seguro que no es la culpa de RRDtool.
Probablemente consigas versiones pre-compiladas por la Internet. Si
provienen de una fuente confiable, u\*'salas. Si, por otro lado, el
programa funciona, pero no te da los resultados que tu esperabas,
puede ser un problema con la configuracio\*'n; revi\*'sala y
compa\*'rala con los ejemplos.
.PP
Hay una lista de correo electro\*'nico y una archivo de la misma. Lee
la lista durante unas cuantas semanas, y busca en el archivo. Es
descorte\*'s hacer una pregunta sin haber revisado el archivo; Xpuede que
tu problema ya haya sido resuelto antes! Normalmente ocurre asi\*' en todas
las listas de correo, no so\*'lo esta. Examina la documentacio\*'n que vino
con RRDtool para ver donde esta\*' el archivo y como usarlo.
.PP
Te sugiero que te tomes un momento y te subscribas a la lista ahora
mismo, enviando un mensaje a rrd\-users\-request@list.ee.ethz.ch
con ti\*'tulo \f(CW\*(C`subscribe\*(C'\fR. Si eventualmente deseas salirte de la lista,
envi\*'a otro correo a la misma direccio\*'n, con ti\*'tulo \f(CW\*(C`unsubscribe\*(C'\fR.
.SS "XCo\*'mo me vas a ayudar?"
.IX Subsection "XCo'mo me vas a ayudar?"
Da\*'ndote descripciones y ejemplos detallados. Asumimos que el seguir
las instrucciones en el orden en que se presentan aqui\*' te dara\*'
suficiente conocimiento de RRDtool como para que experimentes por tu
cuenta. Si no funciona a la primera, puede que te hallas saltado algo;
siguiendo los ejemplos obtendra\*'s algo de experiencia pra\*'ctica y, lo
que es ma\*'s importante, un poco de informacio\*'n sobre como funciona el
programa.
.PP
Necesitara\*'s saber algo sobre nu\*'meros hexadecimales. Si no, empieza
por leer \*(L"bin_dec_hex\*(R" antes de continuar.
.SS "Tu primera base de datos en round-robin"
.IX Subsection "Tu primera base de datos en round-robin"
En mi opinio\*'n, la mejor forma de aprender algo es hacie\*'ndolo. XPor
que\*' no empezamos ya? Vamos a crear una base de datos, poner unos cuantos
valores en ella y extraerlos despue\*'s. La salida que obtengas debe ser
igual a la que aparece en este documento.
.PP
Empezaremos con algo fa\*'cil, comparando un coche con un enrutador, o
por decirlo de otra forma, comparando kilo\*'metros con bits y bytes. A
nosotros nos da lo mismo; son unos nu\*'meros obtenidos en un espacio de tiempo.
.PP
Asumamos que tenemos un dispositivo que transfiere bytes desde y
hacia la Internet. Este dispositivo tiene un contador que empieza en 0
al encenderse y se incrementa con cada byte transferido. Este contador
tiene un valor ma\*'ximo; si ese valor se alcanza y se cuenta un byte
ma\*'s, el contador vuelve a empezar desde cero. Esto es exactamente lo
mismo que pasa con muchos contadores, como el cuentakilo\*'metros del
coche. En muchas de las disertaciones sobre redes se habla de bits por
segundo, asi\*' que empezaremos por acostumbrarnos a esto. Asumamos que un
byte son 8 bits y empecemos a pensar en bits y no en bytes. XEl
contador, sin embargo, sigue contando en bytes! En el mundo
\&\s-1SNMP,\s0 la mayori\*'a de los contadores tienen una
longitud de 32 bits. Esto significa que pueden contar desde 0 hasta
4294967295. Usaremos estos valores en los ejemplos. El dispositivo, cuando
le preguntamos, retorna el valor actual del contador. Como sabemos el
tiempo transcurrido desde la u\*'ltima vez que le preguntamos, sabemos
cuantos bytes se han transferido \f(CW\*(C`***en promedio***\*(C'\fR por
segundo. Esto no es muy difi\*'cil de calcular; primero en palabras,
luego en operaciones:
.IP "1." 4
Toma el valor actual del contador y re\*'stale el valor anterior
.IP "2." 4
Haz lo mismo con la fecha
.IP "3." 4
Divide el resultado del paso (1) por el resultado del paso (2).
El resultado es la cantidad de bytes por segundo. Si lo
multiplicas por ocho obtienes la cantidad de bits por segundo
.PP
.Vb 1
\& bps = (contador_actual \- contador_anterior) / (fecha_actual \- fecha_anterior) * 8
.Ve
.PP
Para algunos sera\*' de ayuda traducir esto a un ejemplo automotor.
No prueben estas velocidades en la pra\*'ctica, y si lo hacen, no me
echen la culpa por los resultados.
.PP
Usaremos las siguientes abreviaturas:
.PP
.Vb 6
\& M: metros
\& KM: kilo\*'metros (= 1000 metros).
\& H: horas
\& S: segundos
\& KM/H: kilo\*'metros por hora
\& M/S: metros por segundo
.Ve
.PP
Vas conduciendo un coche. A las 12:05, miras el contador en el
salpicadero y ves que el coche ha recorrido 12345
\&\s-1KM. A\s0 las 12:10 vuelves a mirar otra vez, y dice
12357 \s-1KM.\s0 Quiere decir, que has recorrido 12
\&\s-1KM\s0 en cinco minutos. Un cienti\*'fico convertiri\*'a
esto en metros por segundos; esto es bastante parecido al problema de
pasar de bytes transferidos en 5 minutos a bits por segundo.
.PP
Viajamos 12 kilo\*'metros, que son 12000 metros. Tardamos 5 minutos, o
sea 300 segundos. Nuestra velocidad es 12000M / 300S igual a 40 M/S.
.PP
Tambie\*'n podemos calcular la velocidad en \s-1KM/H: 12\s0 veces 5 minutos
es una hora, asi\*' que multiplicando los 12 \s-1KM\s0 por 12 obtenemos 144
\&\s-1KM/H.\s0 No intentes esto en casa, o por donde vivo :\-)
.PP
Recuerda que estos nu\*'meros son tan so\*'lo promedios. No hay forma de
deducir, viendo so\*'lo los nu\*'meros, si fuiste a una velocidad constante.
Hay un ejemplo ma\*'s adelante en el tutorial que explica esto.
.PP
Espero que entiendas que no hay diferencia entre calcular la
velocidad en M/S o bps; so\*'lo la forma en que
recogemos los datos es distinta. Inclusive, la K de kilo en este
caso es exactamente la misma, ya que en redes k es 1000
.PP
Ahora vamos a crear una base de datos en la que guardar todos estos
interesantes valores. El me\*'todo a usar para arrancar el programa puede
variar de un sistema de operacio\*'n a otro, pero asumamos que lo puedes
resolver tu mismo en caso que se diferente en el sistema que usas.
Asegu\*'rate de no sobreescribir ningu\*'n archivo en tu sistema al
ejecutarlo y escribe todo como una sola li\*'nea (tuve que partirlo para
que fuera legible), salta\*'ndote todos los caracteres '\e'
.PP
.Vb 5
\& rrdtool create test.rrd \e
\& \-\-start 920804400 \e
\& DS:speed:COUNTER:600:U:U \e
\& RRA:AVERAGE:0.5:1:24 \e
\& RRA:AVERAGE:0.5:6:10
.Ve
.PP
(o sea, escribe: \f(CW\*(C`rrdtool create test.rrd \-\-start 920804400 DS ...\*(C'\fR)
.SS "XQue\*' hemos creado?"
.IX Subsection "XQue' hemos creado?"
Hemos creado una base de datos en round robin llamada test
(test.rrd), que empieza desde el mediodi\*'a del di\*'a en que empece\*' a
escribir este documento (7 de marzo de 1999). En ella se guarda una
fuente de datos (\s-1DS\s0), llamada \*(L"speed\*(R", que se
lee de un contador. En la misma base de datos se guardan dos archivos
en round robin (RRAs), uno promedia los datos cada vez que se leen (o
sea, no hay nada que promediar), y mantiene 24 muestras (24 por 5
minutos = 2 horas de muestras). El otro promedia 6 muestras (media
hora), y guarda 10 de estos promedios (o sea, 5 horas). Las opciones
restantes las veremos ma\*'s adelante.
.PP
RRDtool usa un formato de \*(L"fecha\*(R" especial que viene del mundo de
\&\s-1UNIX.\s0 Estas \*(L"fechas\*(R" son el nu\*'mero de segundos
que han pasado desde el primero de enero de 1970, zona \s-1UTC.\s0 Este
nu\*'mero de segundos se convierte luego en la fecha local, por lo que
varia segu\*'n la franja horaria.
.PP
Lo ma\*'s probable es que tu no vivas en la misma parte del mundo que
yo, por lo que tu franja horaria sera\*' diferente. En los ejemplos,
cuando mencione horas, puede que no sean las mismas para ti; esto no
afecta mucho los resultados, so\*'lo tienes que corregir las horas
mientras lees. Por ejemplo, las 12:05 para mi\*' son las 11:05 para los
amigos en la Gran Bretan\*~a.
.PP
Ahora tenemos que llenar nuestra base de datos con valores. Vamos a
suponer que lei\*'mos estos datos:
.PP
.Vb 10
\& 12:05 12345 KM
\& 12:10 12357 KM
\& 12:15 12363 KM
\& 12:20 12363 KM
\& 12:25 12363 KM
\& 12:30 12373 KM
\& 12:35 12383 KM
\& 12:40 12393 KM
\& 12:45 12399 KM
\& 12:50 12405 KM
\& 12:55 12411 KM
\& 13:00 12415 KM
\& 13:05 12420 KM
\& 13:10 12422 KM
\& 13:15 12423 KM
.Ve
.PP
Llenaremos la base de datos asi\*':
.PP
.Vb 5
\& rrdtool update test.rrd 920804700:12345 920805000:12357 920805300:12363
\& rrdtool update test.rrd 920805600:12363 920805900:12363 920806200:12373
\& rrdtool update test.rrd 920806500:12383 920806800:12393 920807100:12399
\& rrdtool update test.rrd 920807400:12405 920807700:12411 920808000:12415
\& rrdtool update test.rrd 920808300:12420 920808600:12422 920808900:12423
.Ve
.PP
Lo que significa: actualiza nuestra base de datos test con los
siguientes valores:
.PP
.Vb 2
\& fecha 920804700, valor 12345
\& fecha 920805000, valor 12357
\&
\& etce\*'tera.
.Ve
.PP
Como ves, pueden introducirse ma\*'s de un valor en la base de datos
por ejecucio\*'n del comando. Yo los agrupo de tres en tres para hacerlo
legible, pero en realidad el ma\*'ximo depende del sistema de operacio\*'n.
.PP
Ahora podemos recuperar los datos usando ``rrdtool fetch'':
.PP
.Vb 1
\& rrdtool fetch test.rrd AVERAGE \-\-start 920804400 \-\-end 920809200
.Ve
.PP
Debes obtener esto como salida:
.PP
.Vb 1
\& speed
\&
\& 920804400: NaN
\& 920804700: NaN
\& 920805000: 4.0000000000e\-02
\& 920805300: 2.0000000000e\-02
\& 920805600: 0.0000000000e+00
\& 920805900: 0.0000000000e+00
\& 920806200: 3.3333333333e\-02
\& 920806500: 3.3333333333e\-02
\& 920806800: 3.3333333333e\-02
\& 920807100: 2.0000000000e\-02
\& 920807400: 2.0000000000e\-02
\& 920807700: 2.0000000000e\-02
\& 920808000: 1.3333333333e\-02
\& 920808300: 1.6666666667e\-02
\& 920808600: 6.6666666667e\-03
\& 920808900: 3.3333333333e\-03
\& 920809200: NaN
.Ve
.PP
Si no, hay algo mal. Probablemente tu sistema de operacio\*'n muestre ``NaN''
de otra forma; representa \*(L"Not a Number\*(R", o sea \*(L"No es un nu\*'mero\*(R". Si
aparece ``U'' o ``\s-1UNKN\s0'' o algo parecido, es lo mismo. Si hay alguna otra
diferencia, probablemente te equivocaste al introducir algu\*'n P valor
(asumiendo que mi tutorial esta\*' bien, por supuesto :\-). En ese caso, borra
la base de datos y prueba de nuevo.
.PP
Lo que representa exactamente esta salida lo vamos ma\*'s adelante en el tutorial.
.SS "Hora de hacer algunos gra\*'ficos"
.IX Subsection "Hora de hacer algunos gra'ficos"
Prueba este comando:
.PP
.Vb 4
\& rrdtool graph speed.gif \e
\& \-\-start 920804400 \-\-end 920808000 \e
\& DEF:myspeed=test.rrd:speed:AVERAGE \e
\& LINE2:myspeed#FF0000
.Ve
.PP
Este comando crea speed.gif, un gra\*'fico de los datos desde las
12:00 hasta las 13:00. Contiene una definicio\*'n de la variable myspeed
y define el color como rojo. Notara\*'s que el gra\*'fico no comienza
exactamente a las 12:00 sino a las 12:05, y es porque no tenemos datos
suficientes como para calcular el promedio de velocidad antes de ese
momento. Esto so\*'lo ocurre en caso de que se pierdan algu\*'n muestreo, lo
que esperamos que no debe ocurrir muy a menudo.
.PP
Si ha funcionado, Xfelicitaciones!. Si no, revisa que\*' puede estar mal.
.PP
La definicio\*'n de colores se construye a partir del rojo, verde y
azul. Especificas cuanto de cada uno de estos componentes vas a usar
en hexadecimal: 00 significa \*(L"nada de este color\*(R" y \s-1FF\s0 significa
\&\*(L"este color a ma\*'xima intensidad\*(R". El \*(L"color\*(R" blanco es la mezcla
del rojo, verde y azul a toda intensidad:
\&\s-1FFFFFF\s0; el negro es la ausencia de todos los colores: 000000.
.PP
.Vb 5
\& rojo #FF0000
\& verde #00FF00
\& azul #0000FF
\& violeta #FF00FF (mezcla de rojo y azul)
\& gris #555555 (un tercio de cada uno de los colores)
.Ve
.PP
El archivo \s-1GIF\s0 que acabas de crear puede
verse con tu visor de archivos de imagen favorito. Los navegadores lo
mostrara\*'n usando la \s-1URL\s0
``file://el/camino/de/directorios/hasta/speed.gif''
.SS "Gra\*'ficos con un poco de matema\*'tica"
.IX Subsection "Gra'ficos con un poco de matema'tica"
Cuando veas la imagen, notara\*'s que el eje horizontal tiene unas
etiquetas marcando las 12:10, 12:20, 12:30, 12:40 y 12:50. Los otros
dos momentos (12:00 y 13:00) no se pueden mostrar bien por falta de datos, asi\*' que
el programa se los salta. El eje vertical muestra el rango de los valores que
entramos. Introdujimos los kilo\*'metros y luego dividimos entre 300
segundos, por lo que obtuvimos valores bastante bajos. Para ser
exactos, el primer valor, 12 (12357\-12345), dividido entre 300 da
0.04, lo que RRDtool muestra como ``40m'', o sea ``40/1000''. XLa
``m''' no tiene nada que ver con metros, kilo\*'metros o mili\*'metros!.
RRDtool no sabe nada de unidades, el so\*'lo trabaja con nu\*'meros, no con
metros.
.PP
Donde nos equivocamos fue en que debimos medir en metros. Asi\*',
(12357000\-12345000)/300 = 12000/300 = 40.
.PP
Vamos a corregirlo. Podri\*'amos recrear la base de datos con los
valores correctos, pero hay una forma mejor: Xhaciendo los ca\*'lculos
mientras creamos el archivo gif!
.PP
.Vb 6
\& rrdtool graph speed2.gif \e
\& \-\-start 920804400 \-\-end 920808000 \e
\& \-\-vertical\-label m/s \e
\& DEF:myspeed=test.rrd:speed:AVERAGE \e
\& CDEF:realspeed=myspeed,1000,* \e
\& LINE2:realspeed#FF0000
.Ve
.PP
Cuando veas esta imagen, notara\*'s que la ``m'' ha desaparecido, y
ahora tienes los resultados correctos. Adema\*'s hemos an\*~adido una
etiqueta a la imagen. Apartando esto, el archivo \s-1GIF\s0 es el mismo.
.PP
Las operaciones esta\*'n en la seccio\*'n del \s-1CDEF\s0
y esta\*'n escritas en Notacio\*'n Polaca Inversa (Reverse Polish Notation o
``\s-1RPN\s0''). En palabras, dice: \*(L"toma la fuente de
datos myspeed y el numero 1000, y multipli\*'calos\*(R". No te molestes en
meterte con \s-1RPN\s0 todavi\*'a, la veremos con ma\*'s
detalle ma\*'s adelante. Adema\*'s, puede que quieras leer mi tutorial sobre
los \s-1CDEF\s0 y el tutorial de Steve Rader sobre \s-1RPN,\s0 pero primero terminemos con este.
.PP
XUn momento! Si podemos multiplicar los valores por mil, entonces,
Xtambie\*'n deberi\*'a ser posible el mostrar la velocidad en kilo\*'metros por
hora usando los mismos datos!
.PP
Para cambiar el valor que medimos en metros por segundo, calculamos
los metros por hora (valor * 3600) y dividimos entre 1000 para sacar
los kilo\*'metros por hora. Todo junto hace valor * (3600/1000) == valor
* 3.6.
.PP
Como en nuestra base de datos cometimos un error guardando los
valores en kilo\*'metros, debemos compensar por ello, multiplicando por
100, por lo que al aplicar esta correccio\*'n nos queda valor * 3600.
.PP
Ahora vamos a crear este gif, agrea\*'ndole un poco ma\*'s de magia...
.PP
.Vb 10
\& rrdtool graph speed3.gif \e
\& \-\-start 920804400 \-\-end 920808000 \e
\& \-\-vertical\-label km/h \e
\& DEF:myspeed=test.rrd:speed:AVERAGE \e
\& "CDEF:kmh=myspeed,3600,*" \e
\& CDEF:fast=kmh,100,GT,kmh,0,IF \e
\& CDEF:good=kmh,100,GT,0,kmh,IF \e
\& HRULE:100#0000FF:"Maximum allowed" \e
\& AREA:good#00FF00:"Good speed" \e
\& AREA:fast#FF0000:"Too fast"
.Ve
.PP
Esto luce mucho mejor. La velocidad en \s-1KM/H,\s0
y adema\*'s tenemos una li\*'nea extra mostrando la velocidad ma\*'xima
permitida (en el camino por donde conduzco). Tambie\*'n le cambie los
colores de la velocidad, y ahora paso de ser una li\*'nea a un a\*'rea.
.PP
Los ca\*'lculos son ma\*'s complejos ahora. Para calcular la velocidad \*(L"aceptable\*(R":
.PP
.Vb 2
\& Verifica si la velocidad en kmh es mayor que 100 ( kmh,100 ) GT
\& Si es asi\*', retorna 0, si no, retorna la velocidad ((( kmh,100 ) GT ), 0, kmh) IF
.Ve
.PP
Para calcular la parte de velocidad \*(L"excesiva\*(R":
.PP
.Vb 2
\& Verifica si la velocidad en kmh es mayor que 100 ( kmh,100 ) GT
\& Si es asi\*', retorna la velocidad, si no, retorna 0 ((( kmh,100) GT ), kmh, 0) IF
.Ve
.SS "Magia gra\*'fica"
.IX Subsection "Magia gra'fica"
Me gusta creer que virtualmente no hay limites para lo que RRDtool puede
hacer con los datos. No voy a explicarlo en detalle, pero mira este \s-1GIF:\s0
.PP
.Vb 12
\& rrdtool graph speed4.gif \e
\& \-\-start 920804400 \-\-end 920808000 \e
\& \-\-vertical\-label km/h \e
\& DEF:myspeed=test.rrd:speed:AVERAGE \e
\& "CDEF:kmh=myspeed,3600,*" \e
\& CDEF:fast=kmh,100,GT,100,0,IF \e
\& CDEF:over=kmh,100,GT,kmh,100,\-,0,IF \e
\& CDEF:good=kmh,100,GT,0,kmh,IF \e
\& HRULE:100#0000FF:"Maximum allowed" \e
\& AREA:good#00FF00:"Good speed" \e
\& AREA:fast#550000:"Too fast" \e
\& STACK:over#FF0000:"Over speed"
.Ve
.PP
Vamos a crear una pa\*'gina \s-1HTML\s0 simple para ver los tres archivos \s-1GIF:\s0
.PP
.Vb 7
\&
Velocidad
\&
\&
\&
\&
\&
\&
.Ve
.PP
Gua\*'rdalo como ``speed.html'' o algo parecido, y exami\*'nalo con un navegador.
.PP
Ahora, todo lo que tienes que hacer es medir los datos regularmente
y actualizar la base de datos. Cuando quieras verlos, vuelve a crear
los archivos \s-1GIF\s0 y asegu\*'rate que se carguen de nuevo en tu navegador
(Nota: presionar el boto\*'n de \*(L"refrescar\*(R" puede no ser suficiente; en
particular, Netscape tiene un problema al respecto, por lo que
necesitaras darle al boto\*'n mientras presionas la tecla de mayu\*'sculas.
.SS "Actualizaciones de verdad"
.IX Subsection "Actualizaciones de verdad"
Ya hemos usado el comando ``update''; vimos que recibia uno o ma\*'s
para\*'metros en el formato: ``:''. Para
facilitarte las cosas, puedes obtener la fecha actual colocando
``N'' en la fecha. Tambie\*'n podri\*'as usar la funcio\*'n
``time'' de Perl para obtenerla. El ejemplo ma\*'s corto de todo el
tutorial :)
.PP
.Vb 1
\& perl \-e \*(Aqprint time, "\en" \*(Aq
.Ve
.PP
Ahora, la forma de poner a correr un programa a intervalos
regulares de tiempo depende del sistema de operacio\*'n. La
actualizacio\*'n, en pseudo\-co\*'digo, seri\*'a:
.PP
.Vb 2
\& Toma el valor, colo\*'calo en la variable "$speed"
\& rrdtool update speed.rrd N:$speed
.Ve
.PP
(Pero no lo hagas sobre nuestra base de datos de pruebas, que au\*'n
la vamos a usar en otros ejemplos.
.PP
Eso es todo. Ejecutando este script cada 5 minutos, lo u\*'nico que
tienes que hacer para ver los gra\*'ficos actuales es correr los ejemplos
anteriores, que tambie\*'n puedes poner en un script. Luego de correrlo,
basta con cargar index.html
.SS "Unas palabras sobre \s-1SNMP\s0"
.IX Subsection "Unas palabras sobre SNMP"
Me imagino que muy pocas personas sera\*'n capaces de obtener en su
ordenador datos reales de su coche cada 5 minutos; los dema\*'s nos
tendremos que conformar con algu\*'n otro contador. Puedes, por ejemplo,
medir la cantidad de pa\*'ginas que ha hecho una impresora, cuanto cafe\*'
has hecho con la cafetera, el medidor del consumo de electricidad, o
cualquier otra cosa. Cualquier contador incremental puede
monitorizarse y graficarse con lo que has aprendido hasta ahora. Ma\*'s
adelante, veremos tambie\*'n como monitorizar otro tipo de valores, como
la temperatura. La mayori\*'a usaremos alguna vez un contador que lleve
la cuenta de cuantos octetos (bytes) a transferido un dispositivo de
red, asi\*' que vamos a ver como hacer esto. Empezaremos describiendo
como recoger los datos. Hay quien dira\*' que hay herramientas que pueden
recoger estos datos por ti. XEs cierto! Pero, creo que es importante
darse cuenta de que no son necesarias. Cuando tienes que determinar
porque\*' algo no funciona, necesitas saber co\*'mo funciona en primer lugar.
.PP
Una herramienta que mencionamos brevemente al principio del
documento es \s-1SNMP. SNMP\s0 es una forma de comunicarse con tus equipos.
La herramienta particular que voy a usar ma\*'s adelante se llama
``snmpget'', y funciona asi\*':
.PP
.Vb 1
\& snmpget dispositivo clave OID
.Ve
.PP
En \*(L"dispositivo\*(R" colocas el nombre o direccio\*'n \s-1IP\s0 del equipo a
monitorizar. En clave, colocas la \*(L"cadena de caracteres de la
comunidad de lectura\*(R", como se le denomina en el mundillo \s-1SNMP.\s0
Muchos dispositivos aceptara\*'n \*(L"public\*(R" como
cadena por defecto, pero por razones de privacidad y seguridad esta
clave puede estar deshabilitada. Consulta la documentacio\*'n
correspondiente al dispositivo o programa.
.PP
Luego esta el tercer para\*'metro, llamado \s-1OID\s0
(Object IDentifier, identificador de objeto).
.PP
Al principio, cuando empiezas a aprender sobre \s-1SNMP,\s0 parece muy
confuso. No lo es tanto cuando le hechas una ojeada a los
``\s-1MIB\s0'' (Manager Information Base, o Base de
Informacio\*'n Administrativa). Es un a\*'rbol invertido que describe los
datos, empezando en un nodo rai\*'z desde el que parten varias ramas.
Cada rama termina en otro nodo y puede abrir nuevas sub-ramas. Cada
rama tiene un nombre, y forman un camino que nos lleva hasta el fondo
del a\*'rbol. En este ejemplo, las ramas que vamos a tomar se llaman iso,
org, dod, internet, mgmt y mib\-2. Tambie\*'n pueden accederse por su
nu\*'mero relativo; en este caso, estos nu\*'meros son 1, 3, 6, 1, 2 y 1:
.PP
.Vb 1
\& iso.org.dod.internet.mgmt.mib\-2 (1.3.6.1.2.1)
.Ve
.PP
En algunos programas se usa un punto al iniciar el \s-1OID.\s0 Esto puede
ser confuso; no hay ningu\*'n punto inicial en la especificacio\*'n de los
\&\s-1OID...\s0 sin embargo, algunos programas usan por defecto un prefijo
inicial. Para indicar la diferencia entre los \s-1OID\s0 abreviados (o sea, a
los que se le pondra\*' el prefijo inicial) y los completos, estos
programas necesitan que los \s-1OID\s0 completos empiecen por un punto. Para
empeorar las cosas, se usan varios prefijos distintos...
.PP
De acuerdo, sigamos con el inicio de nuestro \s-1OID:\s0 teni\*'amos
1.3.6.1.2.1 . Ahora, nos interesa la rama ``interfaces'', que tiene el
nu\*'mero dos (o sea, 1.3.6.1.2.1.2, o 1.3.6.1.2.1.interfaces).
.PP
Lo primero es hacernos con un programa \s-1SNMP.\s0 Busca algu\*'n
paquete pre-compilado para tu plataforma, si no, puedes
buscar el co\*'digo fuente y compilarlo tu mismo. En Internet encontrara\*'s
muchos programas, bu\*'scalos con un motor de bu\*'squeda o como prefieras.
Mi sugerencia es que busques el paquete CMU-SNMP, que esta bastante difundido.
.PP
Asumamos que ya tienes el programa. Empecemos por tomar ciertos
datos que esta\*'n disponibles en la mayori\*'a de los sistemas. Recuerda:
hay un nombre abreviado para la parte del a\*'rbol que ma\*'s nos interesa.
.PP
Voy a usar la versio\*'n corta, ya que creo que este documento ya es
lo bastante largo. Si no te funciona, an\*~a\*'dele el prefijo .1.3.6.1.2.1
y prueba de nuevo. O prueba leyendo el manual; sa\*'ltate las partes que
no entiendas au\*'n, y busca las secciones que hablan de como arrancar y
usar el programa.
.PP
.Vb 1
\& snmpget myrouter public system.sysdescr.0
.Ve
.PP
El dispositivo debera\*' contestarte con una descripcio\*'n, probablemente
vaci\*'a, de si\*' mismo. Si no consigues una respuesta va\*'lida, prueba con
otra \*(L"clave\*(R" u otro dispositivo; no podemos seguir hasta tener un
resultado.
.PP
.Vb 1
\& snmpget myrouter public interfaces.ifnumber.0
.Ve
.PP
Con suerte, usando este comando obtendra\*'s un nu\*'mero como resultado:
el nu\*'mero de interfaces del dispositivo. Si es asi\*', seguiremos
adelante con otro programa, llamado \*(L"snmpwalk\*(R"
.PP
.Vb 1
\& snmpwalk myrouter public interfaces.iftable.ifentry.ifdescr
.Ve
.PP
Si obtienes una lista de interfaces, ya casi hemos llegado. Aqui\*'
tienes un ejemplo del resultado:
.PP
.Vb 6
\& [user@host /home/alex]$ snmpwalk cisco public 2.2.1.2
\& interfaces.ifTable.ifEntry.ifDescr.1 = "BRI0: B\-Channel 1"
\& interfaces.ifTable.ifEntry.ifDescr.2 = "BRI0: B\-Channel 2"
\& interfaces.ifTable.ifEntry.ifDescr.3 = "BRI0" Hex: 42 52 49 30
\& interfaces.ifTable.ifEntry.ifDescr.4 = "Ethernet0"
\& interfaces.ifTable.ifEntry.ifDescr.5 = "Loopback0"
.Ve
.PP
En este equipo \s-1CISCO,\s0 quiero monitorizar la interfaz \*(L"Ethernet0\*(R".
Viendo que es la cuarta, pruebo con:
.PP
.Vb 1
\& [user@host /home/alex]$ snmpget cisco public 2.2.1.10.4 2.2.1.16.4
\&
\& interfaces.ifTable.ifEntry.ifInOctets.4 = 2290729126
\& interfaces.ifTable.ifEntry.ifOutOctets.4 = 1256486519
.Ve
.PP
Entonces, tengo 2 OIDs que monitorizar, y son (en el formato largo, ahora):
.PP
.Vb 1
\& 1.3.6.1.2.1.2.2.1.10
\&
\& y
\&
\& 1.3.6.1.2.1.2.2.1.16
.Ve
.PP
, ambas con el nu\*'mero de interfaz de 4
.PP
No te engan\*~es, esto no lo logre yo al primer intento. Me tomo\*' un
tiempo entender lo que significaban todos estos nu\*'meros; ayuda cuando
se traducen en un texto descriptivo... por lo menos, cuando oigas
hablar de MIBs y OIDs, ahora sabra\*'s de que\*' se trata. No te olvides
del nu\*'mero de interfaz (0 si el valor no depende de una interfaz), y
prueba con snmpwalk si no obtienes una respuesta clara con snmpget.
.PP
Si entendiste todo esto, y obtienes resultados del dispositivo con
el que esta\*'s probando, sigue adelante con el tutorial. Si no, vuelve a
leer esta seccio\*'n; es importante
.SS "Un ejemplo real"
.IX Subsection "Un ejemplo real"
Ok, empecemos con la diversio\*'n. Primero, crea una base de datos
nueva. Vamos a guardar en ella 2 contadores, \*(L"input\*(R" y \*(L"ouput\*(R". Los
datos los vamos a guardar en archivos que los promediara\*'n, tomando
grupos de 1, 6, 24 o 288 muestras. Tambie\*'n archivaremos los valores
ma\*'ximos. Lo explicaremos con ma\*'s detalle despue\*'s. El intervalo de
tiempo entre las muestras sera\*' de 300 segundos (5 minutos).
.PP
.Vb 4
\& 1 muestra "promediada" sigue siendo 1 muestra cada 5 minutos
\& 6 muestras promediadas son un promedio de cada 30 minutos
\& 24 muestras promediadas son un promedio de cada 2 horas
\& 288 muestras promediadas son un promedio de cada di\*'a
.Ve
.PP
Vamos a tratar de ser compatibles con \s-1MRTG,\s0 que guarda ma\*'s o menos
esta cantidad de datos:
.PP
.Vb 4
\& 600 muestras de 5 minutos: 2 di\*'as y 2 horas
\& 600 promedios de 30 minutos: 12.5 di\*'as
\& 600 promedios de 2 horas: 50 di\*'as
\& 600 promedios de 1 di\*'a: 732 di\*'as
.Ve
.PP
Uniendo todos estos rangos tenemos que en total guardamos datos de
unos 797 di\*'as. RRDtool guarda los datos de una forma distinta a \s-1MRTG\s0;
no empieza el archivo \*(L"semanal\*(R" donde acaba el \*(L"diario\*(R", sino que
ambos archivos contienen la informacio\*'n ma\*'s reciente, Xpor lo que con
RRDtool archivamos ma\*'s datos que con \s-1MRTG\s0!
.PP
Necesitaremos:
.PP
.Vb 4
\& 600 muestras de 5 minutos (2 di\*'as y 2 horas)
\& 700 entradas de 30 minutos (2 di\*'as y 2 horas, ma\*'s 12.5 di\*'as)
\& 775 entradas de 2 horas (lo anterior + 50 di\*'as)
\& 797 entradas de 1 di\*'a (lo anterior + 732 di\*'as, redondeando)
\&
\& rrdtool create myrouter.rrd \e
\& DS:input:COUNTER:600:U:U \e
\& DS:output:COUNTER:600:U:U \e
\& RRA:AVERAGE:0.5:1:600 \e
\& RRA:AVERAGE:0.5:6:700 \e
\& RRA:AVERAGE:0.5:24:775 \e
\& RRA:AVERAGE:0.5:288:797 \e
\& RRA:MAX:0.5:1:600 \e
\& RRA:MAX:0.5:6:700 \e
\& RRA:MAX:0.5:24:775 \e
\& RRA:MAX:0.5:288:797
.Ve
.PP
Lo siguiente es recoger los datos y guardarlos, como en el ejemplo
siguiente. Esta parcialmente en pseudo\-co\*'digo, por lo que tendra\*'s que
buscar exactamente como hacerlo funcionar en tu sistema operativo.
.PP
.Vb 11
\& mientras no sea el fin del universo
\& hacer
\& tomar el resultado de
\& snmpget router community 2.2.1.10.4
\& en la variable $in
\& tomar el resultado de
\& snmpget router community 2.2.1.16.4
\& en la variable $out
\& rrdtool update myrouter.rrd N:$in:$out
\& esperar 5 minutos
\& hecho
.Ve
.PP
Luego, tras recoger datos por un di\*'a, crea una imagen, usando:
.PP
.Vb 5
\& rrdtool graph myrouter\-day.gif \-\-start \-86400 \e
\& DEF:inoctets=myrouter.rrd:input:AVERAGE \e
\& DEF:outoctets=myrouter.rrd:output:AVERAGE \e
\& AREA:inoctets#00FF00:"In traffic" \e
\& LINE1:outoctets#0000FF:"Out traffic"
.Ve
.PP
Este comando debe producir un gra\*'fico del tra\*'fico del di\*'a. Un di\*'a
son 24 horas, de 60 minutos, de 60 segundos: 24*60*60=86400, o sea que
empezamos a \*(L"ahora\*(R" menos 86400 segundos. Definimos (con los DEFs)
\&\*(L"inoctets\*(R" y \*(L"outoctets\*(R" como los valores promedio de la base da datos
myrouter.rrd, dibujando un a\*'rea para el tra\*'fico de entrada y una li\*'nea
para el tra\*'fico de salida.
.PP
Mira la imagen y sigue recogiendo datos por unos cuantos di\*'as. Si
lo deseas, puedes probar con los ejemplos de la base de datos de
pruebas y ver si puedes hacer trabajar las diversas opciones y
operaciones.
.PP
Sugerencia:
.PP
Haz un gra\*'fico que muestre el tra\*'fico en bytes por segundo y en
bits por segundo. Colorea el tra\*'fico Ethernet rojo si sobrepasa los
cuatro megabits por segundo.
.SS "Funciones de consolidacio\*'n"
.IX Subsection "Funciones de consolidacio'n"
Unos cuantos pa\*'rrafos atra\*'s habla\*'bamos sobre la posibilidad de
guardar el valor ma\*'ximo en vez del promedio. Profundicemos un poco en
este tema.
.PP
Recordemos lo que habla\*'bamos sobre la velocidad de un coche.
Supongamos que manejamos a 144 \s-1KM/H\s0 durante 5
minutos y luego nos detiene la polici\*'a durante unos 25 minutos. Al
finalizar el regan\*~o, tomamos nuestro porta\*'til y creamos una imagen
desde nuestra base de datos. Si visualizamos la segunda \s-1RRA\s0 que
creamos, tendremos el promedio de 6 muestreos. Las velocidades
registradas serian 144+0+0+0+0+0=144, lo que en promedio nos da una
velocidad de 24 \s-1KM/H.,\s0 con lo que nos igual nos
pondri\*'an una multa, so\*'lo que no por exceso de velocidad.
.PP
Obviamente, en este caso, no deberi\*'amos tomar en cuenta los
promedios. Estos son u\*'tiles en varios casos. Por ejemplo, si queremos
ver cuantos \s-1KM\s0 hemos viajado, este seri\*'a el
gra\*'fico ma\*'s indicado. Pero por otro lado, para ver la velocidad ha la
que hemos viajado, los valores ma\*'ximos son ma\*'s adecuados.
.PP
Es lo mismo con los datos que recogemos. Si quieres saber la
cantidad total, mira los promedios. Si quieres ver la velocidad, mira
los ma\*'ximos. Con el tiempo, ambas cantidades se separan cada vez ma\*'s.
En la u\*'ltima base de datos que creamos, habi\*'a dos archivos que
guardaban los datos de cada di\*'a. El archivo que guarda los promedios
mostrara\*' valores bajos, mientras que el de ma\*'ximos mostrara\*' valores ma\*'s
altos. Para mi coche, mostrari\*'a valores promedio de 96/24=4 \s-1KM/H\s0
(viajo unos 96 kilo\*'metros por di\*'a), y ma\*'ximos de 1220 \s-1KM/H\s0 (la
velocidad ma\*'xima que alcanzo cada di\*'a)
.PP
Como ves, una gran diferencia. No mires el segundo gra\*'fico para
estimar la distancia que recorro, ni al primero para estimar la
velocidad a la que voy. Esto so\*'lo funciona con muestras muy cercanas,
pero no si sacas promedios.
.PP
Algunas veces, hago un viaje largo. Si hago un recorrido por
Europa, conduciendo por unas 12 horas, el primer gra\*'fico subira\*'
a unos 60 \s-1KM/H.\s0 El segundo mostrara\*' unos 180 \s-1KM/H.\s0 Esto significa que
recorri\*' unos 60 \s-1KM/H\s0 por 24 horas = 1440 \s-1KM.\s0 Muestra adema\*'s que fui a
una velocidad promedio mayor a la normal y a un ma\*'ximo de 180 \s-1KM/H,\s0
Xno que fui 8 horas a una velocidad fija de 180 \s-1KM/H\s0! Este es un
ejemplo real: tengo que seguir la corriente en las autopistas de
Alemania, detenerme por gasolina y cafe\*' de vez en cuando, manejar ma\*'s
lentamente por Austria y Holanda, e ir con cuidado en las montan\*~as y
las villas. Si vie\*'ramos los gra\*'ficos de los promedios de cada 5
minutos, la imagen seri\*'a completamente distinta; veri\*'amos los mismos
valores de promedio y de ma\*'xima. (suponiendo que las mediciones fueran
cada 300 segundos). Se podri\*'a ver cuando pare\*', cuando iba en
primera, cuando iba por las autopistas, etc. La granularidad de los
datos es ma\*'s alta, por lo que se tiene ma\*'s informacio\*'n. Sin embargo,
esto nos lleva unas 12 muestras por hora, o 288 al di\*'a, lo cual es
mucho para guardar por un periodo de tiempo largo. Por lo tanto,
sacamos el promedio, guardando eventualmente un solo valor por di\*'a.
Con este u\*'nico valor, no podemos ver mucho.
.PP
Es importante comprender lo que expuesto en estos u\*'ltimos pa\*'rrafos.
Unos ejes y unas li\*'neas no tienen ningu\*'n valor por si mismos; hay que
saber que representan e interpretar correctamente los valores
obtenidos. Sean cuales sean los datos, esto siempre sera\*' cierto.
.PP
El mayor error que puedes cometer es usar los datos recogidos para
algo para lo cual no sirven. En ese caso, seria hasta mejor no tener
gra\*'fico alguno.
.SS "Repasemos lo que sabemos"
.IX Subsection "Repasemos lo que sabemos"
Ahora ya sabes como crear una base de datos. Puedes guardar valores
en ella, extraerlos creando un gra\*'fico, hacer operaciones matema\*'ticas
con ellos desde la base de datos y visualizar los resultados de estas
en vez de los datos originales. Vimos la diferencia entre los
promedios y los ma\*'ximos y cuando debemos usar cada uno (o al menos una
idea de ello)
.PP
RRDtool puede hacer ma\*'s de lo que hemos visto hasta ahora. Pero
antes de continuar, te recomiendo que releas el texto desde el
principio y pruebes a hacerle algunas modificaciones a los ejemplos.
Asegu\*'rate de entenderlo todo. El esfuerzo valdra\*' la pena, y te ayudara\*',
no so\*'lo con el resto del documento, sino en tu trabajo diario de
monitorizacio\*'n, mucho despue\*'s de terminar con esta introduccio\*'n.
.SS "Tipos de fuentes de datos"
.IX Subsection "Tipos de fuentes de datos"
De acuerdo, quieres continuar. Bienvenido de vuelta otra vez y
prepa\*'rate; voy a ir ma\*'s ra\*'pido con los ejemplos y explicaciones.
.PP
Ya vimos que, para ver el cambio de un contador a lo largo del
tiempo, tenemos que tomar dos nu\*'meros y dividir la diferencia entre el
tiempo transcurrido entre las mediciones. Para los ejemplos que hemos
visto es lo lo\*'gico, pero hay otras posibilidades. Por ejemplo, mi
enrutador me puede dar la temperatura actual en tres puntos distintos,
la entrada de aire, el llamado \*(L"punto caliente\*(R" y la salida de
ventilacio\*'n. Estos valores no son contadores; si tomo los valores de
dos muestreos y lo divido entre 300 segundos, obtendre\*' el cambio de
temperatura por segundo. XEsperemos que sea cero, o tendri\*'amos un
incendio en el cuarto de ordenadores! :)
.PP
Entonces, Xque hacemos? Podemos decirle a RRDtool que guarde los
valores tal como los medimos (esto no es exactamente asi\*', pero se
aproxima bastante a la verdad). Asi\*', los gra\*'ficos se vera\*'n mucho
mejor. Puedo ver cuando el enrutador esta\*' trabajando ma\*'s (en serio,
funciona; como usa ma\*'s electricidad, genera ma\*'s calor y sube la
temperatura), puedo saber cuando me he dejado las puertas abiertas (el
cuarto de ordenadores tiene aire acondicionado; con las puertas
abiertas el aire caliente del resto del edificion entra y sube la
temperatura en la entrada de aire del enrutador), etc. Antes usamos un
tipo de datos de \*(L"contador\*(R", ahora usaremos un tipo de datos
diferente, con un nombre diferente, \s-1GAUGE.\s0
Tenemos otros tipos:
.PP
.Vb 4
\& \- COUNTER este ya lo conocemos
\& \- GAUGE este acabamos de verlo
\& \- DERIVE
\& \- ABSOLUTE
.Ve
.PP
Los otros dos tipos son \s-1DERIVE\s0 y \s-1ABSOLUTE. ABSOLUTE\s0 puede usarse
igual que \s-1COUNTER,\s0 con una diferencia; RRDtool asume que el contador
se reinicia cada vez que se lee. O en otras palabras; el delta entre
los valores no hay que calcularlo, mientras que con \s-1COUNTER\s0 RRDtool
tiene que sacar e\*'l la cuenta. Por ejemplo, nuestro primer ejemplo,
(12345, 12357, 12363, 12363), seri\*'a (unknown, 12, 6, 0) en \s-1ABSOLUTE.\s0
El otro tipo, \s-1DERIVE,\s0 es como \s-1COUNTER,\s0 pero al contrario de \s-1COUNTER,\s0
este valor tambie\*'n puede decrecer, por lo que puede tenerse un delta
negativo.
.PP
Vamos a probarlos todos:
.PP
.Vb 10
\& rrdtool create all.rrd \-\-start 978300900 \e
\& DS:a:COUNTER:600:U:U \e
\& DS:b:GAUGE:600:U:U \e
\& DS:c:DERIVE:600:U:U \e
\& DS:d:ABSOLUTE:600:U:U \e
\& RRA:AVERAGE:0.5:1:10
\& rrdtool update all.rrd \e
\& 978301200:300:1:600:300 \e
\& 978301500:600:3:1200:600 \e
\& 978301800:900:5:1800:900 \e
\& 978302100:1200:3:2400:1200 \e
\& 978302400:1500:1:2400:1500 \e
\& 978302700:1800:2:1800:1800 \e
\& 978303000:2100:4:0:2100 \e
\& 978303300:2400:6:600:2400 \e
\& 978303600:2700:4:600:2700 \e
\& 978303900:3000:2:1200:3000
\& rrdtool graph all1.gif \-s 978300600 \-e 978304200 \-h 400 \e
\& DEF:linea=all.rrd:a:AVERAGE LINE3:linea#FF0000:"Line A" \e
\& DEF:lineb=all.rrd:b:AVERAGE LINE3:lineb#00FF00:"Line B" \e
\& DEF:linec=all.rrd:c:AVERAGE LINE3:linec#0000FF:"Line C" \e
\& DEF:lined=all.rrd:d:AVERAGE LINE3:lined#000000:"Line D"
.Ve
.SS "RRDtool bajo el microscopio"
.IX Subsection "RRDtool bajo el microscopio"
.IP "\(bu" 4
La li\*'nea A es un contador, por lo que
debe incrementarse continuamente y RRDtool tiene que calcular las
diferencias. Adema\*'s RRDtool tiene que dividir la diferencia entre
el tiempo transcurrido. Esto deberi\*'a terminar con una li\*'nea recta
en 1 (los deltas son 300, y los intervalos son de 300)
.IP "\(bu" 4
La li\*'nea B es de tipo \s-1GAUGE.\s0 Estos son
los valores \*(L"reales\*(R", asi\*' que el gra\*'fico debe mostrar lo mismo que
los valores que introducimos: una especie de onda
.IP "\(bu" 4
La li\*'nea C es de tipo \s-1DERIVE.\s0 Es un
contador, y puede decrecer. Va entre 2400 y 0, con 1800 en el medio.
.IP "\(bu" 4
La li\*'nea D es de tipo \s-1ABSOLUTE.\s0 Esto es,
es un contador pero no hay que calcular las diferencias. Los
nu\*'meros son iguales a la li\*'nea A, y espero
que puedas ver la diferencia en los gra\*'ficos.
.PP
Esto equivale a los valores siguientes, empezando a las 23:10 y
terminando a las 00:10 (las U significan desconocido).
.PP
.Vb 4
\& \- Li\*'nea A: u u 1 1 1 1 1 1 1 1 1 u
\& \- Li\*'nea B: u 1 3 5 3 1 2 4 6 4 2 u
\& \- Li\*'nea C: u u 2 2 2 0 \-2 \-6 2 0 2 u
\& \- Li\*'nea D: u 1 2 3 4 5 6 7 8 9 10 u
.Ve
.PP
Si tu archivo \s-1GIF\s0 muestra todo esto, has
entrado los datos correctamente, tu programa RRDtool esta\*' funcionando
bien, el visor de gra\*'ficos no te engan\*~a y hemos entrado en el 2000 sin
problemas :) Puedes probar el mismo ejemplo cuatro veces, una por cada li\*'nea.
.PP
Revisemos los datos otra vez:
.IP "\(bu" 4
Li\*'nea A: 300, 600, 900 , etc.
La diferencia del contador es siempre 300, igual que el intervalo de
tiempo transcurrido entre mediciones. Por lo tanto, el promedio
siempre es 1. Pero, Xpor que\*' el primer punto tiene un valor de
\&\*(L"desconocido\*(R"? XAcaso no era conocido el valor que pusimos en la
base de datos? XSi! Pero no teni\*'amos un valor inicial para
calcular la diferencia. Seri\*'a un error asumir que el contador
empezaba en 0, asi\*' que no conocemos el valor de la diferencia
.IP "\(bu" 4
Li\*'nea B:
No hay nada que calcular, los valores son los mismos que se
introdujeron en la base de datos.
.IP "\(bu" 4
Li\*'nea C:
De nuevo, no conocemos el valor
inicial antes de la primera medicio\*'n, asi\*' que se aplica el mismo
razonamiento que para la li\*'nea A. En este
caso las diferencias no son constantes, asi\*' que la li\*'nea no es
recta. Si hubie\*'semos puesto los mismos valores que en la li\*'nea
A, el gra\*'fico seri\*'a el mismo. Al contrario
que \s-1COUNTER,\s0 el valor puede decrecer, y espero mostrarte ma\*'s
adelante el por que de la diferencia entre ambos tipos.
.IP "\(bu" 4
Li\*'nea D: En este caso, el dispositivo nos
da las diferencias por si\*' mismo. Por lo tanto, conocemos la
diferencia inicial, y podemos graficarla. Tenemos los mismos
valores que en la li\*'nea A, pero su
significado es distinto, por lo que el gra\*'fico tambie\*'n lo es. En
este caso, las diferencias se incrementan en 300 cada vez,
mientras que el intervalo de tiempo permanece constante en 300
segundos, por lo que la divisio\*'n nos da resultados cada vez mayores.
.SS "Reinicializacio\*'n de los contadores"
.IX Subsection "Reinicializacio'n de los contadores"
Todavi\*'a nos quedan algunas cosas por ver. Nos quedan algunas
opciones importantes por cubrir, y aun no hemos hablado de la
reinicializacio\*'n de contadores. Empecemos por ahi\*': Estamos en nuestro
coche, vemos el contador y muestra 999987. Andamos unos 20 \s-1KM,\s0 asi\*' que
el contador debe subir a 1000007. Desafortunadamente, el contador
so\*'lo tiene 6 di\*'gitos, asi\*' que en realidad nos muestra 000007. Si
estuvie\*'ramos guardando los valores en un tipo \s-1DERIVE,\s0 esto
significari\*'a que el contador retrocedio\*' unos 999980 \s-1KM.\s0 Por supuesto
esto no es cierto, por lo que necesitamos alguna proteccio\*'n contra estos
casos. Esta proteccio\*'n so\*'lo la tenemos para el tipo \s-1COUNTER,\s0 el cual
de todas formas era el que teni\*'amos que haber usado para este tipo de
contador. XCo\*'mo funciona? Los valores tipo \s-1COUNTER\s0 no deben decrecer
nunca, Xpor lo que RRDtool asume en ese caso que el contador se ha
reinicializado! Si la diferencia es negativa, esto se compensa sumando
el valor ma\*'ximo del contador + 1. Para nuestro coche, tendri\*'amos:
.PP
.Vb 1
\& Delta = 7 \- 999987 = \-999980 (en vez de 1000007\-999987=20)
\&
\& Delta real= \-999980 + 999999 + 1 = 20
.Ve
.PP
Al momento de escribir este documento, RRDtool maneja contadores de
32 o 64 bits de taman\*~o. Estos contadores pueden manejar los siguientes
valores:
.PP
.Vb 2
\& \- 32 bits: 0 .. 4294967295
\& \- 64 bits: 0 .. 18446744073709551615
.Ve
.PP
Si estos valores te parecen raros, podemos verlos en formato hexadecimal:
.PP
.Vb 2
\& \- 32 bits: 0 .. FFFFFFFF
\& \- 64 bits: 0 .. FFFFFFFFFFFFFFFF
.Ve
.PP
RRDtool maneja ambos contadores de la misma manera. Si ocurre un
desbordamiento y la diferencia es negativa, RRDtool le suma primero
el ma\*'ximo del contador \*(L"menor\*(R" (32 bits) + 1 a la diferencia. Si au\*'n
asi\*' la diferencia es negativa, entonces el contador reinicializado era
mayor (64 bits), por lo que se le suma el valor ma\*'ximo del contador
\&\*(L"largo\*(R" + 1 y se le resta el ma\*'ximo del contador \*(L"pequen\*~o\*(R" que sumamos
erro\*'neamente. Hay un problema con esto: supongamos que un contador
largo se ha reinicializado al suma\*'rsele una diferencia muy grande;
entonces es posible que al an\*~adir el valor ma\*'ximo del contador pequen\*~o
la diferencia nos de\*' positivo. En este caso poco probable, los valores
resultantes no serian correctos. Para que ocurra esto, el incremento
tiene que ser casi tan grande como el valor ma\*'ximo del contador, por
lo que de ocurrir es muy probable que halla varios problemas ma\*'s en
la configuracio\*'n y no merezca la pena preocuparse so\*'lo por este. Au\*'n
asi\*', he incluido un ejemplo de este caso para que lo puedas juzgar por
ti mismo.
.PP
A continuacio\*'n, unos ejemplos de reinicializacio\*'n de los
contadores. Prueba de hacer los ca\*'lculos por ti mismo, o acepta mis
resultados si tu calculadora no puede con los nu\*'meros :)
.PP
Nu\*'meros de correccio\*'n:
.PP
.Vb 2
\& \- 32 bits: (4294967295+1) = 4294967296
\& \- 64 bits: (18446744073709551615+1)\-correction1 = 18446744069414584320
\&
\& Antes: 4294967200
\& Incremento: 100
\& Deberi\*'a ser: 4294967300
\& Pero es: 4
\& Diferencia: \-4294967196
\& Correccio\*'n #1: \-4294967196 + 4294967296 = 100
\&
\& Antes: 18446744073709551000
\& Incremento: 800
\& Deberi\*'a ser: 18446744073709551800
\& Pero es: 184
\& Diferencia: \-18446744073709550816
\& Correccio\*'n #1: \-18446744073709550816 +4294967296 = \-18446744069414583520
\& Correccio\*'n #2: \-18446744069414583520 +18446744069414584320 = 800
\&
\& Antes: 18446744073709551615 ( valor ma\*'ximo )
\& Incremento: 18446744069414584320 ( incremento absurdo,
\& Deberi\*'a ser: 36893488143124135935 mi\*'nimo para que
\& Pero es: 18446744069414584319 funcione el ejemplo)
\& Diferencia: \-4294967296
\& Correccio\*'n #1: \-4294967296 + 4294967296 = 0 (positivo,
\& por tanto no se hace
\& la segunda correccio\*'n)
\&
\& Antes: 18446744073709551615 ( valor ma\*'ximo )
\& Incremento: 18446744069414584319
\& Deberi\*'a ser: 36893488143124135934
\& Pero es: 18446744069414584318
\& Diferencia: \-4294967297
\& Correccio\*'n #1: \-4294967297 +4294967296 = \-1
\& Correccio\*'n #2: \-1 +18446744069414584320 = 18446744069414584319
.Ve
.PP
Como puede verse en los u\*'ltimos ejemplos, necesitas unos valores
bastante extran\*~os para hacer que RRDtool falle (asumiendo que no tenga
ningu\*'n error el programa, por supuesto), asi\*' que esto no deberi\*'a
ocurrir. Sin embargo, \s-1SNMP\s0 o cualquier otro
me\*'todo que uses de recogida de datos puede tambie\*'n reportar algu\*'n
valor erro\*'neo ocasionalmente. No podemos prevenir todos los errores,
pero podemos tomar algunas medidas. El comando \*(L"create\*(R" de RRDtool
tiene dos para\*'metros especialmente para esto, que definen los valores
mi\*'nimo y ma\*'ximo permitidos. Hasta ahora hemos usado \*(L"U\*(R",
\&\*(L"desconocido\*(R". Si le pasas valores para uno o ambos para\*'metros y
RRDtool recibe un valor fuera de esos li\*'mites, los ignorara\*'. Para un
termo\*'metro en grados Celsius, el mi\*'nimo absoluto es \-273. Para mi
enrutador, puedo asumir que ese mi\*'nimo es mucho mayor, digamos que 10.
La temperatura ma\*'xima la pondri\*'a en unos 80 grados; ma\*'s alto y
el aparato no funcionari\*'a. Para mi coche, nunca esperari\*'a obtener
valores negativos, y tampoco esperari\*'a valores mayores a 230.
Cualquier otra cosa seri\*'a un error. Pero recuerda, lo contrario no es
cierto: si los valores pasan este examen no quiere decir que sean los
correctos. Siempre examina bien el gra\*'fico si los valores parecen
extran\*~os.
.SS "Remuestreo de los datos"
.IX Subsection "Remuestreo de los datos"
Hay una funcionalidad importante de RRDtool que no hemos explicado
todavi\*'a: es virtualmente imposible recoger los datos y pasarselos a
RRDtool a intervalos exactos de tiempo. Por tanto, RRDtool interpola
los datos a los intervalos exactos. Si no sabes que significa esto o
como se hace, he aqui\*' la ayuda que necesitas:
.PP
Supongamos un contador se incremente exactamente en 1 cada segundo.
Queremos medirlo cada 300 segundos, por lo que deberi\*'amos tener
valores separados exactamente en 300. Sin embargo, por varias
circunstancias llegamos unos segundos tarde y el intervalo es 303. La
diferencia sera\*' por tanto 303. Obviamente, RRDtool no debe colocar 303
en la base de datos y dar asi\*' la impresio\*'n de que el contador se
incremento\*' 303 en 300 segundos. Aqui\*' es donde RRDtool interpola:
altera\*' el valor 303 al valor que tendri\*'a 3 segundos antes y guarda 300
en 300 segundos. Digamos que la pro\*'xima vez llegamos justo a tiempo;
por tanto, el intervalo actual es 297 segundos, por lo que el contador
deberi\*'a ser 297. De nuevo, RRDtool altera el valor y guarda 300, como
debe ser.
.PP
.Vb 5
\& en RRD en realidad
\& tiempo+000: 0 delta="U" tiempo+000: 0 delta="U"
\& tiempo+300: 300 delta=300 tiempo+300: 300 delta=300
\& tiempo+600: 600 delta=300 tiempo+603: 603 delta=303
\& tiempo+900: 900 delta=300 tiempo+900: 900 delta=297
.Ve
.PP
Creemos dos bases de datos ide\*'nticas. He escogido el rango de
tiempo entre 920805000 y 920805900.
.PP
.Vb 4
\& rrdtool create seconds1.rrd \e
\& \-\-start 920804700 \e
\& DS:seconds:COUNTER:600:U:U \e
\& RRA:AVERAGE:0.5:1:24
\&
\& para Unix: cp seconds1.rrd seconds2.rrd
\& para DOS: copy seconds1.rrd seconds2.rrd
\& para VMS: y yo que se\*' :)
\&
\& rrdtool update seconds1.rrd \e
\& 920805000:000 920805300:300 920805600:600 920805900:900
\& rrdtool update seconds2.rrd \e
\& 920805000:000 920805300:300 920805603:603 920805900:900
\&
\& rrdtool graph seconds1.gif \e
\& \-\-start 920804700 \-\-end 920806200 \e
\& \-\-height 200 \e
\& \-\-upper\-limit 1.05 \-\-lower\-limit 0.95 \-\-rigid \e
\& DEF:seconds=seconds1.rrd:seconds:AVERAGE \e
\& CDEF:unknown=seconds,UN \e
\& LINE2:seconds#0000FF \e
\& AREA:unknown#FF0000
\& rrdtool graph seconds2.gif \e
\& \-\-start 920804700 \-\-end 920806200 \e
\& \-\-height 200 \e
\& \-\-upper\-limit 1.05 \-\-lower\-limit 0.95 \-\-rigid \e
\& DEF:seconds=seconds2.rrd:seconds:AVERAGE \e
\& CDEF:unknown=seconds,UN \e
\& LINE2:seconds#0000FF \e
\& AREA:unknown#FF0000
.Ve
.PP
Los dos gra\*'ficos debe ser iguales.
.SH "RESUMEN"
.IX Header "RESUMEN"
Es hora de concluir este documento. Ahora debes conocer lo ba\*'sico
como para trabajar con RRDtool y leer la documentacio\*'n. Au\*'n hay mucho
ma\*'s por descubrir acerca de RRDtool, y le encontrara\*'s; ma\*'s y ma\*'s usos
para la herramienta. Con los ejemplos y la herramienta puedes crear
fa\*'cilmente muchos gra\*'ficos; tambie\*'n puedes usar las interfaces
disponibles.
.SH "LISTA DE CORREO"
.IX Header "LISTA DE CORREO"
Recuerda subscribirte a la lista de correo. Aunque no contestes los
correos que aparecen en ella, te servira\*' de ayuda a ti y a los dema\*'s.
Mucho de lo que se sobre \s-1MRTG\s0 (y por tanto sobre RRDtool), lo aprendi\*'
tan so\*'lo con leer la lista, sin escribir. No hay por que preguntar las
preguntas ba\*'sicas, que ya tienen su respuesta en la \s-1FAQ\s0 (Xle\*'ela!). Con
miles de usuarios a lo largo del mundo, siempre hay preguntas que tu
puedes responder con lo aprendido en este y otros documentos.
.SH "VER TAMBIE\*'N"
.IX Header "VER TAMBIE'N"
Las pa\*'ginas del manual de RRDtool
.SH "AUTOR"
.IX Header "AUTOR"
Espero que hayas disfrutado con los ejemplos y las descripciones.
Si es asi\*', ayuda a otros refirie\*'ndolos a este documento cuando te
hagan preguntas ba\*'sicas. No so\*'lo obtendra\*'n la respuesta, sino que
aprendera\*'n muchas otras cosas.
.PP
Alex van den Bogaerdt