Skip to content

Commit

Permalink
Sidecar support for tags and collectors with multiple configurations (#…
Browse files Browse the repository at this point in the history
…13433)

* feature branch for multiple configs per collector and tags

* Add "tags" field to DTOs (#13367)

* Add spooldir variable to sidecars and their default collector configs (#13349)

* Add support for multiple configurations per collector

This will need a new sidcar release.
Old sidecars are still supported with just a single configuration.

* Use Java 9 Lists

* Add support for ${sidecar.spoolDir} variable

* Fix tests

* Revert "Add support for multiple configurations per collector"

This reverts commit 0a17743.

* Use ${sidecar.spoolDir} for fresh collector templates

And add explanation to the UI

* make eslint happy

* convert tags to Set and fix Autovalue

* Support configuration_id in CollectorStatus

Co-authored-by: Othello Maurer <[email protected]>

* Sidecar tagged assignments (#13409)

* add assignedFromTags property to assignment

* Don't fail for unknown properties on NodeDetails

This makes it easier to extend the sidecar
in the future

* Create sidecar config assignments based on tags

This is a first naive approach.
Every registration request will rebuild the assignments
and this is probably too expensive.

* fix test

* Fix more Tests

* Fine grained EtagService

Use three different caches for configs, collectors and assignments.

* Add Etag caching for UpdateRegistration results

The response to the registration PUT request contains
configuration assignments, which can be cached as well.

This requires us to invalidate the sidecar etag cache in more
situations:
 - Configration assignments
 - User triggered collector actions (stop, start, restart)

* Cleanup old assignment caching commit

* optimize

* fix after merge

* replace deprecated notempty annotation

* cache assignments per sidecar id

using just the md5 of an assignment result might
leed to sidecars missing out on updates.
An assignment is always meant for a single sidecar, caching the entire
assignment over all sidecars is wrong.

A per sidecar cache entry allows more fine grained cache invalidations.

Bump the cacheMaxSize to 5000 entries, which is a more meaningful
number, considered that this might have to hold all sidecars.

* Refactor sidecar register() call.

Only update the tagged assignments when we miss the cache.

* change cache naming

* more refactoring

* improve cache invalidation

* use fancy java

Co-authored-by: Othello Maurer <[email protected]>

* Add more cases for tag invalidation and fix tests

* add tags to Config summary

* Generate EntityTags with a better hash algorithm

As @thll noticed, Object.hashCode() is prone to having collisions

* Handle manual assignments via API

* rename

* Make tags available as config variables.

This allows configs to be written with conditionals.
E.g.:

```
<#if sidecar.tags.apache??>
 - /var/log/apache/*.log
</#if>
```

* dont lose tags on UI configuration updates

Co-authored-by: Othello Maurer <[email protected]>

* Sidecar tags tests (#13502)

* Only assign tagged configs that match the OS

* rename test

* add tests for SidecarService.updateTaggedConfigurationAssignments()

* add tests for SidecarService.applyManualAssignments()

* Fix cache invalidation for collector actions (#13504)

* Fix cache invalidation for collector actions

The registration cache was using the sidecar "_id",
while the ActionService was invalidating the sidecar "node_id".

Change the entire cache to using the "node_id"

* Rename parameter from sidecarId to sidecarNodeId

Co-authored-by: Othello Maurer <[email protected]>

* Invalidate registration cache only for affected sidecars (#13514)

* Invalidate registration cache only for affected sidecars

* Use node-id for cache invalidation

The cache key has been changed since this PR has been started.

* Consider OS for cache invalidation

Also use symmetric difference of tags to further reduce
unnecessary invalidations

* Invalidate less when creating new configs

* Add description for tag variables

* Add "tags" field to DTOs (#13367)

* show CollectorProcessControl as an action button

* added CollectorConfigurationModal

* made search button in SearchForm optional

* Add spooldir variable to sidecars and their default collector configs (#13349)

* Add support for multiple configurations per collector

This will need a new sidcar release.
Old sidecars are still supported with just a single configuration.

* Use Java 9 Lists

* Add support for ${sidecar.spoolDir} variable

* Fix tests

* Revert "Add support for multiple configurations per collector"

This reverts commit 0a17743.

* Use ${sidecar.spoolDir} for fresh collector templates

And add explanation to the UI

* make eslint happy

* convert tags to Set and fix Autovalue

* Support configuration_id in CollectorStatus

Co-authored-by: Othello Maurer <[email protected]>

* handle edge case very long config names

* handle edge cases when its not possible to configure

* change config list styling

* make CollectorConfigurationModal a reusable component

* added CollectorConfigurationModal in CollectorsAdministrationActions

* icon btn as edit btn progress

* Sidecar tagged assignments (#13409)

* add assignedFromTags property to assignment

* Don't fail for unknown properties on NodeDetails

This makes it easier to extend the sidecar
in the future

* Create sidecar config assignments based on tags

This is a first naive approach.
Every registration request will rebuild the assignments
and this is probably too expensive.

* fix test

* Fix more Tests

* Fine grained EtagService

Use three different caches for configs, collectors and assignments.

* Add Etag caching for UpdateRegistration results

The response to the registration PUT request contains
configuration assignments, which can be cached as well.

This requires us to invalidate the sidecar etag cache in more
situations:
 - Configration assignments
 - User triggered collector actions (stop, start, restart)

* Cleanup old assignment caching commit

* optimize

* fix after merge

* replace deprecated notempty annotation

* cache assignments per sidecar id

using just the md5 of an assignment result might
leed to sidecars missing out on updates.
An assignment is always meant for a single sidecar, caching the entire
assignment over all sidecars is wrong.

A per sidecar cache entry allows more fine grained cache invalidations.

Bump the cacheMaxSize to 5000 entries, which is a more meaningful
number, considered that this might have to hold all sidecars.

* Refactor sidecar register() call.

Only update the tagged assignments when we miss the cache.

* change cache naming

* more refactoring

* improve cache invalidation

* use fancy java

Co-authored-by: Othello Maurer <[email protected]>

* Add more cases for tag invalidation and fix tests

* add tags to Config summary

* Generate EntityTags with a better hash algorithm

As @thll noticed, Object.hashCode() is prone to having collisions

* Handle manual assignments via API

* rename

* Make tags available as config variables.

This allows configs to be written with conditionals.
E.g.:

```
<#if sidecar.tags.apache??>
 - /var/log/apache/*.log
</#if>
```

* dont lose tags on UI configuration updates

Co-authored-by: Othello Maurer <[email protected]>

* renamed btn Assign Configurations

* fix wrong postion of ColorLabel

* disable eslint errors

* added ModalSubTitle styling

* Sidecar tags tests (#13502)

* Only assign tagged configs that match the OS

* rename test

* add tests for SidecarService.updateTaggedConfigurationAssignments()

* add tests for SidecarService.applyManualAssignments()

* Fix cache invalidation for collector actions (#13504)

* Fix cache invalidation for collector actions

The registration cache was using the sidecar "_id",
while the ActionService was invalidating the sidecar "node_id".

Change the entire cache to using the "node_id"

* Rename parameter from sidecarId to sidecarNodeId

Co-authored-by: Othello Maurer <[email protected]>

* Invalidate registration cache only for affected sidecars (#13514)

* Invalidate registration cache only for affected sidecars

* Use node-id for cache invalidation

The cache key has been changed since this PR has been started.

* Consider OS for cache invalidation

Also use symmetric difference of tags to further reduce
unnecessary invalidations

* Invalidate less when creating new configs

* added logic to CollectorConfigurationModal to support multiple sidecars

* onReset resets the search form too

* updated confirmConfigurationChange fnct to support multiple sidecars

* simplify Configuration summary when multiple sidecars are selected

* finalized confirmation summary

* fixed exit dialog by ESC key bug

* Add description for tag variables

* added Configuration Tags field in Collector Configuration page

* prototype: implement auto assigned tags in config selection modal

* finalized tags UI implementation

* fix linter issues

* fix sidecars.node_name type error

* handled case assigned_from_tags with multiple sidecarse

* hide close icon btn when isAssignedFromTags

* fixed TemplatesHelper linter issues

* cleanup

* split CollectorConfigurationModal into 2 components to reduce complexity

* small css changes

* added tests for CollectorConfigurationModal

* fixed too long logic lines

* avoid single charachter variables

* fixed Missing semicolons

* removed React. in hooks

* RegExp instance set into a variable

* destruct props

* used styled components

* css styled component changes

* destruct CollectorsAdministrationActions props

* convert CollectorProcessControl to typescript and using React functional component

* removed React. in hooks

* convert CollectorsAdministration to typescript and using React functional component

* reset file

* convert CollectorsAdministrationActions to typescript and using React functional component

* added types

* fix eslint issues

* typed CollectorProcessControl props

* typed CollectorsAdministration props

* typed CollectorsAdministrationActions props

* typed function args and states

* converted ConfigurationTagsSelect to typescript and  functional component

* converted TemplatesHelper to typescript and functional component

* converted ConfigurationForm to typescript and functional component

* removed unused function

* fixed config creation form

* removed read only from types

* used Proptypes.shape for configuration

* fixed console error in SidecarNewConfigurationPage

* added type SidecarCollectorPairType

* make sure the filterQuery handles case error

* made tags field required

* ColorLabel using className instead of inline style

* converted inline-styling to styled-component in SearchForm

* converted CollectorsAdministration.css into styled-components

* addedstyled component for ColorLabel

* added SidecarCollectorConfigurationFacade.java changes

Co-authored-by: Marco Pfatschbacher <[email protected]>
Co-authored-by: Othello Maurer <[email protected]>
  • Loading branch information
3 people authored Oct 19, 2022
1 parent eac597c commit 2829a8b
Show file tree
Hide file tree
Showing 48 changed files with 2,871 additions and 1,787 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class SidecarPluginConfiguration implements PluginConfigBean {
private Duration cacheTime = Duration.hours(1L);

@Parameter(value = PREFIX + "cache_max_size", validator = PositiveIntegerValidator.class)
private int cacheMaxSize = 100;
private int cacheMaxSize = 5000;

public Duration getCacheTime() {
return cacheTime;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ public void upgrade() {
"output.logstash:\n" +
" hosts: [\"192.168.1.1:5044\"]\n" +
"path:\n" +
" data: /var/lib/graylog-sidecar/collectors/filebeat/data\n" +
" logs: /var/lib/graylog-sidecar/collectors/filebeat/log"
" data: ${sidecar.spoolDir}/data\n" +
" logs: ${sidecar.spoolDir}/log"
);
ensureCollector(
"filebeat",
Expand All @@ -98,8 +98,8 @@ public void upgrade() {
"output.logstash:\n" +
" hosts: [\"192.168.1.1:5044\"]\n" +
"path:\n" +
" data: /var/lib/graylog-sidecar/collectors/filebeat/data\n" +
" logs: /var/lib/graylog-sidecar/collectors/filebeat/log"
" data: ${sidecar.spoolDir}/data\n" +
" logs: ${sidecar.spoolDir}/log"
);
ensureCollector(
"filebeat",
Expand All @@ -117,8 +117,8 @@ public void upgrade() {
"output.logstash:\n" +
" hosts: [\"192.168.1.1:5044\"]\n" +
"path:\n" +
" data: /var/lib/graylog-sidecar/collectors/filebeat/data\n" +
" logs: /var/lib/graylog-sidecar/collectors/filebeat/log"
" data: ${sidecar.spoolDir}/data\n" +
" logs: ${sidecar.spoolDir}/log"
);
ensureCollector(
"winlogbeat",
Expand All @@ -131,8 +131,8 @@ public void upgrade() {
"output.logstash:\n" +
" hosts: [\"192.168.1.1:5044\"]\n" +
"path:\n" +
" data: C:\\Program Files\\Graylog\\sidecar\\cache\\winlogbeat\\data\n" +
" logs: C:\\Program Files\\Graylog\\sidecar\\logs\n" +
" data: ${sidecar.spoolDir}\\data\n" +
" logs: ${sidecar.spoolDir}\\logs\n" +
"tags:\n" +
" - windows\n" +
"winlogbeat:\n" +
Expand Down Expand Up @@ -164,9 +164,9 @@ public void upgrade() {
"Group nxlog\n" +
"\n" +
"Moduledir /usr/lib/nxlog/modules\n" +
"CacheDir /var/spool/nxlog/data\n" +
"PidFile /var/run/nxlog/nxlog.pid\n" +
"LogFile /var/log/nxlog/nxlog.log\n" +
"CacheDir ${sidecar.spoolDir}/data\n" +
"PidFile ${sidecar.spoolDir}/nxlog.pid\n" +
"LogFile ${sidecar.spoolDir}/nxlog.log\n" +
"LogLevel INFO\n" +
"\n" +
"\n" +
Expand Down Expand Up @@ -217,7 +217,7 @@ public void upgrade() {
"C:\\Program Files (x86)\\nxlog\\nxlog.exe",
"-c \"%s\"",
"-v -f -c \"%s\"",
"define ROOT C:\\Program Files (x86)\\nxlog\n" +
"define ROOT ${sidecar.spoolDir}\\nxlog\n" +
"\n" +
"Moduledir %ROOT%\\modules\n" +
"CacheDir %ROOT%\\data\n" +
Expand Down Expand Up @@ -302,8 +302,8 @@ public void upgrade() {
"output.logstash:\n" +
" hosts: [\"192.168.1.1:5044\"]\n" +
"path:\n" +
" data: C:\\Program Files\\Graylog\\sidecar\\cache\\filebeat\\data\n" +
" logs: C:\\Program Files\\Graylog\\sidecar\\logs\n" +
" data: ${sidecar.spoolDir}\\data\n" +
" logs: ${sidecar.spoolDir}\\logs\n" +
"tags:\n" +
" - windows\n" +
"filebeat.inputs:\n" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.auto.value.AutoValue;

import javax.annotation.Nullable;

@AutoValue
@JsonAutoDetect
public abstract class CollectorStatus {
Expand All @@ -36,11 +38,16 @@ public abstract class CollectorStatus {
@JsonProperty("verbose_message")
public abstract String verboseMessage();

@JsonProperty("configuration_id")
@Nullable
public abstract String configurationId();

@JsonCreator
public static CollectorStatus create(@JsonProperty("collector_id") String collectorId,
@JsonProperty("status") int status,
@JsonProperty("message") String message,
@JsonProperty("verbose_message") String verboseMessage) {
return new AutoValue_CollectorStatus(collectorId, status, message, verboseMessage);
@JsonProperty("verbose_message") String verboseMessage,
@JsonProperty("configuration_id") @Nullable String configurationId) {
return new AutoValue_CollectorStatus(collectorId, status, message, verboseMessage, configurationId);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.mongojack.ObjectId;

import javax.annotation.Nullable;
import java.util.Set;

@AutoValue
@WithBeanGetter
Expand All @@ -35,6 +36,7 @@ public abstract class Configuration {
public static final String FIELD_NAME = "name";
public static final String FIELD_COLOR = "color";
public static final String FIELD_TEMPLATE = "template";
public static final String FIELD_TAGS = "tags";

@Id
@ObjectId
Expand All @@ -54,30 +56,37 @@ public abstract class Configuration {
@JsonProperty(FIELD_TEMPLATE)
public abstract String template();

@JsonProperty(FIELD_TAGS)
public abstract Set<String> tags();

@JsonCreator
public static Configuration create(@JsonProperty(FIELD_ID) String id,
@JsonProperty(FIELD_COLLECTOR_ID) String collectorId,
@JsonProperty(FIELD_NAME) String name,
@JsonProperty(FIELD_COLOR) String color,
@JsonProperty(FIELD_TEMPLATE) String template) {
@JsonProperty(FIELD_TEMPLATE) String template,
@JsonProperty(FIELD_TAGS) @Nullable Set<String> tags) {
return builder()
.id(id)
.collectorId(collectorId)
.name(name)
.color(color)
.template(template)
.tags(tags == null ? Set.of() : tags)
.build();
}

public static Configuration create(String collectorId,
String name,
String color,
String template) {
public static Configuration createWithoutId(String collectorId,
String name,
String color,
String template,
Set<String> tags) {
return create(new org.bson.types.ObjectId().toHexString(),
collectorId,
name,
color,
template);
template,
tags);
}

public static Builder builder() {
Expand All @@ -98,6 +107,8 @@ public abstract static class Builder {

public abstract Builder template(String template);

public abstract Builder tags(Set<String> tags);

public abstract Configuration build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import org.mongojack.Id;
import org.mongojack.ObjectId;

import java.util.Set;

@AutoValue
public abstract class ConfigurationSummary {
@JsonProperty("id")
Expand All @@ -38,20 +40,25 @@ public abstract class ConfigurationSummary {
@JsonProperty("color")
public abstract String color();

@JsonProperty("tags")
public abstract Set<String> tags();

@JsonCreator
public static ConfigurationSummary create(@JsonProperty("id") @Id @ObjectId String id,
@JsonProperty("name") String name,
@JsonProperty("collector_id") String collectorId,
@JsonProperty("color") String color) {
return new AutoValue_ConfigurationSummary(id, name, collectorId, color);
@JsonProperty("color") String color,
@JsonProperty("tags") Set<String> tags) {
return new AutoValue_ConfigurationSummary(id, name, collectorId, color, tags);
}

public static ConfigurationSummary create(Configuration configuration) {
return create(
configuration.id(),
configuration.name(),
configuration.collectorId(),
configuration.color());
configuration.color(),
configuration.tags());
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,19 @@

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.auto.value.AutoValue;

import javax.annotation.Nullable;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.List;
import java.util.Set;

@AutoValue
@JsonAutoDetect
@JsonIgnoreProperties(ignoreUnknown = true)
public abstract class NodeDetails {
@JsonProperty("operating_system")
@NotNull
Expand All @@ -50,12 +53,21 @@ public abstract class NodeDetails {
@Nullable
public abstract CollectorStatusList statusList();

@JsonProperty("tags")
public abstract Set<String> tags();

@JsonProperty("collector_configuration_directory")
@Nullable
public abstract String collectorConfigurationDirectory();

@JsonCreator
public static NodeDetails create(@JsonProperty("operating_system") String operatingSystem,
@JsonProperty("ip") @Nullable String ip,
@JsonProperty("metrics") @Nullable NodeMetrics metrics,
@JsonProperty("log_file_list") @Nullable List<NodeLogFile> logFileList,
@JsonProperty("status") @Nullable CollectorStatusList statusList) {
return new AutoValue_NodeDetails(operatingSystem, ip, metrics, logFileList, statusList);
@JsonProperty("status") @Nullable CollectorStatusList statusList,
@JsonProperty("tags") @Nullable Set<String> tags,
@JsonProperty("collector_configuration_directory") @Nullable String configDir) {
return new AutoValue_NodeDetails(operatingSystem, ip, metrics, logFileList, statusList, tags == null ? Set.of() : tags, configDir);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ public static Status fromString(String statusString) {
public abstract NodeDetails nodeDetails();

@JsonProperty
@Nullable
public abstract List<ConfigurationAssignment> assignments();

@JsonProperty
Expand Down Expand Up @@ -133,7 +132,7 @@ public static Sidecar create(@JsonProperty(FIELD_ID) @Id @ObjectId String id,
.nodeId(nodeId)
.nodeName(nodeName)
.nodeDetails(nodeDetails)
.assignments(assignments)
.assignments(assignments == null ? List.of() : assignments)
.sidecarVersion(sidecarVersion)
.lastSeen(lastSeen)
.build();
Expand All @@ -151,6 +150,7 @@ public static Sidecar create(@JsonProperty(FIELD_NODE_ID) String nodeId,
.nodeDetails(nodeDetails)
.sidecarVersion(sidecarVersion)
.lastSeen(DateTime.now(DateTimeZone.UTC))
.assignments(List.of())
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ public abstract class BulkActionRequest {
public abstract List<String> collectorIds();

@JsonCreator
public static BulkActionRequest create(@JsonProperty("sidecar_id") String collectorId,
public static BulkActionRequest create(@JsonProperty("sidecar_id") String sidecarId,
@JsonProperty("collector_ids") List<String> collectorIds) {
return new AutoValue_BulkActionRequest(collectorId, collectorIds);
return new AutoValue_BulkActionRequest(sidecarId, collectorIds);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.auto.value.AutoValue;

import javax.annotation.Nullable;
import java.util.Set;

@AutoValue
@JsonAutoDetect
public abstract class ConfigurationAssignment {
Expand All @@ -30,9 +33,13 @@ public abstract class ConfigurationAssignment {
@JsonProperty
public abstract String configurationId();

@JsonProperty
public abstract Set<String> assignedFromTags();

@JsonCreator
public static ConfigurationAssignment create(@JsonProperty("collector_id") String collectorId,
@JsonProperty("configuration_id") String configurationId) {
return new AutoValue_ConfigurationAssignment(collectorId, configurationId);
@JsonProperty("configuration_id") String configurationId,
@JsonProperty("assigned_from_tags") @Nullable Set<String> assignedFromTags) {
return new AutoValue_ConfigurationAssignment(collectorId, configurationId, assignedFromTags == null ? Set.of() : assignedFromTags);
}
}
Loading

0 comments on commit 2829a8b

Please sign in to comment.