2016-01-11 4 views
3

Я отправляю некоторые данные JSON с сервера Java через TCP в Logstash (Logstash отправляет их в Elasticsearch), и эти данные JSON, кажется, экранированы в Elastic.JSON escaping в Logstash

Java сериализации:

Map<String, Object> jsonMap = new HashMap<>(); 
jsonMap.put("age", event.getAge()); 
for (Entry<String, Serializable> attribute : event.getAttributes().entrySet()) { 
    jsonMap.put("attribute_" + attribute.getKey(), attribute.getValue()); 
} 
jsonMap.put("message", event.getMessage()); 
jsonMap.put("cause", event.getCause()); 
jsonMap.put("timestamp", event.getTimestamp()); 
jsonMap.put("eventid", event.getEventId()); 
jsonMap.put("instanceid", event.getInstanceId()); 
jsonMap.put("origin", event.getOrigin()); 
jsonMap.put("severity", event.getSeverity()); 
jsonMap.put("durability", event.getDurability()); 
jsonMap.put("detail", event.getDetail()); 
int i = 0; 
for (String tag : event.getTags()) { 
    jsonMap.put("tag_" + String.valueOf(i), tag); 
    i++; 
} 

return new JSONObject(jsonMap).toString(); 

Java-оправа:

try (Socket clientSocket = new Socket(url, port); 
    OutputStreamWriter out = new OutputStreamWriter(
     clientSocket.getOutputStream(), "UTF-8")) { 
    out.write(content.toString()); 
    out.flush(); 
} 

Пример данных в упругом:

"message": "{\"detail\":null,\"cause\":null,\"attribute_start\":\"Mon Jan 11 16:15:28 CET 2016\",\"durability\":\"MOMENTARY\",\"attribute_login\":\"\",\"origin\":\"fortuna.ws.navipro\",\"severity\":\"ERROR\",\"attribute_type\":null,\"attribute_methodName\":\"Logout\",\"eventid\":\"ws.navipro.call\",\"attribute_call\":\"[57,7256538816272415441,,OK]{0 connections} CZ() Calling method 'Logout' at 1452525329029(Mon Jan 11 16:15:28 CET 2016-Mon Jan 11 16:15:29 CET 2016; roundtrip=36ms):\\n\\tRequest\\n\\t\\tCLASS com.etnetera.projects.jnp.fortuna.navipro.ws.ClientLogoutRequest\\n\\t\\tkeep: true\\n\\t\\tCLASS com.etnetera.projects.jnp.fortuna.navipro.ws.RequestBody\\n\\t\\tcountry: CZ\\n\\t\\tsessionCC: NULL\\n\\t\\tsessionID:\\n\\t\\tsessionIP:\\n\\t\\tdebug: NULL\\n\\t\\tns: NULL\\n\\t\\tCLASS com.etnetera.projects.jnp.fortuna.navipro.ws.RequestCorpus\\n\\tResponse\\n\\t\\tCLASS com.etnetera.projects.jnp.fortuna.navipro.ws.ClientLogoutResponse\\n\\t\\tCLASS com.etnetera.projects.jnp.fortuna.navipro.ws.ResponseBody\\n\\t\\tCLASS com.etnetera.projects.jnp.fortuna.navipro.ws.ResponseCorpus\\n\\t\\tmessage: \\n\\t\\t[1] \\n\\t\\t\\tCLASS com.etnetera.projects.jnp.fortuna.navipro.ws.Message\\n\\t\\t\\tparam: \\n\\t\\t\\t[1] \\n\\t\\t\\t\\tCLASS com.etnetera.projects.jnp.fortuna.navipro.ws.Message$Param\\n\\t\\t\\t\\tindex: 0\\n\\t\\t\\t\\ttype: NULL\\n\\t\\t\\t\\tvalue: 3\\n\\t\\t\\tid: 104\\n\\t\\t\\tseverity: NOTIFICATION\\n\\t\\t\\tlink: NULL\\n\\t\\tentryLink: NULL\\n\\t\\thint: NULL\\n\\t\\thintType: NULL\\n\\t\\tstatus: OK\\nEND\",\"timestamp\":1452525329030,\"message\":\"NaviPro method Logoutcalled.\",\"tag_1\":\"NaviPro\",\"attribute_end\":\"Mon Jan 11 16:15:29 CET 2016\",\"attribute_sessionId\":\"\",\"age\":0,\"tag_0\":\"Logout\",\"instanceid\":\"Logout\",\"attribute_address\":\""}" 

Logstash конфигурации:

input { 
    syslog { 
    port => 1514 
    } 
    tcp { 
    port => 3333 
    } 
} 

filter { 
    if [type] == "docker" { 
    json { 
     source => "message" 
    } 
    mutate { 
     rename => [ "log", "message" ] 
    } 
    date { 
     match => [ "time", "ISO8601" ] 
    } 
    } 
} 

output { 
    elasticsearch { 
    hosts => "elasticsearch:9200" 
    } 
} 

Я хочу иметь данные в Elastic как JSON, чтобы я мог фильтровать поля в Kibana.

EDIT:

Если я пытаюсь изменить конфигурацию следующим образом:

input { 
    tcp { 
    port => 3333 
    codec => json 
    } 
} 

Logstash отказывается начать с этой строки в журнале:

logstash_1 | {:timestamp=>"2016-01-13T10:13:58.583000+0000", :message=>"SIGTERM received. Shutting down the pipeline.", :level=>:warn} 
+0

Я думаю, что Java убегает строку, не LogStash –

+0

Я также подозревая этого. Но в Eclipse в режиме отладки String отображается как не экранированный. Я также пробовал разные библиотеки для сериализации JSON, но ничего не получилось. Я подозреваю, что запись в выходной поток вызывает экранирование. Вы не знаете, как отправить String через tcp без экранирования? – user3495816

ответ

1

Проблема была неправильной конфигурации Logstash. Logstash работал, но ничего не отправлял через фильтр. Это правильная конфигурация:

input { 
    tcp { 
    port => 3333 
    type => "java" 
    } 
} 

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

output { 
    elasticsearch { 
    hosts => "elasticsearch:9200" 
    } 
} 
+0

Спасибо, это сработало для меня! даже без «типа». –

1

Я создал простой тест и все вам нужно добавить в конфигурацию logstash значение codec => json. Значение по умолчанию - "line", и оно не будет содержать символы в строке.

input { 
    tcp { 
    port => 3333 
    codec => json 
    } 
} 

output { 
    stdout { 
    codec => rubydebug 
    } 

    elasticsearch { 
    hosts => "elasticsearch:9200" 
    } 
} 
+0

Спасибо за предложение, но я уже пробовал это. Теперь ничто не подталкивается к Эластику через Логсташ. – user3495816

+0

Хм. Я не понимаю, почему это изменение сделало бы это. Вы сохранили номер порта одинаковым, запущены логсташ и elasticsearch, и вы запустили приложение? –

+0

Да, я пробовал отлаживать, и сообщение TCP успешно отправляется, Kibana работает, но не показывает никаких данных, так как я перезапустил Logstash с добавленной конфигурацией. (Kibana показывает более старые данные, поэтому Elastic также работает) – user3495816