Skip to content

Commit 58c1759

Browse files
committed
Cleanup and improve the Alarm Log Search Utility
1 parent 112246f commit 58c1759

File tree

3 files changed

+149
-119
lines changed

3 files changed

+149
-119
lines changed

services/alarm-logger/src/main/java/org/phoebus/alarm/logging/ElasticClientHelper.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,30 @@
88
import co.elastic.clients.elasticsearch._types.Result;
99
import co.elastic.clients.elasticsearch.core.BulkRequest;
1010
import co.elastic.clients.elasticsearch.core.BulkResponse;
11+
import co.elastic.clients.elasticsearch.core.IndexRequest;
1112
import co.elastic.clients.elasticsearch.core.IndexResponse;
13+
import co.elastic.clients.elasticsearch.indices.ExistsIndexTemplateRequest;
14+
import co.elastic.clients.elasticsearch.indices.PutIndexTemplateRequest;
15+
import co.elastic.clients.elasticsearch.indices.PutIndexTemplateResponse;
16+
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
1217
import co.elastic.clients.transport.ElasticsearchTransport;
1318
import co.elastic.clients.transport.rest_client.RestClientTransport;
14-
import co.elastic.clients.elasticsearch.indices.*;
15-
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
1619
import com.fasterxml.jackson.databind.ObjectMapper;
1720
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
1821
import org.apache.http.HttpHost;
19-
import co.elastic.clients.elasticsearch.core.IndexRequest;
2022
import org.elasticsearch.client.RestClient;
2123
import org.elasticsearch.client.sniff.Sniffer;
2224
import org.phoebus.applications.alarm.messages.AlarmCommandMessage;
2325
import org.phoebus.applications.alarm.messages.AlarmConfigMessage;
2426
import org.phoebus.applications.alarm.messages.AlarmStateMessage;
25-
import org.springframework.beans.factory.annotation.Configurable;
26-
import org.springframework.beans.factory.annotation.Value;
27-
import org.springframework.context.annotation.ComponentScan;
28-
import org.springframework.context.annotation.Configuration;
29-
import org.springframework.context.annotation.PropertySource;
3027

3128
import java.io.IOException;
3229
import java.io.InputStream;
33-
import java.util.*;
30+
import java.util.AbstractMap.SimpleImmutableEntry;
31+
import java.util.ArrayList;
32+
import java.util.Arrays;
33+
import java.util.Collection;
34+
import java.util.Properties;
3435
import java.util.concurrent.BlockingQueue;
3536
import java.util.concurrent.Executors;
3637
import java.util.concurrent.LinkedBlockingDeque;
@@ -39,7 +40,6 @@
3940
import java.util.concurrent.TimeUnit;
4041
import java.util.concurrent.atomic.AtomicBoolean;
4142
import java.util.logging.Level;
42-
import java.util.AbstractMap.SimpleImmutableEntry;
4343

4444
import static org.phoebus.alarm.logging.AlarmLoggingService.logger;
4545

services/alarm-logger/src/main/java/org/phoebus/alarm/logging/rest/AlarmLogSearchUtil.java

