27 de June de 2016

Jose Manuel

Conectando dos puntos a 8 km de distancia

Normalmente escribo para explicar cosas difíciles pero esta vez escribo para explicar algo extremadamente sencillo: tirar un "cable de red" entre dos puntos a 8 km de distancia a un coste irrisorio.

Nunca había confiado en la tecnología wireless y como además necesitas hacer una inversión en un equipamiento que no sabes si va a funcionar, nunca me había atrevido antes. Pero como este verano tenía un poco de tiempo he pensado que si otros se lo gastan en copas yo me lo puedo gastar en formación jugando a la antena rusa.

El resultado ha sido conseguir unir dos casas con visión directa en unas pocas horas con un "cable wireless".

Lo que queremos

Vamos a hacer que las dos casitas se vean como si estuvieran en la misma red. La casita de la derecha tendrá acceso a internet a través de la casita de la izquierda:

Fundamentos de andar por casa

Salvo que hayas estado viviendo en otro planeta los últimos 5 años, estarás familiarizado con la típica red wifi casera con un portátil (Station) conectado a un punto de acceso (Access Point) utilizando cifrado WPA2 Personal. Pues pon el punto de acceso (AP) en el foco de una antena parabólica, haz lo mismo con el portátil (Station) y aléjalos 1 kilómetro. Verás con sorpresa que sigue habiendo comunicación entre los dos.

Además necesitaríamos un protocolo que retransmitiera entre antenas paquetes como los que se usan para el DHCP. Como si las antenas fueran dos switches conectados por un cable "wireless". Pues el protocolo existe y se llama WDS.

Material que he usado

Dos antenas parabólicas que incluyan la electrónica de red necesaria para hacer de Access Point y Station. Deben poder configurarse en modo bridge y soportar WDS. Mejor si funcionan a 5GHz por la sobreutilización de los 2.4GHz . Las Ubiquiti PowerBeam M5 cumplen esas características.

También necesitaremos dos cables de red para unir el transformador con la antena ya que utiliza PoE (Power Over Ethernet) donde que se usan 2 pares para la red y otros dos pares para la alimentación.

Montaje

Lo primero, monta las antenas tal como pone en las instrucciones. La primera la monté yo y la segunda la montó mi hijo de 6 años así que no debe ser muy difícil.

Ahora, por cada antena, conecta un cable de red a la antena y el otro extremo donde pone PoE. Si enchufas el transformador se deberían encender las lucecitas de la antena.

Pon las antenas una frente a la otra a una cierta distancia. Puedes usar dos sillas, una en cada rincón de la habitación.

Configuración

Para la configuración he utilizado este enlace de ubiquity que describo a continuación.

Para las dos antenas

Entre el conector del transformador donde pone LAN y tu portátil conectas otro cable. Cuidado porque si te equivocas y conectas el portátil a donde pone PoE pasarán 24 voltios por la tarjeta de red, lo que hará que te empiece a oler a quemado y te quedes sin él.

Ahora accede a la antena como diga el manual (probablemente poniendo una dirección IP en un navegador) y configura una IP libre del rango que vayas a usar. En el caso del ejemplo será la 192.168.1.2 para una antena y la 192.168.1.3 para la otra.

Access Point

Elige una de las antenas como Access Point y configúrala de esta forma:

La configuración del "cable wireless" se hace en "Basic Wireless Settings" donde tendremos que poner:

  • Wireless Mode: Access Point
  • WDS: Activado
  • SSID: El SSID de la red wifi entre las dos antenas.

Seguramente querremos cifrar la información que pasa por el "cable wireless" así que podemos configurar WPA2 Personal en "Wireless Security" tal como se ve en la imagen.

Station

La otra antena se configura en modo Station (como si fuera el portátil que se conecta al punto de acceso) de esta forma:

Pruebas de conectividad

Si lo has hecho todo bien, estando conectado a una antena deberías poder hacer ping a la otra. Si esto funciona ya está tirado el cable entre las dos antenas y solo queda "estirarlo".

Orientar las antenas

La orientación de las antenas es un tema bastante delicado porque con una pequeña desviación el invento no funcionará, pero gracias a los móviles que tenemos ahora se puede hacer de una forma bastante sencilla y precisa.

Es extremadamente recomendable que haya dos personas, una en cada antena por si hay que reorientar. Yo lo hice solo y me funcionó a la primera pero reconozco que tuve mucha suerte.

Pon la antena en el poste de forma que no se caiga pero permita ser movida para orientarla correctamente.

Orientación horizontal.

Necesitas un programa tipo OsmAnd donde marcarás como destino el lugar donde vaya a ubicarse la otra antena. Vuelve a la ubicación actual y te saldrá una flechita que te indicará hacia donde orientar la antena.

Bloquea la rotación de la pantalla para que se quede siempre en vertical.

Pon el móvil dentro de la parabólica, justo en el centro y tocándola como si fuera el pincho de la antena (Antenna Feed). Orienta la antena hacia donde indica la flecha.

Orientación vertical.

A ojo la hice yo y me funcionó bien. ;-)

Pero si quieres hacerlo bien activa las curvas de nivel en el móvil, mira a que altura están los dos puntos que quieres unir y la distancia en línea recta. Restando las dos alturas vemos la diferencia de alturas, que es lo que nos interesa. Haz un eje de coordenadas y pon un puntito donde X será la distancia que separa los dos puntos e Y será la diferencia entre las dos alturas.

Para averiguar el ángulo solo tienes que pasar esas coordenadas rectangulares a coordenadas polares (θ = atan( y / x )).

Lo más importante es que si inclinas una antena 1 grado hacia arriba, inclines la otra 1 grado hacia abajo. Lo que subas en un extremo lo tienes que bajar en el otro si quieres que el invento funcione.

Comprobación de la fuerza de la señal

A la hora de orienar la antena podemos usar el programa que viene en la consola de gestión de la antena que nos dará una idea de la fuerza de la señal.

La hora de la verdad

Desde un extremo haz ping al otro y si funciona. ¡ya tienes el cable tirado!

27 de June de 2016 a las 07:00

08 de June de 2016

david::

Photo



08 de June de 2016 a las 15:12

25 de March de 2016

david::

On telegram and dependencies

I’ve just committed two small, but quite interesting, changes to zoe-startup-kit.

First, I’ve deprecated the tg bot in favour of rmed’s tgbot. It’s built on pyTelegramBotAPI, and works out of the box. Create your tg bot, paste the API key in etc/tgbot.conf and you’re done.

Regarding python dependencies, zam made me think. Not only it install the desired agent, it also installs its dependencies in agents/xx/lib. It can, and should, be added to the launch script. Paste your code, paste your dependencies in a file, you’re done.

Here you can find the tgbot agent. Notice the “pip-requirements.txt” file. Now, when it is first launched, its dependencies will be downloaded and added to sys.path automatically. Lovely.

25 de March de 2016 a las 09:37

10 de February de 2016

david::

Slides of my next #t3chfest 2016 talk

10 de February de 2016 a las 23:58

28 de September de 2015

Jose Manuel

Flash: ese spyware de Linux

En esta noche de insomnio he encendido el ordenador para aprovechar el tiempo y al arrancar el navegador el monitor de red registraba un tráfico de red de unos pocos kb/s cuando yo todavía no había abierto una página así que he hecho un "iftop -B -i wlan0" y me he encontrado una sorpresa.

La sorpresa

¡Tráfico desde y hacia la IP 66.117.29.11!

Investigando

Me conecto al puerto 80 y me devuelve un bonito "The requested URL "/test" was not found on this server. That's all we know.". Hago un escaneo de puertos y tiene abierto también el 443. Misma respuesta.

Apago el navegador, desactivo el plugin de flash y deja de haber tráfico. Ups, olvidé hacer un tcpdump para ver a que endpoint llegaba el tráfico.

Buscando en internet

He buscado la IP y parece que es de Adobe pero en virustotal pone que se resuelven dominios tan exóticos como nationalbankofcanada.tt.omtrdc.net y doy fe de que es así.

Mirando en abine veo que el dominio es de una empresa que se dedica a vender datos de usuario.

Conclusión

Supongo que el plugin estaría actualizando mis datos en su base de datos de usuarios.

No se en que momento el plugin de flash paso de ser algo serio a un virus pero no me extraña que haya bastantes empresas que lo rechacen frontalmente y que no funcione en algunos navegadores.

Y así es como mi relación con el plugin de flash terminó un 28 de Septiembre de 2015 a las 6 de la mañana.

28 de September de 2015 a las 05:00

12 de February de 2015

david::

Slides of my next #t3chfest talk

12 de February de 2015 a las 20:14

Jose Manuel

Redis Sentinel (parte 1)

Redis es un gestor de bases de datos nosql clave-valor que por si mismo no funciona en alta disponibilidad. Para conseguir la alta disponibilidad se utiliza sentinel que ya viene con redis desde la versión 2.8.

En este artículo indico como conseguir un redis en HA y como usarlo desde python ahorrándote unas horas de aprendizaje.

Si no tienes conocimientos básicos de clustering tendrás que hacer un acto de fe cuando diga ciertas cosas como que necesitamos al menos tres servidores. No voy a explicarlo en este artículo.

Como funciona

Sistemas

Redis se puede configurar en un conjunto de réplica con un primario y múltiples secundarios. El problema es que no tenemos failover, es decir, si se cae el redis primario todo el sistema deja de funcionar.

Para solucionar el problema, en vez de dotar de failover al propio redis, se ha creado otro componente llamado sentinel que monitoriza a los redis y es capaz de reconfigurar el replicaset para volver a otro estado estable y avisar a los clientes en caso de caída de un nodo de la réplica.p>

Salvando las distancias, es como si en mongodb tuviéramos 3 nodos árbitros y tres nodos de datos sin capacidad de votación. 6 procesos en total.

Desarrollo

Cuando te ofrecen un redis con un primario para hacer las escrituras y un secundario para lecturas asíncronas que seguramente pasarás de usar por si tiene datos desfasados, si se cae el primario tu programa dejará de funcionar.

Para solucionar ese problema, en vez de acceder directamente al redis, accederemos a sentinel que nos dirá cual es el nodo primario de redis y una vez tengamos esa información ya podremos acceder al redis primario.

Es solo agregar una línea más de código.

Despliegue

Necesitas tres servidores que llamaremos redis-01, redis-02 y redis-03.

Por si no quieres montarlos te los puedes bajar de los tres enlaces anteriores. Son contenedores lxc comprimidos así que para usarlos instala lxc con un

sudo apt-get install lxc
los descomprimes en /var/lib/lxc/ y los arrancas con
sudo lxc-start -n redis-01 -d
sudo lxc-start -n redis-02 -d
sudo lxc-start -n redis-03 -d
Puedes conectarte con root/root a las direcciones 10.0.3.201, 10.0.3.202 y 10.0.3.203.

Replica set

Tras instalar redis, nos aseguramos de que en /etc/redis.conf escuche en todas las interfaces comentando la línea:

bind_ip=127.0.0.1

Elegimos uno de los tres como primario y configuramos el resto como esclavos con un:

redis-cli
slaveof 10.0.3.201 6379

Tras hacerlo en los dos esclavos ejecutamos info en el maestro para comprobar que están replicando adecuadamente:

redis-cli
info

Sentinel

Viene junto con redis a partir de la versión 2.8 así que ya lo tendrás instalado sin saberlo.

Lo único que hay decirle a los sentinel es la ip y puerto del primario en la replica set. Con eso sacará cuales son los demás nodos del replica set y los demás sentinel que se hayan conectado a ese maestro.

En /etc/redis/redis-sentinel.conf de todos cambia esta línea

sentinel monitor mymaster 127.0.0.1 6379 2
Por esta otra
sentinel monitor mymaster 10.0.3.201 6379 2
Y ejecutar
redis-sentinel /etc/redis/redis-sentinel.conf
en los tres servidores.

12 de February de 2015 a las 18:24

09 de November de 2014

david::

Slides of my next tech FP talk at GUL UC3M

09 de November de 2014 a las 13:31

02 de November de 2014

david::

Introducing zoe.state

Suppose that you arrive home and Zoe asks you if you want to hear some music. You answer “yes” and she triggers a playlist. This is really easy to do:

  1. Create an agent that detects your presence at home (pinging your phone is enough) and asks you if you want to hear some music
  2. Create a command “yes” that, when invoked, plays your favourite spotify playlist.

Ok that was easy, let’s try something a little bit more difficult. Suppose you hate your neighbour and you are pretty sure that, eventually, you will want him killed. In fact it is not much harder:

  1. Create an agent that detects your anger (pretty easy) and asks you if you are angry because of your neighbour.
  2. Create a command “yes” that, when invoked, kills your neighbour. 

Now, you see the problem, you arrive at home, you are so happy because you got a raise, and Zoe asks you if you want to hear some music. You answer yes. 

Your favourite music starts playing and your neighbour dies. 

This happens because fuzzy commands are not exclusive. This means that you can have two different scripts that are activated with the command “yes”. Zoe can’t tell wether you are answering the music question or wether you are deciding on your neighbour fatal destiny. 

Correlating the “yes” command with your presence or anger would not be an optimal solution, because they are not exclusive: you can arrive at home angry and answer “yes” to the music question, and the killing bot would decide it’s a green light for him.

The solution here is simple: do not create a command that kills people with a single “yes”. Make it triggered with something like “yes, kill my neighbour”.

In any case, this example shows the underlying problem of managing state. Zoe is mostly a stateless machine (well, it depends on your agents). So, it would be great to have her some sense on your state. 

The following picture shows some code I’m working on:

image

  1. When zoe detects my presence, sends a “hello” message to this agent
  2. This agent offers me to hear some music and stores two commands, “yes /please” and “no /thanks”. Those commands are nothing but messages, in this case to the same agent.
  3. When I send her a “yes” or “no”, zoe sends the correct message to this agent.

Pretty easy, isn’t it? There are two main advantages of this:

  1. Inherent to this design, you can implement full workflows with this. 
  2. Now, what would happen if two different agents are triggered at the same time, one of them asking about music and the other asking about killing your neighbour, you answer will be sent only to the agent that asked last.

Now you can write at last your killer app.

02 de November de 2014 a las 18:34

25 de October de 2014

david::

Exact match in Zoe commands

We have just added exact match commands in Zoe. This lets you match the input command against a regexp.

When your command script is queried with –get, just return the regexp quoted in “/” and no \n at the end. That is, 

echo -n “/your regexp here/”

When the user asks for something that matches the regexp, your script will be invoked with the following options:

