Skip to content

Commit

Permalink
Only reacalculate index set ranges in index set maintenance menu (#3252)
Browse files Browse the repository at this point in the history
* Only reacalculate index set ranges in index set maintenance menu

Instead of triggering a recalc job for all indices in all index sets,
only trigger a index range recalc for the current index set.

* Adapt UI texts to last changes
  • Loading branch information
bernd authored and edmundoa committed Dec 27, 2016
1 parent cbdec69 commit fee01fc
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 30 deletions.
Expand Up @@ -49,7 +49,7 @@ public SetIndexReadOnlyAndCalculateRangeJob(SetIndexReadOnlyJob.Factory setIndex
public void execute() { public void execute() {
final SystemJob setIndexReadOnlyJob = setIndexReadOnlyJobFactory.create(indexName); final SystemJob setIndexReadOnlyJob = setIndexReadOnlyJobFactory.create(indexName);
setIndexReadOnlyJob.execute(); setIndexReadOnlyJob.execute();
final SystemJob createNewSingleIndexRangeJob = createNewSingleIndexRangeJobFactory.create(indexSetRegistry, indexName); final SystemJob createNewSingleIndexRangeJob = createNewSingleIndexRangeJobFactory.create(indexSetRegistry.getAllIndexSets(), indexName);
createNewSingleIndexRangeJob.execute(); createNewSingleIndexRangeJob.execute();


} }
Expand Down
Expand Up @@ -18,27 +18,29 @@


import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject; import com.google.inject.assistedinject.AssistedInject;
import org.graylog2.indexer.IndexSetRegistry; import org.graylog2.indexer.IndexSet;
import org.graylog2.shared.system.activities.ActivityWriter; import org.graylog2.shared.system.activities.ActivityWriter;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;


import java.util.Set;

import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;


public class CreateNewSingleIndexRangeJob extends RebuildIndexRangesJob { public class CreateNewSingleIndexRangeJob extends RebuildIndexRangesJob {
private static final Logger LOG = LoggerFactory.getLogger(CreateNewSingleIndexRangeJob.class); private static final Logger LOG = LoggerFactory.getLogger(CreateNewSingleIndexRangeJob.class);
private final String indexName; private final String indexName;


public interface Factory { public interface Factory {
CreateNewSingleIndexRangeJob create(IndexSetRegistry indexSetRegistry, String indexName); CreateNewSingleIndexRangeJob create(Set<IndexSet> indexSets, String indexName);
} }


@AssistedInject @AssistedInject
public CreateNewSingleIndexRangeJob(@Assisted IndexSetRegistry indexSetRegistry, public CreateNewSingleIndexRangeJob(@Assisted Set<IndexSet> indexSets,
@Assisted String indexName, @Assisted String indexName,
ActivityWriter activityWriter, ActivityWriter activityWriter,
IndexRangeService indexRangeService) { IndexRangeService indexRangeService) {
super(indexSetRegistry, activityWriter, indexRangeService); super(indexSets, activityWriter, indexRangeService);
this.indexName = checkNotNull(indexName); this.indexName = checkNotNull(indexName);
} }


Expand Down
Expand Up @@ -24,7 +24,6 @@


import org.graylog2.database.NotFoundException; import org.graylog2.database.NotFoundException;
import org.graylog2.indexer.IndexSet; import org.graylog2.indexer.IndexSet;
import org.graylog2.indexer.IndexSetRegistry;
import org.graylog2.indexer.indices.TooManyAliasesException; import org.graylog2.indexer.indices.TooManyAliasesException;
import org.graylog2.shared.system.activities.Activity; import org.graylog2.shared.system.activities.Activity;
import org.graylog2.shared.system.activities.ActivityWriter; import org.graylog2.shared.system.activities.ActivityWriter;
Expand All @@ -37,7 +36,7 @@


public class RebuildIndexRangesJob extends SystemJob { public class RebuildIndexRangesJob extends SystemJob {
public interface Factory { public interface Factory {
RebuildIndexRangesJob create(IndexSetRegistry indexSetRegistry); RebuildIndexRangesJob create(Set<IndexSet> indexSets);
} }


private static final Logger LOG = LoggerFactory.getLogger(RebuildIndexRangesJob.class); private static final Logger LOG = LoggerFactory.getLogger(RebuildIndexRangesJob.class);
Expand All @@ -47,15 +46,15 @@ public interface Factory {
private volatile int indicesToCalculate = 0; private volatile int indicesToCalculate = 0;
private volatile int indicesCalculated = 0; private volatile int indicesCalculated = 0;


protected final IndexSetRegistry indexSetRegistry; protected final Set<IndexSet> indexSets;
private final ActivityWriter activityWriter; private final ActivityWriter activityWriter;
protected final IndexRangeService indexRangeService; protected final IndexRangeService indexRangeService;


@AssistedInject @AssistedInject
public RebuildIndexRangesJob(@Assisted IndexSetRegistry indexSetRegistry, public RebuildIndexRangesJob(@Assisted Set<IndexSet> indexSets,
ActivityWriter activityWriter, ActivityWriter activityWriter,
IndexRangeService indexRangeService) { IndexRangeService indexRangeService) {
this.indexSetRegistry = indexSetRegistry; this.indexSets = indexSets;
this.activityWriter = activityWriter; this.activityWriter = activityWriter;
this.indexRangeService = indexRangeService; this.indexRangeService = indexRangeService;
} }
Expand Down Expand Up @@ -86,8 +85,7 @@ public void execute() {


// for each index set we know about // for each index set we know about
final ListMultimap<IndexSet, String> indexSets = MultimapBuilder.hashKeys().arrayListValues().build(); final ListMultimap<IndexSet, String> indexSets = MultimapBuilder.hashKeys().arrayListValues().build();
final Set<IndexSet> allIndexSets = indexSetRegistry.getAllIndexSets(); for (IndexSet indexSet : this.indexSets) {
for (IndexSet indexSet : allIndexSets) {
final String[] managedIndicesNames = indexSet.getManagedIndicesNames(); final String[] managedIndicesNames = indexSet.getManagedIndicesNames();
for (String name : managedIndicesNames) { for (String name : managedIndicesNames) {
indexSets.put(indexSet, name); indexSets.put(indexSet, name);
Expand Down
Expand Up @@ -120,7 +120,7 @@ public void upgrade() {
continue; continue;
} }
LOG.info("Recalculating streams in index {}", indexName); LOG.info("Recalculating streams in index {}", indexName);
final CreateNewSingleIndexRangeJob createNewSingleIndexRangeJob = rebuildIndexRangeJobFactory.create(indexSetRegistry, indexName); final CreateNewSingleIndexRangeJob createNewSingleIndexRangeJob = rebuildIndexRangeJobFactory.create(indexSetRegistry.getAllIndexSets(), indexName);
createNewSingleIndexRangeJob.execute(); createNewSingleIndexRangeJob.execute();
} }


Expand Down
Expand Up @@ -28,6 +28,7 @@
import org.graylog2.audit.AuditEventTypes; import org.graylog2.audit.AuditEventTypes;
import org.graylog2.audit.jersey.AuditEvent; import org.graylog2.audit.jersey.AuditEvent;
import org.graylog2.database.NotFoundException; import org.graylog2.database.NotFoundException;
import org.graylog2.indexer.IndexSet;
import org.graylog2.indexer.IndexSetRegistry; import org.graylog2.indexer.IndexSetRegistry;
import org.graylog2.indexer.ranges.CreateNewSingleIndexRangeJob; import org.graylog2.indexer.ranges.CreateNewSingleIndexRangeJob;
import org.graylog2.indexer.ranges.IndexRange; import org.graylog2.indexer.ranges.IndexRange;
Expand All @@ -40,6 +41,7 @@
import org.graylog2.system.jobs.SystemJob; import org.graylog2.system.jobs.SystemJob;
import org.graylog2.system.jobs.SystemJobConcurrencyException; import org.graylog2.system.jobs.SystemJobConcurrencyException;
import org.graylog2.system.jobs.SystemJobManager; import org.graylog2.system.jobs.SystemJobManager;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.NotEmpty; import org.hibernate.validator.constraints.NotEmpty;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
Expand All @@ -54,7 +56,9 @@
import javax.ws.rs.Produces; import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.SortedSet; import java.util.SortedSet;


@RequiresAuthentication @RequiresAuthentication
Expand Down Expand Up @@ -143,14 +147,29 @@ public IndexRangeSummary show(
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@AuditEvent(type = AuditEventTypes.ES_INDEX_RANGE_UPDATE_JOB) @AuditEvent(type = AuditEventTypes.ES_INDEX_RANGE_UPDATE_JOB)
public Response rebuild() { public Response rebuild() {
final SystemJob rebuildJob = rebuildIndexRangesJobFactory.create(indexSetRegistry); submitIndexRangesJob(indexSetRegistry.getAllIndexSets());
try {
this.systemJobManager.submit(rebuildJob); return Response.accepted().build();
} catch (SystemJobConcurrencyException e) { }
final String errorMsg = "Concurrency level of this job reached: " + e.getMessage();
LOG.error(errorMsg, e); @POST
throw new ForbiddenException(errorMsg); @Timed
} @Path("/index_set/{indexSetId}/rebuild")
@RequiresPermissions(RestPermissions.INDEXRANGES_REBUILD)
@ApiOperation(value = "Rebuild/sync index range information for the given index set.",
notes = "This triggers a systemjob that scans every index in the given index set and stores meta information " +
"about what indices contain messages in what timeranges. It atomically overwrites " +
"already existing meta information.")
@ApiResponses(value = {
@ApiResponse(code = 202, message = "Rebuild/sync systemjob triggered.")
})
@Produces(MediaType.APPLICATION_JSON)
@AuditEvent(type = AuditEventTypes.ES_INDEX_RANGE_UPDATE_JOB)
public Response rebuildIndexSet(@ApiParam(name = "indexSetId") @PathParam("indexSetId") @NotBlank final String indexSetId) {
final IndexSet indexSet = indexSetRegistry.get(indexSetId)
.orElseThrow(() -> new javax.ws.rs.NotFoundException("Index set <" + indexSetId + "> not found!"));

submitIndexRangesJob(Collections.singleton(indexSet));


return Response.accepted().build(); return Response.accepted().build();
} }
Expand All @@ -175,7 +194,7 @@ public Response rebuildIndex(
} }
checkPermission(RestPermissions.INDEXRANGES_REBUILD, index); checkPermission(RestPermissions.INDEXRANGES_REBUILD, index);


final SystemJob rebuildJob = singleIndexRangeJobFactory.create(indexSetRegistry, index); final SystemJob rebuildJob = singleIndexRangeJobFactory.create(indexSetRegistry.getAllIndexSets(), index);
try { try {
this.systemJobManager.submit(rebuildJob); this.systemJobManager.submit(rebuildJob);
} catch (SystemJobConcurrencyException e) { } catch (SystemJobConcurrencyException e) {
Expand All @@ -186,4 +205,16 @@ public Response rebuildIndex(


return Response.accepted().build(); return Response.accepted().build();
} }

private void submitIndexRangesJob(final Set<IndexSet> indexSets) {
final SystemJob rebuildJob = rebuildIndexRangesJobFactory.create(indexSets);
try {
this.systemJobManager.submit(rebuildJob);
} catch (SystemJobConcurrencyException e) {
final String errorMsg = "Concurrency level of this job reached: " + e.getMessage();
LOG.error(errorMsg, e);
throw new ForbiddenException(errorMsg);
}
}

} }
Expand Up @@ -15,9 +15,8 @@ const IndicesMaintenanceDropdown = React.createClass({
}, },


_onRecalculateIndexRange() { _onRecalculateIndexRange() {
if (window.confirm('This will recalculate index ranges for ALL index sets using a background system job. Do you want to proceed?')) { if (window.confirm('This will recalculate index ranges for this index set using a background system job. Do you want to proceed?')) {
// TODO 2.2: Only rebuild index set here? It currently rebuilds all index ranges! IndexRangesActions.recalculate(this.props.indexSetId);
IndexRangesActions.recalculate();
} }
}, },
_onCycleDeflector() { _onCycleDeflector() {
Expand All @@ -35,7 +34,7 @@ const IndicesMaintenanceDropdown = React.createClass({
return ( return (
<ButtonGroup> <ButtonGroup>
<DropdownButton bsStyle="info" title="Maintenance" id="indices-maintenance-actions" pullRight> <DropdownButton bsStyle="info" title="Maintenance" id="indices-maintenance-actions" pullRight>
<MenuItem eventKey="1" onClick={this._onRecalculateIndexRange}>Recalculate all index ranges</MenuItem> <MenuItem eventKey="1" onClick={this._onRecalculateIndexRange}>Recalculate index ranges</MenuItem>
{cycleButton} {cycleButton}
</DropdownButton> </DropdownButton>
</ButtonGroup> </ButtonGroup>
Expand Down
2 changes: 1 addition & 1 deletion graylog2-web-interface/src/routing/ApiRoutes.js
Expand Up @@ -79,7 +79,7 @@ const ApiRoutes = {
}, },
IndexRangesApiController: { IndexRangesApiController: {
list: () => { return { url: '/system/indices/ranges' }; }, list: () => { return { url: '/system/indices/ranges' }; },
rebuild: () => { return { url: '/system/indices/ranges/rebuild' }; }, rebuild: (indexSetId) => { return { url: `/system/indices/ranges/index_set/${indexSetId}/rebuild` }; },
rebuildSingle: (index) => { return { url: `/system/indices/ranges/${index}/rebuild` }; }, rebuildSingle: (index) => { return { url: `/system/indices/ranges/${index}/rebuild` }; },
}, },
IndexSetsApiController: { IndexSetsApiController: {
Expand Down
6 changes: 3 additions & 3 deletions graylog2-web-interface/src/stores/indices/IndexRangesStore.js
Expand Up @@ -28,9 +28,9 @@ const IndexRangesStore = Reflux.createStore({


IndexRangesActions.list.promise(promise); IndexRangesActions.list.promise(promise);
}, },
recalculate() { recalculate(indexSetId) {
const url = URLUtils.qualifyUrl(ApiRoutes.IndexRangesApiController.rebuild().url); const url = URLUtils.qualifyUrl(ApiRoutes.IndexRangesApiController.rebuild(indexSetId).url);
const promise = fetch ('POST', url); const promise = fetch('POST', url);
promise promise
.then(UserNotification.success('Index ranges will be recalculated shortly')) .then(UserNotification.success('Index ranges will be recalculated shortly'))
.catch((error) => { .catch((error) => {
Expand Down

0 comments on commit fee01fc

Please sign in to comment.