Include event(s) to alarms. (#6888)

Co-authored-by: kezhenxu94 <kezhenxu94@apache.org>
Co-authored-by: 吴晟 Wu Sheng <wu.sheng@foxmail.com>
This commit is contained in:
chen~ 2021-05-19 14:14:48 +08:00 committed by GitHub
parent d14148d42e
commit bb590daba9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 535 additions and 120 deletions

View File

@ -45,6 +45,7 @@ Release Notes.
* Fix: NPE when configmap has no data. * Fix: NPE when configmap has no data.
* Fix: Dynamic Configuration key `slowTraceSegmentThreshold` not work * Fix: Dynamic Configuration key `slowTraceSegmentThreshold` not work
* Fix: `!=` is not supported in oal when parameters are numbers. * Fix: `!=` is not supported in oal when parameters are numbers.
* Include events of the entity(s) in the alarm.
#### UI #### UI
* Add logo for kong plugin. * Add logo for kong plugin.

View File

@ -26,6 +26,9 @@ import org.apache.skywalking.oap.server.core.storage.query.IEventQueryDAO;
import org.apache.skywalking.oap.server.library.module.ModuleManager; import org.apache.skywalking.oap.server.library.module.ModuleManager;
import org.apache.skywalking.oap.server.library.module.Service; import org.apache.skywalking.oap.server.library.module.Service;
import java.util.List;
import java.util.Objects;
import static java.util.Objects.isNull; import static java.util.Objects.isNull;
import static org.apache.skywalking.apm.util.StringUtil.isBlank; import static org.apache.skywalking.apm.util.StringUtil.isBlank;
@ -53,6 +56,14 @@ public class EventQueryService implements Service {
return getDao().queryEvents(condition); return getDao().queryEvents(condition);
} }
public Events queryEvents(final List<EventQueryCondition> conditions) throws Exception {
EventQueryCondition condition = conditions.stream().filter(c -> isBlank(c.getUuid()) && isDurationInvalid(c.getTime())).findFirst().orElse(null);
if (Objects.nonNull(condition)) {
throw new IllegalArgumentException("time field is required when uuid is absent.");
}
return getDao().queryEvents(conditions);
}
boolean isDurationInvalid(final Duration duration) { boolean isDurationInvalid(final Duration duration) {
return isNull(duration) || (isBlank(duration.getStart()) || isBlank(duration.getEnd())); return isNull(duration) || (isBlank(duration.getStart()) || isBlank(duration.getEnd()));
} }

View File

@ -21,6 +21,7 @@ package org.apache.skywalking.oap.server.core.query.type;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.apache.skywalking.oap.server.core.query.enumeration.Scope; import org.apache.skywalking.oap.server.core.query.enumeration.Scope;
import org.apache.skywalking.oap.server.core.query.type.event.Event;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -33,7 +34,9 @@ public class AlarmMessage {
private String id; private String id;
private String message; private String message;
private Long startTime; private Long startTime;
private transient String id1;
private final List<KeyValue> tags; private final List<KeyValue> tags;
private List<Event> events = new ArrayList<>(2);
public AlarmMessage() { public AlarmMessage() {
tags = new ArrayList<>(); tags = new ArrayList<>();

View File

@ -58,5 +58,4 @@ public class Event {
this.parameters = map.entrySet().stream().map(e -> new KeyValue(e.getKey(), e.getValue())).collect(Collectors.toList()); this.parameters = map.entrySet().stream().map(e -> new KeyValue(e.getKey(), e.getValue())).collect(Collectors.toList());
} }
} }
} }

View File

