Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
49a093e
feature: include support for labels in downsampling
salvatore-campagna Jun 8, 2022
d65790c
fix: add missing parent constructor call
salvatore-campagna Jun 15, 2022
4e81297
fix: add getter for label fields
salvatore-campagna Jun 15, 2022
6240a36
fix: collect last value for labels
salvatore-campagna Jun 21, 2022
d08c72e
fix: extract collection logic in Collectable interface
salvatore-campagna Jun 21, 2022
eab6819
fix: extract common metric and label logic in AbstractFieldProducer
salvatore-campagna Jun 21, 2022
c253102
comment: clarify comment about metrics vs labels usage
salvatore-campagna Jun 21, 2022
0084baf
fix: extract common collect method for labels and metrics
salvatore-campagna Jun 21, 2022
2115d3a
fix: introduce a FieldProducer interface
salvatore-campagna Jun 22, 2022
eb87a60
fix: use more descriptive exception message
salvatore-campagna Jun 22, 2022
cbd1d8b
fix: restore metric names
salvatore-campagna Jun 22, 2022
3f586ba
fix: use Sets.union instead of streams and collect
salvatore-campagna Jun 22, 2022
6c02521
fix: double instead of numeric
salvatore-campagna Jun 22, 2022
0413373
todo: boolean and other types like integer still do not work
salvatore-campagna Jun 22, 2022
698868b
fix: unit test Label collection
salvatore-campagna Jun 22, 2022
8458d5a
fix: code format violations
salvatore-campagna Jun 22, 2022
f6df2ca
fix: remove unused interface
salvatore-campagna Jun 22, 2022
d099317
fix: import code format violation
salvatore-campagna Jun 23, 2022
b76b5c7
fix: make 'label' field final
salvatore-campagna Jun 23, 2022
d9ec390
test: add more tests for different types
salvatore-campagna Jun 23, 2022
6b4b8d8
fix: now lables are rolledup too
salvatore-campagna Jun 23, 2022
ee46911
fix: use the correct DocValueFormat for each field
salvatore-campagna Jun 23, 2022
cab6597
fix: cannot compare a docuble counter to an integer
salvatore-campagna Jun 23, 2022
51dab01
fix: usage of forbidden api getHostAddress
salvatore-campagna Jun 23, 2022
2dc4d1c
fix: make boolean a valid type
salvatore-campagna Jun 23, 2022
c604c0a
fix: support booleans for label fields
salvatore-campagna Jun 23, 2022
26d67d2
test: test more label field types
salvatore-campagna Jun 23, 2022
1a2b6fc
fix: propagate additional field properties for labels
salvatore-campagna Jun 27, 2022
8fb5247
fix: do not use field caps for dimension fields
salvatore-campagna Jun 27, 2022
182cb7a
docs: fix javadoc after method signature change
salvatore-campagna Jun 27, 2022
83e244d
fix: extract duplicated code into method
salvatore-campagna Jun 27, 2022
8934188
fix: code format violation
salvatore-campagna Jun 27, 2022
8333e8a
fix: handle nested fields
salvatore-campagna Jun 27, 2022
5ef104b
fix: fetch source mappings just once
salvatore-campagna Jun 27, 2022
5b3b582
Merge branch 'master' into feature/downsampling-labels
salvatore-campagna Jun 27, 2022
466f851
fix: remove merge conflict markers
salvatore-campagna Jun 27, 2022
e889bda
fix: remove source index deletion check
salvatore-campagna Jun 27, 2022
b1dd837
fix: code format violations
salvatore-campagna Jun 27, 2022
63d0fce
fix: code style violations
salvatore-campagna Jun 27, 2022
257939b
fix: do not use field capabilities for metrics
salvatore-campagna Jun 28, 2022
2089dd0
fix: support multi value labels
salvatore-campagna Jun 28, 2022
0b2757b
fix: handle multi value labels
salvatore-campagna Jun 28, 2022
ddacd66
fix: use different labels values
salvatore-campagna Jun 28, 2022
04fd189
Merge branch 'master' into feature/downsampling-labels
elasticmachine Jun 28, 2022
a8e70b7
fix: check the field is not a metric field
salvatore-campagna Jun 29, 2022
0795c09
fix: improve index setting assertions
salvatore-campagna Jun 29, 2022
a85d3f1
fix: improve for loop
salvatore-campagna Jun 30, 2022
fa42616
fix: select the correct value for the @timestamp value
salvatore-campagna Jun 30, 2022
c84e90f
fix: get rid of field capabilities
salvatore-campagna Jun 30, 2022
e6eee3a
fix: use the same date format for the index start_time
salvatore-campagna Jun 30, 2022
40420e0
fix: use the same date format across time_series settings
salvatore-campagna Jun 30, 2022
a853130
fix: prevent a possible NullPointerException
salvatore-campagna Jun 30, 2022
db60214
Merge branch 'master' into feature/downsampling-labels
elasticmachine Jul 4, 2022
f34e666
fix: remove unused methods
salvatore-campagna Jul 4, 2022
7bdcbe9
fix: typo
salvatore-campagna Jul 5, 2022
dc5a148
fix: remove unused method parameter
salvatore-campagna Jul 5, 2022
c61d377
refactor: extract logic to identify time series field types
salvatore-campagna Jul 6, 2022
2d96533
fix: remove redundant public modifiers
salvatore-campagna Jul 6, 2022
1ab1e11
fix: remove FieldCapabilities from tests
salvatore-campagna Jul 6, 2022
c36a31c
fix: make class and interface package private and add javadoc
salvatore-campagna Jul 11, 2022
1108b40
fix: code format violations
salvatore-campagna Jul 11, 2022
71a7d94
test: collect unmapped labels
salvatore-campagna Jul 11, 2022
f0de8c8
fix: use top_hits for the metric last value
salvatore-campagna Jul 11, 2022
a7a6067
fix: remove stored field setter call
salvatore-campagna Jul 11, 2022
37ee629
Merge branch 'master' into feature/downsampling-labels
elasticmachine Jul 11, 2022
0e98d68
Merge branch 'master' into feature/downsampling-labels
salvatore-campagna Jul 13, 2022
bee0eea
fix: code format violations
salvatore-campagna Jul 13, 2022
c024d63
fix: remove Collectable interface
salvatore-campagna Jul 14, 2022
6c38dbd
Merge branch 'master' into feature/downsampling-labels
elasticmachine Jul 19, 2022
4b3b9be
fix: rename class
salvatore-campagna Jul 19, 2022
6355514
fix: improve java doc
salvatore-campagna Jul 19, 2022
e13c89a
fix: initialization already happens in the parent consructor
salvatore-campagna Jul 19, 2022
f106e69
fix: lazily compute field values
salvatore-campagna Jul 19, 2022
4d003b7
fix: trhow exception instead of passing failure handler
salvatore-campagna Jul 19, 2022
332692b
fix: use Set.of
salvatore-campagna Jul 19, 2022
ca5eb2d
fix: bump up skipped version to handle labels
salvatore-campagna Jul 19, 2022
5293c5c
fix: move classes to new package
salvatore-campagna Jul 19, 2022
723ae5e
fix: extract methods in assertRollupIndex
salvatore-campagna Jul 19, 2022
bddcec8
fix: typo in method name
salvatore-campagna Jul 19, 2022
1f0e80a
fix: remove incorrect exports
salvatore-campagna Jul 19, 2022
7424629
Revert "fix: move classes to new package"
salvatore-campagna Jul 19, 2022
1bab3c0
fix: helper class
salvatore-campagna Jul 19, 2022
ca7badb
fix: code format violations
salvatore-campagna Jul 19, 2022
d28db9e
fix: code format violations
salvatore-campagna Jul 19, 2022
31ee759
fix: suppress unchecked warning
salvatore-campagna Jul 19, 2022
594003f
fix: rename field to name
salvatore-campagna Jul 20, 2022
808758c
fix: rename field to name
salvatore-campagna Jul 20, 2022
a673369
fix: clarify skip reason
salvatore-campagna Jul 22, 2022
3972f79
fix: use the right variable ion the error message
salvatore-campagna Jul 22, 2022
00dae30
fix: use the log guard to avoid traces
salvatore-campagna Jul 22, 2022
aa8d3f3
Merge branch 'master' into feature/downsampling-labels
elasticmachine Jul 22, 2022
6b1440a
Merge remote-tracking branch 'origin/main' into feature/downsampling-…
salvatore-campagna Jul 25, 2022
e254486
fix: code format violations
salvatore-campagna Jul 25, 2022
2eec140
fix: datetime format
salvatore-campagna Jul 25, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,19 @@ public static class Request extends BroadcastRequest<Request> implements Indices
private RollupAction.Request rollupRequest;
private String[] dimensionFields;
private String[] metricFields;