If you are a sysadmin or a more-than-a-newby UNIX user, you will feel so comfortable with this. Have a taste of this exact match support in https://github.com/voiser/zoe-startup-kit/blob/master/cmdproc/regexp.sh

25 de October de 2014 a las 10:10

07 de September de 2014

Jose Manuel

Ubuntu 14.04 con el escritorio clásico

Aburrido estarás ya de sitios en los que dicen que Ubuntu es la solución al hambre en el mundo. No lo es pero en este momento me parece la mejor distribución que hay para cualquier uso muy por encima del resto.

Una de las cosas que me enerva hasta el punto de haberme pasado a KDE durante una temporada es Unity o el nuevo Gnome que viene en Ubuntu Gnome así que vamos a ver cómo cargárnoslos para poner un Gnome normal al que le funcione todo incluidos los efectos de escritorio.

¡32 bits por favor!

Como cada dos años he vuelto a cometer el mismo error: instalar Ubuntu de 64 bits. Este año el escarmiento ha venido por haber intentado asistir a un webinar con webex y no poder hacerlo porque el javaleches que utilizaba sólo funcionaba bien con 32 bits.

Con esto no digo que la de 64 bits vaya mal pero siempre hay alguna aplicación privativa que no te va a funcionar y necesitas que funcione.

Es increíble que a estas alturas sigamos así pero "esto es lo que hay y nosotros no hemos sido". Advertido quedas.

Ubuntu != Ubuntu Gnome

Después de hacer todo lo que pongo abajo no quedará el mismo escritorio con uno que con otro empezando por el gestor de archivos que es distinto en uno o en otro, o la posibilidad de usar una segunda fila de escritorios que con Ubuntu Gnome se vuelve más engorrosa.

Si todavía no has elegido mejor instala Ubuntu con Unity que tras los cambios te resultará más familiar.

Instalando gnome sin efectos

Instalamos los paquetes necesarios:

sudo apt-get install gnome-session-flashback

Activando los efectos: empiezan los problemas

Como te podrás imaginar para lo de arriba no me molesto en escribir una entrada. Los problemas vienen a partir de ahora cuando activamos los efectos porque deja de funcionar el Alt-Tab y no podemos elegir el número de escritorios.

Activar drivers privativos

Necesitamos que la tarjeta de vídeo funcione bien así que vamos a controladores adicionales:

E instalamos los que nos toquen. En mi caso los de nvidia.

Cuando acabes reinicia y arranca con Gnome Flashback (Compiz).

Instalando gnome con efectos

Primero instala los paquetes necesarios:

sudo apt-get install compiz-plugins compiz-plugins-default compizconfig-settings-manager

Arrancando CompizConfig Settings Manager

Nos interesa el el Compiz Config Settings Manager así que ve a "Herramientas del sistema|Preferencias|CompizConfig Settings Manager"

Configurando varios escritorios

Pincha en "Opciones Generales":

Ve a la pestaña de la derecha que pone "Tamaño de Escritorio". No se ve así que tienes que darle a la flecha de la derecha hasta que aparezca:

En este punto puedes elegir el número de escritorios y su disposición en altura y longitud. Si has instalado Ubuntu Gnome sólo podrás moverte con Ctrl-Alt-Cursor de forma horizontal. Supongo que para moverte de forma vertical tendrás que configurar algo en algún sitio que no me he molestado en mirar.

Configurando Alt-Tab para cambiar entre ventanas

Vamos a "Gestión de ventanas|Cambiador de Aplicaciones" y lo activamos:

En este punto ya funcionará el Alt-Tab pero se verá un poco feo así que vamos a ir a su configuración pinchando en su icono y desactivamos el check de "Icono".

cerrar,minimizar,maximizar:menu

Desde mi punto de vista los botones del marco de la ventana deberían estar a la izquierda en ese orden pero hay gente que los quiere más a lo Windows.

Si has instalado Ubuntu Gnome los tienes a lo Windows y si es Ubuntu los tendrás a la izquierda.

Para cambiarlos ejecuta instala dconf-editor y luego ejecuta dconf-editor en cualquier terminal y ve a la clave "org|gnome|desktop|wm|preferences|button-layout" o dale a buscar button-layout y te saldrá directamente la clave que buscamos.

Resultado de "close,minimize,maximize:menu":

Resultado de ":minimize,maximize,close":

El álbum de hoy

Nomoredolls - Nomoredolls (caché), un poco de rock para empezar la mañana:

07 de September de 2014 a las 15:37

28 de July de 2014

Jose Manuel

Introducción a ELK (Elasticsearch, Logstash y Kibana) (parte 3)

En todas las aplicaciones que he conocido el cuello de botella siempre ha estado en el mismo sitio: el almacenamiento.

Puedes poner 20 frontales web y 20 servidores de aplicación pero en la capa de persistencia tiene que haber un almacenamiento compartido que puede provocar verdaderos quebraderos de cabeza y muchas noches de insomnio al sysadmin de turno.

Para entender la problemática vamos a ver que tiempos manejamos en un entorno típico con mysql y cómo escalamos con Elasticsearch. En los siguientes artículos de SQL vs NoSQL entraré más en el detalle. En este artículo sólo quiero que se entienda la problemática y cómo se podría "resolver" con Elasticsearch.

Más rápido por favor

Imaginémonos que usamos mysql en mi portátil manejando unos tiempos de 0.01 segundos por inserción:

mysql> create table `tabla` (`id` varchar(5) NOT NULL, `data` varchar(5), primary key(`id`));
Query OK, 0 rows affected (0.02 sec)

mysql> insert into `tabla` values ("1","2");
Query OK, 1 row affected (0.01 sec)

mysql> insert into `tabla` values ("2","2");
Query OK, 1 row affected (0.00 sec)

mysql> insert into `tabla` values ("3","2");
Query OK, 1 row affected (0.00 sec)

mysql> insert into `tabla` values ("4","2");
Query OK, 1 row affected (0.02 sec)

mysql> 

Eso nos da una capacidad máxima de 100 inserciones por segundo que podrá parecer mucho pero ahora imagínate 10 servidores enviando líneas de log a razón de 10 por segundo de forma simultánea y verás como no te parece tanto.

Con elasticsearch dentro de una máquina virtual con discos de portátil estoy sacando unas 300 inserciones por segundo. Está mejor pero también tenemos un techo.

Soluciones SQL

Usar el típico entorno de replicación de mysql no soluciona el problema porque tenemos más escrituras que lecturas. En todo caso lo empeoraría porque la base de datos estaría más tiempo ocupada enviando datos a sus réplicas.

También podríamos tener varios servidores de mysql e ir enviando las líneas de log en roundrobin pero eso obligaría al software que va a explotar esos datos a hacer una gestión extra.

Además, al utilizar SQL, el software que va a insertar y explotar esos datos está obligado a cambiar el esquema de la base de datos cada vez que haya un cambio de un campo en un archivo de log.

Solución Elasticsearch

Elasticsearch es un gestor de bases de datos NoSQL que para el caso que nos ocupa tiene tres ventajas:

  • Todos son maestros: En un grupo de replica (replica set) puedes insertar datos en cualquier servidor que ellos se las apañarán para replicarlos en los demás.
  • Inserción asíncrona: Se envían los datos a la base de datos y el servidor te da el OK antes de hacer la inserción real en la base de datos y replicarlo al resto. Esto reduce muuuuucho los tiempos de inserción aunque crea otros problemas de latencia que en este dominio nos dan exactamente igual.
  • Sin esquema: en una misma "tabla" puedes insertar "filas" con diferentes esquemas lo que posibilita poder insertar líneas de log desde diferentes orígenes. Pongo tabla y filas entre comillas porque ni las tablas se llaman tablas ni las filas se llaman filas, pero ya lo veremos en un artículo posterior.

Solución escalable

"Solucionando" cuellos de botella

En esta solución utilizaremos un servidor de redis que es otro gestor NoSQL (¡sorpresa!) utilizado como catalizador para que el logstash que almacena los datos en elasticsearch no explote. Se usará como un gestor de colas donde los agentes irán metiendo líneas de log desde los servidores y logstash las irá recogiendo para insertarlas en la base de datos.

De esta forma conseguimos:

  • Paliar el problema con el cuello de botella en la base de datos.
  • Monitorizar cuando nos vamos quedando sin capacidad mirando la longitud de la cola en redis. Por ejemplo haciendo un plugin de Zabbix que mire el tamaño de la cola de redis y nos devuelva un número que luego se podrá representar en una gráfica. Si el número supera un umbral. ¡alerta, necesitamos más capacidad!

Visto en código suponiendo que tomamos los datos de un apache en el agente fíjate en el output:

input {
  file {
    type => "auth"
    path => "/var/log/auth.log"
  }
}
filter {
  # This is a standard syslog line like this:
  # Mar  9 17:17:02 path-precise CRON[25638]: pam_unix(cron:session): session closed for user root
  if [type]=="auth" {
    # Look for patterns in /opt/logstash/patterns/grok-patterns
    grok {
      match => [ "message", "%{SYSLOGLINE}" ]
    }
    # Set timestamp: http://logstash.net/docs/1.4.1/filters/date#match
    date {
      match => [ "timestamp", "MMM dd HH:mm:ss",
                              "MMM  d HH:mm:ss",
                              "ISO8601" ]
    }
  }
}
output {
  redis {
    host => "localhost"
  }
}
Y en el servidor de logstash fíjate en input:
input {
  redis {
    host => "localhost"
  }
}
output {
  elasticsearch_http {
    host => "127.0.0.1"
  }
}

Podríamos tener múltiples agentes disparando al mismo redis y de ahí viene la solución oficial:

Hay que tener cuidado con redis porque para ganar velocidad almacena en memoria los datos así que en caso de dejar de funcionar el logstash o el elasticsearch durante un período de tiempo prolongado te puedes encontrar con un redis que ocupa en memoria 4GB. Si, también me ha pasado, ... hace una semana (nota mental: volver a poner 4GB de memoria al servidor de logstash ;-) ).

Escalando horizontalmente

La alarma que tenemos para la longitud de la cola de redis se dispara y en el kibana vemos datos de lo que pasó hace una hora. El problema puede estar en Logstash o en Elasticsearch así que vamos a crear otra máquina virtual con la pila completa de Redis, Logstash, Elasticsearch en cluster con el otro y un Kibana.

¡Cuidado! Para escalar realmente necesitaríamos tocar conceptos como el sharding que se tocarán en un artículo posterior. Aquí vamos a crear un conjunto de réplica entre dos servidores de Elasticsearch.

¿Has replicado ya el entorno anterior? ¿Y a qué estás esperando? Cuando tengas los dos servidores de Elasticsearch levantados en la misma red verás con sorpresa que ¡Ya están en el conjunto de réplica! Abre los kibanas de ambas instancias y verás como ves los mismos datos.

Este fue el detonante que me impulsó a meterme en el mundo NoSQL. Yo que vengo de un mundo de almacenamientos compartidos, clusters RedHat, IPs flotantes, réplicas que no se recuperan automáticamente en caso de caída de un maestro ... y va este y se configura sólo con un doble click sin pedirle permiso al sistema operativo.

Configuración de Elasticsearch

Su configuración por defecto está escuchando a que alguien dentro del cluster "elasticsearch" se anuncie por multicast. Cuando eso ocurre los dos servidores se sincronizan y a partir de ahí los datos que insertas en un servidor están disponibles en el otro un segundo más tarde.

La configuración más relevante que puedes encontrar en /etc/elasticsearch/elasticsearch.yml y que permite este comportamiento es la siguiente:

cluster.name: elasticsearch
discovery.zen.ping.multicast.enabled: true

Con un rápido vistazo en el archivo de configuración podrás ver entre otras cosas que también puedes utilizar unicast para la configuración entre los nodos en caso de que estés usando una red que no permita usar multicast o servidores en la nube como por ejemplo dos instancias de Amazon EC2.

Plugin para ver el estado del cluster en un navegador

Con el plugin elasticsearch-head podemos ver el estado del cluster y gestionarlo desde un navegador.

Solución a problemas que te acabarán ocurriendo

Antes de nada ten presente que logstash crea una "base de datos", que en elasticsearch se llama indice, cada día. Supongo que hace esto para que el indice de logs no crezca hasta el infinito haciéndose inmanejable. Puedes ver los que ha ido creando en /var/lib/elasticsearch/elasticsearch/nodes/0/indices/.

Too many open files

Te pasará más o menos en el momento en que todo el mundo se haya acostumbrado a usar el kibana y se haya convertido en una aplicación crítica para la empresa pero no tengas sufiente experiencia para solucionar el problema rápidamente. Como será algo con lo que no contabas probablemente tampoco tengas tiempo para solucionarlo. Eso fue lo que me pasó a mi.

La causa del problema es que cada vez que logstash crea un índice en elasticsearch éste crea y mantiene abiertos un porrón de archivos. En mi caso para el índice logstash-2014.07.08 tiene abiertos 62 archivos:

root@path-precise:/etc/elasticsearch# lsof | grep /var/lib/elasticsearch/elasticsearch/nodes/0/indices/logstash-2014.06.26 | wc
     62     558   10582
root@path-precise:/etc/elasticsearch# 

Como además la configuración por defecto de elasticsearch crea tres shards el número de archivos abiertos se triplica. No voy a explicar esta afirmación. Veremos que es un shard en un artículo posterior.

Llegar al límite de 1024 archivos, se llega bastante rápido así que deberás realizar estas tres cosas en el servidor:

  • Reducir el número de shards a 1: Si tu elasticsearch va sobrado de capacidad en el archivo de configuración de elasticsearch /etc/elasticsearch/elasticsearch.yml, sección Index, deja la siguiente configuración:
    index.number_of_shards: 1
    index.number_of_replicas: 0
    
  • Desactivar o eliminar los indices que no utilices: esto hará que la información de los mismos no esté accesible pero tampoco se abran los archivos que componen el indice:
    • Desactivar un indice:
      curl -XPOST 'localhost:9200/logstash-2014.06.26/_close'
    • Eliminar un indice:
      curl -XDELETE 'http://localhost:9200/logstash-2014.06.26/
  • Aumentar el límite de archivos abiertos en el /etc/security/limits.conf: se puede aumentar agregando las líneas:
    logstash  hard  nofile 32000
    logstash  soft  nofile 32000

Se me ha llenado el disco y ahora elasticsearch no arranca

No digo que me haya pasado, porque si me hubiera pasado significaría que no tenía bien monitorizada la máquina y que no me habría dado cuenta cuando ocurrió, pero en el hipotético caso de que me hubiera pasado, que no digo que me haya pasado, lo que hay que hacer es arreglar o borrar unos archivos de datos que se han corrompido.

