mirror of
https://github.com/NationalSecurityAgency/timely.git
synced 2026-11-10 11:51:29 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1597ec61ae |
No files matched your search
@@ -4,7 +4,6 @@ if [[ $(uname) == "Darwin" ]]; then
|
||||
THIS_SCRIPT=$(python -c 'import os,sys; print os.path.realpath(sys.argv[1])' "$0")
|
||||
else
|
||||
THIS_SCRIPT=$(readlink -f "$0")
|
||||
TCNATIVE_SUFFIX="so"
|
||||
HW=`uname -m`
|
||||
OS_PATH=linux-${HW}
|
||||
fi
|
||||
@@ -56,8 +55,8 @@ if [ "$PID" == "" ]; then
|
||||
|
||||
if [[ -n "$OS_PATH" ]]; then
|
||||
pushd "${BASE_DIR}/bin" || exit
|
||||
"${JAVA_HOME}"/bin/jar xf "${LIB_DIR}"/netty-tcnative-boringssl-static-*.Final-"${OS_PATH}".jar META-INF/native/libnetty_tcnative_linux_"${HW}".so
|
||||
"${JAVA_HOME}"/bin/jar xf "${LIB_DIR}"/netty-transport-native-epoll-*-"${OS_PATH}".jar META-INF/native/libnetty_transport_native_epoll_"${HW}".so
|
||||
"${JAVA_HOME}"/bin/jar xf "${LIB_DIR}"/netty-tcnative-boringssl-static-*.Final-"${OS_PATH}".jar ${NATIVE_DIR}/libnetty_tcnative_linux_"${HW}".so
|
||||
"${JAVA_HOME}"/bin/jar xf "${LIB_DIR}"/netty-transport-native-epoll-*-"${OS_PATH}".jar ${NATIVE_DIR}/libnetty_transport_native_epoll_"${HW}".so
|
||||
popd || exit
|
||||
JVM_ARGS="${JVM_ARGS} -Djava.library.path=${NATIVE_DIR}"
|
||||
fi
|
||||
|
||||
+21
-5
@@ -118,11 +118,27 @@ public abstract class CollectDPluginParent {
|
||||
String instance = null;
|
||||
if (!typeInstance.startsWith("nsq")) {
|
||||
String[] parts = typeInstance.split("\\.");
|
||||
if (parts.length % 2 == 1) {
|
||||
// EtsyStatsD format -- metric.(tagName.tagValue)*
|
||||
metric.append(STATSD_PREFIX).append(PERIOD).append(parts[0]);
|
||||
for (int x = 1; x < parts.length; x += 2) {
|
||||
addTag(tagMap, parts[x], parts[x + 1]);
|
||||
if (parts.length % 2 == 1 && parts.length >= 3) {
|
||||
switch(parts[0]) {
|
||||
case "dwingest":
|
||||
if (parts.length >= 4) {
|
||||
metric.append(STATSD_PREFIX).append(PERIOD).append(parts[1]).append(PERIOD).append(parts[3]);
|
||||
instance = parts[0];
|
||||
}
|
||||
break;
|
||||
case "dwquery":
|
||||
if (parts.length >= 4) {
|
||||
metric.append(STATSD_PREFIX).append(PERIOD).append(parts[1]).append(PERIOD).append(parts[3]);
|
||||
addTag(tagMap, "queryId", parts[0]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// EtsyStatsD format -- metric.(tagName.tagValue)*
|
||||
metric.append(STATSD_PREFIX).append(PERIOD).append(parts[0]);
|
||||
for (int x = 1; x < parts.length; x += 2) {
|
||||
addTag(tagMap, parts[x], parts[x + 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (statsd_4_groups.matches()) {
|
||||
// Here we are processing the statsd metrics coming from the Hadoop Metrics2 StatsDSink without the host name.
|
||||
|
||||
@@ -32,6 +32,7 @@ public class QueryRequest extends AuthenticatedRequest implements HttpGetRequest
|
||||
private boolean counter = false;
|
||||
private long counterMax = 0;
|
||||
private long resetValue = 0;
|
||||
private Optional<String> interval = Optional.empty();
|
||||
|
||||
public RateOption() {}
|
||||
|
||||
@@ -84,12 +85,21 @@ public class QueryRequest extends AuthenticatedRequest implements HttpGetRequest
|
||||
this.resetValue = resetValue;
|
||||
}
|
||||
|
||||
public Optional<String> getInterval() {
|
||||
return interval;
|
||||
}
|
||||
|
||||
public void setInterval(Optional<String> interval) {
|
||||
this.interval = interval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
ToStringBuilder tsb = new ToStringBuilder(this);
|
||||
tsb.append("counter", counter);
|
||||
tsb.append("counterMax", counterMax);
|
||||
tsb.append("resetValue", resetValue);
|
||||
tsb.append("interval", interval);
|
||||
return tsb.toString();
|
||||
}
|
||||
|
||||
@@ -99,6 +109,7 @@ public class QueryRequest extends AuthenticatedRequest implements HttpGetRequest
|
||||
hcb.append(counter);
|
||||
hcb.append(counterMax);
|
||||
hcb.append(resetValue);
|
||||
hcb.append(interval);
|
||||
return hcb.toHashCode();
|
||||
}
|
||||
|
||||
@@ -536,9 +547,12 @@ public class QueryRequest extends AuthenticatedRequest implements HttpGetRequest
|
||||
options.setCounter(rateOptions[x].endsWith("counter"));
|
||||
break;
|
||||
case 1:
|
||||
options.setCounterMax(Long.parseLong(rateOptions[x]));
|
||||
options.setInterval(Optional.of(rateOptions[x]));
|
||||
break;
|
||||
case 2:
|
||||
options.setCounterMax(Long.parseLong(rateOptions[x]));
|
||||
break;
|
||||
case 3:
|
||||
options.setResetValue(Long.parseLong(rateOptions[x]));
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -1,11 +1,96 @@
|
||||
module github.com/NationalSecurityAgency/timely-datasource
|
||||
|
||||
go 1.14
|
||||
go 1.21
|
||||
|
||||
toolchain go1.22.1
|
||||
|
||||
require (
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.111.0
|
||||
github.com/hashicorp/go-hclog v0.16.1
|
||||
github.com/mattn/go-colorable v0.1.6 // indirect
|
||||
github.com/prometheus/common v0.29.0 // indirect
|
||||
golang.org/x/net v0.17.0 // indirect
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.218.0
|
||||
github.com/hashicorp/go-hclog v1.6.2
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.3.2 // indirect
|
||||
github.com/apache/arrow/go/v15 v15.0.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/cheekybits/genny v1.0.0 // indirect
|
||||
github.com/chromedp/cdproto v0.0.0-20220208224320-6efb837e6bc2 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||
github.com/elazarl/goproxy v0.0.0-20230731152917-f99041a5c027 // indirect
|
||||
github.com/fatih/color v1.15.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
||||
github.com/getkin/kin-openapi v0.120.0 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
||||
github.com/go-openapi/swag v0.22.4 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/google/flatbuffers v23.5.26+incompatible // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gorilla/mux v1.8.0 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect
|
||||
github.com/hashicorp/go-plugin v1.6.0 // indirect
|
||||
github.com/hashicorp/yamux v0.1.1 // indirect
|
||||
github.com/invopop/yaml v0.2.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.16.7 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
|
||||
github.com/magefile/mage v1.15.0 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattetti/filebuffer v1.0.1 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.9 // indirect
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
|
||||
github.com/oklog/run v1.1.0 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/perimeterx/marshmallow v1.1.5 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.18 // indirect
|
||||
github.com/prometheus/client_golang v1.18.0 // indirect
|
||||
github.com/prometheus/client_model v0.5.0 // indirect
|
||||
github.com/prometheus/common v0.46.0 // indirect
|
||||
github.com/prometheus/procfs v0.12.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/smartystreets/goconvey v1.6.4 // indirect
|
||||
github.com/unknwon/bra v0.0.0-20200517080246-1e3013ecaff8 // indirect
|
||||
github.com/unknwon/com v1.0.1 // indirect
|
||||
github.com/unknwon/log v0.0.0-20150304194804-e617c87089d3 // indirect
|
||||
github.com/urfave/cli v1.22.14 // indirect
|
||||
github.com/zeebo/xxh3 v1.0.2 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.49.0 // indirect
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.22.0 // indirect
|
||||
go.opentelemetry.io/contrib/samplers/jaegerremote v0.18.0 // indirect
|
||||
go.opentelemetry.io/otel v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.1.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
|
||||
golang.org/x/mod v0.13.0 // indirect
|
||||
golang.org/x/net v0.22.0 // indirect
|
||||
golang.org/x/sys v0.18.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/tools v0.14.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect
|
||||
google.golang.org/grpc v1.62.1 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
+229
-642
File diff suppressed because it is too large.
Load diff
@@ -398,6 +398,13 @@ func (td *TimelyDatasource) convertTimelyQuery(timelyQueryForm *TimelyQueryForm)
|
||||
timelyQuery.RateOptions.Counter = timelyQueryForm.IsCounter
|
||||
}
|
||||
|
||||
if len(timelyQueryForm.RateInterval) > 0 {
|
||||
rateInterval, error := strconv.ParseInt(timelyQueryForm.RateInterval, 10, 32)
|
||||
if error == nil {
|
||||
timelyQuery.RateOptions.Interval = int32(rateInterval)
|
||||
}
|
||||
}
|
||||
|
||||
if len(timelyQueryForm.CounterMax) > 0 {
|
||||
counterMax, error := strconv.ParseInt(timelyQueryForm.CounterMax, 10, 32)
|
||||
if error == nil {
|
||||
|
||||
@@ -11,6 +11,7 @@ type TimelyQueryForm struct {
|
||||
Tags map[string]string `json:"tags"`
|
||||
Filters []Filter `json:"filters"`
|
||||
ShouldComputeRate bool `json:"shouldComputeRate"`
|
||||
RateInterval string `json:"rateInterval"`
|
||||
IsCounter bool `json:"isCounter"`
|
||||
CounterMax string `json:"counterMax"`
|
||||
CounterResetValue string `json:"counterResetValue"`
|
||||
@@ -34,6 +35,7 @@ type TimelyQueryServer struct {
|
||||
Tags map[string]string `json:"tags"`
|
||||
Filters []Filter `json:"filters"`
|
||||
ShouldComputeRate bool `json:"shouldComputeRate"`
|
||||
RateInterval string `json:"rateInterval"`
|
||||
IsCounter bool `json:"isCounter"`
|
||||
CounterMax string `json:"counterMax"`
|
||||
CounterResetValue string `json:"counterResetValue"`
|
||||
@@ -50,6 +52,7 @@ type Filter struct {
|
||||
}
|
||||
|
||||
type RateOptions struct {
|
||||
Interval int32 `json:"interval"`
|
||||
Counter bool `json:"counter"`
|
||||
CounterMax int32 `json:"counterMax"`
|
||||
ResetValue int32 `json:"resetValue"`
|
||||
@@ -96,4 +99,4 @@ type TimelyErrorResponse struct {
|
||||
ResponseCode int32 `json:responseCode`
|
||||
Message string `json:message`
|
||||
DetailMessage string `json:detailMessage`
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,7 @@ export class QueryEditor extends Component<Props, State> {
|
||||
downsampleInterval: '1m',
|
||||
downsampleAggregator: 'avg',
|
||||
shouldComputeRate: false,
|
||||
rateInterval: '1m',
|
||||
isCounter: false,
|
||||
tags: {},
|
||||
};
|
||||
@@ -123,6 +124,15 @@ export class QueryEditor extends Component<Props, State> {
|
||||
});
|
||||
};
|
||||
|
||||
onRateIntervalChange = (option: React.FormEvent<HTMLInputElement>) => {
|
||||
const value = e.target.value;
|
||||
this.setState((state, props) => {
|
||||
var query = Object.assign(state.query, { rateInterval: value });
|
||||
this.updateQuery(query);
|
||||
return { query: query };
|
||||
});
|
||||
};
|
||||
|
||||
onCounterChange = (option: React.FormEvent<HTMLInputElement>) => {
|
||||
const checked = option.currentTarget.checked;
|
||||
this.setState((state, props) => {
|
||||
@@ -247,7 +257,7 @@ export class QueryEditor extends Component<Props, State> {
|
||||
const { metric, aggregator, alias } = this.state.query;
|
||||
const { downsampleInterval, downsampleAggregator, disableDownsampling } = this.state.query;
|
||||
const { tags } = this.state.query;
|
||||
const { shouldComputeRate, isCounter, counterResetValue, counterMax } = this.state.query;
|
||||
const { shouldComputeRate, rateInterval, isCounter, counterResetValue, counterMax } = this.state.query;
|
||||
const aggregatorOptions: Array<{}> = _.map(this.state.aggregatorTypes, (value: string) => ({
|
||||
label: value,
|
||||
value: value,
|
||||
@@ -345,7 +355,7 @@ export class QueryEditor extends Component<Props, State> {
|
||||
spellCheck={false}
|
||||
value={downsampleInterval || ''}
|
||||
onChange={this.onDownsampleChange}
|
||||
placeholder={'interval'}
|
||||
placeholder={'downsample interval'}
|
||||
/>
|
||||
</div>
|
||||
<div className="gf-form timely">
|
||||
@@ -390,6 +400,13 @@ export class QueryEditor extends Component<Props, State> {
|
||||
onChange={this.onRateChange}
|
||||
/>
|
||||
<div hidden={!shouldComputeRate}>
|
||||
<Input
|
||||
className={'min-width-6 flex-grow-1'}
|
||||
spellCheck={false}
|
||||
value={rateInterval || ''}
|
||||
onChange={this.onRateIntervalChange}
|
||||
placeholder={'rate interval'}
|
||||
/>
|
||||
<Switch
|
||||
label={'Counter'}
|
||||
labelClass="width-10"
|
||||
|
||||
@@ -9,6 +9,7 @@ export interface TimelyQueryForm extends DataQuery {
|
||||
downsampleAggregator?: string;
|
||||
tags: { [key: string]: string };
|
||||
shouldComputeRate?: boolean;
|
||||
rateInterval?: string;
|
||||
isCounter?: boolean;
|
||||
counterMax?: string;
|
||||
counterResetValue?: string;
|
||||
|
||||
@@ -4,7 +4,6 @@ if [[ $(uname) == "Darwin" ]]; then
|
||||
THIS_SCRIPT=$(python -c 'import os,sys; print os.path.realpath(sys.argv[1])' "$0")
|
||||
else
|
||||
THIS_SCRIPT=$(readlink -f "$0")
|
||||
TCNATIVE_SUFFIX="so"
|
||||
HW=`uname -m`
|
||||
OS_PATH=linux-${HW}
|
||||
fi
|
||||
@@ -56,8 +55,8 @@ if [ "$PID" == "" ]; then
|
||||
|
||||
if [[ -n "$OS_PATH" ]]; then
|
||||
pushd "${BASE_DIR}/bin" || exit
|
||||
"${JAVA_HOME}"/bin/jar xf "${LIB_DIR}"/netty-tcnative-boringssl-static-*-"${OS_PATH}".jar META-INF/native/libnetty_tcnative_linux_"${HW}".so
|
||||
"${JAVA_HOME}"/bin/jar xf "${LIB_DIR}"/netty-transport-native-epoll-*-"${OS_PATH}".jar META-INF/native/libnetty_transport_native_epoll_"${HW}".so
|
||||
"${JAVA_HOME}"/bin/jar xf "${LIB_DIR}"/netty-tcnative-boringssl-static-*-"${OS_PATH}".jar ${NATIVE_DIR}/libnetty_tcnative_linux_"${HW}".so
|
||||
"${JAVA_HOME}"/bin/jar xf "${LIB_DIR}"/netty-transport-native-epoll-*-"${OS_PATH}".jar ${NATIVE_DIR}/libnetty_transport_native_epoll_"${HW}".so
|
||||
popd || exit
|
||||
JVM_ARGS="${JVM_ARGS} -Djava.library.path=${NATIVE_DIR}"
|
||||
fi
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [[ `uname` == "Darwin" ]]; then
|
||||
THIS_SCRIPT=`python -c 'import os,sys; print os.path.realpath(sys.argv[1])' $0`
|
||||
THIS_SCRIPT=`python -c 'import os,sys; print os.path.realpath(sys.argv[1])' $0`
|
||||
else
|
||||
THIS_SCRIPT=`readlink -f $0`
|
||||
THIS_SCRIPT=`readlink -f $0`
|
||||
HW=`uname -m`
|
||||
OS_PATH=linux-${HW}
|
||||
fi
|
||||
|
||||
export INSTANCE="1"
|
||||
@@ -23,5 +25,13 @@ JVM_ARGS="-Xmx256m -Xms128m"
|
||||
JVM_ARGS="${JVM_ARGS} -Dlogging.config=${CONF_DIR}/log4j2-console.yml"
|
||||
JVM_ARGS="${JVM_ARGS} -Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector"
|
||||
|
||||
if [[ -n "$OS_PATH" ]]; then
|
||||
pushd "${BASE_DIR}/bin" || exit
|
||||
"${JAVA_HOME}"/bin/jar xf "${LIB_DIR}"/netty-tcnative-boringssl-static-*.Final-"${OS_PATH}".jar ${NATIVE_DIR}/libnetty_tcnative_linux_"${HW}".so
|
||||
"${JAVA_HOME}"/bin/jar xf "${LIB_DIR}"/netty-transport-native-epoll-*-"${OS_PATH}".jar ${NATIVE_DIR}/libnetty_transport_native_epoll_"${HW}".so
|
||||
popd || exit
|
||||
JVM_ARGS="${JVM_ARGS} -Djava.library.path=${NATIVE_DIR}"
|
||||
fi
|
||||
|
||||
echo "$JAVA_HOME/bin/java ${JVM_ARGS} -jar ${BIN_DIR}/timely-server*-exec.jar metrics"
|
||||
$JAVA_HOME/bin/java ${JVM_ARGS} -jar ${BIN_DIR}/timely-server-*-exec.jar metrics
|
||||
@@ -1,9 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [[ `uname` == "Darwin" ]]; then
|
||||
THIS_SCRIPT=`python -c 'import os,sys; print os.path.realpath(sys.argv[1])' $0`
|
||||
THIS_SCRIPT=`python -c 'import os,sys; print os.path.realpath(sys.argv[1])' $0`
|
||||
else
|
||||
THIS_SCRIPT=`readlink -f $0`
|
||||
THIS_SCRIPT=`readlink -f $0`
|
||||
HW=`uname -m`
|
||||
OS_PATH=linux-${HW}
|
||||
fi
|
||||
|
||||
export INSTANCE="1"
|
||||
@@ -23,5 +25,13 @@ JVM_ARGS="-Xmx1024m -Xms128m"
|
||||
JVM_ARGS="${JVM_ARGS} -Dlogging.config=${CONF_DIR}/log4j2-console.yml"
|
||||
JVM_ARGS="${JVM_ARGS} -Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector"
|
||||
|
||||
if [[ -n "$OS_PATH" ]]; then
|
||||
pushd "${BASE_DIR}/bin" || exit
|
||||
"${JAVA_HOME}"/bin/jar xf "${LIB_DIR}"/netty-tcnative-boringssl-static-*.Final-"${OS_PATH}".jar ${NATIVE_DIR}/libnetty_tcnative_linux_"${HW}".so
|
||||
"${JAVA_HOME}"/bin/jar xf "${LIB_DIR}"/netty-transport-native-epoll-*-"${OS_PATH}".jar ${NATIVE_DIR}/libnetty_transport_native_epoll_"${HW}".so
|
||||
popd || exit
|
||||
JVM_ARGS="${JVM_ARGS} -Djava.library.path=${NATIVE_DIR}"
|
||||
fi
|
||||
|
||||
echo "$JAVA_HOME/bin/java ${JVM_ARGS} -jar ${BIN_DIR}/timely-server*-exec.jar tablet --spring.profiles.active=timely,tablet"
|
||||
$JAVA_HOME/bin/java ${JVM_ARGS} -jar ${BIN_DIR}/timely-server-*-exec.jar tablet --spring.profiles.active=timely,tablet
|
||||
@@ -1,5 +1,7 @@
|
||||
package timely.server.sample.iterators;
|
||||
|
||||
import static org.apache.accumulo.core.conf.ConfigurationTypeHelper.getTimeInMillis;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
@@ -20,12 +22,14 @@ import timely.api.request.timeseries.QueryRequest;
|
||||
public class RateIterator extends TimeSeriesGroupingIterator {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(RateIterator.class);
|
||||
private static final String COUNTER_MAX = "rate.counter.max";
|
||||
private static final String RATE_RESET_VALUE = "rate.reset.value";
|
||||
public static final String COUNTER_MAX = "rate.counter.max";
|
||||
public static final String RATE_RESET_VALUE = "rate.reset.value";
|
||||
public static final String RATE_INTERVAL = "rate.interval";
|
||||
|
||||
private boolean isCounter = false;
|
||||
private long maxCounter = 0;
|
||||
private long resetValue = 0;
|
||||
private long interval = 1;
|
||||
|
||||
public static void setRateOptions(IteratorSetting is, QueryRequest.RateOption options) {
|
||||
if (options != null && options.isCounter()) {
|
||||
@@ -33,6 +37,11 @@ public class RateIterator extends TimeSeriesGroupingIterator {
|
||||
is.addOption(COUNTER_MAX, Long.toString(options.getCounterMax()));
|
||||
is.addOption(RATE_RESET_VALUE, Long.toString(options.getResetValue()));
|
||||
}
|
||||
if (options != null && options.getInterval().isPresent()) {
|
||||
is.addOption(RATE_INTERVAL, Long.toString(getTimeInMillis(options.getInterval().get())));
|
||||
} else {
|
||||
is.addOption(RATE_INTERVAL, "1");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -41,8 +50,11 @@ public class RateIterator extends TimeSeriesGroupingIterator {
|
||||
this.isCounter = true;
|
||||
this.maxCounter = Long.parseLong(options.get(COUNTER_MAX));
|
||||
this.resetValue = Long.parseLong(options.get(RATE_RESET_VALUE));
|
||||
log.trace("Setting rate counter options cm:{}, rv:{}", this.maxCounter, this.resetValue);
|
||||
}
|
||||
if (options.containsKey(RATE_INTERVAL)) {
|
||||
this.interval = Long.parseLong(options.get(RATE_INTERVAL));
|
||||
}
|
||||
log.trace("Setting rate options interval:{} isCounter:{} cm:{}, rv:{}", this.interval, this.isCounter, this.maxCounter, this.resetValue);
|
||||
Map<String,String> opts = new HashMap<>(options);
|
||||
opts.put(FILTER, "-1,1");
|
||||
super.init(source, opts, env);
|
||||
@@ -76,7 +88,9 @@ public class RateIterator extends TimeSeriesGroupingIterator {
|
||||
if (timeDiff == 0) {
|
||||
return 0.0D;
|
||||
}
|
||||
Double result = ((secondVal - firstVal) / timeDiff);
|
||||
// (secondVal - firstVal) / timeDiff will be value per millisecond, so multiply by interval to get
|
||||
// value per interval. Example 60000 milliseconds in 1m, so multiply by 60000 milliseconds
|
||||
Double result = ((secondVal - firstVal) / timeDiff * interval);
|
||||
log.trace("compute - result: {}", result);
|
||||
|
||||
if (isCounter && resetValue > 0 && result > resetValue) {
|
||||
|
||||
@@ -700,6 +700,12 @@ public class DataStore {
|
||||
if (query.isRate()) {
|
||||
log.trace("Adding rate iterator");
|
||||
IteratorSetting rate = new IteratorSetting(499, RateIterator.class);
|
||||
RateOption rateOptions = query.getRateOptions();
|
||||
// if there is no rate interval set, then use the downsample value
|
||||
// so that the result is the change per downsample period
|
||||
if (rateOptions != null && !rateOptions.getInterval().isPresent()) {
|
||||
rateOptions.setInterval(Optional.of(downsample + "ms"));
|
||||
}
|
||||
RateIterator.setRateOptions(rate, query.getRateOptions());
|
||||
scanner.addScanIterator(rate);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.Executors;
|
||||
@@ -765,7 +766,13 @@ public class DataStoreCache {
|
||||
if (subQuery.isRate()) {
|
||||
log.trace("Adding rate iterator");
|
||||
IteratorSetting rate = new IteratorSetting(499, RateIterator.class);
|
||||
RateIterator.setRateOptions(rate, subQuery.getRateOptions());
|
||||
QueryRequest.RateOption rateOptions = subQuery.getRateOptions();
|
||||
// if there is no rate interval set, then use the downsample value
|
||||
// so that the result is the change per downsample period
|
||||
if (rateOptions != null && !rateOptions.getInterval().isPresent()) {
|
||||
rateOptions.setInterval(Optional.of(downsamplePeriod + "ms"));
|
||||
}
|
||||
RateIterator.setRateOptions(rate, rateOptions);
|
||||
RateIterator rateIterator = new RateIterator();
|
||||
rateIterator.init(itr, rate.getOptions(), null);
|
||||
itr = rateIterator;
|
||||
|
||||
@@ -7,6 +7,7 @@ import static org.junit.Assert.assertTrue;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
import java.util.TreeMap;
|
||||
|
||||
@@ -46,14 +47,26 @@ public class RateIteratorTest extends IteratorTestBase {
|
||||
|
||||
@Test
|
||||
public void testConstantTimeRate() throws Exception {
|
||||
testInterval(null, 0.001D);
|
||||
testInterval("1ms", 0.001D);
|
||||
testInterval("1s", 1.0D);
|
||||
testInterval("60s", 60.0D);
|
||||
}
|
||||
|
||||
private void testInterval(String interval, double result) throws Exception {
|
||||
SortedMapIterator source = new SortedMapIterator(table);
|
||||
RateIterator iter = new RateIterator();
|
||||
IteratorSetting settings = new IteratorSetting(100, RateIterator.class);
|
||||
QueryRequest.RateOption rateOption = new QueryRequest.RateOption();
|
||||
if (interval != null) {
|
||||
rateOption.setInterval(Optional.of(interval));
|
||||
}
|
||||
RateIterator.setRateOptions(settings, rateOption);
|
||||
iter.init(source, settings.getOptions(), SCAN_IE);
|
||||
iter.seek(new Range(), EMPTY_COL_FAMS, true);
|
||||
for (int i = 0; i < 99; i++) {
|
||||
assertTrue(iter.hasTop());
|
||||
assertEquals(0.001D, MetricAdapter.decodeValue(iter.getTopValue().get()), 0.0D);
|
||||
assertEquals(result, MetricAdapter.decodeValue(iter.getTopValue().get()), 0.0D);
|
||||
iter.next();
|
||||
}
|
||||
assertFalse(iter.hasTop());
|
||||
|
||||
Reference in new issue
Block a user