public Request(RollupAction.Request rollupRequest, final String[] dimensionFields, final String[] metricFields) {
private String[] labelFields;

public Request(
RollupAction.Request rollupRequest,
final String[] dimensionFields,
final String[] metricFields,
final String[] labelFields
) {
super(rollupRequest.indices());
this.rollupRequest = rollupRequest;
this.dimensionFields = dimensionFields;
this.metricFields = metricFields;
this.labelFields = labelFields;
}

public Request() {}
Expand All @@ -58,6 +66,7 @@ public Request(StreamInput in) throws IOException {
this.rollupRequest = new RollupAction.Request(in);
this.dimensionFields = in.readStringArray();
this.metricFields = in.readStringArray();
this.labelFields = in.readStringArray();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

I think we don't need bwc here because this is behind a feature flag.

}

@Override
Expand All @@ -82,6 +91,10 @@ public String[] getMetricFields() {
return this.metricFields;
}

public String[] getLabelFields() {
return labelFields;
}

@Override
public Task createTask(long id, String type, String action, TaskId parentTaskId, Map<String, String> headers) {
return new RollupTask(id, type, action, parentTaskId, rollupRequest.getRollupIndex(), rollupRequest.getRollupConfig(), headers);
Expand All @@ -93,6 +106,7 @@ public void writeTo(StreamOutput out) throws IOException {
rollupRequest.writeTo(out);
out.writeStringArray(dimensionFields);
out.writeStringArray(metricFields);
out.writeStringArray(labelFields);
}

@Override
Expand All @@ -106,6 +120,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
builder.field("rollup_request", rollupRequest);
builder.array("dimension_fields", dimensionFields);
builder.array("metric_fields", metricFields);
builder.array("label_fields", labelFields);
builder.endObject();
return builder;
}
Expand All @@ -115,6 +130,7 @@ public int hashCode() {
int result = rollupRequest.hashCode();
result = 31 * result + Arrays.hashCode(dimensionFields);
result = 31 * result + Arrays.hashCode(metricFields);
result = 31 * result + Arrays.hashCode(labelFields);
return result;
}

Expand All @@ -125,6 +141,7 @@ public boolean equals(Object o) {
Request request = (Request) o;
if (rollupRequest.equals(request.rollupRequest) == false) return false;
if (Arrays.equals(dimensionFields, request.dimensionFields) == false) return false;
if (Arrays.equals(labelFields, request.labelFields) == false) return false;
return Arrays.equals(metricFields, request.metricFields);
}
}
Expand Down Expand Up @@ -225,6 +242,10 @@ public String[] getMetricFields() {
return request.getMetricFields();
}