Lines changed: 136 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
/**
3636
* A Job to search for alarm messages logged by the alarm logging service
37+
*
3738
* @author Kunal Shroff
3839
*/
3940
public class AlarmLogSearchUtil {
@@ -43,6 +44,7 @@ public class AlarmLogSearchUtil {
4344
private static final PreferencesReader prefs = new PreferencesReader(AlarmLoggingService.class, "/application.properties");
4445

4546
private static ObjectMapper mapper;
47+
4648
static {
4749
mapper = new ObjectMapper();
4850
mapper.registerModule(new JavaTimeModule());
@@ -60,137 +62,165 @@ public class AlarmLogSearchUtil {
6062
private static final String ENDTIME = "end";
6163

6264
public static List<AlarmLogMessage> search(ElasticsearchClient client,
63-
String pattern,
6465
Map<String, String> searchParameters) {
65-
logger.info("searching for alarm log entires : " + pattern);
66+
logger.info("searching for alarm log entires : " +
67+
searchParameters.entrySet().stream().map(e -> e.getKey() + ": " + e.getValue()).collect(Collectors.joining()));
6668

6769
String from = formatter.format(Instant.now().minus(7, ChronoUnit.DAYS));
6870
String to = formatter.format(Instant.now());
69-
String searchPattern = "*".concat(pattern).concat("*");
70-
int size = prefs.getInt("es_max_size");
71-
Boolean configSet = false;
71+
72+
// The maximum search result size
73+
int maxSize = prefs.getInt("es_max_size");
74+
boolean configSet = false;
75+
boolean temporalSearch = false;
7276

7377
BoolQuery.Builder boolQuery = new BoolQuery.Builder();
7478

75-
for (Map.Entry<String, String> entry : searchParameters.entrySet()) {
76-
String key = entry.getKey();
77-
String value = entry.getValue();
78-
if (key.equals("start")) {
79-
Object time = TimeParser.parseInstantOrTemporalAmount(value);
80-
if (time instanceof Instant) {
81-
from = formatter.format((Instant)time);
82-
} else if (time instanceof TemporalAmount) {
83-
from = formatter.format(Instant.now().minus((TemporalAmount)time));
84-
}
85-
continue;
86-
}
87-
if (key.equals("end")) {
88-
Object time = TimeParser.parseInstantOrTemporalAmount(value);
89-
if (time instanceof Instant) {
90-
to = formatter.format((Instant)time);
91-
} else if (time instanceof TemporalAmount) {
92-
to = formatter.format(Instant.now().minus((TemporalAmount)time));
93-
}
94-
continue;
95-
}
96-
if (key.equals("size")) {
97-
size = Math.min(size, Integer.parseInt(value));
98-
continue;
99-
}
100-
if (!value.equals("*")) {
101-
if (key.equals("command")) {
102-
if (value.equalsIgnoreCase("Enabled")) {
103-
key = "enabled";
104-
value = "true";
105-
} else if (value.equalsIgnoreCase("Disabled")) {
106-
key = "enabled";
107-
value = "false";
79+
for (Map.Entry<String, String> parameter : searchParameters.entrySet()) {
80+
switch (parameter.getKey().strip().toLowerCase()) {
81+
case STARTTIME:
82+
Object startTime = TimeParser.parseInstantOrTemporalAmount(parameter.getValue().strip());
83+
if (startTime instanceof Instant) {
84+
from = formatter.format((Instant) startTime);
85+
} else if (startTime instanceof TemporalAmount) {
86+
from = formatter.format(Instant.now().minus((TemporalAmount) startTime));
10887
}
109-
}
110-
if (key.equals("pv")) {
111-
value = "*".concat(value).concat("*");
112-
String finalValue = value; //Effectively final
88+
temporalSearch = true;
89+
break;
90+
case ENDTIME:
91+
Object endTime = TimeParser.parseInstantOrTemporalAmount(parameter.getValue().strip());
92+
if (endTime instanceof Instant) {
93+
to = formatter.format((Instant) endTime);
94+
} else if (endTime instanceof TemporalAmount) {
95+
to = formatter.format(Instant.now().minus((TemporalAmount) endTime));
96+
}
97+
temporalSearch = true;
98+
break;
99+
case "size":
100+
maxSize = Math.min(maxSize, Integer.parseInt(parameter.getValue().strip()));
101+
break;
102+
case COMMAND:
103+
if (parameter.getValue().strip().equalsIgnoreCase("Enabled")) {
104+
boolQuery.must(WildcardQuery.of(w -> w.field("enabled").value("true"))._toQuery());
105+
} else if (parameter.getValue().strip().equalsIgnoreCase("Disabled")) {
106+
boolQuery.must(WildcardQuery.of(w -> w.field("enabled").value("false"))._toQuery());
107+
}
108+
break;
109+
case PV:
113110
boolQuery.must(Query.of(q -> q
114111
.wildcard(WildcardQuery.of(w -> w
115112
.field("config")
116-
.value(finalValue)
113+
.value("*" + parameter.getValue().strip() + "*")
117114
)
118115
)
119116
)
120117
);
121118
configSet = true;
122-
continue;
123-
}
119+
break;
120+
case SEVERITY:
121+
boolQuery.must(WildcardQuery.of(w -> w
122+
.field(SEVERITY)
123+
.value(parameter.getValue().strip().toUpperCase()))._toQuery()
124+
);
125+
break;
126+
case CURRENTSEVERITY:
127+
boolQuery.must(WildcardQuery.of(w -> w
128+
.field(CURRENTSEVERITY)
129+
.value(parameter.getValue().strip().toUpperCase()))._toQuery()
130+
);
131+
break;
132+
case MESSAGE:
133+
boolQuery.must(WildcardQuery.of(w -> w
134+
.field(MESSAGE)
135+
.value(parameter.getValue().strip().toUpperCase()))._toQuery()
136+
);
137+
break;
138+
case CURRENTMESSAGE:
139+
boolQuery.must(WildcardQuery.of(w -> w
140+
.field(CURRENTMESSAGE)
141+
.value(parameter.getValue().strip().toUpperCase()))._toQuery()
142+
);
143+
break;
144+
case USER:
145+
boolQuery.must(WildcardQuery.of(w -> w
146+
.field(USER)
147+
.value(parameter.getValue().strip()))._toQuery()
148+
);
149+
break;
150+
case HOST:
151+
boolQuery.must(WildcardQuery.of(w -> w
152+
.field(HOST)
153+
.value(parameter.getValue().strip()))._toQuery()
154+
);
155+
break;
156+
default:
157+
// Unsupported search parameters are ignored
158+
break;
159+
}
160+
161+
if (!configSet) {
162+
boolQuery.must(Query.of(q -> q
163+
.wildcard(WildcardQuery.of(w -> w
164+
.field("config")
165+
.value("*")
166+
)
167+
)
168+
)
169+
);
170+
}
171+
172+
// Add the temporal queries
173+
if (temporalSearch) {
174+
// TODO check that the start is before the end
124175
//Effectively final
125-
String finalVal2 = value;
126-
String finalKey2 = key;
127-
//
128-
boolQuery.must(Query.of(q->q
129-
.wildcard(WildcardQuery.of(w->w
130-
.field(finalKey2)
131-
.value(finalVal2)
132-
)
176+
String finalFrom = from;
177+
String finalTo = to;
178+
boolQuery.must(
179+
Query.of(q -> q
180+
.range(RangeQuery.of(r -> r
181+
.field("message_time")
182+
.from(finalFrom)
183+
.to(finalTo)
184+
)
185+
)
133186
)
134-
)
135187
);
136188
}
137-
}
138-
if (!configSet) {
139-
boolQuery.must(Query.of(q->q
140-
.wildcard(WildcardQuery.of(w->w
141-
.field("config")
142-
.value(searchPattern)
189+
190+
int finalSize = maxSize; //Effectively final
191+
SearchRequest searchRequest = SearchRequest.of(r -> r
192+
.query(Query.of(q -> q
193+
.bool(boolQuery.build())
143194
)
144-
)
145195
)
146-
);
147-
}
148-
//Effectively final
149-
String finalFrom = from;
150-
String finalTo = to;
151-
//
152-
boolQuery.must(
153-
Query.of(q->q
154-
.range(RangeQuery.of(r->r
155-
.field("message_time")
156-
.from(finalFrom)
157-
.to(finalTo)
158-
)
159-
)
160-
)
161-
);
162-
int finalSize = size; //Effectively final
163-
SearchRequest searchRequest = SearchRequest.of(r->r
164-
.query(Query.of(q->q
165-
.bool(boolQuery.build())
166-
)
167-
)
168-
.size(finalSize)
169-
.sort(SortOptions.of(o->o
170-
.field(FieldSort.of(f->f
171-
.field("message_time")
172-
.order(SortOrder.Desc)
196+
.size(finalSize)
197+
.sort(SortOptions.of(o -> o
198+
.field(FieldSort.of(f -> f
199+
.field("message_time")
200+
.order(SortOrder.Desc)
201+
)
202+
)
173203
)
174-
)
175204
)
176-
)
177-
);
178-
final List<AlarmLogMessage> result = new ArrayList<>();
179-
try {
180-
SearchResponse<JsonNode> strResponse = client.search(searchRequest, JsonNode.class);
181-
return strResponse.hits().hits().stream().map(hit -> {
182-
JsonNode jsonNode = hit.source();
183-
try {
184-
return mapper.treeToValue(jsonNode, AlarmLogMessage.class);
185-
} catch (JsonProcessingException e) {
186-
logger.log(Level.SEVERE, "Failed to parse the searched alarm log messages. " + hit, e);
187-
}
188-
return null;
189-
}).collect(Collectors.toList());
190-
} catch (IOException e) {
191-
logger.log(Level.SEVERE, "Failed to search for alarm logs ", e);
205+
);
206+
final List<AlarmLogMessage> result = new ArrayList<>();
207+
try {
208+
SearchResponse<JsonNode> strResponse = client.search(searchRequest, JsonNode.class);
209+
return strResponse.hits().hits().stream().map(hit -> {
210+
JsonNode jsonNode = hit.source();
211+
try {
212+
return mapper.treeToValue(jsonNode, AlarmLogMessage.class);
213+
} catch (JsonProcessingException e) {
214+
logger.log(Level.SEVERE, "Failed to parse the searched alarm log messages. " + hit, e);
215+
}
216+
return null;
217+
}).collect(Collectors.toList());
218+
} catch (IOException e) {
219+
logger.log(Level.SEVERE, "Failed to search for alarm logs ", e);
220+
}
221+
return result;
192222
}
193-
return result;
223+
return null;
194224
}
195225

196226
}

services/alarm-logger/src/main/java/org/phoebus/alarm/logging/rest/SearchController.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,23 +82,23 @@ public String info() {
8282

8383
@RequestMapping(value = "/search/alarm", method = RequestMethod.GET)
8484
public List<AlarmLogMessage> search(@RequestParam Map<String, String> allRequestParams) {
85-
List<AlarmLogMessage> result = AlarmLogSearchUtil.search(ElasticClientHelper.getInstance().getClient(), "*", Collections.emptyMap());
85+
List<AlarmLogMessage> result = AlarmLogSearchUtil.search(ElasticClientHelper.getInstance().getClient(), allRequestParams);
8686
return result;
8787
}
8888

8989
@RequestMapping(value = "/search/alarm/{pv}", method = RequestMethod.GET)
9090
public List<AlarmLogMessage> searchPv(@PathVariable String pv) {
9191
Map<String, String> searchParameters = new HashMap<>();
9292
searchParameters.put("pv", pv);
93-
List<AlarmLogMessage> result = AlarmLogSearchUtil.search(ElasticClientHelper.getInstance().getClient(), "*", searchParameters);
93+
List<AlarmLogMessage> result = AlarmLogSearchUtil.search(ElasticClientHelper.getInstance().getClient(), searchParameters);
9494
return result;
9595
}
9696

9797
@RequestMapping(value = "/search/alarm/{config}", method = RequestMethod.GET)
9898
public List<AlarmLogMessage> searchConfig(@PathVariable String config) {
9999
Map<String, String> searchParameters = new HashMap<>();
100100
searchParameters.put("config", config);
101-
List<AlarmLogMessage> result = AlarmLogSearchUtil.search(ElasticClientHelper.getInstance().getClient(), "*", searchParameters);
101+
List<AlarmLogMessage> result = AlarmLogSearchUtil.search(ElasticClientHelper.getInstance().getClient(), searchParameters);
102102
return result;
103103
}
104104

0 commit comments

Comments
 (0)