Skip to content

Commit 112246f

Browse files
committed
WIP: cleanup search controller
1 parent a493458 commit 112246f

File tree

3 files changed

+386
-69
lines changed

3 files changed

+386
-69
lines changed
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
package org.phoebus.alarm.logging.rest;
2+
3+
import com.fasterxml.jackson.annotation.JsonFormat;
4+
import com.fasterxml.jackson.annotation.JsonIgnore;
5+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
6+
import com.fasterxml.jackson.annotation.JsonInclude;
7+
import com.fasterxml.jackson.annotation.JsonInclude.Include;
8+
import com.fasterxml.jackson.core.JsonParser;
9+
import com.fasterxml.jackson.core.JsonProcessingException;
10+
import com.fasterxml.jackson.databind.DeserializationContext;
11+
import com.fasterxml.jackson.databind.JsonDeserializer;
12+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
13+
14+
import java.io.IOException;
15+
import java.time.Instant;
16+
import java.time.ZoneId;
17+
import java.time.format.DateTimeFormatter;
18+
import java.time.temporal.TemporalAccessor;
19+
import java.util.TimeZone;
20+
21+
@JsonIgnoreProperties(ignoreUnknown = true)
22+
@JsonInclude(Include.NON_NULL)
23+
public class AlarmLogMessage {
24+
25+
private String severity;
26+
private String message;
27+
private String value;
28+
@JsonDeserialize(using = AlarmInstantDeserializer.class)
29+
private Instant time;
30+
private String current_severity;
31+
private String current_message;
32+
private String mode;
33+
@JsonDeserialize(using = AlarmInstantDeserializer.class)
34+
private Instant message_time;
35+
private String config;
36+
private String config_msg;
37+
private String pv;
38+
private String user;
39+
private String host;
40+
private String command;
41+
private boolean enabled;
42+
43+
public String getConfig() {
44+
return config;
45+
}
46+
47+
public void setConfig(String config) {
48+
this.config = config;
49+
}
50+
51+
public String getPv() {
52+
return pv;
53+
}
54+
55+
public void setPv(String pv) {
56+
this.pv = pv;
57+
}
58+
59+
public String getSeverity() {
60+
return severity;
61+
}
62+
63+
public void setSeverity(String severity) {
64+
this.severity = severity;
65+
}
66+
67+
public String getMessage() {
68+
return message;
69+
}
70+
71+
public void setMessage(String message) {
72+
this.message = message;
73+
}
74+
75+
public String getValue() {
76+
return value;
77+
}
78+
79+
public void setValue(String value) {
80+
this.value = value;
81+
}
82+
83+
public Instant getTime() {
84+
return time;
85+
}
86+
87+
public void setTime(Instant time) {
88+
this.time = time;
89+
}
90+
91+
public String getCurrent_severity() {
92+
return current_severity;
93+
}
94+
95+
public void setCurrent_severity(String current_severity) {
96+
this.current_severity = current_severity;
97+
}
98+
99+
public String getCurrent_message() {
100+
return current_message;
101+
}
102+
103+
public void setCurrent_message(String current_message) {
104+
this.current_message = current_message;
105+
}
106+
107+
public String getMode() {
108+
return mode;
109+
}
110+
111+
public void setMode(String mode) {
112+
this.mode = mode;
113+
}
114+
115+
public Instant getMessage_time() {
116+
return message_time;
117+
}
118+
119+
public void setMessage_time(Instant message_time) {
120+
this.message_time = message_time;
121+
}
122+
123+
public String getConfig_msg() {
124+
return config_msg;
125+
}
126+
127+
public void setConfig_msg(String config_msg) {
128+
this.config_msg = config_msg;
129+
}
130+
131+
public String getUser() {
132+
return user;
133+
}
134+
135+
public void setUser(String user) {
136+
this.user = user;
137+
}
138+
139+
public String getHost() {
140+
return host;
141+
}
142+
143+
public void setHost(String host) {
144+
this.host = host;
145+
}
146+
147+
public String getCommand() {
148+
return command;
149+
}
150+
151+
public void setCommand(String command) {
152+
this.command = command;
153+
}
154+
155+
public boolean isEnabled() {
156+
return enabled;
157+
}
158+
159+
public void setEnabled(boolean enabled) {
160+
this.enabled = enabled;
161+
}
162+
163+
public static class AlarmInstantDeserializer extends JsonDeserializer<Instant> {
164+
165+
private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS").withZone(ZoneId.systemDefault());
166+
167+
public AlarmInstantDeserializer() {
168+
}
169+
170+
@Override
171+
public Instant deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
172+
return Instant.from(formatter.parse(p.getText()));
173+
}
174+
}
175+
}
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
package org.phoebus.alarm.logging.rest;
2+
3+
import co.elastic.clients.elasticsearch.ElasticsearchClient;
4+
import co.elastic.clients.elasticsearch._types.FieldSort;
5+
import co.elastic.clients.elasticsearch._types.SortOptions;
6+
import co.elastic.clients.elasticsearch._types.SortOrder;
7+
import co.elastic.clients.elasticsearch._types.query_dsl.BoolQuery;
8+
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
9+
import co.elastic.clients.elasticsearch._types.query_dsl.RangeQuery;
10+
import co.elastic.clients.elasticsearch._types.query_dsl.WildcardQuery;
11+
import co.elastic.clients.elasticsearch.core.SearchRequest;
12+
import co.elastic.clients.elasticsearch.core.SearchResponse;
13+
import com.fasterxml.jackson.core.JsonProcessingException;
14+
import com.fasterxml.jackson.databind.JsonNode;
15+
import com.fasterxml.jackson.databind.ObjectMapper;
16+
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
17+
import org.phoebus.alarm.logging.AlarmLoggingService;
18+
import org.phoebus.framework.preferences.PreferencesReader;
19+
import org.phoebus.util.time.TimeParser;
20+
21+
import java.io.IOException;
22+
import java.time.Instant;
23+
import java.time.ZoneId;
24+
import java.time.format.DateTimeFormatter;
25+
import java.time.temporal.ChronoUnit;
26+
import java.time.temporal.TemporalAmount;
27+
import java.util.ArrayList;
28+
import java.util.List;
29+
import java.util.Map;
30+
import java.util.logging.Level;
31+
import java.util.stream.Collectors;
32+
33+
import static org.phoebus.alarm.logging.rest.SearchController.logger;
34+
35+
/**
36+
* A Job to search for alarm messages logged by the alarm logging service
37+
* @author Kunal Shroff
38+
*/
39+
public class AlarmLogSearchUtil {
40+
41+
private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS").withZone(ZoneId.of("UTC"));
42+
43+
private static final PreferencesReader prefs = new PreferencesReader(AlarmLoggingService.class, "/application.properties");
44+
45+
private static ObjectMapper mapper;
46+
static {
47+
mapper = new ObjectMapper();
48+
mapper.registerModule(new JavaTimeModule());
49+
}
50+
51+
private static final String PV = "pv";
52+
private static final String SEVERITY = "severity";
53+
private static final String MESSAGE = "message";
54+
private static final String CURRENTSEVERITY = "current_severity";
55+
private static final String CURRENTMESSAGE = "current_message";
56+
private static final String USER = "user";
57+
private static final String HOST = "host";
58+
private static final String COMMAND = "command";
59+
private static final String STARTTIME = "start";
60+
private static final String ENDTIME = "end";
61+
62+
public static List<AlarmLogMessage> search(ElasticsearchClient client,
63+
String pattern,
64+
Map<String, String> searchParameters) {
65+
logger.info("searching for alarm log entires : " + pattern);
66+
67+
String from = formatter.format(Instant.now().minus(7, ChronoUnit.DAYS));
68+
String to = formatter.format(Instant.now());
69+
String searchPattern = "*".concat(pattern).concat("*");
70+
int size = prefs.getInt("es_max_size");
71+
Boolean configSet = false;
72+
73+
BoolQuery.Builder boolQuery = new BoolQuery.Builder();
74+
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";
108+
}
109+
}
110+
if (key.equals("pv")) {
111+
value = "*".concat(value).concat("*");
112+
String finalValue = value; //Effectively final
113+
boolQuery.must(Query.of(q -> q
114+
.wildcard(WildcardQuery.of(w -> w
115+
.field("config")
116+
.value(finalValue)
117+
)
118+
)
119+
)
120+
);
121+
configSet = true;
122+
continue;
123+
}
124+
//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+
)
133+
)
134+
)
135+
);
136+
}
137+
}
138+
if (!configSet) {
139+
boolQuery.must(Query.of(q->q
140+
.wildcard(WildcardQuery.of(w->w
141+
.field("config")
142+
.value(searchPattern)
143+
)
144+
)
145+
)
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)
173+
)
174+
)
175+
)
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);
192+
}
193+
return result;
194+
}
195+
196+
}

0 commit comments

Comments
 (0)