Обновление timezone в logstash

в 8:16, , рубрики: jruby, kibana, linux, logstash, timezone

Всем привет! Уже как пару месяцев наша компания успешно использует в продакшене связку logstash-elasticsearch-kibana для сбора и обработки достаточно большого объема логов. Заглянув в kibana после перевода часов обнаружилось, что все логи идут с отставанием по времени в 1 час. Под катом хочу поделиться решением проблемы с timezones в связке logstash-elasticsearch-kibana и готовой сборкой logstash с обновленными timezones.

Не буду особенно вникать, в то как повлияла смена timezone на конечный вид логов, но по факту в kibana мы получали событие созданное в текущий момент времени как события часом ранее. Получилась достаточно забавная картина, учитывая, что не все rsyslogd перезапустились автоматом и подхватили новые timezone, пара серверов продолжали работать по старым часовым поясам.

Обновление timezone в logstash
(График кол-ва событий в момент перехода на logstash с корректными timezones)

Решить проблему можно конечно костыльной настройкой logstash, но я решил полноценно обновить timezone в logstash.

У Logstash возможны сразу три источника временных зон — одна в java, вторая в геме ruby tzinfo, третья закомпилирована в jruby (артефакт joda-time и joda-timezones).

  1. Начнем с простого — обновим tzdata в java:

    Для этого воспользуемся утилитой от Oracle tzupdater, можно скачать с сайта Oracle.

    Обновление происходит буквально в одну команду:

    java -jar tzupdater.jar  -V
    tzupdater version 1.4.7-b01
    JRE time zone data version: tzdata2014c
    Embedded time zone data version: tzdata2014g
    java -jar tzupdater.jar  -u
    java -jar tzupdater.jar  -V
    tzupdater version 1.4.7-b01
    JRE time zone data version: tzdata2014g
    Embedded time zone data version: tzdata2014g
    
  2. Сборка jruby с новой tzdata:

    1. Для начала соберем артефакт joda-time с новыми timezones:
      Перед сборкой установим пакеты maven и ant:

      apt-get install maven ant 

      Скачиваем последний доступный пакет joda-timezones, заменяем в нем версию tzdata и в зависимостях указываем более свежий joda-time(2.5 от 3.10.2014):

      mkdir joda-time
      cd joda-time
      wget http://search.maven.org/remotecontent?filepath=org/jruby/joda-timezones/2013d/joda-timezones-2013d.pom -O pom.xml
      sed -i 's/2013d/2014g/' pom.xml
      sed -i 's/<version>2.2/<version>2.5/' pom.xml
      mvn package
      mvn instal
      

      Теперь, maven получил актуальную версию joda-timezones.

    2. Скачиваем исходники версии jruby, которая используется в logstash (для logstash 1.4 это jruby-1.7.11):
      wget https://github.com/jruby/jruby/archive/1.7.11.tar.gz
      tar -xvf 1.7.11.tar.gz
      cd jruby-1.7.11/
      

      Заменяем версию артефакта в ./core/pom.xml:

      sed -i 's/<tzdata.version>2013d/<tzdata.version>2014g/' ./core/pom.xml
      sed -i 's/<tzdata.jar.version>2013d/<tzdata.jar.version>2014g/' ./core/pom.xml
      

      В ./pom.xml:

      sed -i 's/<joda.time.version>2.3/<joda.time.version>2.5/' ./pom.xml
      

      Собираем jruby:

      ~/jruby-1.7.11# mvn -Pcomplete
      

      После сборки проверим какую версию tz ответит jruby, заодно сравним время с реальным (в конце я запускаю http-server, что бы было удобнее собирать logstash):

      ~/jruby-1.7.11# java -jar ./maven/jruby-complete/target/jruby-complete-1.7.11.jar -rrbconfig -e 'p RbConfig::CONFIG["tzdata.version"]'
      "2014g"
      ~/jruby-1.7.11# java  -jar ./maven/jruby-complete/target/jruby-complete-1.7.11.jar -e 'p Time.now'
      2014-10-29 14:58:07 +0500
      ~/jruby-1.7.11# cd ./maven/jruby-complete/target/;python -m SimpleHTTPServer
      

  3. Собираем logstash:

    Скачиваем распаковываем:

    wget https://github.com/elasticsearch/logstash/archive/v1.4.2.tar.gz
    tar -xvf v1.4.2.tar.gz
    mv logstash-1.4.2 logstash-contrib;cd logstash-contrib
    

    Вносим изменения:

    diff --git a/Makefile b/Makefile
    index 0ec3da1..7fcca1a 100644
    --- a/Makefile
    +++ b/Makefile
    @@ -7,7 +7,7 @@ ELASTICSEARCH_VERSION=1.1.1
     
     WITH_JRUBY=java -jar $(shell pwd)/$(JRUBY) -S
     JRUBY=vendor/jar/jruby-complete-$(JRUBY_VERSION).jar
    -JRUBY_URL=http://jruby.org.s3.amazonaws.com/downloads/$(JRUBY_VERSION)/jruby-complete-$(JRUBY_VERSION).jar
    +JRUBY_URL=http://127.0.0.1:8000/jruby-complete-$(JRUBY_VERSION).jar
     JRUBY_CMD=bin/logstash env java -jar $(JRUBY)
     
     ELASTICSEARCH_URL=http://download.elasticsearch.org/elasticsearch/elasticsearch
    diff --git a/logstash.gemspec b/logstash.gemspec
    index 4917d83..6ba8ae4 100644
    --- a/logstash.gemspec
    +++ b/logstash.gemspec
    @@ -23,6 +23,7 @@ Gem::Specification.new do |gem|
       gem.add_runtime_dependency "stud"               #(Apache 2.0 license)
       gem.add_runtime_dependency "clamp"              # for command line args/flags (MIT license)
       gem.add_runtime_dependency "i18n", [">=0.6.6"]  #(MIT license)
    +  gem.add_runtime_dependency "tzinfo", [">=1.2.2"]#(MIT license)
     
       # Web dependencies
       gem.add_runtime_dependency "ftw", ["~> 0.0.39"] #(Apache 2.0 license)
    diff --git a/tools/Gemfile.jruby-1.9.lock b/tools/Gemfile.jruby-1.9.lock
    index dc11fd5..41e4362 100644
    --- a/tools/Gemfile.jruby-1.9.lock
    +++ b/tools/Gemfile.jruby-1.9.lock
    @@ -169,7 +165,7 @@ GEM
           http_parser.rb (~> 0.5.0)
           json (~> 1.8)
           simple_oauth (~> 0.2.0)
    -    tzinfo (1.1.0)
    +    tzinfo (1.2.2)
           thread_safe (~> 0.1)
         user_agent_parser (2.1.2)
         uuidtools (2.1.4)
    

    И запускаем сборку:

    make tarball
    

    По завершению сборки получим ./build/logstash-1.4.2.tar.gz — готовый logstash с обновленной tzdata!

P.S. Все манипуляции производились на ubuntu 14.04 с установленной Oracle Java(TM) Development Kit (JDK) 7 (build 1.7.0_72-b14)

Готовую сборку logstash 1.4.3 с обновленными timezone можно скачать c yandex-disk или mail.ru.

Автор: danteg41

Источник

Поделиться

* - обязательные к заполнению поля