Elasticsearch, antes de insertar datos de verdad, los guarda en unos archivos de texto que usa como si fuera un buffer. El problema es que al estar el disco lleno esos archivos de texto se corrompen así que cuando Elasticsearch va a leerlos para indexar esos datos no puede hacerlo y se pega un tortazo.

Una vez liberado el disco, el archivo que tienes que arreglar o borrar con la consecuente pérdida de datos está en el directorio translog del indice que de problemas. El log del elasticsearch te dirá cual está fallando. Por ejemplo, si te dice que el shard 0 del indice test está fallando vas a /var/lib/elasticsearch/elasticsearch/nodes/0/indices/test/0/translog y dentro verás que hay dos archivos, un translog-1405060275771 y otro translog-1405060275771.recovering. El que tienes que arreglar o borrar es el que se apellida .recovering .

El álbum de hoy

Shedneryan debe ser la obra que más he escuchado de Jamendo (caché). Ideal para trabajar:

Espero que este artículo te haya servido de ayuda.

28 de July de 2014 a las 05:53

06 de July de 2014

Jose Manuel

ManiaDrive

Maniadrive es un juego de coches de los que jugábamos cuando éramos pequeños. Me vino a la cabeza porque ahora tengo un hijo pequeño así que lo he sacado del cajón y empaquetado para vosotros.

Se trata de un clon del conocido trackmania pero con licencia libre.

Descripción

Incluye un montón de pistas así que se puede jugar en modo historia.

También puedes usar el modo multijugador por internet o crear tus propias pistas con el editor que viene integrado. Hice esta pista para que el niño aprendiera a usar su primer juego de coches:


Si quieres usarla descarga el archivo en ~/.mania_drive/data y cárgala desde el editor.

Paquete para Ubuntu

He hecho un paquete a partir de los binarios que se pueden bajar desde sourceforge que configura el sonido a través de alsa-oss y añade las entradas "ManiaDrive" y "ManiaDrive track editor" en el apartado de juegos:

Algunas imágenes del juego

Espero que os guste:

06 de July de 2014 a las 15:35

26 de June de 2014

Jose Manuel

Introducción a ELK (Elasticsearch, Logstash y Kibana) (parte 2)

Vamos a hacer algo útil con los datos que tenemos sin modificar mucho el ejemplo anterior. La salida, en vez de ir a un correo vamos a meterla en Elasticsearch para luego poder hacer consultas con Kibana.

Hay multitud de tutoriales en internet así que no me voy a extender mucho en el cómo hacerlo sino en qué cosas puede hacer que funcione mejor en base a mi experiencia en los casi dos años que llevo usándolo.

¿Cómo funciona?

El esquema será el que ilustra la imagen de la portada donde se ve el flujo de los datos.
Esta imagen no refleja el cómo los datos viajan de un lado al otro y eso es lo que realmente hace falta entender así que ahí va la misma imagen ligeramente retocada:

Como ves hay dos almacenes (log y elasticsearch) en los que están los datos que nos interesan y dos piezas de software (logstash y kibana) que hacen transformaciones con ellos y los mueven o los muestran como nosotros queremos.

Logstash

Si has seguido las instrucciones del artículo anterior ya lo tienes instalado.

Para acceder a los logs que necesitamos es necesario que se ejecute como root así que ve a /etc/default/logstash y pon LS_USER=root.

Dado que va a leer de los logs en este caso (aunque podría leer desde otro sitio) y escribir en elasticsearch necesitamos saber cómo son los logs de los que vamos a leer y cómo meter los datos en elasticsearch.

read

La primera parte es la más peliaguda porque cada aplicación tiene un log distinto pero hay un par de cosas que tendremos que tener en cuenta siempre:

  • Formato de la hora que usa la aplicación para escribir en el log
  • Datos que podemos querer consultar del log
timestamp

Me viene a la cabeza el log de squid donde la hora viene en el primer campo en segundos desde 01/Ene/1970 (fecha epoch) hasta la del apache donde viene en formato legible en el cuarto campo pasando por las de diversas aplicaciones que guardan el día y la hora en dos campos distintos separados por un pipe "|".

Si queremos hacer una consulta del estilo "¿qué paso esta noche a las 3 de la madrugada?" necesitamos que logstash sea capaz de entender todos esos formatos de hora para poder insertarlos en la base de datos con el mismo timestamp.

fields

Pongamos por caso que tenemos el log de apache siguiente:

127.0.0.1 - - [20/Jul/2013:08:16:58 +0200] "POST /my/machines HTTP/1.1" 404 443 "-" "-"

Si utilizamos como separador de campo los espacios veremos que nos meterá la fecha en dos campos y eso no es lo que queremos. Tampoco podemos separar campos utilizando comillas porque no todos los campos tienen comillas así que hay que gestionar esto de una forma más inteligente.

write

En este caso concreto es bien fácil, ya que existe el output elasticsearch al que le indicamos donde está la base de datos y el resto lo gestiona él.

Hay dos cosas a tener en cuenta:

  • Utilizar el plugin de elasticsearch con protocol => "http" para utilizar el API Rest de la base de datos. De esta forma ante una actualización de logstash o la base de datos, es menos probable que se rompa la aplicación.
  • logstash crea una base de datos diaria y realiza muchos accesos a disco lo cual, tras meses de uso, puede desembocar en problemas para el sistema operativo que se tratarán en la sección de elasticsearch.

Ejemplo completo: SpyYourFriend

Queremos poder responder a la siguiente pregunta: ¿cuando se eliminó el directorio /var/www/kibana del servidor y quien lo hizo?

Vamos a utilizar como fuente de datos el .bash_history y el /var/log/auth.log.

Pasos:

  • Configurar la bash para que agregue líneas en el history cada vez que se pulsa el enter y que ponga la fecha de cada comando en el log.
  • Configurar logstash para extraer los campos de cada log e insertar la información en la base de datos.
Configurar la bash

No me extiendo mucho. Simplemente agrega esto al .bashrc de root:

export HISTTIMEFORMAT="%F %T "
export PROMPT_COMMAND='history -a'

Con esto dejaremos el timestamp de cada comando en /root/.bash_history y forzaremos a escribir en el history cada vez que tecleamos un comando en vez de al hacer logout.

Configurar logstash para extraer datos de /var/log/auth.log

Vamos a introducir la variable type que utilizaremos para "etiquetar" un flujo y poderle dar un trato diferencial a lo largo del archivo de configuración de logstash. A tener en cuenta:

  • Entrada: líneas del archivo en "/var/log/auth.log"
  • Proceso: extraer campos y configurar timestamp.
  • Salida: enviar todo a elasticsearch.
input {
  file {
    type => "auth"
    path => "/var/log/auth.log"
  }
}
filter {
  # This is a standard syslog line like this:
  # Mar  9 17:17:02 path-precise CRON[25638]: pam_unix(cron:session): session closed for user root
  if [type]=="auth" {
    # Look for patterns in /opt/logstash/patterns/grok-patterns
    grok {
      match => [ "message", "%{SYSLOGLINE}" ]
    }
    # Set timestamp: http://logstash.net/docs/1.4.1/filters/date#match
    date {
      match => [ "timestamp", "MMM dd HH:mm:ss",
                              "MMM  d HH:mm:ss",
                              "ISO8601" ]
    }
  }
}
output {
  elasticsearch {
    protocol => "http"
    host => "localhost"
  }
}

Este es el ejemplo más sencillo que puede haber pero se puede complicar bastante. Pasemos al ejemplo siguiente.

Configurar logstash para extraer datos del history

El archivo de history tiene una pinta como esta:

root@yinyan-precise:~# tail .bash_history 
#1403070049
history
#1403070054
ls
#1403070056
history
#1403070062
cd
#1403070066
more .bash_history 
root@yinyan-precise:~#

donde como se puede observar el timestamp está escrito en formato epoch precedido por un "#" y además el comando está en la siguiente línea. Esto último seguro que te recuerda al catalina.out del tomcat donde cada "línea" de log está compuesta de múltiples líneas.

  • Entrada: /root/.bash_history
  • Proceso:
    1. Juntamos las dos líneas en una sola eliminando '\n' y '#'
    2. Extraemos el campo de la fecha y el de la línea de comandos
    3. Utilizamos la fecha en formato epoch para poner valor al timestamp
    4. Agregamos un campo con la línea en formato más legible
  • Salida: Elasticsearch

Agárrate que vienen curvas:

input {
  file {
    type => "bash_history"
    path => "/root/.bash_history"
  }
}
filter {
  if [type]=="bash_history" {
    # Poner las dos líneas como una sola en el campo message
    multiline {
      pattern => "^#"
      what => "next"
    }
    # Cambiar fecha del principio
    # Vamos a separar los campos eliminando el retorno de carro y el comentario
    mutate {
      add_field => ["temp_message", "%{message}"]
    }
    mutate {
      gsub => [
        "temp_message", "\n", " ",
        "temp_message", "^#", ""
      ]
    }
    grok {
      match => [ "temp_message", "%{WORD:unix_date} %{GREEDYDATA:command_line}"]
    }
    mutate {
      remove_field => ["temp_message"]
    }
    # Copio el contenido del timestamp a otra variable para conservar el momento
    # en que el mensaje llegó al servidor de logstash
    mutate {
      add_field => [ "input_timestamp", "%{@timestamp}" ]
    }
    # Sobreescribo el timestamp con la fecha que pone en el archivo de log
    date {
      match => [ "unix_date", "UNIX"]
    }
    mutate {
      remove_field => ["unix_date"]
    }
    # Agrego un campo con la línea en formato legible
    mutate {
      add_field => [ "human_readable_message", "%{@timestamp} %{command_line}" ]
    }
  }
}
output {
  elasticsearch {
    protocol => "http"
    host => "localhost"
  }
}
Toda la configuración junta
input {
  file {
    type => "auth"
    path => "/var/log/auth.log"
  }
  file {
    type => "bash_history"
    path => "/root/.bash_history"
  }
}
filter {
  # This is a standard syslog line like this:
  # Mar  9 17:17:02 path-precise CRON[25638]: pam_unix(cron:session): session closed for user root
  if [type]=="auth" {
    # Look for patterns in /opt/logstash/patterns/grok-patterns
    grok {
      match => [ "message", "%{SYSLOGLINE}" ]
    }
    # Set timestamp: http://logstash.net/docs/1.4.1/filters/date#match
    date {
      match => [ "timestamp", "MMM dd HH:mm:ss",
                              "MMM  d HH:mm:ss",
                              "ISO8601" ]
    }
  }
  if [type]=="bash_history" {
    # Example: "#1403708872\n tar -zxvf kibana-3.1.0.tar.gz "
    # This is a multiline log. Set message var with both lines.
    multiline {
      pattern => "^#"
      what => "next"
    }
    # Split fields. First field unix_date until first space. Second field command line after first space.
    # Use aux var temp_message.
    mutate {
      add_field => ["temp_message", "%{message}"]
    }
    # temp_message=="#1403708872\n tar -zxvf kibana-3.1.0.tar.gz "
    # Remove \n and #
    mutate {
      gsub => [
        "temp_message", "\n", " ",
        "temp_message", "^#", ""
      ]
    }
    # temp_message=="1403708872 tar -zxvf kibana-3.1.0.tar.gz "
    # Set unix_date and command_line
    grok {
      match => [ "temp_message", "%{WORD:unix_date} %{GREEDYDATA:command_line}"]
    }
    mutate {
      remove_field => ["temp_message"]
    }
    # unix_date=="1403708872"
    # command_line=="tar -zxvf kibana-3.1.0.tar.gz "
    # Set input_timestamp to the timestamp when the log line is processed by logstash
    mutate {
      add_field => [ "input_timestamp", "%{@timestamp}" ]
    }
    # Set timestamp and remove temporal var unix_date
    date {
      match => [ "unix_date", "UNIX"]
    }
    mutate {
      remove_field => ["unix_date"]
    }
    # Add a field with the log line in human readable format
    mutate {
      add_field => [ "human_readable_message", "%{@timestamp} %{command_line}" ]
    }
  }
}
output {
  elasticsearch {
    protocol => "http"
    host => "localhost"
  }
}

Elasticsearch

Su instalación consiste en bajarse el paquete de aquí e instalarlo.

En el siguiente post haré un monográfico de elasticsearch. De momento sólo diré que para enviar la información a la base de datos hay que poner esto en el output:

output {
  elasticsearch {
    protocol => "http"
    host => "localhost"
  }
}

Kibana

Yo lo defino como un visualizador gráfico de consultas lucene que sirve para hacer búsquedas que no sabes que vas a hacer hasta que las haces.

Esto te da una enorme flexibilidad pero no te permitirá hacer unos buenos informes. El tema de los informes se tratará más adelante en el siguiente post.

Instalación y ejecución

En versiones anteriores Kibana era una aplicación Ruby que funcionaba sobre Sinatra en el servidor. Ahora es una aplicación que se ejecuta enteramente en el navegador, lo que significa que desde tu navegador hará falta acceso a la base de datos (se puede restringir).

Bájate el kibana de aquí, lo descomprimes en /var/www/ y en config.js escribe la url que vas a poner en el navegador para acceder a tu servidor de elastisearch.

SpyMyFriend en funcionamiento

Si abrimos en el navegador la url donde hemos descomprimido el kibana y pinchamos en "here" veremos como tanto las líneas del auth que nos indican el momento y el origen de la conexión por ssh al servidor como los comandos que se han ido ejecutando han sido correctamente indexados.

Hacer búsquedas es bastante sencillo ya que se usa la sintaxis de lucene así que no hay que saber acerca de cómo funciona la base de datos que hay detrás. Si queremos buscar cuando se ejecutó un rm basta con poner "rm" y lo buscará.

Si pulsamos en el evento nos saldrá una descripción de los campos con sus valores, lo que nos dará una idea para hacer más búsquedas:


Ahí vemos que la búsqueda "correcta" hubiera sido command_line:"*rm*"

Ahora vamos a poner en verde las líneas del auth.log, en amarillo las del bash_history y en rojo la línea donde se ha borrado el kibana.

Sigue habiendo mucho ruido. De las líneas del auth.log nos interesan las que nos indican una conexión por ssh:


Al parecer tras hacer el estropicio quien sea se dejó la sesión abierta porque tras hacerlo no hay actividad en el auth.log de cierre de sesión ssh.