public String[] getLabelFields() {
return request.getLabelFields();
}

@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
setup:
- skip:
version: " - 8.2.99"
reason: tsdb indexing changed in 8.3.0
version: " - 8.3.99"
reason: "rollup: labels support added in 8.4.0"

- do:
indices.create:
Expand Down Expand Up @@ -32,8 +32,18 @@ setup:
time_series_dimension: true
name:
type: keyword
created_at:
type: date_nanos
running:
type: boolean
number_of_containers:
type: integer
ip:
type: ip
tags:
type: keyword
values:
type: integer
network:
properties:
tx:
Expand All @@ -48,21 +58,21 @@ setup:
index: test
body:
- '{"index": {}}'
- '{"@timestamp": "2021-04-28T18:50:04.467Z", "metricset": "pod", "k8s": {"pod": {"name": "cat", "uid":"947e4ced-1786-4e53-9e0c-5c447e959507", "ip": "10.10.55.1", "network": {"tx": 2001818691, "rx": 802133794}}}}'
- '{"@timestamp": "2021-04-28T18:50:04.467Z", "metricset": "pod", "k8s": {"pod": {"name": "cat", "uid":"947e4ced-1786-4e53-9e0c-5c447e959507", "ip": "10.10.55.1", "network": {"tx": 2001818691, "rx": 802133794}, "created_at": "2021-04-28T19:34:00.000Z", "running": false, "number_of_containers": 2, "tags": ["backend", "prod"], "values": [2, 3, 6]}}}'
- '{"index": {}}'
- '{"@timestamp": "2021-04-28T18:50:24.467Z", "metricset": "pod", "k8s": {"pod": {"name": "cat", "uid":"947e4ced-1786-4e53-9e0c-5c447e959507", "ip": "10.10.55.1", "network": {"tx": 2005177954, "rx": 801479970}}}}'
- '{"@timestamp": "2021-04-28T18:50:24.467Z", "metricset": "pod", "k8s": {"pod": {"name": "cat", "uid":"947e4ced-1786-4e53-9e0c-5c447e959507", "ip": "10.10.55.26", "network": {"tx": 2005177954, "rx": 801479970}, "created_at": "2021-04-28T19:35:00.000Z", "running": true, "number_of_containers": 2, "tags": ["backend", "prod", "us-west1"], "values": [1, 1, 3]}}}'
- '{"index": {}}'
- '{"@timestamp": "2021-04-28T20:50:44.467Z", "metricset": "pod", "k8s": {"pod": {"name": "cat", "uid":"947e4ced-1786-4e53-9e0c-5c447e959507", "ip": "10.10.55.1", "network": {"tx": 2006223737, "rx": 802337279}}}}'
- '{"@timestamp": "2021-04-28T20:50:44.467Z", "metricset": "pod", "k8s": {"pod": {"name": "cat", "uid":"947e4ced-1786-4e53-9e0c-5c447e959507", "ip": "10.10.55.41", "network": {"tx": 2006223737, "rx": 802337279}, "created_at": "2021-04-28T19:36:00.000Z", "running": true, "number_of_containers": 2, "tags": ["backend", "prod", "us-west2"], "values": [4, 1, 2]}}}'
- '{"index": {}}'
- '{"@timestamp": "2021-04-28T20:51:04.467Z", "metricset": "pod", "k8s": {"pod": {"name": "cat", "uid":"947e4ced-1786-4e53-9e0c-5c447e959507", "ip": "10.10.55.2", "network": {"tx": 2012916202, "rx": 803685721}}}}'
- '{"@timestamp": "2021-04-28T20:51:04.467Z", "metricset": "pod", "k8s": {"pod": {"name": "cat", "uid":"947e4ced-1786-4e53-9e0c-5c447e959507", "ip": "10.10.55.22", "network": {"tx": 2012916202, "rx": 803685721}, "created_at": "2021-04-28T19:37:00.000Z", "running": true, "number_of_containers": 2, "tags": ["backend", "prod"], "values": [2, 3, 1]}}}'
- '{"index": {}}'
- '{"@timestamp": "2021-04-28T18:50:03.142Z", "metricset": "pod", "k8s": {"pod": {"name": "dog", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876ea9", "ip": "10.10.55.3", "network": {"tx": 1434521831, "rx": 530575198}}}}'
- '{"@timestamp": "2021-04-28T18:50:03.142Z", "metricset": "pod", "k8s": {"pod": {"name": "dog", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876ea9", "ip": "10.10.55.33", "network": {"tx": 1434521831, "rx": 530575198}, "created_at": "2021-04-28T19:42:00.000Z", "running": false, "number_of_containers": 1, "tags": ["backend", "test"], "values": [2, 3, 4]}}}'
- '{"index": {}}'
- '{"@timestamp": "2021-04-28T18:50:23.142Z", "metricset": "pod", "k8s": {"pod": {"name": "dog", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876ea9", "ip": "10.10.55.3", "network": {"tx": 1434577921, "rx": 530600088}}}}'
- '{"@timestamp": "2021-04-28T18:50:23.142Z", "metricset": "pod", "k8s": {"pod": {"name": "dog", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876ea9", "ip": "10.10.55.56", "network": {"tx": 1434577921, "rx": 530600088}, "created_at": "2021-04-28T19:43:00.000Z", "running": false, "number_of_containers": 1, "tags": ["backend", "test", "us-west2"], "values": [2, 1, 1]}}}'
- '{"index": {}}'
- '{"@timestamp": "2021-04-28T19:50:53.142Z", "metricset": "pod", "k8s": {"pod": {"name": "dog", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876ea9", "ip": "10.10.55.3", "network": {"tx": 1434587694, "rx": 530604797}}}}'
- '{"@timestamp": "2021-04-28T19:50:53.142Z", "metricset": "pod", "k8s": {"pod": {"name": "dog", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876ea9", "ip": "10.10.55.37", "network": {"tx": 1434587694, "rx": 530604797}, "created_at": "2021-04-28T19:44:00.000Z", "running": true, "number_of_containers": 1, "tags": ["backend", "test", "us-west1"], "values": [4, 5, 2]}}}'
- '{"index": {}}'
- '{"@timestamp": "2021-04-28T19:51:03.142Z", "metricset": "pod", "k8s": {"pod": {"name": "dog", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876ea9", "ip": "10.10.55.3", "network": {"tx": 1434595272, "rx": 530605511}}}}'
- '{"@timestamp": "2021-04-28T19:51:03.142Z", "metricset": "pod", "k8s": {"pod": {"name": "dog", "uid":"df3145b3-0563-4d3b-a0f7-897eb2876ea9", "ip": "10.10.55.120", "network": {"tx": 1434595272, "rx": 530605511}, "created_at": "2021-04-28T19:45:00.000Z", "running": true, "number_of_containers": 1, "tags": ["backend", "test", "us-west1"], "values": [3, 2, 1]}}}'

