1616 */
1717package org .graylog .plugins .usagestatistics .collectors ;
1818
19+ import com .fasterxml .jackson .databind .JsonNode ;
1920import com .google .common .collect .Sets ;
20- import com .google .gson .JsonElement ;
21- import com .google .gson .JsonObject ;
2221import io .searchbox .client .JestClient ;
2322import io .searchbox .client .JestResult ;
2423import io .searchbox .cluster .NodesInfo ;
3130import org .graylog .plugins .usagestatistics .dto .elasticsearch .IndicesStats ;
3231import org .graylog .plugins .usagestatistics .dto .elasticsearch .NodesStats ;
3332import org .graylog2 .indexer .cluster .jest .JestUtils ;
34- import org .graylog2 .indexer .gson .GsonUtils ;
3533import org .graylog2 .system .stats .ClusterStatsService ;
3634import org .graylog2 .system .stats .elasticsearch .ElasticsearchStats ;
37- import org .slf4j .Logger ;
38- import org .slf4j .LoggerFactory ;
3935
4036import javax .inject .Inject ;
41- import java .io . IOException ;
37+ import java .util . ArrayList ;
4238import java .util .Collections ;
39+ import java .util .Iterator ;
4340import java .util .List ;
44- import java .util .Optional ;
41+ import java .util .Map ;
4542import java .util .Set ;
46- import java .util .stream .Collectors ;
47- import java .util .stream .Stream ;
48- import java .util .stream .StreamSupport ;
4943
5044public class ElasticsearchCollector {
51- private static final Logger LOG = LoggerFactory .getLogger (ElasticsearchCollector .class );
52-
5345 private final ClusterStatsService clusterStatsService ;
5446 private final JestClient jestClient ;
5547
@@ -60,80 +52,66 @@ public ElasticsearchCollector(ClusterStatsService clusterStatsService, JestClien
6052 }
6153
6254 public Set <ElasticsearchNodeInfo > getNodeInfos () {
63- final JsonObject nodesMap = fetchNodeInfos ();
64- if (nodesMap == null ) {
55+ final JsonNode nodesMap = fetchNodeInfos ();
56+ if (nodesMap . isMissingNode () ) {
6557 return Collections .emptySet ();
6658 }
67- final Set <ElasticsearchNodeInfo > elasticsearchNodeInfos = Sets .newHashSetWithExpectedSize (nodesMap .entrySet ().size ());
68- Optional .of (nodesMap )
69- .map (JsonObject ::entrySet )
70- .map (Iterable ::spliterator )
71- .map (splitr -> StreamSupport .stream (splitr , false ))
72- .orElse (Stream .empty ())
73- .forEach (entry -> {
74-
75- // TODO remove these as soon as the backend service treats HostInfo as optional
76- // the host info details aren't available in Elasticsearch 2.x anymore, but we still report the empty
77- // bean because the backend service still expects some data (even if it is empty)
78- final MacAddress macAddress = MacAddress .EMPTY ;
79- final HostInfo .Cpu cpu = null ;
80- final HostInfo .Memory memory = null ;
81- final HostInfo .Memory swap = null ;
82- final HostInfo hostInfo = HostInfo .create (macAddress , cpu , memory , swap );
83-
84- final Optional <JsonObject > jvm = Optional .of (entry .getValue ())
85- .map (JsonElement ::getAsJsonObject )
86- .map (nodeInfo -> GsonUtils .asJsonObject (nodeInfo .get ("jvm" )));
87-
88- final List <String > garbageCollectors = jvm
89- .map (jvmInfo -> GsonUtils .asJsonArray (jvmInfo .get ("gc_collectors" )))
90- .map (Iterable ::spliterator )
91- .map (splitr -> StreamSupport .stream (splitr , false ))
92- .orElse (Stream .empty ())
93- .map (String ::valueOf )
94- .collect (Collectors .toList ());
95-
96- final Optional <JsonObject > memInfo = jvm .map (jvmInfo -> GsonUtils .asJsonObject (jvmInfo .get ("mem" )));
97-
98- final JvmInfo .Memory jvmMemory = JvmInfo .Memory .create (
99- memInfo .map (mem -> GsonUtils .asLong (mem .get ("heap_init_in_bytes" ))).orElse (-1L ),
100- memInfo .map (mem -> GsonUtils .asLong (mem .get ("heap_max_in_bytes" ))).orElse (-1L ),
101- memInfo .map (mem -> GsonUtils .asLong (mem .get ("non_heap_init_in_bytes" ))).orElse (-1L ),
102- memInfo .map (mem -> GsonUtils .asLong (mem .get ("non_heap_max_in_bytes" ))).orElse (-1L ),
103- memInfo .map (mem -> GsonUtils .asLong (mem .get ("direct_max_in_bytes" ))).orElse (-1L )
104- );
105-
106- final Optional <JsonObject > osInfo = Optional .of (entry .getValue ())
107- .map (JsonElement ::getAsJsonObject )
108- .map (nodeInfo -> GsonUtils .asJsonObject (nodeInfo .get ("os" )));
109-
110- final JvmInfo .Os jvmOs = JvmInfo .Os .create (
111- osInfo .map (os -> GsonUtils .asString (os .get ("name" ))).orElse ("<unknown>" ),
112- osInfo .map (os -> GsonUtils .asString (os .get ("version" ))).orElse ("<unknown>" ),
113- osInfo .map (os -> GsonUtils .asString (os .get ("arch" ))).orElse ("<unknown>" )
114- );
115- final JvmInfo jvmInfo = JvmInfo .create (
116- jvm .map (j -> GsonUtils .asString (j .get ("version" ))).orElse ("<unknown>" ),
117- jvm .map (j -> GsonUtils .asString (j .get ("vm_name" ))).orElse ("<unknown>" ),
118- jvm .map (j -> GsonUtils .asString (j .get ("vm_version" ))).orElse ("<unknown>" ),
119- jvm .map (j -> GsonUtils .asString (j .get ("vm_vendor" ))).orElse ("<unknown>" ),
120- jvmOs ,
121- jvmMemory ,
122- garbageCollectors
123- );
124- final String esVersion = Optional .of (entry .getValue ())
125- .map (JsonElement ::getAsJsonObject )
126- .map (nodeInfo -> GsonUtils .asString (nodeInfo .get ("version" )))
127- .orElse ("<unknown>" );
128-
129- final ElasticsearchNodeInfo elasticsearchNodeInfo = ElasticsearchNodeInfo .create (
130- esVersion ,
131- hostInfo ,
132- jvmInfo
133- );
134-
135- elasticsearchNodeInfos .add (elasticsearchNodeInfo );
136- });
59+ final Set <ElasticsearchNodeInfo > elasticsearchNodeInfos = Sets .newHashSet ();
60+ final Iterator <Map .Entry <String , JsonNode >> fields = nodesMap .fields ();
61+ while (fields .hasNext ()) {
62+ final Map .Entry <String , JsonNode > entry = fields .next ();
63+ // TODO remove these as soon as the backend service treats HostInfo as optional
64+ // the host info details aren't available in Elasticsearch 2.x anymore, but we still report the empty
65+ // bean because the backend service still expects some data (even if it is empty)
66+ final MacAddress macAddress = MacAddress .EMPTY ;
67+ final HostInfo .Cpu cpu = null ;
68+ final HostInfo .Memory memory = null ;
69+ final HostInfo .Memory swap = null ;
70+ final HostInfo hostInfo = HostInfo .create (macAddress , cpu , memory , swap );
71+
72+ final JsonNode jvm = entry .getValue ().path ("jvm" );
73+ final List <String > garbageCollectors = new ArrayList <>();
74+ for (JsonNode jsonNode :jvm .path ("gc_collectors" )) {
75+ if (jsonNode .isTextual ()) {
76+ garbageCollectors .add (jsonNode .asText ());
77+ }
78+ }
79+ final JsonNode memInfo = jvm .path ("mem" );
80+
81+ final JvmInfo .Memory jvmMemory = JvmInfo .Memory .create (
82+ memInfo .path ("heap_init_in_bytes" ).asLong (-1L ),
83+ memInfo .path ("heap_max_in_bytes" ).asLong (-1L ),
84+ memInfo .path ("non_heap_init_in_bytes" ).asLong (-1L ),
85+ memInfo .path ("non_heap_max_in_bytes" ).asLong (-1L ),
86+ memInfo .path ("direct_max_in_bytes" ).asLong (-1L )
87+ );
88+
89+ final JsonNode osInfo = entry .getValue ().path ("os" );
90+
91+ final JvmInfo .Os jvmOs = JvmInfo .Os .create (
92+ osInfo .path ("name" ).asText ("<unknown>" ),
93+ osInfo .path ("version" ).asText ("<unknown>" ),
94+ osInfo .path ("arch" ).asText ("<unknown>" )
95+ );
96+ final JvmInfo jvmInfo = JvmInfo .create (
97+ jvm .path ("version" ).asText ("<unknown>" ),
98+ jvm .path ("vm_name" ).asText ("<unknown>" ),
99+ jvm .path ("vm_version" ).asText ("<unknown>" ),
100+ jvm .path ("vm_vendor" ).asText ("<unknown>" ),
101+ jvmOs ,
102+ jvmMemory ,
103+ garbageCollectors
104+ );
105+ final String esVersion = entry .getValue ().path ("version" ).asText ("<unknown>" );
106+
107+ final ElasticsearchNodeInfo elasticsearchNodeInfo = ElasticsearchNodeInfo .create (
108+ esVersion ,
109+ hostInfo ,
110+ jvmInfo
111+ );
112+
113+ elasticsearchNodeInfos .add (elasticsearchNodeInfo );
114+ }
137115
138116 return elasticsearchNodeInfos ;
139117 }
@@ -147,7 +125,7 @@ public ElasticsearchClusterStats getClusterStats() {
147125 );
148126 }
149127
150- private JsonObject fetchNodeInfos () {
128+ private JsonNode fetchNodeInfos () {
151129 final String errorMessage = "Unable to fetch node infos." ;
152130 final NodesInfo .Builder requestBuilder = new NodesInfo .Builder ()
153131 .withHttp ()
@@ -160,8 +138,11 @@ private JsonObject fetchNodeInfos() {
160138 .withThreadPool ()
161139 .withTransport ();
162140 final JestResult result = JestUtils .execute (jestClient , requestBuilder .build (), () -> errorMessage );
163- return Optional .of (result .getJsonObject ())
164- .map (json -> GsonUtils .asJsonObject (json .get ("nodes" )))
165- .orElseThrow (() -> new IllegalStateException (errorMessage + " Unable to parse reply: " + result .getJsonString ()));
141+ final JsonNode nodeInfos = result .getJsonObject ().path ("nodes" );
142+ if (nodeInfos .isMissingNode ()) {
143+ throw new IllegalStateException (errorMessage + " Unable to parse reply: " + result .getJsonString ());
144+ }
145+
146+ return nodeInfos ;
166147 }
167148}
0 commit comments