Encontramos actividad de ssh en el auth a las 17:06 y que luego se han tecleado una serie de comandos. Ampliamos la parte que nos interesa:

Ahora vamos a los eventos y vemos que alguien se conectó desde 127.0.0.1 y seguidamente estuvo trasteando con la instalación de kibana pero que luego la dejó bien. ¡Oh sorpresa! ¡He sido yo mismo!

Anotaciones

Este ejemplo, sobre todo la parte del bash_history, es bastante complicado pero si lo has entendido y lo has repetido en tu computadora te puedes considerar un usuario con experiencia de logstash y kibana.

Existen otras alternativas a logstash como por ejemplo fluentd que también es bastante popular. Entiendo que una vez entiendas cómo funciona logstash podrás hacer extensible ese conocimiento al resto de alternativas tanto libres como privativas.

Elasticsearch es un mundo en si mismo así que lo dejo para el siguiente post en el que intentaré hacer un "mapeo" entre SQL y NoSQL (mongodb y elasticsearch) ya que si nunca has usado una base de datos NoSQL pero eres un experto en SQL siento decirte que de NoSQL no tienes ni idea. Cambia tanto la filosofía a nivel de sistemas como a nivel de desarrollo.

Espero que este post os ayude.

26 de June de 2014 a las 07:23

08 de June de 2014

Jose Manuel

Introducción a ELK (Elasticsearch, Logstash y Kibana) (parte 1)

Se trata de un gestor de logs, o eso es al menos lo que nos venden.

En realidad yo lo veo como algo mucho más genérico: una navaja suiza para gestión de datos que permite su transporte entre máquinas, procesamiento y consulta en tiempo real.

En este artículo escribiré sobre logstash para en artículos posteriores hablar de su integración con Elasticsearch y Kibana.

Cuando conozcas la potencia de ELK no sabrás como has sido capaz de vivir sin él hasta ahora.

Ventajas aplicadas a archivos de log

Con logstash no necesitas hacer una recolección de logs porque ya te la hace él, y tampoco necesitas hacer un tratamiento de los datos porque se le puede decir que te lo haga él o programarle una rutina que te actualice lo que sea en tiempo real. De esta forma en cualquier momento puedes saber lo que está pasando en tus sistemas y aplicaciones.

Se puede usar tanto para procesar logs de apache como para procesar logs de aplicaciones internas o bases de datos por lo que puedes generar informes útiles tanto para la dirección como para ti o el equipo de desarrolladores. Por ejemplo, tal como viene "de fábrica" se le puede pedir un diagrama de barras con el número de peticiones que ha hecho un cliente a tu API agrupadas cada 5 minutos.

Ahora imagínate que tienes un montón de instancias en Amazon que están constantemente creándose y destruyéndose en función de la carga pero quieres saber qué está pasando con ellas: cuando las creas configuras un logstash en ellas para que envíe los datos que te interesan a tu servidor de logs y problema solucionado. El accesorio perfecto para la descentralización de sistemas.

Cómo funciona: el sistema de plugins/

Pues como todos los programas: recibe unas entradas, las procesa y crea unas salidas. Sólo que es en sentido literal. Para ilustrarlo mira este dibujo:

En él puedes ver lo que es logstash y en los plugins en los que que tienes que pensar cuando vas a diseñar un sistema con él: entradas, codecs/filtros y salidas.

Una entrada es un plugin que utiliza logstash para extraer datos de algún sitio y pasársela al plugin de codec/filtro que devuelve otros datos y por último pasársela al plugin de salida.

Intencionalmente he juntado los codecs y los filtros en el mismo saco porque aunque esto es incorrecto, me parece más didáctico. Más adelante lo aclararé.

A estas alturas te habrás dado cuenta, y sino te lo digo yo, que lo realmente importante no es logstash sino sus plugins. En logstash todo gira alrededor de los plugins. Te puedes encontrar un listado abajo en la página de documentación.

Instalación básica

En este post me centraré más en mostrar cómo funciona logstash, no cómo se instala en producción así que ve a la página de http://logstash.net/docs/1.4.1/repositories, agrega el repositorio y ejecuta apt-get install logstash logstash-contrib. También hay paquetes para CentOS.

Si no usas Debian ni CentOS puedes ir a http://logstash.net, pinchar en el botón gordo que pone "Download" y deja el archivo en algún sitio. Necesitarás java así que instálalo con un apt-get install default-jdk.

Ejemplo de uso

Vamos a suponer que en tu site hay una nueva página llamada /my/machines.html y quieres saber si la visita alguien así que haremos que cuando aparezca una entrada con ese texto en tu archivo de log, te llegue un mensaje al correo avisándote.

Instala un apache en tu PC con un apt-get install apache2.

Vamos a la página de documentación donde están los plugins disponibles y elegimos los que nos interesan:

  • plugin de entrada: file
  • plugin para filtro: grep
  • plugin de salida: email

