OpenStack, Logstash and Elasticsearch: living on the edge

As part of my work for Bigfoot, I deployed a system to gather application logs and metering data coming from an OpenStack installation into Elasticsearch, for data analysis and processing. This post is based on OpenStack Icehouse.

Ceilometer to Elasticsearch

Ceilometer promises to gather metering data from the OpenStack cloud and aggregate it into a database, where it can be accessed by monitoring and billing software. In reality getting some data is very easy, but getting all the data is very hard, and in some cases, impossible.

Some OpenStack projects integrate the metering functionality and send their samples (VM CPU usage, disk, network, etc.) via RabbitMQ to a central agent. Other do not integrate Ceilometer (why? I don’t know) and the administrator has to run periodically a separate script/daemon to gather the information and send it out. The lack of documentation in this area is almost complete, I found out about “neutron-metering-agent” and “cinder-volume-usage-audit” by chance and doing Google searches for them, right now, results in nothing that explains what they are and how to use them.

Once the data is gathered, Ceilometer wants to store it into a database. MongoDB is highly suggested, but it does not work together with Sahara, another OpenStack project. The issue ticket has been opened almost a year ago, and it is still open.

Mysql is not up to the task, a week of data causes the database to grow to a few tens of gigabytes. The script provided by Ceilometer to delete old data then tries to load everything in memory, hits swap and all hope is lost. I let it run for a week trying to delete one day of data, then I decided to try something else.

Ceilometer can send the data in msgpack format via UDP to an external collector. I removed the central agent and the database and pointed Ceilometer to Logstash. Connecting Logstash to Elasticsearch is very easy and now I can do something useful with the data. It works quite well, and here is how I did it:

First, the Ceilometer pipeline.yaml:

sources:
  - name: bigfoot_source
    interval: 60
    meters:
        - "*"
    sinks:
        - bigfoot_sink
sinks:
  - name: bigfoot_sink
    transformers: 
    publishers:
      - udp://<logstash ip>:<logstash port>

This file has to be copied to all OpenStack hosts running Ceilometer agents (even on the Swift Proxy that does not have a standalone agent). Logstash needs an input:

input {
  udp {
    port => <some port>
    codec => msgpack
    type => ceilometer
  }
}

and some filters:

filter {
  if [type] == "ceilometer" and [counter_name] == "bandwidth" {
    date {
      match => [ "timestamp", "YYY-MM-dd HH:mm:ss.SSSSSS" ]
      remove_field => "timestamp"
      timezone => "UTC"
    }
  }
  if [type] == "ceilometer" and [counter_name] == "volume" {
    date {
      match => [ "timestamp", "YYY-MM-dd HH:mm:ss.SSSSSS" ]
      remove_field => "timestamp"
      timezone => "UTC"
    }
    date {
      match =>["[resource_metadata][created_at]","YYY-MM-dd HH:mm:ss"]
      remove_field => "[resource_metadata][created_at]"
      target => "[resource_metadata][created_at_parsed]"
      timezone => "UTC"
    }
  }
  if [type] == "ceilometer" and [counter_name] == "volume.size" {
    date {
      match => [ "timestamp", "YYY-MM-dd HH:mm:ss.SSSSSS" ]
      remove_field => "timestamp"
      timezone => "UTC"
    }
    date {
      match =>["[resource_metadata][created_at]","YYY-MM-dd HH:mm:ss"]
      remove_field => "[resource_metadata][created_at]"
      target => "[resource_metadata][created_at_parsed]"
      timezone => "UTC"
    }
  }
}

These filters are needed because date formats in Ceilometer messages are inconsistent. Without these filters Elasticsearch will try to parse them and fail, discarding the messages. Perhaps there are other messages with this problem, but the only way to find them is wait for a parser exception in Elasticsearch logs.

I think this configuration is much more scalable, flexible and useful to the end user than the standard Ceilometer way, with its database and custom API for which there are no consumers.

Application logs

