Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/**
* This file is part of Graylog.
*
* Graylog is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Graylog is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Graylog. If not, see .
*/
package org.graylog.events.legacy;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Streams;
import com.mongodb.Block;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.Filters;
import org.bson.Document;
import org.graylog.events.conditions.Expr;
import org.graylog.events.conditions.Expression;
import org.graylog.events.notifications.DBNotificationService;
import org.graylog.events.notifications.EventNotificationHandler;
import org.graylog.events.notifications.EventNotificationSettings;
import org.graylog.events.notifications.NotificationDto;
import org.graylog.events.notifications.NotificationResourceHandler;
import org.graylog.events.processor.EventDefinitionDto;
import org.graylog.events.processor.EventDefinitionHandler;
import org.graylog.events.processor.EventProcessorConfig;
import org.graylog.events.processor.aggregation.AggregationConditions;
import org.graylog.events.processor.aggregation.AggregationEventProcessorConfig;
import org.graylog.events.processor.aggregation.AggregationFunction;
import org.graylog.events.processor.aggregation.AggregationSeries;
import org.graylog2.database.MongoConnection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javax.inject.Named;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Strings.isNullOrEmpty;
/**
* Takes care of migrating legacy alert condition and alarm callback configurations to new {@link org.graylog.events.processor.EventDefinition event definitions}
* and {@link org.graylog.events.notifications.EventNotificationConfig notification configurations}.
*
* This class is deliberately avoiding the usage of the legacy Java classes by using the raw MongoDB client
* so we can safely delete the legacy classes at one point and still run the migrations.
*/
public class LegacyAlertConditionMigrator {
private static final Logger LOG = LoggerFactory.getLogger(LegacyAlertConditionMigrator.class);
private final MongoCollection streamsCollection;
private final MongoCollection alarmCallbacksCollection;
private final EventDefinitionHandler eventDefinitionHandler;
private final NotificationResourceHandler notificationResourceHandler;
private final DBNotificationService dbNotificationService;
private final long executeEveryMs;
@Inject
public LegacyAlertConditionMigrator(MongoConnection mongoConnection,
EventDefinitionHandler eventDefinitionHandler,
NotificationResourceHandler notificationResourceHandler,
DBNotificationService dbNotificationService,
@Named("alert_check_interval") int alertCheckInterval) {
this.streamsCollection = mongoConnection.getMongoDatabase().getCollection("streams");
this.alarmCallbacksCollection = mongoConnection.getMongoDatabase().getCollection("alarmcallbackconfigurations");
this.eventDefinitionHandler = eventDefinitionHandler;
this.notificationResourceHandler = notificationResourceHandler;
this.dbNotificationService = dbNotificationService;
// The old alert conditions have been executed every "alert_check_interval" in seconds
this.executeEveryMs = alertCheckInterval * 1000L;
}
public MigrationResult run(Set completedAlertConditions, Set completedAlarmCallbacks) {
final MigrationResult.Builder result = MigrationResult.builder();
streamsCollection.find().forEach((Block) stream -> {
final String streamId = stream.getObjectId("_id").toHexString();
final String streamTitle = stream.getString("title");
final FindIterable iterable = alarmCallbacksCollection.find(Filters.eq("stream_id", streamId));
final Set notifications = Streams.stream(iterable)
.map(alarmCallback -> {
final String callbackId = alarmCallback.getObjectId("_id").toHexString();
if (completedAlarmCallbacks.contains(callbackId)) {
result.addCompletedAlarmCallback(callbackId);
return dbNotificationService.get(callbackId).orElse(null);
}
try {
final NotificationDto notificationDto = migrateAlarmCallback(alarmCallback);
result.addCompletedAlarmCallback(callbackId);
return notificationDto;
} catch (Exception e) {
LOG.error("Couldn't migrate legacy alarm callback on stream <{}/{}>: {}", streamTitle, streamId, alarmCallback, e);
return null;
}
})
.filter(Objects::nonNull)
.collect(Collectors.toSet());
if (!stream.containsKey("alert_conditions")) {
return;
}
@SuppressWarnings("unchecked")
final List list = (List) stream.get("alert_conditions");
list.forEach(alertCondition -> {
final String conditionId = alertCondition.getString("id");
final String conditionType = alertCondition.getString("type");
if (completedAlertConditions.contains(conditionId)) {
result.addCompletedAlertCondition(conditionId);
return;
}
try {
switch (conditionType) {
case "message_count":
migrateMessageCount(new Helper(stream, alertCondition, notifications));
result.addCompletedAlertCondition(conditionId);
break;
case "field_value":
migrateFieldValue(new Helper(stream, alertCondition, notifications));
result.addCompletedAlertCondition(conditionId);
break;
case "field_content_value":
migrateFieldContentValue(new Helper(stream, alertCondition, notifications));
result.addCompletedAlertCondition(conditionId);
break;
default:
LOG.warn("Couldn't migrate unknown legacy alert condition type: {}", conditionType);
}
} catch (Exception e) {
LOG.error("Couldn't migrate legacy alert condition on stream <{}/{}>: {}", streamTitle, streamId, alertCondition, e);
}
});
});
return result.build();
}
/**
* Example alarm callback data structure:
*
*/
private void migrateFieldValue(Helper helper) {
final String type = helper.parameters().getString("type");
final String field = helper.parameters().getString("field");
final String seriesId = helper.newSeriesId();
final AggregationSeries.Builder aggregationSeriesBuilder = AggregationSeries.builder()
.id(seriesId)
.field(field);
switch (type.toUpperCase(Locale.US)) {
case "MEAN":
aggregationSeriesBuilder.function(AggregationFunction.AVG);
break;
case "MIN":
aggregationSeriesBuilder.function(AggregationFunction.MIN);
break;
case "MAX":
aggregationSeriesBuilder.function(AggregationFunction.MAX);
break;
case "SUM":
aggregationSeriesBuilder.function(AggregationFunction.SUM);
break;
case "STDDEV":
aggregationSeriesBuilder.function(AggregationFunction.STDDEV);
break;
default:
LOG.warn("Couldn't migrate field value alert condition with unknown type: {}", type);
return;
}
final AggregationSeries aggregationSeries = aggregationSeriesBuilder.build();
final Expression expression = helper.createExpression(seriesId, "HIGHER");
final EventProcessorConfig config = helper.createAggregationProcessorConfig(aggregationSeries, expression, executeEveryMs);
final EventDefinitionDto definitionDto = helper.createEventDefinition(config);
LOG.info("Migrate legacy field value alert condition <{}>", definitionDto.title());
eventDefinitionHandler.create(definitionDto);
}
/**
* Example field content value alert condition data structure on streams:
*