Pinchando en el plugin de entrada file podemos ver que para procesar los archivos de log que están en /var/log/apache2/*log debemos decirle algo como:

input {
  file {
    path = ["/var/log/apache2/*log"]
  }
}

Pinchando en el plugin para filtro grep y teniendo en cuenta que una línea de log sería algo así:

127.0.0.1 - - [20/Jul/2013:08:16:58 +0200] "POST /my/machines.html HTTP/1.1" 404 443 "-" "-"

Tendríamos que configurarlo de esta forma:

filter {
  grep {
    match = {"message", "/my/machines.html"}
  }
}

Y por último, pinchando en el plugin de salida email y suponiendo que utilizaremos una cuenta de correo de un proveedor externo para enviar los correos tenemos que poner como plugin de salida:

output {
  email {
    subject => "Nueva visita"
    to => "direccion@gmail.com"
    from => "direccion@gmail.com"
    body => "%{message}"
    via => "smtp"
    options => [
      "smtpIporHost", "smtp.gmail.com",
      "port", "587",
      "enable_ssl", "true",
      "authenticationType", "plain",
      "userName", "cuentaDeEnvio",
      "password", "contrasenyaDeCuentaDeEnvio",
      "starttls", "true"
    ]
  }
}

Cada vez que ejecutemos esto:
wget http://localhost/my/machines.html
nos aparecerá en nuestro archivo de log el acceso a esa página, logstash lo verá y nos enviará un e-mail advirtiéndolo.

Este ejemplo no es muy útil porque nadie quiere que le inunden el correo con líneas de log pero nos da una idea de lo que se puede hacer con los filtros y plugins.

En marcha

Si has seguido los pasos de arriba ya tienes instalado todo lo que necesitas así que vamos a ponerlo todo junto.

Crea un archivo llamado /etc/logstash/conf.d/logstash.conf con el contenido:

input {
  file {
    path => ["/var/log/apache2/*log"]
  }
}
filter {
  grep {
    match => {"message" => "/my/machines.html"}
  }
}
output {
  stdout {}
  email {
    subject => "Nueva visita"
    to => "direccion@gmail.com"
    from => "direccion@gmail.com"
    body => "%{message}"
    via => "smtp"
    options => [
      "smtpIporHost", "smtp.gmail.com",
      "port", "587",
      "enable_ssl", "true",
      "authenticationType", "plain",
      "userName", "cuentaDeEnvio",
      "password", "contrasenyaDeCuentaDeEnvio",
      "starttls", "true"
    ]
  }
}

Advertencias en producción

Esto es sólo un ejemplo muy didáctico para ver cómo funciona el sistema de plugins en Logstash: entrada, procesado y salida. Así que me he permitido introducir un par de incorrecciones.

El filtro grep no se usa

La forma correcta sería con el input que he descrito, sin filter y metiendo dentro del output una condición para que se envíe el e-mail cuando la línea la cumpla. Más adelante lo aclararé.

Cuando encuentra un error muchas veces Logstash se para

En el ejemplo utilizamos como salida el smtp de gmail y esto es una mala idea porque en caso de estar inaccesible mientras Logstash intenta enviar un e-mail, nos devolverá un error y se parará. Si mientras nos damos cuenta de que está parado se rotan los logs habremos "perdido" todo el procesamiento de esa información que está entre la parada y el momento de rotar los logs.

Con esto quiero decir que es siempre mejor tener un relay de correo en local configurado para reenviar los correos al relay de tu red o a tu proveedor externo.

08 de June de 2014 a las 07:53

06 de May de 2014

david::

Zoe controlling my TV (thanks to this)



Zoe controlling my TV (thanks to this)

06 de May de 2014 a las 10:59

03 de May de 2014

Jose Manuel

Google Code Jam 2014 ... con obstáculos - Round 1A, 1B y fin

El comentario de anonimo en mi post anterior me ha descubierto una cosa que no conocía: la Programación Competitiva. Yo pensaba que esto era un invento de Google pero resulta que ya estaba inventado. Un gran aporte. Muchas gracias.

Le he estado dando bastantes vueltas y he decidido mantener mi mente "virgen" porque lo que me interesa es saber hasta donde puedo llegar con mis limitaciones actuales, no preparame para ganar un concurso. El año que viene ya veremos si opino lo mismo.

Round 1A

Gracias a un "papá miedo" tuve la "suerte" de despertarme a las 3 de la mañana así que aproveché para ver los tres problemas y hacerme una idea de la dificultad. Vi asequibles tanto el "Problem A. Charging Chaos" como el "Problem B. Full Binary Tree" pero el "Problem C. Proper Shuffle" era más difícil.

Al día siguiente vi que el corte estaba en hacer los dos primeros problemas sin cometer equivocaciones así que tomé nota para la siguiente.

Round 1B

Tras haber solicitado el correspondiente permiso marital para poder pasar la tarde frente al ordenador empiezo por el primer problema.

Problem A. The Repeater

Lo que nos piden

En el primer problema nos piden cual es el número mínimo de pasos necesarios para igualar varias cadenas de texto cadenas de texto siguiendo dos reglas:

  • Si hay dos caracteres consecutivos iguales se puede eliminar uno de los dos.
  • Si hay un caracter se puede duplicar.

Por ejemplo, si tenemos la cadena "aaabcc" y queremos llegar a "abbbcc" tenemos que pasar por "aabcc", "abcc" y "abbcc". ¿Fácil no?

Aquí tenemos unos ejemplos del concurso:

  • Caso 1: Cadenas:
    • mmaw
    • maw
    Solución: Case #1: 1
  • Caso 2: Cadenas:
    • gcj
    • cj
    Solución: Case #2: Fegla Won
  • Caso 3: Cadenas:
    • aaabbb
    • ab
    • aabb
    Solución: Case #3: 4
  • Caso 4: Cadenas:
    • abc
    • abc
    Solución: Case #4: 0
  • Caso 5: Cadenas:
    • aabc
    • abbc
    • abcc
    Solución: Case #5: 3

La solución

La solución consiste en primero comprobar si el problema tiene solución y en caso de tenerla averiguar cuantos pasos son necesarios para llegar desde una cadena a la otra. Si has hecho este problema probablemente esto te sonará un poco raro pero me explicaré más adelante.

#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import time
 
def getValue(inputFile,dataType="string"):
  line=""
  value=0
  while len(line) 1:
    line=inputFile.readline()
 
  if dataType=="string":
    value=line.split()[0]
  elif dataType=="integer":
    value=int(line.split()[0])
  elif dataType=="float":
    value=float(line.split()[0])
 
  return value
 
def reducedCase(case):
  char=""
  reduced=""

  i=0
  while i len(case):
    if not(char==case[i]):
      char=case[i]
      reduced=reduced+char
    i=i+1

  return reduced

def testPossible(cases):
  # For each case test if removing duplicates make them the same
  reduced=reducedCase(cases[0][0])
  possible=1
  i=1
  while i len(cases) and possible==1:
    if not(reduced==reducedCase(cases[i][0])):
      possible=0
    i=i+1
  return possible

def convert(case1, case2):
  # Try to find the number of steps to translate case1 to case2
  steps=0

  diff=0
  i=0
  j=0
  char=case1[0]
  while i len(case1) and j len(case2):
    found=0
    while i len(case1) and found==0:
      if char==case1[i]:
        i=i+1
      else: 
        found=1
    found=0
    while j len(case2) and found==0:
      if char==case2[j]:
        j=j+1
      else:
        found=1
    steps=steps+abs(i-j-diff)
    diff=abs(i-j)

    if i len(case1):
      char=case1[i]
  return steps
   
### solve it! ###
def solveIt(cases):
  res=1

  # Reducir duplicados en todos y comprobar que sale la misma cadena para ver si
  # es posible resolverlo
  possible=testPossible(cases)
  if possible==1:
    i=1
    while i len(cases):
      #Elegir uno como plantilla e igualar el resto.
      steps=convert(cases[0][0],cases[i][0])
      cases[i][1]=steps
      i=i+1

    res=0
    for case in cases:
      if case[1]>res:
        res=case[1]
  else:
    res=-1
 
  return res
 
if __name__=='__main__':
  # Open input and output files
  inputFile=open(sys.argv[1],'r')
  outputFile=open(sys.argv[2],'w')
 
  # Get number of cases
  NoC=int(getValue(inputFile))
  # for each case
  for i in range(NoC):
    # get case data
    inputs=getValue(inputFile,"integer")
    cases=[]
    while inputs>0:
      case=getValue(inputFile,"string")
      cases.append([case,-1])
      inputs=inputs-1
    # solve problem
    res=solveIt(cases)
 
    # write data
    if res==-1:
      outputFile.write("Case #"+str(i+1)+": Fegla Won\n")
      print "Case #"+str(i+1)+": Fegla Won"
    else:
      outputFile.write("Case #"+str(i+1)+": "+str(res)+"\n")
      print "Case #"+str(i+1)+": "+str(res)
 
  # Close input and output files
  inputFile.close()
  outputFile.close()

Resultados

En el ejemplo que viene la entrada es:

5
2
mmaw
maw
2
gcj
cj
3
aaabbb
ab
aabb
2
abc
abc
3
aabc
abbc
abcc

Y la salida correcta es:

Case #1: 1
Case #2: Fegla Won
Case #3: 4
Case #4: 0
Case #5: 3

Sin embargo a mi me sale mal el último resultado y me empiezo a poner nervioso:

Case #1: 1
Case #2: Fegla Won
Case #3: 4
Case #4: 0
Case #5: 2

19:45

"La cagamos Luis"

... dijo Carlos Sainz cuando se enteró de que su motor llevaba estando defectuoso desde la salida.

Resuelvo el problema que he descrito pero no el que me piden y a estas horas ya no me da tiempo a rectificar.

Para resolver el problema hay que tener en cuenta todas las cadenas simultáneamente y yo las he tenido en cuenta de una en una

En el último caso yo obtengo como resultado 2 porque aabc->abc->abbc y aabc->abc->abcc . Así que como mucho necesito dos pasos pero lo que en realidad hay que hacer entiendo es pasar a la vez todas las cadenas a una sóla de esta forma:

["aabc","abbc"]->["abc","abbc"]->["abc","abc"]->["abcc","abcc"]
Y de ahí salen los tres pasos.

No tengo tiempo para volver a rediseñar el programa así que se acabó esta ronda para mí.

¿Round 1C?

"En habiendo agotado" todos los permisos maritales que tenía para el Google Code Jam, me tengo que retirar de esta convocatoria así que ya veremos el año que viene si aprendo a leer.

Creo que me tendré que conformar con presentarme al Tuenti Challenge 4 y acabar mi curso de mongodb para desarrolladores y mi curso de mongodb para administradores avanzados.

03 de May de 2014 a las 18:41

23 de April de 2014

david::

I'll make my own Zoe. With blackjack. And hookers.

I’m working in a reduced distribution of Zoe with the basic components, so you can build your own assistant with the basic services running out of the box. So you don’t have to clone our installation and trim all the services you don’t care about.

It includes the basic agents (natural, broadcast, users, log, relay), some natural language commands, the communication agents (mail, jabber, twitter) and some example agents.

In order to make it easier to add new agents, the server has been updated to feature dynamic agent registration, which means that instead of registering your agent in a configuration file, you can send a message to the server with the agent parameters (name, host, port and optionally a list of topics it listens to). This message is automatically generated by the Python library zoe.deco, which I think is the best option to start writing agents.

By the way, the server’s source code has been updated to make use of Akka instead of scala.actor, and to have a cleaner and more functional style. I’m still a complete newbie at FP so I beg you to forgive me if the code does not reach the pure functional meta-existentialist beauty standards :P

As soon as it is tested in Linux and OS X I’ll drop the code to a new Github repo.

23 de April de 2014 a las 19:50

13 de April de 2014

Jose Manuel

Google Code Jam 2014 ... con obstáculos - Qualification Round

Preparando el concurso

Dado que la entrada y salida de datos es siempre exactamente igual he hecho una plantilla que usaré en todos los retos:

# -*- coding: utf-8 -*-
#!/usr/bin/python
import sys
import time


def getValue(inputFile, dataType="string"):
    line = ""
    value = 0
    while len(line)  1:
        line = inputFile.readline()

    if dataType == "string":
        value = line.split()[0]
    elif dataType == "integer":
        value = int(line.split()[0])
    elif dataType == "float":
        value = float(line.split()[0])

    return value


def getList(inputFile, dataType="string", separator="space"):
    # dataType could be string, integer and float
    # separator can be space or none
    datalist = []

    line = ""
    while len(line)  1:
        line = inputFile.readline()

        if  separator == "space":
            datalist = line.split()
        elif separator == "none":
            line = line.rstrip('\n')
            for i in range(len(line)):
                datalist.append(line[i])

    #if dataType=="string": ... already a string
    if dataType == "integer":
        i = 0
        while (i  len(datalist)):
            datalist[i] = int(datalist[i])
            i = i + 1
    elif dataType == "float":
        i = 0
        while (i  len(datalist)):
            datalist[i] = float(datalist[i])
            i = i + 1
    return datalist


def getBoard(inputFile, dimX, dimY, dataType="string", separator="none"):
    board = []

    for y in range(dimY):
        board.append(getList(inputFile, dataType, separator))

    return board


def printBoard(board, array="0"):
    #print board
    for i in range(len(board)):
        for j in range(len(board[i])):
            if array == "1":
                sys.stdout.write("[\"" + str(board[i][j]) + "\"]")
            else:
                sys.stdout.write(str(board[i][j]))

    print ("")


### solve it! ###
def solveIt(inputs, values, board):
#    time.sleep(1)
#    print ""
#    print inputs
#    print values
#    print board

    res = []
    i = 0
    j = 1

    res.append(i)
    res.append(j)

    return res

if __name__ == '__main__':
    # Open input and output files
    inputFile = open(sys.argv[1], 'r')
    outputFile = open(sys.argv[2], 'w')

    # Get number of cases
    NoC = int(getValue(inputFile))

    # for each case
    for i in range(NoC):
        # get case data
        inputs = getValue(inputFile, "integer")
        values = getList(inputFile, "integer")
        board = getBoard(inputFile, "integer")
        # solve problem
        res = solveIt(inputs, values, board)

        # write data
        outputFile.write("Case #" + str(i + 1) + ": " + str(res[0] + 1) + " " + str(res[1] + 1) + "\n")
#        print "Case #"+str(i+1)+": "+str(res[0]+1)+" "+str(res[1]+1)

    # Close input and output files
    inputFile.close()
    outputFile.close()

Y pensarás ¿no puedes hacer eso el día del concurso? Pues no porque tengo los minutos contados. 10 minutos pueden suponer la diferencia entre que de tiempo a resolver un problema o no.

Insomnio provocado

4:00

Aprovecho una subida de fiebre del niño para despertarme del todo y valorar la dificultad de los problemas.

Esta vez me voy directo al "Contest scoreboard" donde veo que los mejores tardan 15 minutos en resolver el primero, otros 15 el segundo y alrededor de una hora el tercero y el cuarto así que supongo que los fáciles son el primero y el segundo.

Tras leer el primero, parece más una broma que un problema. El segundo también parece fácil pero necesita de una lectura más profunda del problema y con menos sueño.

Mañana será otro día. Bueno, hoy dentro de un rato será otro día.

Problem A. Magic Trick

7:30

Este problema es facilísimo. Nos dan dos arrays distintos en los que los números cambian de posición y nos piden que busquemos los números de una fila del primer array en otra fila del segundo array.

  • Si se encuentran 2 -> Case #x: Bad magician!
  • Si no se encuentran -> Volunteer cheated!
  • Si se encuentra 1 -> Case #x: x
8:40

Tras un "tengo pis" y un "dale el antibiótico al niño" la solución, utilizando la plantilla como librería es la siguiente contenida en la función solveIt:

#!/usr/bin/python
# -*- coding: utf-8 -*- 
import time
import sys 
import gcjtemplate

### solve it! ###
def solveIt(row1,board1,row2,board2):
  res=[]
  for i in board2[row2-1]:
    if i in board1[row1-1]:
      res.append(i)

  return res

if __name__=='__main__':
  # Open input and output files
  inputFile=open(sys.argv[1],'r')
  outputFile=open(sys.argv[2],'w')

  # Get number of cases
  NoC=int(gcjtemplate.getValue(inputFile))

  # for each case
  for i in range(NoC):
    # get case data
    row1=gcjtemplate.getValue(inputFile,"integer")
    board1=gcjtemplate.getBoard(inputFile,4,4,"integer","space")
    row2=gcjtemplate.getValue(inputFile,"integer")
    board2=gcjtemplate.getBoard(inputFile,4,4,"integer","space")
    # solve problem
    res=solveIt(row1, board1, row2, board2)

    # write data    
    if len(res)==0:
      outputFile.write("Case #"+str(i+1)+": Volunteer cheated!\n")
      print ("Case #"+str(i+1)+": Volunteer cheated!")
    elif len(res)==1:
      outputFile.write("Case #"+str(i+1)+": "+str(res[0])+"\n")
      print ("Case #"+str(i+1)+": "+str(res[0]))
    elif len(res)>1:
      outputFile.write("Case #"+str(i+1)+": Bad magician!\n")
      print ("Case #"+str(i+1)+": Bad magician!")
    else:
      time.sleep(5)
      print "HELP, HELP!"

  # Close input and output files
  inputFile.close()
  outputFile.close()

Problem B. Cookie Clicker Alpha

8:45

En este problema la dificultad está más en comprenderlo que en resolverlo.

Tu objetivo es llegar a tener un número de galletas en el menor tiempo posible. Empiezas con una fábrica de galletas y que te ha costado x galletas. Cuando llegas a esas x galletas puedes elegir entre comprar una fábrica para doblar la capacidad de producción o seguir produciendo como hasta ahora.

Se trata de elegir la mejor estrategia para decir cual es el menor número de segundos que se tarda en llegar a conseguir el número de galletas que queremos.

Hay que tener en cuenta que nos dan unos límites que, aunque en python nos dan igual, en otros lenguajes nos vienen bien para elegir el tipo de datos.

9:09

Se levanta la tropa, les llevo al parque, reunión familiar, comilona, ...

23:43

Estoy a 1:15 de decidir si paso a la siguiente fase o no. En teoría es factible pero no me gusta ir tan corto de tiempo.

00:35

El que nos den 8 minutos para entregar el resultado de nuestro programa en vez de los 4 habituales es un indicador de que puede ser bastante costoso en términos computacionales.

Este problema es de naturaleza recursiva ya que para decidir entre comprar o no comprar otra fábrica de galletas hay que saber qué es lo que pasaría si no se comprara otra o qué pasaría si se comprara otra, en cuyo caso habría que volver a saber qué es lo que pasaría si no se comprara otra o qué pasaría si se comprara otra, ... hasta que viéramos que deja de salir a cuenta comprar otra fábrica.

Sin embargo el problema se puede enfocar desde un punto de vista más lineal si pensamos en qué vamos a basar la decisión final: si con la capacidad de producción que tengo ahora tardo menos en producir las galletas que aumentando la producción en una fábrica más es que no debo comprar más fábricas.

Ignorando el resto de la plantilla que he puesto arriba del todo, la solución es la siguiente:

### solve it! ###
def solveIt(c,f,x):
  res=0.0

  speed=2
  cookies=0.0
  spentSeconds=0

  finish=0
  while finish==0:
    withoutMoreFarms=x/speed

    secondsToBuyFarm=c/speed
    newSpeed=speed+f
    withOneMoreFarm=secondsToBuyFarm+x/newSpeed

    if withOneMoreFarm withoutMoreFarms:
      spentSeconds=spentSeconds+secondsToBuyFarm
      speed=newSpeed
    else:
      spentSeconds=spentSeconds+withoutMoreFarms
      finish=1
    
#    print "spentSeconds: "+str(spentSeconds)

  res=spentSeconds
  return res

if __name__=='__main__':
  # Open input and output files
  inputFile=open(sys.argv[1],'r')
  outputFile=open(sys.argv[2],'w')

  # Get number of cases
  NoC=int(getValue(inputFile))

  # for each case
  for i in range(NoC):
    # get case data
    c,f,x=getList(inputFile,"float")
    # solve problem
    res=solveIt(c,f,x)

    # write data    
    outputFile.write("Case #"+str(i+1)+": "+str(round(res,7))+"\n")
    #print "Case #"+str(i+1)+": "+str(round(res,7))

  # Close input and output files
  inputFile.close()
  outputFile.close()

Una vez enviada la respuesta al Large Set te indican que:
You have already tried this input set. (Judged at the end of the contest.)
Así que no hay forma de saber si ya tengo los 25 puntos que necesito o no.

¿Mas?

1:00

Pues va a ser que a estas horas lo que me apetece es dormir. Mañana publicaré este post y el resultado del concurso.

9:20

¡He pasado!

Lo que no entiendo muy bien es cómo puede haber gente que lo haya hecho peor todavía que yo y haber pasado también, pero ahí están los resultados.

Para la próxima a mirar la librería multiprocessing que me hará falta para utilizar todos los cores de mi máquina.

13 de April de 2014 a las 07:35

17 de December de 2013

Ana

Voy a comprar pasta de dientes sin flúor

Me he quedado flipando, pero resulta que el flúor es tóxico y provoca caries O_o

Lo usaban los alemanes en la II Guerra Mundial para controlar a la población O_O
Y España fluorando el agua.

Dos extractillos y enlace a la noticia, por si queréis echarle un vistazo (y si alguien sabe algo sobre si es verdad o mentira, que lo diga, porfa).

http://r-evolucion.es/2013/09/03/espana-fomenta-la-fluoracion-del-agua-y-el-mundo-la-prohibe/

"se comprobó que la fluoración causó ligeros daños a una parte específica del cerebro, haciendo más difícil para la persona afectada defendiera su libertad y causando que la persona llegue a ser más dócil a la autoridad. El flúor sigue siendo una de las más fuertes substancias anti-psicóticas conocidas, y está contenida en un 25% de los mayores tranquilizantes"

"Durante la década de los años ´90, la investigación realizada por la toxicóloga Dra. Phillis Mullenix de Harvard demostró que el flúor en el agua puede llevar a un menor coeficiente intelectual, y los síntomas producidos en ratas se parecían fuertemente al déficit de atención e hiperactividad (SDAH)"

17 de December de 2013 a las 14:25

15 de August de 2013

Ana

¡Software libre en la uni! II

No sé qué os parecerá a vosotros, pero a mí me ha sorprendido:

http://www.uc3m.es/portal/page/portal/cultura_y_deporte/espacio_abierto/cursos/sw_libre

Taller de Diseño Gráfico con Software Libre

Desde luego es una buena opción para aprender, para enseñar y para manejarse después, aunque algunas personas crean que el software privativo tiene que ser mejor "porque si no no habría gente que paga por él".

Me parece una buena iniciativa. Aunque a lo mejor hace competencia a los cursos del GUL :p

15 de August de 2013 a las 21:38

11 de October de 2012

Fernando Cerezal

Elecciones a delegados en la universidad

Llegan este año las elecciones a delegados. Parece que nos han escuchado de años anteriores y ahora aparece un anuncio en aula global y se mandan correos sobre el tema.

Este año vuelvo a presentarme, al igual que los dos anteriores. Este año hemos conseguido que se cambien algunos profesores, y se han dado toques de atención a algunos departamentos. Poco a poco, vamos consiguiendo que las cosas cambien. Aún hay muchas cosas en las que trabajar, y es necesario poder expresar de una forma responsable y sin miedo los problemas que existen, tanto directamente a los profesores como a las instancias superiores que sean necesarias. Si bien parece que los alumnos estamos en desventaja, saber con quien hablar puede dejar en clara desventaja a quien no sigue las normas de la universidad. Y algunos ya sabéis de mis más y mis menos con algunos profesores, y que en la mayoría de las ocasiones han tenido que ceder: De las entregas de boletines de ejercicios por sorpresa en clase a cambiar la forma de evaluación durante el curso. Al final han tenido que acogerse a lar normas.

Aunque tuve una etapa anterior en la delegación, sobre el 2007, muchas cosas han cambiado en esta nueva etapa. Hemos tenido que pegarnos con los problemas en la implantación de las últimas fases de los grados, y con la implantación del plan 2011 de las ingenierías TIC (a.k.a. plan ABET). Conocer los problemas que aparecen en cada momento es vital para solucionarlos cuanto antes.

Ser estos dos últimos años subdelegado de curso y de titulación, y el último año miembro del Claustro, me han permitido conocer trabajar con mucha gente. Para empezar habría que agradecer a Paco Valera su dedicación como subdirector de la titulación en los últimos años con los problemas de los nuevos planes de estudio, y cuya puerta siempre estaba abierta para hablar de cualquier problema, o dar a un toque a los profesores que fuese necesario.  Si bien apenas acaba de empezar el curso, la misma sensación tengo con el nuevo subdirector, Mario Muñoz, con quien ya he tratado algunos problemas.

Aunque vuelvo a presentarme, salga quien salga sabe que puede contar con mi ayuda para lo que necesite.

11 de October de 2012 a las 13:43

30 de September de 2012

Fernando Cerezal

REAMDE, como soltarle una pullita a Google

Hace poco que he empezado a leer "REAMDE", el último libro de Neal Stephenson. En él habla de un personaje que ha creado un videojuego cuyas primeras imágenes al cargar son como las de Google Earth, pero que el personaje no tienen ningún remordimiento porque los que los que hicieron Google Earth copiaron esa idea de un libro.


30 de September de 2012 a las 16:37

27 de May de 2010

Fernando J. Pereda

iostreams are VERY thread-unsafe on Mac OS X

This was both surprising and disgusting. Our in-house data acquisition software needs to convert lots of floats to ascii so that they can ve viewed in real time. This is very easy to do with a stringify-like function like the one found in paludis/paludis/util/stringify.hh.

stringify looks trivial, there’s no shared state nor there is any static data, so I thought that I could call stringify from several threads at the same time. I don’t think there’s any guarantee about thread safety of ostringstream’s operator<< but it looked like a safe assumption. Well, incorrect.

operator<< calls vsnprintf, which should be thread-safe by itself. However, OSX's vsnprintf ultimately calls localeconv_l, which is not thread-safe. And, you end up with something like this:

#0 0x96f734a9 in malloc_error_break ()
#1 0x96f6e497 in szone_error ()
#2 0x96e98503 in szone_free ()
#3 0x96e9836d in free ()
#4 0x96e97f24 in localeconv_l ()
#5 0x96e93335 in __vfprintf ()
#6 0x96ecb9b5 in vsnprintf ()
#7 0x0144615e in std::__convert_from_v ()
#8 0x01437d2a in std::num_put<char, std::ostreambuf_iterator<char, std::char_traits > >::_M_insert_float ()
#9 0x0143803d in std::num_put<char, std::ostreambuf_iterator<char, std::char_traits > >::do_put ()
#10 0x0144ab6a in std::ostream::_M_insert ()
#11 0x0000fb25 in std::basic_ostringstream<char, std::char_traits, std::allocator >::str () at sstream:217
...

Which means there’s no way of converting stuff to human readable in a thread-safe manner. I’m not sure whether I’m missing something or not… but this looks very fishy. I ended up adding a stupid big mutex around my stringify calls, but that looks more like a workaround that a final solution to the problem. Plus, this doesn’t protect ANY other uses of iostream’s operator<< such as loggers.

Ok… looks like that wasn’t a very accurate diagnostic. This is going to be more annoying than I thought.

— ferdy


Tagged: C, osx, programming, threads

27 de May de 2010 a las 08:33

01 de May de 2010

Fernando J. Pereda

Finally, a real AMSV (Autonomous Marine Surface Vehicle)

After lots of work from different people, it finally is a real AMSV. Nothing too fancy yet (just a mere PD controller for speed and heading). It is, nonetheless, a very interesting platform for future research.

With semi-strong current and some wind it managed to follow a very nice path across some waypoints:

The trajectory between p2 and the shore was done manually using a joystick. Interestingly enough, that path is less nice than those done by the autonomous control.

I hope to be able to post more niceties soon.

— ferdy

01 de May de 2010 a las 15:15

17 de December de 2009

Roberto Muñoz

Poliamor

«Como digo, soy un hombre. Me gustan las mujeres. A veces esa atracción está incluso fuera de mi control. Puedo controlar mis actos, aunque no lo que siento. Miro a las chicas por la calle, y a algunas las encuentro realmente atractivas. No sentiré especial devoción por Sorolla o Velázquez, pero es que no todas las obras de arte se encuentran en los museos. A veces me salto a los intermediarios y voy directamente a la exposición de Dios.»
-- Javier Malonda (aunque bien se puede atribuir a cualquier hombre heterosexual)

Al final de la entrada de donde he extraído lo anterior se da el enlace de la Wikipedia del Poliamor. Después de leerlo veo que un poliamoroso famoso es Eric S. Raymond. Que la wikipedia lo define como:
«Raymond es un neopagano, un confeso anarcocapitalista, y un defensor del derecho a poseer y utilizar armas de fuego. Tiene un gran interés en la ciencia ficción. Es músico amateur y cinturón negro de taekwondo. Además sufre una leve parálisis cerebral congénita.»
A eso añádele poliamoroso. El amigo «dospistolas» no se aburre, y es más listo que el hambre, como se suele decir.

17 de December de 2009 a las 18:58

02 de November de 2009

Roberto Muñoz

TTS 2.0

He publicado la versión 2.0 de TTS (TalkToSerial) que tiene las siguientes mejoras:


Para más info visitad el Wiki. Y si se quiere descargar, aquí está el código fuente.

02 de November de 2009 a las 19:59

29 de May de 2009

Fernando J. Pereda

MSDNAA, clever?

So MSDNAA lets university students get some Microsoft products for free for educational purposes. That’s all fine and dandy except that you can’t directly download stuff, you have to do it using a shitty download manager.

It is hilarious that you have to run a Windows executable to download a copy of Windows XP.

Chicken and egg?… Yeah, that’s clever.

One point for you Suckrosoft.


Tagged: enterprisey, idiots, rant, suckrosoft

29 de May de 2009 a las 09:02

10 de May de 2009

Fernando J. Pereda

OpenSceneGraph

For SpaceFish I wanted a quick way to load a 3D model and be able to rotate it easily. This, along with an artificial horizon is a nice way to see the attitude of the plane while it is far to see it. It is also quite good to replay recorded data during experiments to study it further in the lab.

Since I haven’t really done anything in OpenGL beyond stupid examples and helloworld-like programs and given that I don’t have much time to devote to this task I decided to use an existing framework. Among Irrlicht, OpenSceneGraph and Ogre. I decided to give OpenSceneGraph a try, for no particular reason.

Unfortunately, it took a while to get it working under OSX… it needs something like this. I use MacPorts for this kind of stuff under OSX:

fixOpenSceneGraph()
{
	local lib_dir=/opt/local/lib
	pushd ${lib_dir} > /dev/null
	echo pushd ${lib_dir}
	for i in libosg*.dylib* libOpenThreads*.dylib* ; do
		echo install_name_tool -id ${lib_dir}/${i} ${i}
		otool -L ${i} | sed -e 1d | while read f ; do
			if [[ ${f} =~ ^libosg ]] || [[ ${f} =~ ^libOpenThreads ]] ; then
				l=${f%% *}
				echo install_name_tool -change ${l} ${lib_dir}/${l} ${i}
			fi
		done
	done
	popd > /dev/null
	echo popd
	port contents OpenSceneGraph |
		sed -n -e '/^[[:space:]]*\/opt\/local\/bin\//p' -e '/\.so/p' |
		while read f ; do
		otool -L ${f} | sed -e 1d | while read d ; do
			if [[ ${d} =~ ^libosg ]] || [[ ${d} =~ ^libOpenThreads ]] ; then
				l=${d%% *}
				echo install_name_tool -change ${l} ${lib_dir}/${l} ${f}
			fi
		done
	done
}

It wasn’t fun to figure that out (thank you CMake)…

Anyway, I think I’ll stick to OpenSceneGraph until it annoys me enough. For now, I managed to do what I wanted in less than 2 hours, which is pretty good when you have a stupidly tight schedule.

— ferdy


Tagged: cmake-sucks-goat-balls, cpp, openscenegraph, osx, spacefish

10 de May de 2009 a las 22:18

27 de April de 2009

Fernando J. Pereda

Small C trivia

This is somehow surprising the first time you see it and it is interesting to remind it to people from time to time. The question is easy, does this program always return 0? That is, are those summations the same?

If there’s a case when it doesn’t, provide a sample input and explain why it happens.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
	float f[argc - 1];
	for (int i = 1; i < argc; i++)
		f[i - 1] = atof(argv[i]);
	float r1 = 0;
	for (int i = 0; i < argc - 1; i++)
		r1 += f[i];
	float r2 = 0;
	for (int i = argc - 2; i >= 0; i--)
		r2 += f[i];
	return r1 != r2;
}

As usual, I’ll post the solution in a couple of days or when someone gets it right (which is always the case :))

— fpereda

Update: correct typo spotted by Snaury.


Tagged: C, CS, programming, trivia

27 de April de 2009 a las 09:21

21 de March de 2009

Fernando J. Pereda

The Burning Ship fractal

I finally sat down and wrote support for drawing the Burning Ship Fractal into gmandel. It only took a couple of minutes, but I haven’t really had spare time lately.

Some parts of the fractal are quite interesting and different from other fractals derived from the Mandelbrot set. Here are some pictures using gmandel:

burningship1 burningship2 burningship3

— fpereda


Tagged: burningship, chaos, fractal, gmandel

21 de March de 2009 a las 19:11

15 de March de 2009

Fernando J. Pereda

Bye-Bye Gentoo

My retirement from Gentoo is complete now.

Good luck to everybody. I hope some people understand the real needs of Gentoo and where it should go. Even if I’m not planning to come back to Gentoo (either as a user or as a developer), I certainly hope the best for it.

Cheers.

— ferdy


Tagged: gentoo

15 de March de 2009 a las 17:23

16 de February de 2009

Fede Mon

esta tarde a la expo de Star Wars en Madrid, quien se viene?

16 de February de 2009 a las 12:03

13 de February de 2009

Fede Mon

me encanta: la camiseta con el piechart de la procastinación: http://ping.fm/caI56

13 de February de 2009 a las 00:54

10 de February de 2009

Fernando J. Pereda

Selected!

So this led to this

’nuff said!

Mood: Extremelly happy.

— ferdy


Tagged: esa, estec, happy, research, spacefish

10 de February de 2009 a las 18:11

02 de February de 2009

Fernando J. Pereda

More reading

I finished reading Anathem a while ago, and I really do recommend it. It was weird at first, but really nice in the end. It finished a bit fast, I’d say it needs another hundred pages to tie some of the stuff.

Also, Ricardo Cervera (you don’t have an url these days, you do?) sent me Introduction to Algorithms which I’ve been skimming through. Really nice book, of course. — Thanks.

As part of one of the research projects I’m involved, I just started reading/studying Aircraft control and simulation. Fortunately, it is not hurting as much as I expected. Though it is not for the faint of heart.

— ferdy


Tagged: book, reading, thanks

02 de February de 2009 a las 12:05

ESTEC and EeePC’s first big test

This year I joined a couple of research projects at the Computer Architecture and Automatics Department of UCM. Since I’m still finishing my Computer Science degree I can’t spend as much time as I’d liked on the projects I’m taking part. I’m mostly doing softwar and learning quite a bit of electronics and such.

Tomorrow morning I’m heading ESA’s ESTEC to attend the first workshop of this year’s RexusBexus campaign. We’ll be there until friday. We’ve worked quite hard and are hoping to get selected for the next phase. Even if we are continuing our research even if we don’t get accepted, it is a great opportunity to test the thing.

Given that I really hate checking luggage at airports I was planning to travel as light as possible. Not needing lots of computing power the Eee came as the best candidate to carry around. I haven’t really done much with it than using it to go to University and back home so this is going to be its firs big test. I get to see whether this netbook thing really works for me, though I think it will.

We’ll see how it works…

— ferdy


Tagged: asus, eee pc, eeepc, esa, estec, netbook, ucm

02 de February de 2009 a las 09:07

25 de November de 2008

Fede Mon

Undervolting

Anoche me divertí mucho. Me acosté como a las 3:30.

Andaba buceando intentando investigar por qué Xorg me consume más CPU últimamente, y no lo encontré, pero casi sin querer me encontré con un tipo que había hecho undervolting en su macbook.

Básicamente se trata de disminuir el voltaje suministrado a la CPU hasta el límite en el que ésta siga funcionando correctamente.

De esta manera dura más la batería, se calienta menos el procesador, se encienden menos los ventiladores... son todo ventajas. Mi batería ha empezado a durarme una hora más!!

Para usarlo en linux, tenemos que usar linux-phc: https://www.dedigentoo.org/trac/linux-phc/

En los foros de ubuntu [[http://ubuntuforums.org/showthread.php?t=786402] se pueden conseguir los módulos compilados, así como un howto para descubrir tu configuración (los voltajes mínimos para tu procesador).

Lo malo es que el script que hay en el foro es para procesadores con un solo core, de manera que si tienes un dual core, hay que retocarlo para que ponga la misma frecuencia en ambos cores, y les baje el voltaje a los dos, asimismo hay que lanzar otro burnMMX que se coma la otra CPU, ya que el script sólo lanza uno.

Para que funcione con dos procesadores:

Creamos una variable nueva para la segunda CPU:
cpufreq1=/sys/devices/system/cpu/cpu1/cpufreq

y buscamos "$cpufreq", añadiendo una linea extra pero con "$cpufreq1", por ejemplo:

printf "ondemand" | sudo tee $cpufreq/scaling_governor > /dev/null
printf "ondemand" | sudo tee $cpufreq1/scaling_governor > /dev/null

Eso sí, en otra terminal hay que lanzar otro burnMMX para que se funda el segundo procesador.

Sin duda, averiguar tu configuración es lo más divertido del tema, consiste en, para cada frecuencia del procesador, ir bajando el voltaje hasta que la salida de las puertas deje de ser estable, lo que conlleva un reboot instantáneo.

Bueno, happy undervolting, y hasta el año que viene!

25 de November de 2008 a las 09:26

07 de September de 2007

Fede Mon

Y luego decimos que los yankies son tontos

Yo pensaba que hacían entrevistas a la gente antes de dejarla ir a estos programas.

¿Qué es lo que gira alrededor de la Tierra?


Vía: Gran Angular

07 de September de 2007 a las 11:10

Una patada en el culo a la política

Ya sé a quién voy a votar en las próximas elecciones:

Eva Hache se presenta a presidenta.

Al menos éstos no se meten al gobierno para sacar tajada, y seguro que a la hora de tomar decisiones estarán más cerca del pueblo que cualquier otro partido político.

07 de September de 2007 a las 10:43

05 de September de 2007

Fede Mon

Comics

Sí, ya sé que es una mierda de post después de tanto tiempo sin postear, pero es que termino antes que enseñándooslo uno por uno:

No son Bilo y Nano, ni Raulito el Friki, es diferente, pero es genial.

Es Alberto Montt

Para muestra, un botón:

05 de September de 2007 a las 02:57

16 de May de 2007

Fede Mon

I am C

You are C. You do what you're told, even if you know the result will be bad.
Which Programming Language are You?

16 de May de 2007 a las 01:06

17 de April de 2007

Fede Mon

Taller en la UAM: Reciclaje de ordenadores (LTSP para entendidos)

Mi hermanito Sergio Tena me ha invitado a participar en la Semana Verde que está organizando en la UAM (él estudia Medio Ambiente) y me ha ofrecido dar una taller de cómo reutilizar ordenadores viejos.

Así que me estoy preparando para hacer una demo de todo el poder del Linux Terminal Server Project. El LTSP, para los que no les suene, es un proyecto para conectar ordenadores poco potentes como clientes de uno bien potente. Esto hace posible, por ejemplo, montar un aula de informática en un colegio con un ordenador nuevo y 20 viejos, más el coste de instalar linux sólo en el potente.

Eso sí, para asistir al taller hay que pasarse por el despacho de Ecocampus a apuntarse, y no existe la posibilidad de apuntarse vía web, así que es de esperar que se apunten pocos geeks. Dependiendo del porcentaje de geeks, me meteré más adentro (cómo ponerse uno y cómo funciona exactamente) , o más general, así que ya sabéis, os invito a todos a que asistáis, la intención es que todos aprendamos algo.

17 de April de 2007 a las 03:08

04 de November de 2006

Fede Mon

Dr. Esperanzado

No es coña. Pienso aprenderlo de verdad. Esta vez voy a llegar hasta el final. No como haskell, prolog, C++, C#, python, mecanografía... que al final he pasado de ellos sin haberlos dominado (bueno, aún estoy aprendiendo haskell, pero no se yo si llegaré a dominarlo).

Con el Esperanto pienso llegar hasta el final y más allá. Voy a contribuir a aumentar el vocabulario. Pienso conseguir que pongan diccionarios esperanto-español, español-esperanto en la biblio de informática. Y voy a empezar a mover hilos para que se enseñe en todas las escuelas de españa en lugar del francés (que sirve para poco más que ligar y hablar con To sin que nadie se entere de ná)... y no me quedaré ahí, llegaré hasta más lejos que el final y haré que el Esperanto se convierta en la lengua oficial de la unión europea.

Fuera de coña, lo de las lenguas está muy bien. Es muy importante entenderse con la gente que no vive en este país. Por eso me voy a tomar en serio lo del esperanto, pero no me voy a quedar ahí (Fede siempre queriendo ir más lejos) Luego me gustaría aprender chino y/o japonés. Estoy convencido de que son los idiomas del futuro. El imperio amarillo será el consecutivo al imperio yankee. Si éstos son capaces de dejar ánima sobre la tierra cuando vean que lo bueno se acaba y que aún quedan cabezas nucleares en sus arsenales, claro.

El otro proyecto es algo más difícil. La idea es de Maribel, y es buena, pero no sé cómo puedo aprender a hablar bien el castellano (aparte de meterme a filología hispánica, cosa que no pienso hacer).

Pues eso chicos. Que si al final el Esperanto acaba como lengua oficial de alguna parte y veis que yo aún no hago oraciones de más de 5 palabras, no es que no haya sido yo, es que unas cosas se me dan mejor que otras ;-)

04 de November de 2006 a las 18:49

Mis noches de marcha

Hay cosas en la vida que te suben la moral. Normalmente son estupideces, pero cuando te pasan te sientes bien, que es lo que importa.

Acabo de llegar a casa de salir por Madrid, y es sin duda de los días que más cansado he llegado. No he tomado alcohol, ni he bailado nada, no son aún las 2 y media, y ahí es donde reside la extravagancia del caso.

Resulta que vivo donde el diablo perdió el poncho, y solo tengo búhos que lleguen a mi pueblo los viernes y sábados, uno a la 1:15 y otro a las 3:15. La alternativa es tomarme uno que llegue hasta Parla y llamar a mi viejo para que me vaya a buscar en coche, y de esos hay uno cada hora.

La cosa es que yo salí con tiempo suficiente para llegar a la parada del búho a la 1:15, (Realmente había tiempo, Mari) pero iba en metro con mi amigo Luis Diez, y por viajar más paradas juntos, no hice el camino ideal en metro. Finalmente nos despedimos en Sol, donde yo me bajaba para tomar la línea 1 hasta atocha. Eran ya la 1:00 de la mañana, y cuando llego al andén correspondiente, veo en el letrero luminoso: "Próximo tren: 13 min".

Entonces abro mucho la boca y los ojos, y unas niñas que había en el andén se asustan bastante. Acto seguido, pronuncio entre dientes una frase que incluía defecar en algo no muy concreto, y salgo pitando de allí.

Soy un desastre. Para casi todo. Y encima si voy sobrio me tomo este tipo de situaciones bastante peor, y tengo menos imaginación que el resto del tiempo. Para colmo ese "Para casi todo" incluye "Para andar sin perderme por el centro de madrid". De forma que comparé el plano del metro con el plano zonal, me dije: "Hacia el sudeste". Elegí la salida del metro que me convenía y salí pitando.

Ah, cuando voy sobrio, para colmo aprovecho "mejor" los ciclos de reloj, de forma que en mi huida, me paro en la taquilla del metro y no se me ocurre otra cosa que decirle a la taquillera: "Perdone, ¿como se va hasta Atocha?" Entonces la señorita me miró como pensando "Este chico es más estúpido de lo que parece" y me responde: "Por la línea 1". Claro, yo sonrío, y le replico, "No, pero ... andando". Lógicamente, ella no supo que responderme mientras terminaba de sacar la conclusión de que "_realmente_ las apariencias engañan".

Y yo no tenía tiempo de contarle mi vida, porque ya serían casi y cinco, así que tiré, corrí hasta que la calle carretas dejó de llamarse carretas, y luego tiré hacia el oeste. De repente dejaron de sonarme los nombres de las calles y me frenó un poco el cansancio y un grupo de chavales a los que no conseguía adelantar. Entonces empecé a ver carteles de Lavapiés nosequé y Lavapiés nosecuantitos, y fui consciente por primera vez en mi vida de dónde queda Lavapiés.

Eran ya y diez, y tenía la esperanza casi más perdida de lo que estaba yo, cuando oigo a uno de estos chavales pronunciar la dupla que me hizo encontrarme, junto con mi esperanza: Antón Martín. Y así, como iluminados por un rayo de sol a la 1 y 11 de la mañana, apareció ante mí la boca de metro, una calle llamada Atocha, y recuperé las fuerzas para un último aliento.

Y tiré. Cuesta abajo. La gente no sabía hacia qué lado apartarse, casi me trago a uno que se me cruzó para tirar algo en una papelera.

Giré finalmente la esquina y allí había un bus! la 1:16! la última vez, llegué a y 18, y el bus que había era ya el de Parla, para salir a y media.

Pero esta vez era él!! Era el mío! Con las pocas fuerzas que me quedaban, subí los escalones y pregunté por si acaso al conductor, si llegaba el bus hasta mi pueblo, (era increíble para mis sobrios ojos).

Hubiera bailado y cantado de alegría. Pero tenía los muslos demasiado agarrotados.

04 de November de 2006 a las 18:49

Parecidos Razonables

Últimamente me dicen que me parezco al Che, con esos pelos que llevo. Me aburría estudiando los lenguajes incontextuales y decidí jugar a ser revolucionario. Éste desastre es el resultado.

FedeChe

En fin... a ver si estudio más TALF y me dejo de hacer el chorra.

04 de November de 2006 a las 18:49

South Park


South Park
Originally uploaded by gnufede.

Siguiendo la pasada moda de hazte-tu-propio-personaje-de-South-Park, aquí­ os dejo esto, que vendría a ser yo en versión southparkesiana.
Gracias a Flop y por hacérmelo!
Se observa el lightsaber rojo del lado oscuro de la Fuerza, así como la cerveza, que por alguna extraña razón está llena, el pelo sin peinar y secado en el metro de viaje a la facultad, y los ojos rojos y las ojeras a causa de la tensión acumulada frente al TFT.
La camiseta de superman se debe a que no habí­a camiseta de debian de entre las que elegir, y la sangre y la cara de acojonao le dan un aspecto más realista si cabe.
A quien le apetezca hacerse el suyo, le animo a ello, en el Planearium.

04 de November de 2006 a las 18:49

Asimov

Hola a todos!!

Ayer terminé el último libro de la saga de "La Fundación": "Fundación y tierra".

Estoy realmente enganchado a Asimov. Todo empezó el día que Porras (Sergio Gil) me dijo que Londres le pareció una ciudad muy "trantoriana", y aquí me veis, comenzando a investigar acerca del orden de la saga de los robots, tras haber leído los 7 de la fundación, uno de cuentos cortos que me dejó Porras, y "Némesis", y con ganas de más.



Creo que Asimov es el hombre de quien más páginas he leído, y en qué poco tiempo. Es increíble. Un autor que me encanta, sus libros son de una lectura muy fácil, y sus historias, muy bien pensadas. Siempre sorprendente, y con diferentes estilos, creo que cada uno de los 7 libros de la fundación es muy diferente del anterior, pero todos tienen en común que el desenlace del libro y de toda la trama se da en las últimas 2 páginas. Algún día escribiré mi comentario sobre cada uno de ellos.

Me despido recomendando estas lecturas, si hay alguno que no encontréis, decídmelo, que tengo los 7 (bueno, excepto por alguno que ya tengo prestado).

Saludos a todos!!

04 de November de 2006 a las 18:49

Gentoo

Hola Mundo!

A la vuelta del puente (sí, sí, a mi me dura hasta hoy, pues mis viejos vuelven esta noche de Amsterdam) os quería relatar en qué he aprovechado estas minivacaciones. Muchos creerías que me he ido a alguna parte, o me he quedado estudiando, y en esta ocasión habéis acertado los que pensabais que me he quedado haciendo alguna frikada: He metido Gentoo en mi portátil!


A pesar de que a muchos debianitas les duela, y me tachen de chaquetero, es así. La verdad es que a mi pentium 3, Gnome 2.10 se le resistía a funcionar bien con nuestros queridos .deb (especialmente el sonido, que comenzaba a entrecortarse), y tras probar la velocidad de GARNOME frente a los precompilados i386 que me ofrece debian, me decidí a instalar gentoo.


Afortunadamente elegí un puente lo suficientemente largo, y me pude valer de la ubuntu de 64 bits en el sobremesa para entretenerme, porque si hay algo que gentoo requiere, es paciencia.


A pesar de que no me acaba de tirar todo (creo que ya solo me falta que funcione el totem-xine), estoy contento con el cambio. Costó, porque a pesar de lo que dicen de que debian es chungo de instalar y tal... una vez que te aprendes como instalar tu tarjeta gráfica, lo demás es coser y cantar, mientras en gentoo, todo es más "háztelo-tú-mismo". Sin embargo, el handbook de gentoo no tiene precio, creo que en debian no hay nada similar (la verdad es que en debian tampoco es demasiado necesario).


En fin, como un par de anécdotas os cuento que el stage1 tardó 6 horas en compilar, el stage2 nunca lo supe, pues petaba de vez en cuando algún paquete y se quedaba ahí sin hacer nada durante horas, hasta que se me ocurría ir a verle, y un par de veces el portátil alcanzó temperaturas extremas y se apagó solito. En una de ellas estuve presente, según él, había llegado a los 110 grados Celsius (menos mal que no me lo suelo poner en el regazo cuando compila...) y al final, harto de que petaran los paquetes, recurrí a mi querido script cabezón, que se ocupó de que se acabara de compilar el stage2 y comenzara a compilar el stage3:



emerge --emptytree system;
while (! emerge --resume --skipfirst);
do sleep 1s;
done;
emerge gnome;


Por cierto, que duro me parece lo de openoffice: 1 día en compilar, y dependiendo del ordenador, puede tardar más! El mío está cerca de las 24 horas, y no parece que le falte poco. Cómo hacen los desarrolladores para depurarlo?? Me queda tanto por aprender...

04 de November de 2006 a las 18:49

Al Fin!!

Sí señores, una de las cosas más esperadas de este mundo ya está disponible.

"Gracias" Adobe

(Ya era hora, coño)



technorati tags:, , ,

04 de November de 2006 a las 18:49

Matrícula de Honor en LEC


Matrícula de Honor en LEC
Originally uploaded by gnufede.
Olé, hacía tiempo que no me llevaba una alegría tan grande

04 de November de 2006 a las 18:49

Xgl


Cubo
Originally uploaded by gnufede.
Venga va, que no me he aguantado a acabar los exámenes, así que hoy me he boicoteado el día poniéndome xgl.

Aquí tenéis mi cubo.

Saluditos, y suerte en los exámenes

04 de November de 2006 a las 18:49

El juego de las sillas

Mi biblioteca parece estos días (supongo que como todas en ese momento justo antes de los exámenes, pero aún con clase) el puto juego de las sillas.

Ese que tan poco me gustaba de que para alguien la música y te tienes que sentar pero no hay sillas para todos, así que alguien acaba con el culo en el suelo.

La diferencia es que aquí no hay nada organizado, como aquellos papeles de la Carlos III (que Rebe me recordaba que tampoco allí se acaban usando) donde pone la hora a la que te largas dejando tu puesto lleno de apuntes.

Pero lo peor es que la gente además no se entera de que la "reserva" de dejar tus cosas, expira en 15 minutos, y da mucha lástima ver a la cantidad de gente que come corriendo para ver si encuentran sitio en la biblio y se encuentran cada puesto sembrado de papeles.

Se supone que la idea es que el bibliotecario te busque un sitio que lleve libre más de 15 minutos, pero claro, solo tiene vigilada la primera fila, así que he comenzado a tomarme la justicia por mi mano, usurpando puestos y os invito a todos a hacerlo:

  1. Te pones en el sitio que más te guste de una mesa cuanto más desierta mejor.
  2. Apuntas la hora a la que llegas.
  3. Avisas al bibliotecario que te gusta ese sitio, y que si no sabe cuanto tiempo lleva libre, apunte él también la hora.
  4. Vuelves a tu sitio y ordenas los apuntes del otro encima del estante que tienen las mesas (o le pides al bibliotecario que lo haga).
  5. Si el dueño vuelve antes de 15 minutos, usurpas el siguiente sitio libre que quede en la mesa.(Uno que lleve libre desde que llegaste, claro)
Hale, cuando lleves en un sitio más de 15 minutos, es tuyo!

Y atención, el éxito está prácticamente garantizado (hasta ahora he usurpado todos los puestos con éxito), algunos incluso se rebotan, pero suele ser porque no conocen la norma, pero tampoco suelen conocer ninguna que les dé la razón, entonces no tienes más que señalar alguna columna que tenga un cartel (que no sea de los carteles de WiFi), y decirle: "Háblale a la columna, que tengo las orejas sucias que te cagas".

04 de November de 2006 a las 18:49

Dedicado a quienes no me creen


Calle Generalisimo Franco (REAL)
Originally uploaded by gnufede.
Ea, aquí tenéis la prueba, ya nadie puede no creer mi historia: "Mi pueblo está tan lejos que por allí no pasa ni el tiempo"

Gracias a Mikel por darme la idea de bloguear esto, la verdad es que se lo merece.

Bueno, sé que no se ve demasiado bien, pero creo que se llega a inteligir:

Son las placas de la (actualmente, oficialmente) calle real de mi pueblo, en la de arriba pone "Calle Real", y en la de abajo "CALLE DEL GENERALISIMO FRANCO".

Es la calle principal de mi pueblo, como os podréis imaginar, y esta placa está a la altura a la que paran todos los autobuses que pasan por mi pueblo.

04 de November de 2006 a las 18:49

RITSI

Llevo casi 30 horas en Madrid, he vuelto de Valencia, de la XXIII RITSI, una reunión de estudiantes de ingenierías en informática a nivel nacional, y aún no me aclimato.

Demasiadas neuronas asesinadas, porque creo que las horas de sueño ya las he recuperado. Lo cierto es que, al menos por mi parte, mucha juerga por la noche, y casi tanto curro por el día, que bueno, no fue tanto porque la mayor parte era consistía en escuchar conferencias, y porque las actividades de participar activamente fueron más dejadas de lado, demasiados retrasos en el orden del día sacrificaron el tiempo para sacar conclusiones e intercambiar opiniones.

Pero aún así pienso que ha valido la pena, y a partir de ahora, dedicaré parte de mi tiempo a que valga mucho más la pena.

Debemos aprovechar estas reuniones para intercambiar opiniones, y ayudarnos mutuamente para conseguir que nuestras respectivas facultades y escuelas vayan a mejor, además de movilizarnos en los temas que ahora nos competen para crear unas nuevas titulaciones de Informáticos lo mejor posible.

Un saludo desde aquí a todos los asistentes de la XXIII RITSI, y en especial a mi compi de habitación, el novato Sergio y a los demás integrantes de la junta directiva, confío plenamente en vosotros y estoy seguro de que trabajaremos mucho y muy bien.

04 de November de 2006 a las 18:49

Telefónica

Hola, me llamo Federico, tengo un teléfono Movistar y se me calienta fácilmente.


Llevo tiempo planteándome cambiarme de compañía telefónica por las medidas monopolísticas que usaba Telefónica Movistar y que sigue usando en su nueva imagen Movistar. Con medidas monopolísticas me refiero a eso de hacer lo que les da la gana y cobrarnos cada vez más por lo que antes no nos cobraban.


Sé de una fuente fiable, que Telefónica Movistar cambió su imagen para pasar a llamarse Movistar "a secas" precisamente porque una encuesta que llevaron a cabo les decía que la idea que la gente tiene de Telefónica es que es una empresa a la que se la suda el cliente.


Pero el anuncio está siendo la gota que colma el vaso. Mientras otras compañías dedican a hacer anuncios sobre las garantías y los servicios que ofrecen, Movistar se regocija de tener la mayor cuota de mercado, y engaña a la gente haciéndole creer que las llamadas entre la misma compañía son más baratas "como todo el mundo sabe" (son más baratas porque a ellos les da la real gana) y porque como gran parte del mercado es de Movistar, las llamadas salen más baratas. Esto es MENTIRA. Las llamadas saldrían más baratas si te dedicaras a llamar a todos los números de España al azar, pero si tienes Movistar únicamente llamas a tu madre y tu novia que tienen tienen Amena y Vodafone, vas jodido.


La conclusión es que Movistar no sólo sigue siendo una empresa que pasa de sus clientes y sigue con sus costumbres monopolísticas, sino que se rogocija desvergonzadamente de ello y nos MIENTE a través de los medios como le da la gana.


Lo siento por la gente a la que le saldrá más caro llamarme, así que os invito a todos a que nos cambiemos a Vodafone, para que "como todo el mundo sabe", os siga saliendo barato llamarme

04 de November de 2006 a las 18:49

De Política y otras escatologías


Siento tristeza porque este voto no fuera nada constructivo. Sí y No, se me queda corto para decir lo que pienso sobre una constitución y que se debería hacer para mejorarla.

Siento impotencia porque este voto fuera meramente consultivo. Eso es despilfarrar. Use papel higiénico oiga, que fin y al cabo sirve para lo mismo, y sale mucho más barato.

Siento respeto por la gente que no fue a votar por estar desinformada. Eso es ser acorde.

Siento que las razones del SI se redujeran a "Porque es por Europa, y en Europa todo es maravilloso y multicolor, y tenemos que seguir dando pasos hacia adelante y hacia arriba y todos unidos y cogidos de la mano". Me hubiera gustado que me mostraran lo bueno que tiene esta constitución. Eso es ocultar cosas.

Siento asco por la gente que dice que hay que votar sí y por detrás vota que no, solo pa joder diciendo: "Que mal lo hace este Zapatero. Mira la de NOs que hay por su culpa." 80% de NO en la Moraleja, eso es, se han vuelto todos de Izquierda Unida de la noche a la mañana. Eso es ser hipócrita.

No sé que sentir con respecto a la gente que no votó porque estuvo en pijama todo el día. Eso es ser vago.

04 de November de 2006 a las 18:49

Gmail


Hola a todos!!


En mi afán por acumular cuentas de correo, he puesto a flote algunas en Gmail, ahora que han habilitado un POP3 como la gente (antes habí­a que hacer movidas extrañas). La verdad es que no me hace mucha ilu, sé que la moda de gmail no es más que eso, una moda. Si a alguno le hace ilu escribirme ahí­, es GNU.Fede ARROBA gmail.com, pero sabed que va a parar al mismo sitio que GNUfede EN ya.com, la de paralosgordosparalosflacos en yahoo.es, la de federicomon en hotmail... a mi querido Evolution jejeje


Ah, me quedan 9 invitaciones, si alguien quiere una, que me escriba a cualquiera de mis correos ;-)


Os quiero a todos

04 de November de 2006 a las 18:49

Navidad

Hola, hoy estreno este blog hablando de la navidad.

Hoy ya es el día de nochebuena, las fechas del amor y del consumismo. Es decir, del consumismo, porque, con sinceridad, aparte de comprando regalos, como demuestra la gente ese "amor" es mandando tarjetas y deseando feliz navidad por teléfono; pero desear es fácil, y perder el tiempo escribiendo esas típicas tarjetas no vale la pena.

El amor a los demás hay que demostrarlo día a día, esforzándose por hacer mejor la vida de las personas. Quizá no sea la persona más indicada para hablar de hacer mejor la vida de los demás, pero al menos no soy un hipócrita más escribiendo "Felices Fiestas" en una tarjeta que me sobró del año pasado.

A fin de cuentas, la navidad me parece un timo, primero, porque Jesús no nació en Diciembre. Nadie sabe cuándo cojones nació Jesucristo, es más, este año, no es el 2004 después de cristo, en realidad es el 2010, porque el astrónomo que se ocupó de esto para el vaticano, se equivocó en 6 años, al parecer. Pero además, el día, tampoco se sabía (hoy hay gente que piensa que pudo nacer en Septiembre), sino que el papa Julio I, decidió que Jesús nació el día que hasta ese entonces se celebraba la festividad oficial al sol invictus.

La movida de los regalos y de Papá Noel es mucho más larga, el que quiera enterarse, que busque "Navidad" y "Papá Noel" en la wikipedia.

Bueno, a lo que iba, que hay que ser buena persona todo el año, no demostramos nada portándonos bien ahora, no hace falta que intentemos engañar a los reyes magos.

Un beso a todos, os quiero mucho.

04 de November de 2006 a las 18:49

27 de May de 2005

Sergio Martín

Frikeando...

Wenas gente, hacía tiempo que no escribía nada (de hecho, creo que este es mi segundo post...)
Ayer fue un día especialmente de enredos. Ni curré, ni estudié... pero me lo pasé a lo grande.
Tras llevar a mi madre al curro y tomarme algo allí (tenemos una cafeteria, para los que no lo sepan y les interese), me dió la picada y me pillé una PS2 Slim en color Plata. Ya estuve enredando viendo que si el DMS3 o DMS4, chip protector de sobretensión en la lente... etc. Nada productivo. Y por ahí me quieren sajar 120 lauros... casi que me lo sigo buscando yo y me lo instalo, que como la electrónica también me va... En fin. A esto le dediqué poco tiempo ya que tenía muchas cositas por delante... Pero unas partidillas al Enter the Matrix que me dejó un colega si me eché...

Tras esto y después de solucionar algunas cosillas para tener cierto soft de p2p a punto siempre (un ordenador dedicado a ello en exclusiva y las unidades de musica, video etc del disco duro externo - Maxtor 250Gb en caja [http://www.modix.co.kr/] Modix 3510, al que tambien le actualizé el firmware ¡¡¡y que ya tengo lleno!!!- mapeadas por smb en los otros, ya sabéis que SO es y que soft de p2p a que si?) y líos de drivers para que funcionasen las cosas bajo una conceptronic pci con 4+2 usb2.0 (4 externos, 2 internos, creo que es una c480i que en linux (Ubuntu Hoary) no me pillaba bien porque se pegaban los controladores de ehci_hcd, uhci_hcd y ohci_hcd), q al final pinché en un Win98 (es una maquina pelin viejilla, y sino no me tira bien el SO... y como con linux no tenia muxo tiempo pa enredar...), reconfigurar 2 routers (el mio y el de un vecino que me estaba machacando mi wifi) y algunas cosillas menores, me bajé a por el juego antes mencionado a casa de mi amigo, y entre arreglarle tb problemillas a él de redes (el no es nada linuxero pero... es un buen amigo...) y preguntarle por una memory de sobra (se que no deberia que no son fechas... y mejor que no tuviera, me aguantare las ganas de jugar hasta el 30 de junio... ultimo examen...) surgió la opción de ir por la tarde al cine... Si os digo que el finde pasado no era plan de ir con la novia a verla y ayer si era plan de ir con un colega, sin duda ya sabréis que me refiero al Episodio III. 2h 30min de peli para quien no la haya visto. Y no os pondré aquí mi opinión para no aburriros más...

Total que ya volvimos de la peli, le configuré el cortafuegos del P*nd* *ntivirus que menuda basura es para que pudiera jugar en Lan a cierto juego de estrategia con aldeanos, barquitos etc etc de la empresa del Bill, le configuré tb su router para que le metiera algo más de seguridad (tanto que me pase y ahora no puedo ni conectarme yo...) y me subí a casa a cenar y enredar otro poco.

Así que ya chateando con Flype, que taba currandose un scriptcillo para la vpn de la uc3m y demás (Flype dando el callo = exámenes próximos xD) me acordé de que en mi gnome 2.10 nuevito (instalé hace no mucho linux (Ubuntu Hoary) de nuevo en el portátil y todo bien a la primera, menuda maravilla) me parecía recordar haber visto por ahí que soportaba sombras, transparencias y cosas así... Un pequeño paseo por Google y encontré lo que buscaba. xcompmgr y transset, mas una pequeña config del xorg.conf. Yo anoche lo hice siguiendo un howto en inglés, [http://www.ubuntuforums.org/showthread.php?t=20769] pero ahora rebuscandolo para ponerlo aquí (toy en el despacho en la uni) lo encontré en español... [http://linuxcordoba.org/node/view/112].De lo que pone por ahí, yo tan solo meti la sección de "Extensions" y ya me iba... pero claro sin mucha aceleración asi que algunas cosas van despacito... ya lo trastearé pero es super sencillo (el transset lo probe pero no me puse teclas rapidas ni nada asi... que eran las 2 de la mañana y hoy queria venir a clase... anque llegué tarde y de ahí escribir tanto, que hasta las 10 que nos vayamos a por unas bravas y eso...). Luego acabas metiendo el programa en las sesiones de gnome... y listo.
También me puse con los colores del bash, editando el .bashrc...
Me configuré un par de hotkeys... mi Alt+k para abrirme un terminal y cosillas así.
Enredé también con [http://www.videolan.org/vlc/] VLC que no se porqué no me sacaba interfaz... y ya lo configuré bien.

Y terminé de configurarme el [http://www.jinzora.com/] jinzora, un soft de streamings de audio/video para acceso web y asi tener siempre todo el contenido multimedia del disco externo a punto... (como comentario, me conecto desde el portatil al servidos con el jinzora que apunta a las unidades que estan mapeadas en el otro ordenador... si echáis las cuentas os tienen que salir 3 ordenadores...)
Otra de las cosillas que hice hace tiempo, para aquellos que quieran tener un bootsplash sin meterse en líos de parches de kernel etc, miraros [http://wiki.nanofreesoft.org/index.php/Splashy] Splashy y el foro donde lo vi http://www.ubuntu-es.org/node/3344, que para personalizarlo es tan sencillo como currarte 3 imágenes png, tener soporte para framebuffer y editar un config.xml, todo lo explican ahí. Si a alguien le interesa me mande un mail a sanok@gul·uc3m·es y le envio lo que hice yo... o le pongo un screen en algun lao...
En fin, eso es todo. Me salio un post largo pero espero que ameno o de alguna utilidad para alguien... ya que escribo poco al menos que sirva para algo no?
Os dejo ya que son las 9.45 y tengo que ver que esto publique bien y demás antes de irme a llenar el buche.

Byes!!.

27 de May de 2005 a las 04:33