- do:
indices.put_settings:
Expand Down Expand Up @@ -99,7 +109,12 @@ setup:
- match: { hits.hits.0._source.k8s\.pod\.network\.tx.min: 2001818691 }
- match: { hits.hits.0._source.k8s\.pod\.network\.tx.max: 2005177954 }
- match: { hits.hits.0._source.k8s\.pod\.network\.tx.value_count: 2 }
- is_false: hits.hits.0._source.k8s\.pod\.ip # k8s.pod.ip isn't a dimension and is not rolled up
- match: { hits.hits.0._source.k8s\.pod\.ip: "10.10.55.26" }
- match: { hits.hits.0._source.k8s\.pod\.created_at: "2021-04-28T19:35:00.000Z" }
- match: { hits.hits.0._source.k8s\.pod\.number_of_containers: 2 }
- match: { hits.hits.0._source.k8s\.pod\.tags: ["backend", "prod", "us-west1"] }
- match: { hits.hits.0._source.k8s\.pod\.values: [1, 1, 3] }
- is_true: hits.hits.0._source.k8s\.pod\.running

# Assert rollup index settings
- do:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

package org.elasticsearch.xpack.rollup.v2;

/**
* Base class for classes that read metric and label fields.
*/
abstract class AbstractRollupFieldProducer<T> {

protected final String name;
protected boolean isEmpty;

AbstractRollupFieldProducer(String name) {
this.name = name;
this.isEmpty = true;
}

/**
* Collect a value for the field applying the specific subclass collection strategy.
* @param value the value to collect.
*/
public abstract void collect(T value);

/**
* @return the name of the field.
*/
public String name() {
return name;
}

/**
* @return the value of the field.
*/
public abstract Object value();

/**
* Resets the collected value to the specific subclass reset value.
*/
public abstract void reset();

/**
* @return true if the field has not collected any value.
*/
public boolean isEmpty() {
return isEmpty;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
Expand All @@ -30,8 +28,20 @@
*/
class FieldValueFetcher {

private static final Set<Class<?>> VALID_TYPES = Collections.unmodifiableSet(
new HashSet<>(Arrays.asList(Long.class, Double.class, BigInteger.class, String.class, BytesRef.class))
private static final Set<Class<?>> VALID_METRIC_TYPES = Set.of(
Long.class,
Double.class,
BigInteger.class,
String.class,
BytesRef.class
);
private static final Set<Class<?>> VALID_LABEL_TYPES = Set.of(
Long.class,
Double.class,
BigInteger.class,
String.class,
BytesRef.class,
Boolean.class
);

private final String name;
Expand Down Expand Up @@ -66,7 +76,7 @@ public IndexFieldData<?> fieldData() {

FormattedDocValues getLeaf(LeafReaderContext context) {

final FormattedDocValues delegate = fieldData.load(context).getFormattedValues(DocValueFormat.RAW);
final FormattedDocValues delegate = fieldData.load(context).getFormattedValues(format);
return new FormattedDocValues() {
@Override
public boolean advanceExact(int docId) throws IOException {
Expand Down Expand Up @@ -102,28 +112,36 @@ Object format(Object value) {
/**
* Retrieve field fetchers for a list of fields.
*/
static List<FieldValueFetcher> build(SearchExecutionContext context, String[] fields) {
private static List<FieldValueFetcher> build(SearchExecutionContext context, String[] fields, Set<Class<?>> validTypes) {
List<FieldValueFetcher> fetchers = new ArrayList<>(fields.length);
for (String field : fields) {
MappedFieldType fieldType = context.getFieldType(field);
if (fieldType == null) {
throw new IllegalArgumentException("Unknown field: [" + field + "]");
}
IndexFieldData<?> fieldData = context.getForField(fieldType);
fetchers.add(new FieldValueFetcher(field, fieldType, fieldData, getValidator(field)));
fetchers.add(new FieldValueFetcher(field, fieldType, fieldData, getValidator(field, validTypes)));
}
return Collections.unmodifiableList(fetchers);
}

static Function<Object, Object> getValidator(String field) {
static Function<Object, Object> getValidator(String field, Set<Class<?>> validTypes) {
return value -> {
if (VALID_TYPES.contains(value.getClass()) == false) {
if (validTypes.contains(value.getClass()) == false) {
throw new IllegalArgumentException(
"Expected [" + VALID_TYPES + "] for field [" + field + "], " + "got [" + value.getClass() + "]"
"Expected [" + validTypes + "] for field [" + field + "], " + "got [" + value.getClass() + "]"
);
}
return value;
};
}

static List<FieldValueFetcher> forMetrics(SearchExecutionContext context, String[] metricFields) {
return build(context, metricFields, VALID_METRIC_TYPES);
}

static List<FieldValueFetcher> forLabels(SearchExecutionContext context, String[] labelFields) {
return build(context, labelFields, VALID_LABEL_TYPES);
}

}
Loading