@ -18,7 +18,10 @@
package org.apache.skywalking.oap.server.core.query.type.event; package org.apache.skywalking.oap.server.core.query.type.event;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.skywalking.oap.server.core.query.enumeration.Order; import org.apache.skywalking.oap.server.core.query.enumeration.Order;
import org.apache.skywalking.oap.server.core.query.input.Duration; import org.apache.skywalking.oap.server.core.query.input.Duration;
@ -26,6 +29,9 @@ import static org.apache.skywalking.oap.server.core.storage.query.IEventQueryDAO
import static org.apache.skywalking.oap.server.core.storage.query.IEventQueryDAO.MAX_SIZE; import static org.apache.skywalking.oap.server.core.storage.query.IEventQueryDAO.MAX_SIZE;
@Data @Data
@AllArgsConstructor
@NoArgsConstructor
@Builder(toBuilder = true)
public class EventQueryCondition { public class EventQueryCondition {
private String uuid; private String uuid;

View File

@ -19,10 +19,12 @@
package org.apache.skywalking.oap.server.core.query.type.event; package org.apache.skywalking.oap.server.core.query.type.event;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
@Data @Data
@Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class Source { public class Source {

View File

@ -22,9 +22,13 @@ import org.apache.skywalking.oap.server.core.query.type.event.EventQueryConditio
import org.apache.skywalking.oap.server.core.query.type.event.Events; import org.apache.skywalking.oap.server.core.query.type.event.Events;
import org.apache.skywalking.oap.server.core.storage.DAO; import org.apache.skywalking.oap.server.core.storage.DAO;
import java.util.List;
public interface IEventQueryDAO extends DAO { public interface IEventQueryDAO extends DAO {
int DEFAULT_SIZE = 20; int DEFAULT_SIZE = 20;
int MAX_SIZE = 100; int MAX_SIZE = 100;
Events queryEvents(final EventQueryCondition condition) throws Exception; Events queryEvents(final EventQueryCondition condition) throws Exception;
Events queryEvents(final List<EventQueryCondition> conditionList) throws Exception;
} }

View File

@ -19,26 +19,43 @@
package org.apache.skywalking.oap.query.graphql.resolver; package org.apache.skywalking.oap.query.graphql.resolver;
import com.coxautodev.graphql.tools.GraphQLQueryResolver; import com.coxautodev.graphql.tools.GraphQLQueryResolver;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.skywalking.oap.server.core.CoreModule; import org.apache.skywalking.oap.server.core.CoreModule;
import org.apache.skywalking.oap.server.core.analysis.IDManager;
import org.apache.skywalking.oap.server.core.analysis.manual.searchtag.Tag; import org.apache.skywalking.oap.server.core.analysis.manual.searchtag.Tag;
import org.apache.skywalking.oap.server.core.query.AlarmQueryService; import org.apache.skywalking.oap.server.core.query.AlarmQueryService;
import org.apache.skywalking.oap.server.core.query.EventQueryService;
import org.apache.skywalking.oap.server.core.query.enumeration.Scope; import org.apache.skywalking.oap.server.core.query.enumeration.Scope;
import org.apache.skywalking.oap.server.core.query.input.Duration; import org.apache.skywalking.oap.server.core.query.input.Duration;
import org.apache.skywalking.oap.server.core.query.type.AlarmMessage;
import org.apache.skywalking.oap.server.core.query.type.AlarmTrend; import org.apache.skywalking.oap.server.core.query.type.AlarmTrend;
import org.apache.skywalking.oap.server.core.query.type.Alarms; import org.apache.skywalking.oap.server.core.query.type.Alarms;
import org.apache.skywalking.oap.server.core.query.type.Pagination; import org.apache.skywalking.oap.server.core.query.type.Pagination;
import org.apache.skywalking.oap.server.core.query.type.event.Event;
import org.apache.skywalking.oap.server.core.query.type.event.EventQueryCondition;
import org.apache.skywalking.oap.server.core.query.type.event.Source;
import org.apache.skywalking.oap.server.core.source.DefaultScopeDefine;
import org.apache.skywalking.oap.server.core.storage.query.IEventQueryDAO;
import org.apache.skywalking.oap.server.library.module.ModuleManager; import org.apache.skywalking.oap.server.library.module.ModuleManager;
import static com.google.common.base.Strings.isNullOrEmpty;
import static java.util.Objects.isNull;
import static java.util.Objects.nonNull; import static java.util.Objects.nonNull;
import static org.apache.skywalking.oap.server.library.util.CollectionUtils.isNotEmpty;
public class AlarmQuery implements GraphQLQueryResolver { public class AlarmQuery implements GraphQLQueryResolver {
private final ModuleManager moduleManager; private final ModuleManager moduleManager;
private AlarmQueryService queryService; private AlarmQueryService queryService;
private EventQueryService eventQueryService;
public AlarmQuery(ModuleManager moduleManager) { public AlarmQuery(ModuleManager moduleManager) {
this.moduleManager = moduleManager; this.moduleManager = moduleManager;
} }
@ -50,23 +67,125 @@ public class AlarmQuery implements GraphQLQueryResolver {
return queryService; return queryService;
} }
private EventQueryService getEventQueryService() {
if (eventQueryService == null) {
this.eventQueryService = moduleManager.find(CoreModule.NAME).provider().getService(EventQueryService.class);
}
return eventQueryService;
}
public AlarmTrend getAlarmTrend(final Duration duration) { public AlarmTrend getAlarmTrend(final Duration duration) {
return new AlarmTrend(); return new AlarmTrend();
} }
public Alarms getAlarm(final Duration duration, final Scope scope, final String keyword, public Alarms getAlarm(final Duration duration, final Scope scope, final String keyword,
final Pagination paging, final List<Tag> tags) throws IOException { final Pagination paging, final List<Tag> tags) throws Exception {
Integer scopeId = null; Integer scopeId = null;
if (scope != null) { if (scope != null) {
scopeId = scope.getScopeId(); scopeId = scope.getScopeId();
} }
long startSecondTB = 0; long startSecondTB = 0;
long endSecondTB = 0; long endSecondTB = 0;
final EventQueryCondition.EventQueryConditionBuilder conditionPrototype = EventQueryCondition.builder().size(IEventQueryDAO.MAX_SIZE);
if (nonNull(duration)) { if (nonNull(duration)) {
startSecondTB = duration.getStartTimeBucketInSec(); startSecondTB = duration.getStartTimeBucketInSec();
endSecondTB = duration.getEndTimeBucketInSec(); endSecondTB = duration.getEndTimeBucketInSec();
conditionPrototype.time(duration);
} }
return getQueryService().getAlarm( Alarms alarms = getQueryService().getAlarm(
scopeId, keyword, paging, startSecondTB, endSecondTB, tags); scopeId, keyword, paging, startSecondTB, endSecondTB, tags);
return findRelevantEvents(alarms, conditionPrototype);
}
private Alarms findRelevantEvents(
final Alarms alarms,
final EventQueryCondition.EventQueryConditionBuilder conditionPrototype
) throws Exception {
if (alarms.getTotal() < 1) {
return alarms;
}
final List<EventQueryCondition> allConditions =
alarms.getMsgs()
.stream()
.flatMap(m -> buildEventSources(m).stream().map(conditionPrototype::source))
.map(EventQueryCondition.EventQueryConditionBuilder::build)
.collect(Collectors.toList());
final List<Event> events = getEventQueryService().queryEvents(allConditions).getEvents();
final Map<String, List<Event>> eventsKeyedBySourceId =
events.stream()
.filter(it -> !isNullOrEmpty(buildSourceID(it)))
.collect(Collectors.groupingBy(this::buildSourceID));
alarms.getMsgs().forEach(a -> {
if (isNotEmpty(eventsKeyedBySourceId.get(a.getId()))) {
a.getEvents().addAll(eventsKeyedBySourceId.get(a.getId()));
}
if (isNotEmpty(eventsKeyedBySourceId.get(a.getId1()))) {
a.getEvents().addAll(eventsKeyedBySourceId.get(a.getId1()));
}
});
return alarms;
}
private List<Source> buildEventSources(AlarmMessage msg) {
final List<Source> sources = new ArrayList<>(2);
final Source.SourceBuilder sourcePrototype = Source.builder();
switch (msg.getScopeId()) {
case DefaultScopeDefine.SERVICE_RELATION:
final IDManager.ServiceID.ServiceIDDefinition destServiceIdDef = IDManager.ServiceID.analysisId(msg.getId1());
sources.add(sourcePrototype.service(destServiceIdDef.getName()).build());
// fall through
case DefaultScopeDefine.SERVICE:
final IDManager.ServiceID.ServiceIDDefinition sourceServiceIdDef = IDManager.ServiceID.analysisId(msg.getId());
sources.add(sourcePrototype.service(sourceServiceIdDef.getName()).build());
break;
case DefaultScopeDefine.SERVICE_INSTANCE_RELATION:
final IDManager.ServiceInstanceID.InstanceIDDefinition destInstanceIdDef = IDManager.ServiceInstanceID.analysisId(msg.getId1());
final String destServiceName = IDManager.ServiceID.analysisId(destInstanceIdDef.getServiceId()).getName();
sources.add(sourcePrototype.service(destServiceName).serviceInstance(destInstanceIdDef.getName()).build());
// fall through
case DefaultScopeDefine.SERVICE_INSTANCE:
final IDManager.ServiceInstanceID.InstanceIDDefinition sourceInstanceIdDef = IDManager.ServiceInstanceID.analysisId(msg.getId());
final String serviceName = IDManager.ServiceID.analysisId(sourceInstanceIdDef.getServiceId()).getName();
sources.add(sourcePrototype.serviceInstance(sourceInstanceIdDef.getName()).service(serviceName).build());
break;
case DefaultScopeDefine.ENDPOINT_RELATION:
final IDManager.EndpointID.EndpointIDDefinition destEndpointIDDef = IDManager.EndpointID.analysisId(msg.getId1());
final String destEndpointServiceName = IDManager.ServiceID.analysisId(destEndpointIDDef.getServiceId()).getName();
sources.add(sourcePrototype.service(destEndpointServiceName).build());
// fall through
case DefaultScopeDefine.ENDPOINT:
final IDManager.EndpointID.EndpointIDDefinition endpointIDDef = IDManager.EndpointID.analysisId(msg.getId());
final String endpointServiceName = IDManager.ServiceID.analysisId(endpointIDDef.getServiceId()).getName();
sources.add(sourcePrototype.service(endpointServiceName).build());
break;
}
return sources;
}
protected String buildSourceID(final Event event) {
final Source source = event.getSource();
if (isNull(source)) {
return "";
}
final String service = source.getService();
if (isNullOrEmpty(service)) {
return "";
}
final String instance = source.getServiceInstance();
if (isNullOrEmpty(instance)) {
return IDManager.ServiceID.buildId(service, true);
}
return IDManager.ServiceInstanceID.buildId(service, instance);
} }
} }

@ -1 +1 @@
Subproject commit 0c2388ba18cfc1b1b103ddad71f9765bd21dff6e Subproject commit 84c635180b8dde4210865f655b83d101c68fe741

View File

@ -90,6 +90,7 @@ public class AlarmQueryEsDAO extends EsDAO implements IAlarmQueryDAO {
AlarmMessage message = new AlarmMessage(); AlarmMessage message = new AlarmMessage();
message.setId(String.valueOf(alarmRecord.getId0())); message.setId(String.valueOf(alarmRecord.getId0()));
message.setId1(String.valueOf(alarmRecord.getId1()));
message.setMessage(alarmRecord.getAlarmMessage()); message.setMessage(alarmRecord.getAlarmMessage());
message.setStartTime(alarmRecord.getStartTime()); message.setStartTime(alarmRecord.getStartTime());
message.setScope(Scope.Finder.valueOf(alarmRecord.getScope())); message.setScope(Scope.Finder.valueOf(alarmRecord.getScope()));

View File

@ -18,6 +18,7 @@
package org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query; package org.apache.skywalking.oap.server.storage.plugin.elasticsearch.query;
import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -53,26 +54,27 @@ public class ESEventQueryDAO extends EsDAO implements IEventQueryDAO {
@Override @Override
public Events queryEvents(final EventQueryCondition condition) throws Exception { public Events queryEvents(final EventQueryCondition condition) throws Exception {
final SearchSourceBuilder sourceBuilder = buildQuery(condition); final SearchSourceBuilder sourceBuilder = buildQuery(condition);
return getEventsResultByCurrentBuilder(sourceBuilder);
}
@Override
public Events queryEvents(List<EventQueryCondition> conditionList) throws Exception {
final SearchSourceBuilder sourceBuilder = buildQuery(conditionList);
return getEventsResultByCurrentBuilder(sourceBuilder);
}
private Events getEventsResultByCurrentBuilder(final SearchSourceBuilder sourceBuilder) throws IOException {
final SearchResponse response = getClient() final SearchResponse response = getClient()
.search(IndexController.LogicIndicesRegister.getPhysicalTableName(Event.INDEX_NAME), sourceBuilder); .search(IndexController.LogicIndicesRegister.getPhysicalTableName(Event.INDEX_NAME), sourceBuilder);
final Events events = new Events(); final Events events = new Events();
events.setTotal((int) response.getHits().totalHits); events.setTotal((int) response.getHits().totalHits);
events.setEvents(Stream.of(response.getHits().getHits()) events.setEvents(Stream.of(response.getHits().getHits())
.map(this::parseSearchHit) .map(this::parseSearchHit)
.collect(Collectors.toList())); .collect(Collectors.toList()));
return events; return events;
} }
protected SearchSourceBuilder buildQuery(final EventQueryCondition condition) { private void buildMustQueryListByCondition(final EventQueryCondition condition, final List<QueryBuilder> mustQueryList) {
final SearchSourceBuilder sourceBuilder = SearchSourceBuilder.searchSource();
final BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
sourceBuilder.query(boolQueryBuilder);
final List<QueryBuilder> mustQueryList = boolQueryBuilder.must();
if (!isNullOrEmpty(condition.getUuid())) { if (!isNullOrEmpty(condition.getUuid())) {
mustQueryList.add(QueryBuilders.termQuery(Event.UUID, condition.getUuid())); mustQueryList.add(QueryBuilders.termQuery(Event.UUID, condition.getUuid()));
} }
@ -112,6 +114,33 @@ public class ESEventQueryDAO extends EsDAO implements IEventQueryDAO {
.lt(startTime.getEndTimestamp())); .lt(startTime.getEndTimestamp()));
} }
} }
}
protected SearchSourceBuilder buildQuery(final List<EventQueryCondition> conditionList) {
final SearchSourceBuilder sourceBuilder = SearchSourceBuilder.searchSource();
BoolQueryBuilder linkShouldBuilder = QueryBuilders.boolQuery();
sourceBuilder.query(linkShouldBuilder);
conditionList.forEach(condition -> {
final BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
final List<QueryBuilder> mustQueryList = boolQueryBuilder.must();
linkShouldBuilder.should(boolQueryBuilder);
buildMustQueryListByCondition(condition, mustQueryList);
});
EventQueryCondition condition = conditionList.get(0);
final Order queryOrder = isNull(condition.getOrder()) ? Order.DES : condition.getOrder();
sourceBuilder.sort(Event.START_TIME, Order.DES.equals(queryOrder) ? SortOrder.DESC : SortOrder.ASC);
sourceBuilder.size(condition.getSize());
return sourceBuilder;
}
protected SearchSourceBuilder buildQuery(final EventQueryCondition condition) {
final SearchSourceBuilder sourceBuilder = SearchSourceBuilder.searchSource();
final BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
sourceBuilder.query(boolQueryBuilder);
final List<QueryBuilder> mustQueryList = boolQueryBuilder.must();
buildMustQueryListByCondition(condition, mustQueryList);
final Order queryOrder = isNull(condition.getOrder()) ? Order.DES : condition.getOrder(); final Order queryOrder = isNull(condition.getOrder()) ? Order.DES : condition.getOrder();
sourceBuilder.sort(Event.START_TIME, Order.DES.equals(queryOrder) ? SortOrder.DESC : SortOrder.ASC); sourceBuilder.sort(Event.START_TIME, Order.DES.equals(queryOrder) ? SortOrder.DESC : SortOrder.ASC);

View File

@ -92,6 +92,7 @@ public class AlarmQueryEs7DAO extends EsDAO implements IAlarmQueryDAO {
AlarmMessage message = new AlarmMessage(); AlarmMessage message = new AlarmMessage();
message.setId(String.valueOf(alarmRecord.getId0())); message.setId(String.valueOf(alarmRecord.getId0()));
message.setId1(String.valueOf(alarmRecord.getId1()));
message.setMessage(alarmRecord.getAlarmMessage()); message.setMessage(alarmRecord.getAlarmMessage());
message.setStartTime(alarmRecord.getStartTime()); message.setStartTime(alarmRecord.getStartTime());
message.setScope(Scope.Finder.valueOf(alarmRecord.getScope())); message.setScope(Scope.Finder.valueOf(alarmRecord.getScope()));

View File

@ -18,6 +18,8 @@
package org.apache.skywalking.oap.server.storage.plugin.elasticsearch7.query; package org.apache.skywalking.oap.server.storage.plugin.elasticsearch7.query;
import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.apache.skywalking.oap.server.core.event.Event; import org.apache.skywalking.oap.server.core.event.Event;
@ -37,7 +39,16 @@ public class ES7EventQueryDAO extends ESEventQueryDAO {
@Override @Override
public Events queryEvents(final EventQueryCondition condition) throws Exception { public Events queryEvents(final EventQueryCondition condition) throws Exception {
final SearchSourceBuilder sourceBuilder = buildQuery(condition); final SearchSourceBuilder sourceBuilder = buildQuery(condition);
return getEventsResultByCurrentBuilder(sourceBuilder);
}
@Override
public Events queryEvents(List<EventQueryCondition> conditionList) throws Exception {
final SearchSourceBuilder sourceBuilder = buildQuery(conditionList);
return getEventsResultByCurrentBuilder(sourceBuilder);
}
private Events getEventsResultByCurrentBuilder(final SearchSourceBuilder sourceBuilder) throws IOException {
final SearchResponse response = getClient() final SearchResponse response = getClient()
.search(IndexController.LogicIndicesRegister.getPhysicalTableName(Event.INDEX_NAME), sourceBuilder); .search(IndexController.LogicIndicesRegister.getPhysicalTableName(Event.INDEX_NAME), sourceBuilder);
@ -46,7 +57,6 @@ public class ES7EventQueryDAO extends ESEventQueryDAO {
events.setEvents(Stream.of(response.getHits().getHits()) events.setEvents(Stream.of(response.getHits().getHits())
.map(this::parseSearchHit) .map(this::parseSearchHit)
.collect(Collectors.toList())); .collect(Collectors.toList()));
return events; return events;
} }
} }

View File

@ -19,9 +19,11 @@
package org.apache.skywalking.oap.server.storage.plugin.influxdb.query; package org.apache.skywalking.oap.server.storage.plugin.influxdb.query;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.oap.server.core.event.Event; import org.apache.skywalking.oap.server.core.event.Event;
@ -38,6 +40,7 @@ import org.apache.skywalking.oap.server.storage.plugin.influxdb.InfluxConstants;
import org.influxdb.dto.Query; import org.influxdb.dto.Query;
import org.influxdb.dto.QueryResult; import org.influxdb.dto.QueryResult;
import org.influxdb.querybuilder.SelectQueryImpl; import org.influxdb.querybuilder.SelectQueryImpl;
import org.influxdb.querybuilder.WhereNested;
import org.influxdb.querybuilder.WhereQueryImpl; import org.influxdb.querybuilder.WhereQueryImpl;
import static com.google.common.base.Strings.isNullOrEmpty; import static com.google.common.base.Strings.isNullOrEmpty;
@ -55,35 +58,24 @@ public class EventQueryDAO implements IEventQueryDAO {
@Override @Override
public Events queryEvents(final EventQueryCondition condition) throws Exception { public Events queryEvents(final EventQueryCondition condition) throws Exception {
final WhereQueryImpl<SelectQueryImpl> recallQuery = buildQuery(condition); List<WhereQueryImpl<SelectQueryImpl>> whereQueries = buildWhereQueries(condition);
final SelectQueryImpl countQuery = select().count(Event.UUID).from(client.getDatabase(), Event.INDEX_NAME); buildQueryByCondition(whereQueries, condition);
recallQuery.getClauses().forEach(countQuery::where);
final Query query = new Query(countQuery.getCommand() + recallQuery.getCommand()); List<QueryResult.Result> results = execute(whereQueries.get(0), whereQueries.get(1));
final List<QueryResult.Result> results = client.query(query);
if (log.isDebugEnabled()) { return buildEventsByQueryResult(results);
log.debug("SQL: {}", query.getCommand());
log.debug("Result: {}", results);
}
if (results.size() != 2) {
throw new IOException("Expecting to get 2 Results, but it is " + results.size());
} }
final QueryResult.Series counterSeries = results.get(0).getSeries().get(0); @Override
final List<QueryResult.Series> recallSeries = results.get(1).getSeries(); public Events queryEvents(List<EventQueryCondition> conditionList) throws Exception {
List<WhereQueryImpl<SelectQueryImpl>> whereQueries = buildWhereQueries(conditionList.get(0));
final Events events = new Events(); buildQueryByCondition(whereQueries, conditionList);
events.setTotal(((Number) counterSeries.getValues().get(0).get(1)).longValue()); List<QueryResult.Result> results = execute(whereQueries.get(0), whereQueries.get(1));
recallSeries.forEach( return buildEventsByQueryResult(results);
series -> series.getValues().forEach(
values -> events.getEvents().add(parseSeriesValues(series, values))
)
);
return events;
} }
protected org.apache.skywalking.oap.server.core.query.type.event.Event parseSeriesValues(final QueryResult.Series series, final List<Object> values) { protected org.apache.skywalking.oap.server.core.query.type.event.Event parseSeriesValues(final QueryResult.Series series, final List<Object> values) {
@ -116,49 +108,147 @@ public class EventQueryDAO implements IEventQueryDAO {
return event; return event;
} }
protected WhereQueryImpl<SelectQueryImpl> buildQuery(final EventQueryCondition condition) { protected List<WhereQueryImpl<SelectQueryImpl>> buildWhereQueries(final EventQueryCondition condition) {
List<WhereQueryImpl<SelectQueryImpl>> queries = new ArrayList<>(2);
final String topFunc = Order.DES.equals(condition.getOrder()) ? InfluxConstants.SORT_DES : InfluxConstants.SORT_ASC; final String topFunc = Order.DES.equals(condition.getOrder()) ? InfluxConstants.SORT_DES : InfluxConstants.SORT_ASC;
final WhereQueryImpl<SelectQueryImpl> query = final WhereQueryImpl<SelectQueryImpl> recallWhereQuery =
select().raw(ALL_FIELDS) select().raw(ALL_FIELDS)
.function(topFunc, Event.START_TIME, condition.getSize()) .function(topFunc, Event.START_TIME, condition.getSize())
.from(client.getDatabase(), Event.INDEX_NAME) .from(client.getDatabase(), Event.INDEX_NAME)
.where(); .where();
final SelectQueryImpl countQuery = select().count(Event.UUID).from(client.getDatabase(), Event.INDEX_NAME);
final WhereQueryImpl<SelectQueryImpl> countWhereQuery = countQuery.where();
queries.add(countWhereQuery);
queries.add(recallWhereQuery);
return queries;
}
protected void buildQueryByCondition(List<WhereQueryImpl<SelectQueryImpl>> queries, EventQueryCondition condition) {
WhereQueryImpl<SelectQueryImpl> countWhereQuery = queries.get(0);
WhereQueryImpl<SelectQueryImpl> recallWhereQuery = queries.get(1);
if (!isNullOrEmpty(condition.getUuid())) { if (!isNullOrEmpty(condition.getUuid())) {
query.and(eq(Event.UUID, condition.getUuid())); recallWhereQuery.and(eq(Event.UUID, condition.getUuid()));
countWhereQuery.and(eq(Event.UUID, condition.getUuid()));
} }
final Source source = condition.getSource(); final Source source = condition.getSource();
if (source != null) { if (source != null) {
if (!isNullOrEmpty(source.getService())) { if (!isNullOrEmpty(source.getService())) {
query.and(eq(Event.SERVICE, source.getService())); recallWhereQuery.and(eq(Event.SERVICE, source.getService()));
countWhereQuery.and(eq(Event.SERVICE, source.getService()));
} }
if (!isNullOrEmpty(source.getServiceInstance())) { if (!isNullOrEmpty(source.getServiceInstance())) {
query.and(eq(Event.SERVICE_INSTANCE, source.getServiceInstance())); recallWhereQuery.and(eq(Event.SERVICE_INSTANCE, source.getServiceInstance()));
countWhereQuery.and(eq(Event.SERVICE_INSTANCE, source.getServiceInstance()));
} }
if (!isNullOrEmpty(source.getEndpoint())) { if (!isNullOrEmpty(source.getEndpoint())) {
query.and(contains(Event.ENDPOINT, source.getEndpoint().replaceAll("/", "\\\\/"))); recallWhereQuery.and(contains(Event.ENDPOINT, source.getEndpoint().replaceAll("/", "\\\\/")));
countWhereQuery.and(contains(Event.ENDPOINT, source.getEndpoint().replaceAll("/", "\\\\/")));
} }
} }
if (!isNullOrEmpty(condition.getName())) { if (!isNullOrEmpty(condition.getName())) {
query.and(eq(InfluxConstants.NAME, condition.getName())); recallWhereQuery.and(eq(InfluxConstants.NAME, condition.getName()));
countWhereQuery.and(eq(InfluxConstants.NAME, condition.getName()));
} }
if (condition.getType() != null) { if (condition.getType() != null) {
query.and(eq(Event.TYPE, condition.getType().name())); recallWhereQuery.and(eq(Event.TYPE, condition.getType().name()));
countWhereQuery.and(eq(Event.TYPE, condition.getType().name()));
} }
final Duration startTime = condition.getTime(); final Duration startTime = condition.getTime();
if (startTime != null) { if (startTime != null) {
if (startTime.getStartTimestamp() > 0) { if (startTime.getStartTimestamp() > 0) {
query.and(gt(Event.START_TIME, startTime.getStartTimestamp())); recallWhereQuery.and(gt(Event.START_TIME, startTime.getStartTimestamp()));
countWhereQuery.and(gt(Event.START_TIME, startTime.getStartTimestamp()));
} }
if (startTime.getEndTimestamp() > 0) { if (startTime.getEndTimestamp() > 0) {
query.and(lt(Event.END_TIME, startTime.getEndTimestamp())); recallWhereQuery.and(lt(Event.END_TIME, startTime.getEndTimestamp()));
countWhereQuery.and(lt(Event.END_TIME, startTime.getEndTimestamp()));
}
} }
} }
return query; protected void buildQueryByCondition(List<WhereQueryImpl<SelectQueryImpl>> queries, List<EventQueryCondition> conditions) {
WhereQueryImpl<SelectQueryImpl> countWhereQuery = queries.get(0);
WhereQueryImpl<SelectQueryImpl> recallWhereQuery = queries.get(1);
conditions.stream().forEach(c -> {
WhereNested<WhereQueryImpl<SelectQueryImpl>> recallOrNested = recallWhereQuery.orNested();
WhereNested<WhereQueryImpl<SelectQueryImpl>> countOrNested = countWhereQuery.orNested();
// by current condition, we should not have uuid. If one day you need to use UUIDs as the query condition, this might be applied.
if (!isNullOrEmpty(c.getUuid())) {
recallWhereQuery.and(eq(Event.UUID, c.getUuid()));
countWhereQuery.and(eq(Event.UUID, c.getUuid()));
}
final Source source = c.getSource();
if (source != null) {
if (!isNullOrEmpty(source.getService())) {
recallOrNested.and(eq(Event.SERVICE, source.getService()));
countOrNested.and(eq(Event.SERVICE, source.getService()));
}
if (!isNullOrEmpty(source.getServiceInstance())) {
recallOrNested.and(eq(Event.SERVICE_INSTANCE, source.getServiceInstance()));
countOrNested.and(eq(Event.SERVICE_INSTANCE, source.getServiceInstance()));
}
if (!isNullOrEmpty(source.getEndpoint())) {
recallOrNested.and(contains(Event.ENDPOINT, source.getEndpoint().replaceAll("/", "\\\\/")));
countOrNested.and(contains(Event.ENDPOINT, source.getEndpoint().replaceAll("/", "\\\\/")));
}
}
if (!isNullOrEmpty(c.getName())) {
recallOrNested.and(eq(InfluxConstants.NAME, c.getName()));
countOrNested.and(eq(InfluxConstants.NAME, c.getName()));
}
if (c.getType() != null) {
recallOrNested.and(eq(Event.TYPE, c.getType().name()));
countOrNested.and(eq(Event.TYPE, c.getType().name()));
}
final Duration startTime = c.getTime();
if (startTime != null) {
if (startTime.getStartTimestamp() > 0) {
recallOrNested.and(gt(Event.START_TIME, startTime.getStartTimestamp()));
countOrNested.and(gt(Event.START_TIME, startTime.getStartTimestamp()));
}
if (startTime.getEndTimestamp() > 0) {
recallOrNested.and(lt(Event.END_TIME, startTime.getEndTimestamp()));
countOrNested.and(lt(Event.END_TIME, startTime.getEndTimestamp()));
}
}
recallOrNested.close();
countOrNested.close();
});
}
protected List<QueryResult.Result> execute(WhereQueryImpl<SelectQueryImpl> countWhereQuery, WhereQueryImpl<SelectQueryImpl> recallWhereQuery) throws IOException {
final Query query = new Query(countWhereQuery.getCommand() + recallWhereQuery.getCommand());
final List<QueryResult.Result> results = client.query(query);
if (log.isDebugEnabled()) {
log.debug("SQL: {}", query.getCommand());
log.debug("Result: {}", results);
}
if (results.size() != 2) {
throw new IOException("Expecting to get 2 Results, but it is " + results.size());
}
return results;
}
protected Events buildEventsByQueryResult(List<QueryResult.Result> results) {
final QueryResult.Series counterSeries = results.get(0).getSeries().get(0);
final List<QueryResult.Series> recallSeries = results.get(1).getSeries();
final Events events = new Events();
events.setTotal(((Number) counterSeries.getValues().get(0).get(1)).longValue());
recallSeries.forEach(
series -> series.getValues().forEach(
values -> events.getEvents().add(parseSeriesValues(series, values))
)
);
return events;
} }
} }

View File

@ -128,6 +128,7 @@ public class H2AlarmQueryDAO implements IAlarmQueryDAO {
while (resultSet.next()) { while (resultSet.next()) {
AlarmMessage message = new AlarmMessage(); AlarmMessage message = new AlarmMessage();
message.setId(resultSet.getString(AlarmRecord.ID0)); message.setId(resultSet.getString(AlarmRecord.ID0));
message.setId1(resultSet.getString(AlarmRecord.ID1));
message.setMessage(resultSet.getString(AlarmRecord.ALARM_MESSAGE)); message.setMessage(resultSet.getString(AlarmRecord.ALARM_MESSAGE));
message.setStartTime(resultSet.getLong(AlarmRecord.START_TIME)); message.setStartTime(resultSet.getLong(AlarmRecord.START_TIME));
message.setScope(Scope.Finder.valueOf(resultSet.getInt(AlarmRecord.SCOPE))); message.setScope(Scope.Finder.valueOf(resultSet.getInt(AlarmRecord.SCOPE)));

View File

@ -18,20 +18,22 @@
package org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao; package org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao;
import io.vavr.Tuple;
import io.vavr.Tuple2;
import java.sql.Connection; import java.sql.Connection;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.oap.server.core.event.Event; import org.apache.skywalking.oap.server.core.event.Event;
import org.apache.skywalking.oap.server.core.query.input.Duration; import org.apache.skywalking.oap.server.core.query.input.Duration;
import org.apache.skywalking.oap.server.core.query.type.event.EventQueryCondition; import org.apache.skywalking.oap.server.core.query.type.event.EventQueryCondition;
import org.apache.skywalking.oap.server.core.query.type.event.EventType;
import org.apache.skywalking.oap.server.core.query.type.event.Events; import org.apache.skywalking.oap.server.core.query.type.event.Events;
import org.apache.skywalking.oap.server.core.query.type.event.Source; import org.apache.skywalking.oap.server.core.query.type.event.Source;
import org.apache.skywalking.oap.server.core.query.type.event.EventType;
import org.apache.skywalking.oap.server.core.storage.query.IEventQueryDAO; import org.apache.skywalking.oap.server.core.storage.query.IEventQueryDAO;
import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCHikariCPClient; import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCHikariCPClient;
@ -44,8 +46,102 @@ public class H2EventQueryDAO implements IEventQueryDAO {
@Override @Override
public Events queryEvents(final EventQueryCondition condition) throws Exception { public Events queryEvents(final EventQueryCondition condition) throws Exception {
final List<String> conditions = new ArrayList<>(); final Tuple2<Stream<String>, Stream<Object>> conditionsParametersPair = buildQuery(condition);
final List<Object> parameters = new ArrayList<>(); final Stream<String> conditions = conditionsParametersPair._1();
final Object[] parameters = conditionsParametersPair._2().toArray();
final String whereClause = conditions.collect(Collectors.joining(" and ", " where ", ""));
final Events result = new Events();
try (final Connection connection = client.getConnection()) {
String sql = "select count(1) total from " + Event.INDEX_NAME + whereClause;
if (log.isDebugEnabled()) {
log.debug("Count SQL: {}, parameters: {}", sql, parameters);
}
try (final ResultSet resultSet = client.executeQuery(connection, sql, parameters)) {
if (!resultSet.next()) {
return result;
}
result.setTotal(resultSet.getInt("total"));
}
sql = "select * from " + Event.INDEX_NAME + whereClause + " limit " + condition.getSize();
if (log.isDebugEnabled()) {
log.debug("Query SQL: {}, parameters: {}", sql, parameters);
}
try (final ResultSet resultSet = client.executeQuery(connection, sql, parameters)) {
while (resultSet.next()) {
result.getEvents().add(parseResultSet(resultSet));
}
}
}
return result;
}
@Override
public Events queryEvents(List<EventQueryCondition> conditions) throws Exception {
final List<Tuple2<Stream<String>, Stream<Object>>> conditionsParametersPair = conditions.stream()
.map(this::buildQuery)
.collect(Collectors.toList());
final Object[] parameters = conditionsParametersPair.stream()
.map(Tuple2::_2)
.reduce(Stream.empty(), Stream::concat)
.toArray();
final String whereClause = conditionsParametersPair.stream()
.map(Tuple2::_1)
.map(it -> it.collect(Collectors.joining(" and ")))
.collect(Collectors.joining(" or ", " where ", ""));
final int size = conditions.stream().mapToInt(EventQueryCondition::getSize).sum();
final Events result = new Events();
try (final Connection connection = client.getConnection()) {
String sql = "select count(1) total from " + Event.INDEX_NAME + whereClause;
if (log.isDebugEnabled()) {
log.debug("Count SQL: {}, parameters: {}", sql, parameters);
}
try (final ResultSet resultSet = client.executeQuery(connection, sql, parameters)) {
if (!resultSet.next()) {
return result;
}
result.setTotal(resultSet.getInt("total"));
}
sql = "select * from " + Event.INDEX_NAME + whereClause + " limit " + size;
if (log.isDebugEnabled()) {
log.debug("Query SQL: {}, parameters: {}", sql, parameters);
}
try (final ResultSet resultSet = client.executeQuery(connection, sql, parameters)) {
while (resultSet.next()) {
result.getEvents().add(parseResultSet(resultSet));
}
}
}
return result;
}
protected org.apache.skywalking.oap.server.core.query.type.event.Event parseResultSet(final ResultSet resultSet) throws SQLException {
final org.apache.skywalking.oap.server.core.query.type.event.Event event = new org.apache.skywalking.oap.server.core.query.type.event.Event();
event.setUuid(resultSet.getString(Event.UUID));
final String service = resultSet.getString(Event.SERVICE);
final String serviceInstance = resultSet.getString(Event.SERVICE_INSTANCE);
final String endpoint = resultSet.getString(Event.ENDPOINT);
event.setSource(new Source(service, serviceInstance, endpoint));
event.setName(resultSet.getString(Event.NAME));
event.setType(EventType.parse(resultSet.getString(Event.TYPE)));
event.setMessage(resultSet.getString(Event.MESSAGE));
event.setParameters(resultSet.getString(Event.PARAMETERS));
event.setStartTime(resultSet.getLong(Event.START_TIME));
event.setEndTime(resultSet.getLong(Event.END_TIME));
return event;
}
protected Tuple2<Stream<String>, Stream<Object>> buildQuery(final EventQueryCondition condition) {
final Stream.Builder<String> conditions = Stream.builder();
final Stream.Builder<Object> parameters = Stream.builder();
if (!isNullOrEmpty(condition.getUuid())) { if (!isNullOrEmpty(condition.getUuid())) {
conditions.add(Event.UUID + "=?"); conditions.add(Event.UUID + "=?");
@ -90,53 +186,6 @@ public class H2EventQueryDAO implements IEventQueryDAO {
} }
} }
final String whereClause = conditions.isEmpty() ? "" : conditions.stream().collect(Collectors.joining(" and ", " where ", "")); return Tuple.of(conditions.build(), parameters.build());
final Events result = new Events();
try (final Connection connection = client.getConnection()) {
String sql = "select count(1) total from " + Event.INDEX_NAME + whereClause;
if (log.isDebugEnabled()) {
log.debug("Count SQL: {}, parameters: {}", sql, parameters);
}
try (final ResultSet resultSet = client.executeQuery(connection, sql, parameters.toArray())) {
if (!resultSet.next()) {
return result;
}
result.setTotal(resultSet.getInt("total"));
}
sql = "select * from " + Event.INDEX_NAME + whereClause + " limit " + condition.getSize();
if (log.isDebugEnabled()) {
log.debug("Query SQL: {}, parameters: {}", sql, parameters);
}
try (final ResultSet resultSet = client.executeQuery(connection, sql, parameters.toArray())) {
while (resultSet.next()) {
result.getEvents().add(parseResultSet(resultSet));
}
}
}
return result;
}
protected org.apache.skywalking.oap.server.core.query.type.event.Event parseResultSet(final ResultSet resultSet) throws SQLException {
final org.apache.skywalking.oap.server.core.query.type.event.Event event = new org.apache.skywalking.oap.server.core.query.type.event.Event();
event.setUuid(resultSet.getString(Event.UUID));
final String service = resultSet.getString(Event.SERVICE);
final String serviceInstance = resultSet.getString(Event.SERVICE_INSTANCE);
final String endpoint = resultSet.getString(Event.ENDPOINT);
event.setSource(new Source(service, serviceInstance, endpoint));
event.setName(resultSet.getString(Event.NAME));
event.setType(EventType.parse(resultSet.getString(Event.TYPE)));
event.setMessage(resultSet.getString(Event.MESSAGE));
event.setParameters(resultSet.getString(Event.PARAMETERS));
event.setStartTime(resultSet.getLong(Event.START_TIME));
event.setEndTime(resultSet.getLong(Event.END_TIME));
return event;
} }
} }

View File

@ -18,6 +18,8 @@
package org.apache.skywalking.e2e; package org.apache.skywalking.e2e;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneOffset; import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
@ -32,6 +34,7 @@ public abstract class AbstractQuery<T extends AbstractQuery<T>> {
private String start; private String start;
private String end; private String end;
private String step = "SECOND"; private String step = "SECOND";
private String name;
public String start() { public String start() {
if (start != null) { if (start != null) {
@ -135,4 +138,16 @@ public abstract class AbstractQuery<T extends AbstractQuery<T>> {
this.step = "SECOND"; this.step = "SECOND";
return (T) this; return (T) this;
} }
public String name() {
if (!StringUtils.isEmpty(name)) {
return name;
}
return null;
}
public T name(String name) {
this.name = name;
return (T) this;
}
} }

View File

@ -20,6 +20,7 @@ package org.apache.skywalking.e2e.alarm;
import lombok.Data; import lombok.Data;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import org.apache.skywalking.e2e.common.KeyValue; import org.apache.skywalking.e2e.common.KeyValue;
import org.apache.skywalking.e2e.event.Event;
import java.util.List; import java.util.List;
@ -31,4 +32,5 @@ public class Alarm {
private String id; private String id;
private String message; private String message;
private List<KeyValue> tags; private List<KeyValue> tags;
private List<Event> events;
} }

View File

@ -18,15 +18,20 @@
package org.apache.skywalking.e2e.alarm; package org.apache.skywalking.e2e.alarm;
import lombok.Data; import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.e2e.common.KeyValue; import org.apache.skywalking.e2e.common.KeyValue;
import org.apache.skywalking.e2e.common.KeyValueMatcher; import org.apache.skywalking.e2e.common.KeyValueMatcher;
import org.apache.skywalking.e2e.event.Event;
import org.apache.skywalking.e2e.event.EventMatcher;
import org.apache.skywalking.e2e.verification.AbstractMatcher; import org.apache.skywalking.e2e.verification.AbstractMatcher;
import org.springframework.util.CollectionUtils;
import java.util.List; import java.util.List;
import static java.util.Objects.nonNull; import static java.util.Objects.nonNull;
import static org.assertj.core.api.Assertions.fail; import static org.assertj.core.api.Assertions.fail;
@Slf4j
@Data @Data
public class AlarmMatcher extends AbstractMatcher<Alarm> { public class AlarmMatcher extends AbstractMatcher<Alarm> {
private String startTime; private String startTime;
@ -34,10 +39,10 @@ public class AlarmMatcher extends AbstractMatcher<Alarm> {
private String id; private String id;
private String message; private String message;
private List<KeyValueMatcher> tags; private List<KeyValueMatcher> tags;
private List<EventMatcher> events;
@Override @Override
public void verify(Alarm alarm) { public void verify(Alarm alarm) {
doVerify(this.startTime, alarm.getStartTime());
doVerify(this.scope, alarm.getScope()); doVerify(this.scope, alarm.getScope());
doVerify(this.id, alarm.getId()); doVerify(this.id, alarm.getId());
doVerify(this.message, alarm.getMessage()); doVerify(this.message, alarm.getMessage());
@ -57,5 +62,22 @@ public class AlarmMatcher extends AbstractMatcher<Alarm> {
} }
} }
} }
if (!CollectionUtils.isEmpty(getEvents())) {
for (final EventMatcher matcher : getEvents()) {
boolean matched = false;
for (final Event event : alarm.getEvents()) {
try {
matcher.verify(event);
matched = true;
} catch (Throwable ignore) {
//ignore.
}
}
if (!matched) {
fail("\nExpected: %s\n Actual: %s", getEvents(), alarm.getEvents());
}
}
}
} }
} }

View File

@ -18,6 +18,7 @@
package org.apache.skywalking.e2e.alarm; package org.apache.skywalking.e2e.alarm;
import org.apache.skywalking.e2e.AbstractQuery; import org.apache.skywalking.e2e.AbstractQuery;
import org.apache.skywalking.e2e.event.Event;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -28,15 +29,26 @@ import java.util.HashMap;
public class AlarmQuery extends AbstractQuery<AlarmQuery> { public class AlarmQuery extends AbstractQuery<AlarmQuery> {
private List<Map<String, String>> tags = Collections.emptyList(); private List<Map<String, String>> tags = Collections.emptyList();
private List<Event> events = Collections.emptyList();
public List<Map<String, String>> tags() { public List<Map<String, String>> tags() {
return tags; return tags;
} }
public List<Event> events() {
return events;
}
public AlarmQuery tags(List<Map<String, String>> tags) { public AlarmQuery tags(List<Map<String, String>> tags) {
this.tags = tags; this.tags = tags;
return this; return this;
} }
public AlarmQuery events(List<Event> events) {
this.events = events;
return this;
}
public AlarmQuery addTag(String key, String value) { public AlarmQuery addTag(String key, String value) {
if (Collections.EMPTY_LIST.equals(tags)) { if (Collections.EMPTY_LIST.equals(tags)) {
tags = new ArrayList<>(); tags = new ArrayList<>();
@ -47,4 +59,13 @@ public class AlarmQuery extends AbstractQuery<AlarmQuery> {
tags.add(tag); tags.add(tag);
return this; return this;
} }
public AlarmQuery addEvents(List<Event> events) {
if (Collections.EMPTY_LIST.equals(events)) {
events = new ArrayList<>();
}
events.addAll(events);
return this;
}
} }

View File

@ -29,6 +29,19 @@
tags { tags {
key, value key, value
} }
events {
name
source {
service serviceInstance endpoint
}
startTime
endTime
message
parameters {
key value
}
uuid
}
} }
}}", }}",
"variables":{ "variables":{

View File

@ -17,6 +17,8 @@
package org.apache.skywalking.e2e.alarm; package org.apache.skywalking.e2e.alarm;
import java.util.List;
import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.skywalking.e2e.annotation.ContainerHostAndPort; import org.apache.skywalking.e2e.annotation.ContainerHostAndPort;
import org.apache.skywalking.e2e.annotation.DockerCompose; import org.apache.skywalking.e2e.annotation.DockerCompose;
@ -35,9 +37,6 @@ import org.junit.jupiter.api.TestMethodOrder;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.testcontainers.containers.DockerComposeContainer; import org.testcontainers.containers.DockerComposeContainer;
import java.util.List;
import java.util.concurrent.TimeUnit;
import static org.apache.skywalking.e2e.utils.Times.now; import static org.apache.skywalking.e2e.utils.Times.now;
import static org.apache.skywalking.e2e.utils.Yamls.load; import static org.apache.skywalking.e2e.utils.Yamls.load;

View File

@ -24,6 +24,9 @@ matchers:
value: CRITICAL value: CRITICAL
- key: receivers - key: receivers
value: zhangsan value: zhangsan
events:
- source:
service: e2e-service-provider
- startTime: gt 0 - startTime: gt 0
scope: Service scope: Service
id: ZTJlLXNlcnZpY2UtcHJvdmlkZXI=.1 id: ZTJlLXNlcnZpY2UtcHJvdmlkZXI=.1
@ -33,4 +36,6 @@ matchers:
value: CRITICAL value: CRITICAL
- key: receivers - key: receivers
value: zhangsan value: zhangsan
events:
- source:
service: e2e-service-provider

View File

@ -24,6 +24,9 @@ matchers:
value: WARNING value: WARNING
- key: receivers - key: receivers
value: lisi value: lisi
events:
- source:
service: e2e-service-provider
- startTime: gt 0 - startTime: gt 0
scope: Service scope: Service
id: ZTJlLXNlcnZpY2UtcHJvdmlkZXI=.1 id: ZTJlLXNlcnZpY2UtcHJvdmlkZXI=.1
@ -33,3 +36,6 @@ matchers:
value: WARNING value: WARNING
- key: receivers - key: receivers
value: lisi value: lisi
events:
- source:
service: e2e-service-provider

View File

@ -24,3 +24,6 @@ matchers:
value: CRITICAL value: CRITICAL
- key: receivers - key: receivers
value: zhangsan value: zhangsan
events:
- source:
service: e2e-service-provider

View File

@ -24,3 +24,6 @@ matchers:
value: WARNING value: WARNING
- key: receivers - key: receivers
value: lisi value: lisi
events:
- source:
service: e2e-service-provider