Logstash и JSON


(Aleksei) #1

У нас все логи веб-приложений пишутся в JSON, при этом "кто в лес кто по дрова". Собирается все на центральный сервер syslog-ng который переодически перестает работать из-за лимита json ключей 65к. Пытаюсь скормить такой JSON в ELK. Затыкается((((

Каждый логи JSON большой:
{"PROGRAM":"test","context":{"route":"privilege_get_token","_id":"2939","project_id":"[null]","user":"2939","user_role":"ROLE_OWNER","http_status_code":"200","plain_request":"POST /test/test/2939/token HTTP/1.1\r\nAccept: application/json\r\nAccept-Encoding: gzip,deflate,br\r\nAuthorization: Basic 9384hf9dsh4387hq0J==\r\nConnection: close\r\nContent-Length: 187\r\nContent-Type: application/json\r\nHost: api.test.com\r\nHttps: on\r\nPhp-Auth-Pw: 98h34f-sdfh\r\nPhp-Auth-User: 2939\r\nUser-Agent: AppEngine-Google; (+http://code.google.com/appengine; appid: s~realmoemadd)\r\nX-Cloud-Trace-Context: d585aa33f31342534f3457379d5f/125734ref3ef3d410406\r\nX-Forwarded-For: 107.10.33.79\r\nX-Forwarded-Port: 443\r\nX-Forwarded-Proto: https\r\nX-Php-Ob-Level: 2\r\nX-Real-Ip: 107.10.33.79\r\n\r\n{\"user\": {\"id\": {\"hidden\": true, \"value\": \"stworks:76584\"}, \"email\": {\"value\": \"stworks: 76584\"}}, \"settings\": {\"project_id\": 20, \"ui\": {\"theme\": \"dark\"}}}"},"level_name":"INFO","datetime":"2017-02-15 23:59:59","extra":{"uid":"1b7","http":{"SERVER":{"HTTP_HOST":"api.test.com","HTTP_X_REAL_IP":"107.10.33.79","REMOTE_ADDR":"107.10.33.79","CONTENT_TYPE":"application/json","REQUEST_URI":"/test/test/2939/token","QUERY_STRING":""},"PHP_INPUT":{"user":{"id":{"hidden":"[true]","value":"stworks:76592484"},"email":{"value":"stworks:76561184"}},"settings":{"project_id":"20","ui":{"theme":"dark"}}}}},"MESSAGE":"API response","LEVEL_NUM":"6","HOST":"api.local","UNIXTIME":1487192399,"SOURCEIP":"172.16.16.12","ISODATE":"2017-02-15T23:59:59+03:00"}

Конфиг для logstash пытался делать такой:

input {
        file {
                type => "json"
                path => [ "api.local.txt" ]
                start_position => "beginning"
        }
}

filter {
if [type] == "json" {
        json {
                source => "message"
                add_tag => ["tokens"]
        }
}
}

output {
if [type] == "json" {
        elasticsearch {
                hosts => ["localhost:9200"]
                sniffing => false
                manage_template => false
                index => "token-%{+ddMMYYYY}-%{type}"
                document_type => "%{type}"
        }
}
}

Подскажите что нужно еще использоваться чтобы оптимизировано парсить такие json?


(Igor Motov) #2

А кто затыкается? Logstash или elasticsearch? И как? Какой меппинг у поля plain_request?


(Aleksei) #3

лог с json весил 900мб, elastic сделал индекс на полтора гига, кибана зависала когда я пробовал в паттерны зайти, или в discovery выбрать этот индекс. Попробовал сделать файл со 100 такими json и скормил его, 388 fields из 100 json...

маппингов никаких не делал...


(Igor Motov) #4

Это, в общем-то, нормально.

А вот это не хорошо. Сколько полей у вас в этом случае было?


(Aleksei) #5

не могу сказать, если со 100 строк 388 ключей было... то думаю оочень много. при этом ключ в паттернах дублировались только добавлялось .keyword


(Igor Motov) #6

Да, слишком большое количество полей представляет серьезную проблему. В elasticsearch 5.0 и выше мы даже добавили специальную проверку, которая не позволяет создавать типы с 1000 полей или больше с установками по умолчанию.


(Aleksei) #7

а можно как-то сделать чтобы создались 500 первые, а потом как plain text все были?
или указать поля которые постоянно есть в логах, а остальные как plain text?


(Igor Motov) #8

Можно выбрать эти 500 полей и создать меппинг вручную и потом выключить dynamic mapping.


(Aleksei) #9

Igor_Motov, спасибо большое, попробую завтра разобраться с маппингом...


(Aleksei) #10

Добрый день, а можно ли задать например чтобы fields создавались только для верхнего уровня, для nested 3 и ниже уже не делались. Я пробовал:

"index.mapping.total_fields.limit": 1000,
"index.mapping.depth.limit": 3,
"index.mapping.nested_fields.limit": 100

Но в этом случае он ругается что есть элементы ниже и вообще документы не добавляет в индекс:

java.lang.IllegalArgumentException: Limit of mapping depth [4] in index [token-20022017] has been exceeded due to object field [extra.http.PHP_INPUT.user]

Как сделать так чтобы обрабатывались только ключи выше?


(Aleksei) #11
"properties" : {
      "extra" : {
        "dynamic" : false,
        "type" : "nested"
      }
    }

Решил пока так...


(Igor Motov) #12

Я думаю, лучше сделать так:

 "properties" : {
      "extra" : {
        "type" : "object",
        "enabled" : false
      }
    }

(Aleksei) #13

А как все же сделать чтобы index pattern создавался и доставал все fields?
Я направил боевой трафик логов-json (за сутки инедкс 15г), они складываются в индекс с rate ~70 сообщений в секунду. По нагрузке все ок. Но как только я через kibana захожу в Index Pattern и пытаюсь создать кибана долго думает и вылетает по таймауту. Я пробовал увеличить до 2х минут этот таймаут - не помогает((


(Igor Motov) #14

А сколько индексов и полей в каждом индексе у вас сейчас в кластере?


(Aleksei) #15

Индекс посуточный. Вчера запустил - соответственно два индекса, в одном 1m доков во втором 624к.
Вот что случается после запуска создания index pattern в кибана:


(Aleksei) #16

На самом деле на вид все отлично если воспользоваться вашим советом и выключить context. Он даже все fields внутри context показывает в discovery но со статусом "No cache mapping for this fields" , но все летает


(Igor Motov) #17

Это я понял. Я хочу сообщить команде, которая занимается проектом Kibana, об этой проблеме, но первое что они спросят это как воспроизвести эту проблему, и для этого нам нужно знать сколько полей (не документов) в каждом из этих индексов. То есть если вы запустите curl localhost:9200/ИМЯ_ИНДЕКСА/_mappings сколько типов и сколько элементов в properties в каждом типе вы получите.


(Aleksei) #18

Игорь, спасибо за помощь и советы(я на самом деле активно пытался читать документацию но она с виду супер но когда читаешь вообще ничего не понятно). Я не знал что это поля называется, я так понимаю это соответствует количеству fileds в index pattern? Если да то я полагаю - десятки тысяч. Проверить не могу потому что умирает не кибана а эластик. Но: я пробовал удалить все индексы, паттерны и включить на минуту логи и затем выключить logstash, у меня за минуту кибана смогла отобразить почти 3к fields. Сейчас я выключил пару ключей json по вашему совету и у меня все работает, я отдал на тестирование. Только я не понял одного - если enabled: false выключает парсинг и индексирование этих ключей, то почему он все равно все эти ключи показывает в discovery(с восклицательным знаком) и ищет по ним?


(Igor Motov) #19

А какая версия elasticsearch и kibana?


(Aleksei) #20

5.2, весь стэк последние вроде как