Managing an OpenStack deployment is hard. It is a complex distributed system, composed of many processes running on different physical machines. Each process logs to a different file, on the machine it is running on. A general lack of documentation and inconsistent use of log levels across OpenStack projects means that trying to investigate an issue is a tedious and time consuming job. Processes need to be restarted with debugging enabled, and a few important lines get lost among tons of other stuff.

To try to simplify this situation I used again Logstash+Elasticsearch to gather all the application logs coming from OpenStack. To work at its best and provide meaningful searches (all messages from a certain Python module, all messages with exception traces), I decided to use a Python logging module that would translate the Python log objects into Logstash (json) dictionaries. This way the structure is conserved and not lost in syslog-like text translation.

Doing that is fairly simple, with a few caveats. First you will need to install python-logstash (my version reduces the number of fields that get discarded).

Then add this file to the configuration directory of the project you want to get the logs from (for example /etc/neutron/logging.conf):

[loggers]
keys=root

[handlers]
keys=stream

[formatters]
keys=

[logger_root]
level=INFO
handlers=stream

[handler_stream]
class=logstash.UDPLogstashHandler
args=(<logstash server>, <logstash port>, 'pythonlog', None, False, 1)

And finally add this option to Neutron’s config file (it is the same for the other projects):

log_config_append=/etc/neutron/logging.conf

Configuring logstash is easy, just add this:

input {
  udp {
    codec => "json"
    port => <some port>
    type => "pythonlog"
    buffer_size => 16384
  }
}

Now, the caveats:

  • this will disable completely any other logging option you set in the configuration files (debug, verbose, log_dir, …). Disregard what the documentation says about the fact the logging conguration will be appended, it does not, it overrides anything else and because of how the python logging system is made, there is nothing that can be done. If you use that option, all logging configuration has to reside in the logging.conf file.
  • The configuration above discard all logs with a level lower than INFO. DEBUG level is needed to investigate issues, but the volume of logs coming from a full OpenStack install at DEBUG level is just too big and imposes useless load.
  • Depending on the size and the load of your deployment, you may need to scale up both logstash and elasticsearch.

Prezzi di primavera

  • Ciliege: 8 €/Kg
  • Albicocche: 6 €/Kg (marce e aspre)
  • Pere: 2,5 €/kg (importate dall’Argentina)

Benvenuti in costa azzurra a fine giugno!

Agende nel 2014

Sono sempre alla ricerca di modi per organizzarmi meglio e periodicamente parto per delle quest, alla ricerca della soluzione definitiva ai miei problemi. Oggi riassumo i risultati delle mie ricerche sui modi migliori per organizzare una agenda di cose da fare.

I miei requisiti sono semplici, almeno all’apparenza:

  1. Client offline Android e PC (windows), sincronizzazione automatica
  2. I dati devono risiedere sul mio server
  3. Integrazione con la rubrica (compleanni, liste di persone presenti alle riunioni)
  4. Integrazione con un gestore di “attività/task”. Mi riferisco ai task inclusi nella specifica del protocollo caldav (i VTODO nella definizione dell’RFC 2445).

Sinceramente, non penso di chiedere la Luna. Il punto 1 dovrebbe essere piuttosto diffuso vista la quantità di telefoni Android e PC Windows in circolazione.Il punto 2 dovrebbe interessare a chiunque abbia o un minimo di riguardo per la propria privacy, o voglia tenere i dati della propria attività lavorativa sotto il proprio controllo e non cederlo a terzi.
Il punto 3 è questione di integrazione tra servizi esistenti, niente di nuovo da inventare. Outlook con Exchange lo fa già molto bene da tanto tempo, ad esempio.
Il punto 4, i task: mi piacerebbe poter tenere una lista delle cose che ho in mente di fare. Alcune hanno delle scadenze e altre no. Quelle che hanno scadenza dovrebbero apparire nell’agenda. Di nuovo, integrazione tra servizi, niente di nuovo.

Dopo innumerevoli ricerche, ripensamenti, installazioni e software in prova sono giunto alla conclusione che c’è parecchia strada da fare. Vediamo un po’.

Server

Per fare sincronizzazione facile ed affidabile ci vuole un server. La soluzione più promettente in quanto standardizzata e aperta sembra essere caldav. Ci sono vari server, uno che ho provato è baïkal, che mi sembra faccia il suo lavoro egregiamente ed è facile da installare. Un altro è radicale, ma è implementato in Python e quindi non è facile da installare su un web server in hosting. In realtà faccio uso del server SabreDAV fornito dal mio provider di posta, a cui hanno aggiunto un’interfaccia web.

Il lato server è il più facile, ci sono varie soluzioni, tutte buone.

Client Android

Qui inizia il calvario. Android non supporta caldav. Ci sono app a pagamento o gratuite (beta) che fanno la sincronizzazione (ma non la fanno dei task per qualche motivo a me ignoto). Questo già mi sembra un po’ tanto grave in un sistema operativo che fa di un punto di forza il suo essere aperto e libero.
Una volta che l’agenda è sincronizzata (ma non i task/attività, ripeto) ci sono varie app, alcune anche molto carine e ben fatte. Uso Business Calendar Pro, che ha dei bei widget, ma c’è anche SolCalendar.

Businness Calendar ha un supporto parziale per gli inviti ai meeting che arrivano da un calendario Google. Dico parziale perché appare la domanda “vuoi partecipare a questo meeting?”, ma poi non mi sembra che accada alcunché, qualunque sia la riposta.

Esiste una app, chiamata Birthday Adapter, che riempie un calendario a scelta coi compleanni presi dalla rubrica di Android. È utile, ma è un tapullo. Gli eventi sono visibili solo sul cellulare ed è ancora un altro servizio che deve girare su un dispositivo a batteria quando invece potrebbe essere fatto lato server ed essere condiviso su tutti i dispositivi.

Per i task c’è Mirakel. Che vuole una versione con patch della app per sincronizzare caldav. È tutto molto beta. Oppure c’è una app della stessa persona che fa caldav-sync, la app a pagamento per la sincronizzazione, ma è limitata e non fa cose fondamentali come i task ricorrenti (tipo qualcosa che si ripete una volta a settimana).

Client Windows

C’è Thunderbird con l’addon lightning. Poverino, fa il suo dovere e ha qualche bachetto. Zero sincronizzazione con la rubrica, che comunque in Thunderbird non si sincronizza. Non trova da solo tutti i calendari in un account e bisogna aggiungerli uno alla volta manualmente.
In alternativa c’è eM client. Che è un client di posta più moderno, ma che non solo vuole una licenza, ma aggiunge veramente pochissimo (una rubrica che si sincronizza) a quello che fa Thunderbird. Non sono a conoscenza di altri software, forse ci sono dei port di software Linux, come Evolution, ma nella mia esperienza è raro che tali progetti di porting funzionino decentemente e siano supportati bene.

Personalizzazioni

Ho sviluppato uno script che scarica un calendario condiviso e lo ripubblica all’interno di un calendario privato. Serve ad accentrare in un punto unico (il mio server) tutti i calendari di cui ho bisogno. Ad esempio uso un calendario pubblico di festività francesi e lo importo sul mio server, a questo modo ho quegli eventi su tutti i miei dispositivi automaticamente.Ho intenzione di estendere la cosa anche per i compleanni, basta leggere dalla rubrica condivisa e creare degli eventi in un calendario apposta.

Conclusioni

Manca del tutto un sistema di organizzazione personale, per singoli individui. Un sistema che racchiuda rubrica, calendario, posta e task manager, usando tecnologie e software esistenti e già diffusi, senza reinventare la ruota. La maggior parte delle componenti esiste già, mancano un po’ di pezzetti qui e là ed un po’ di colla per tenere insieme il tutto e dargli un aspetto decoroso. Ad averci il tempo potrebbe essere anche un progetto interessante, ma per ora purtroppo, si va avanti a script o si fa senza.

Curiosità

Durante la mia quest ho incontrato siti interessanti: