mirror of
https://github.com/NationalSecurityAgency/timely.git
synced 2026-11-09 17:36:01 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d9214ed406 | ||
|
|
9a1c0e6e2f | ||
|
|
95f3e3d596 | ||
|
|
aaa0d91f11 | ||
|
|
48509e747b | ||
|
|
286bb85cab | ||
|
|
abfebeca60 | ||
|
|
e335eeb3b4 | ||
|
|
12d3695f10 | ||
|
|
61df23e6ba | ||
|
|
2640cbaf80 | ||
|
|
11a417c890 | ||
|
|
780e8f37b8 | ||
|
|
5ce377b15c | ||
|
|
4ed6eb98de | ||
|
|
4d08db3fbc | ||
|
|
16d73a1845 | ||
|
|
42b06cf60c | ||
|
|
e772728159 | ||
|
|
ebce93684a | ||
|
|
ff7a75c7c4 | ||
|
|
ad61f2cc85 | ||
|
|
e8beb77cb9 | ||
|
|
d6839fbc6c | ||
|
|
d53079a996 | ||
|
|
2e7489afef | ||
|
|
ee71a2c74f | ||
|
|
89a374f9a2 | ||
|
|
f145d0d1a4 | ||
|
|
387140722c | ||
|
|
b3617820f7 | ||
|
|
ac2d9463dc | ||
|
|
c32867685f | ||
|
|
08057e7d67 | ||
|
|
a058e5a816 | ||
|
|
99b81986a4 | ||
|
|
d7ecbd345f | ||
|
|
0f9059b6b6 | ||
|
|
fcbdd9296b | ||
|
|
df3ade7929 | ||
|
|
823a6fa08f | ||
|
|
89ab2635fd | ||
|
|
13d8db5ab7 |
No files matched your search
@@ -8,4 +8,5 @@ logs/
|
||||
server/pki/
|
||||
client/src/main/python/setup.py
|
||||
grafana/timely-app/yarn-error.log
|
||||
grafana/timely-app/data/
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>2.1.0</version>
|
||||
<version>2.2.1</version>
|
||||
</parent>
|
||||
<artifactId>timely-analytics</artifactId>
|
||||
<!--
|
||||
|
||||
@@ -25,6 +25,3 @@ AUTHORIZATION_CERTIFICATE_TYPE=
|
||||
AUTHORIZATION_CERTIFICATE_FILE=
|
||||
ANONYMOUS_HTTP=true
|
||||
ANONYMOUS_WEBSOCKET=true
|
||||
|
||||
REQUIRED_ROLES=
|
||||
REQUIRED_AUTHS=
|
||||
@@ -1,26 +1,24 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [[ $(uname) == "Darwin" ]]; then
|
||||
THIS_SCRIPT=$(python -c 'import os,sys; print os.path.realpath(sys.argv[1])' "$0")
|
||||
TCNATIVE_SUFFIX="jnilib"
|
||||
THIS_SCRIPT=$(python -c 'import os,sys; print os.path.realpath(sys.argv[1])' "$0")
|
||||
else
|
||||
THIS_SCRIPT=$(readlink -f "$0")
|
||||
TCNATIVE_SUFFIX="so"
|
||||
THIS_SCRIPT=$(readlink -f "$0")
|
||||
HW=`uname -m`
|
||||
OS_PATH=linux-${HW}
|
||||
fi
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
export INSTANCE="1"
|
||||
export INSTANCE="1"
|
||||
else
|
||||
export INSTANCE="$1"
|
||||
export INSTANCE="$1"
|
||||
fi
|
||||
|
||||
PID=$(jps -m | grep -E 'timely-balancer-.*-exec.jar' | grep "instance=${INSTANCE}" | awk '{print $1}')
|
||||
|
||||
if [ "$PID" == "" ]; then
|
||||
|
||||
THIS_DIR="${THIS_SCRIPT%/*}"
|
||||
BASE_DIR=$(cd "$THIS_DIR"/.. && pwd)
|
||||
TMP_DIR="${BASE_DIR}/tmp"
|
||||
LIB_DIR="${BASE_DIR}/lib"
|
||||
BIN_DIR="${BASE_DIR}/bin"
|
||||
export CONF_DIR="${BASE_DIR}/conf"
|
||||
@@ -33,34 +31,34 @@ if [ "$PID" == "" ]; then
|
||||
# use either a value from timely-balancer-env.sh or the default
|
||||
export LOG_DIR="${TIMELY_LOG_DIR:-${BASE_DIR}/logs}"
|
||||
|
||||
if [[ -e ${TMP_DIR} ]]; then
|
||||
rm -rf "${TMP_DIR}"
|
||||
if [[ ! -e ${NATIVE_DIR} ]]; then
|
||||
mkdir -p "${NATIVE_DIR}"
|
||||
fi
|
||||
mkdir "${TMP_DIR}"
|
||||
|
||||
if [[ -e ${NATIVE_DIR} ]]; then
|
||||
rm -rf "${NATIVE_DIR}"
|
||||
fi
|
||||
mkdir -p "${NATIVE_DIR}"
|
||||
|
||||
if [[ ! -e ${LOG_DIR} ]]; then
|
||||
mkdir "${LOG_DIR}"
|
||||
mkdir "${LOG_DIR}"
|
||||
fi
|
||||
|
||||
pushd "${BASE_DIR}/bin" || exit
|
||||
"${JAVA_HOME}/bin/jar xf ${LIB_DIR}/netty-tcnative-boringssl-static*.jar META-INF/native/libnetty_tcnative_linux_x86_64.${TCNATIVE_SUFFIX}"
|
||||
"${JAVA_HOME}/bin/jar xf ${LIB_DIR}/netty-all*.jar META-INF/native/libnetty_transport_native_epoll_x86_64.${TCNATIVE_SUFFIX}"
|
||||
popd || exit
|
||||
|
||||
JVM_ARGS="-Xmx2G -Xms2G -XX:NewSize=1G -XX:MaxNewSize=1G"
|
||||
JVM_ARGS="${JVM_ARGS} -Djava.library.path=${NATIVE_DIR}"
|
||||
JVM_ARGS="${JVM_ARGS} -Dlogging.config=${CONF_DIR}/log4j2.yml"
|
||||
JVM_ARGS="${JVM_ARGS} -Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector"
|
||||
JVM_ARGS="${JVM_ARGS} -XX:+UseG1GC -XX:+UseStringDeduplication"
|
||||
JVM_ARGS="${JVM_ARGS} -Djava.net.preferIPv4Stack=true"
|
||||
JVM_ARGS="${JVM_ARGS} -XX:+UseNUMA"
|
||||
|
||||
echo "${JAVA_HOME}/bin/java ${JVM_ARGS} -jar ${THIS_DIR}/timely-balancer-*-exec.jar --instance=${INSTANCE}"
|
||||
nohup "${JAVA_HOME}"/bin/java ${JVM_ARGS} -jar "${THIS_DIR}"/timely-balancer-*-exec.jar --instance="${INSTANCE}" >> "${LOG_DIR}/timely-balancer${INSTANCE}.out" 2>&1 &
|
||||
# for linux varieties of OS, extract native libraries if not already present
|
||||
if [[ -n "$OS_PATH" ]]; then
|
||||
if [[ ! -d ${NATIVE_DIR} || -z "$(ls -A ${NATIVE_DIR})" ]]; 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
|
||||
popd || exit
|
||||
fi
|
||||
JVM_ARGS="${JVM_ARGS} -Djava.library.path=${NATIVE_DIR}"
|
||||
fi
|
||||
|
||||
echo "${JAVA_HOME}/bin/java ${JVM_ARGS} -jar ${BIN_DIR}/timely-balancer-*-exec.jar --instance=${INSTANCE}"
|
||||
nohup "${JAVA_HOME}"/bin/java ${JVM_ARGS} -jar "${BIN_DIR}"/timely-balancer-*-exec.jar --instance="${INSTANCE}" >> "${LOG_DIR}/timely-balancer${INSTANCE}.out" 2>&1 &
|
||||
else
|
||||
echo "timely-balancer --instance=${INSTANCE} already running with pid ${PID}"
|
||||
fi
|
||||
@@ -9,7 +9,7 @@ Configuration:
|
||||
- name: PID
|
||||
value: "????"
|
||||
- name: LOG_PATTERN
|
||||
value: "%clr{%d{yyyy-MM-dd HH:mm:ss.SSS}}{faint} %clr{%5p} %clr{${sys:PID}}{magenta} %clr{---}{faint} %clr{[%15.15t]}{faint} %clr{%-40.40c{1.}}{cyan} %clr{:}{faint} %m%n%wEx"
|
||||
value: "%d{ISO8601} %-5p [%-40.40t] [%-40.40c{1.}] %m%n%wEx"
|
||||
|
||||
Appenders:
|
||||
RollingFile:
|
||||
|
||||
@@ -8,8 +8,6 @@ timely:
|
||||
cache-expiration-minutes: 60
|
||||
cache-refresh-minutes: 5
|
||||
authorization-url: ${AUTHORIZATION_URL}
|
||||
required-roles: ${REQUIRED_ROLES}
|
||||
required-auths: ${REQUIRED_AUTHS}
|
||||
allow-anonymous-http-access: ${ANONYMOUS_HTTP:true}
|
||||
allow-anonymous-ws-access: ${ANONYMOUS_WEBSOCKET:true}
|
||||
server-ssl:
|
||||
|
||||
+20
-5
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>2.1.0</version>
|
||||
<version>2.2.1</version>
|
||||
</parent>
|
||||
<artifactId>timely-balancer</artifactId>
|
||||
<description>Timely Balancer</description>
|
||||
@@ -44,10 +44,6 @@
|
||||
<groupId>io.github.classgraph</groupId>
|
||||
<artifactId>classgraph</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.javacsv</groupId>
|
||||
<artifactId>javacsv</artifactId>
|
||||
@@ -162,6 +158,25 @@
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-tcnative-boringssl-static</artifactId>
|
||||
<classifier>linux-aarch_64</classifier>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-tcnative-boringssl-static</artifactId>
|
||||
<classifier>linux-x86_64</classifier>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-transport-native-epoll</artifactId>
|
||||
<classifier>linux-aarch_64</classifier>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-transport-native-epoll</artifactId>
|
||||
<classifier>linux-x86_64</classifier>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
Vendored
+5
-3
@@ -19,8 +19,10 @@
|
||||
<directory>${project.build.directory}/lib</directory>
|
||||
<outputDirectory>lib</outputDirectory>
|
||||
<includes>
|
||||
<include>netty-tcnative-boringssl-static*.jar</include>
|
||||
<include>netty-all*.jar</include>
|
||||
<include>netty-tcnative-boringssl-static*linux-x86_64.jar</include>
|
||||
<include>netty-tcnative-boringssl-static*linux-aarch_64.jar</include>
|
||||
<include>netty-transport-native-epoll*linux-x86_64.jar</include>
|
||||
<include>netty-transport-native-epoll*linux-aarch_64.jar</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
<fileSet>
|
||||
@@ -52,4 +54,4 @@
|
||||
</includes>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
</assembly>
|
||||
</assembly>
|
||||
@@ -91,17 +91,21 @@ public class MetricResolver {
|
||||
final protected BalancerProperties balancerProperties;
|
||||
final protected CacheProperties cacheProperties;
|
||||
final protected HealthChecker healthChecker;
|
||||
final protected Path assignmentFile;
|
||||
final protected FileSystem fs;
|
||||
|
||||
private enum BalanceType {
|
||||
HIGH_LOW, HIGH_AVG, AVG_LOW
|
||||
}
|
||||
|
||||
public MetricResolver(CuratorFramework curatorFramework, BalancerProperties balancerProperties, CacheProperties cacheProperties,
|
||||
HealthChecker healthChecker) {
|
||||
HealthChecker healthChecker) throws Exception {
|
||||
this.curatorFramework = curatorFramework;
|
||||
this.balancerProperties = balancerProperties;
|
||||
this.cacheProperties = cacheProperties;
|
||||
this.healthChecker = healthChecker;
|
||||
this.assignmentFile = new Path(balancerProperties.getAssignmentFile());
|
||||
this.fs = getFileSystem(this.assignmentFile);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
@@ -916,10 +920,8 @@ public class MetricResolver {
|
||||
|
||||
protected void createAssignmentFile() {
|
||||
try {
|
||||
log.info("Creating assignment file: " + balancerProperties.getAssignmentFile());
|
||||
Path assignmentFile = new Path(balancerProperties.getAssignmentFile());
|
||||
FileSystem fs = getFileSystem(assignmentFile);
|
||||
fs.create(assignmentFile);
|
||||
log.info("Creating assignment file: " + this.assignmentFile);
|
||||
this.fs.create(this.assignmentFile);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
@@ -927,9 +929,7 @@ public class MetricResolver {
|
||||
|
||||
protected long getLastWrittenToHdfsTimestamp() {
|
||||
try {
|
||||
Path assignmentFile = new Path(balancerProperties.getAssignmentFile());
|
||||
FileSystem fs = getFileSystem(assignmentFile);
|
||||
FileStatus fileStatus = fs.getFileStatus(assignmentFile);
|
||||
FileStatus fileStatus = this.fs.getFileStatus(this.assignmentFile);
|
||||
return fileStatus.getModificationTime();
|
||||
} catch (FileNotFoundException e) {
|
||||
createAssignmentFile();
|
||||
@@ -960,16 +960,15 @@ public class MetricResolver {
|
||||
// proceed with reading from HDFS
|
||||
|
||||
Map<String,TimelyBalancedHost> assignedMetricToHostMap = new TreeMap<>();
|
||||
CsvReader reader = null;
|
||||
try {
|
||||
boolean acquired = false;
|
||||
while (!acquired) {
|
||||
acquired = assignmentsIPRWLock.readLock().acquire(60, TimeUnit.SECONDS);
|
||||
}
|
||||
balancerLock.writeLock().lock();
|
||||
Path assignmentFile = new Path(balancerProperties.getAssignmentFile());
|
||||
FileSystem fs = getFileSystem(assignmentFile);
|
||||
FSDataInputStream iStream = fs.open(assignmentFile);
|
||||
CsvReader reader = new CsvReader(iStream, ',', Charset.forName("UTF-8"));
|
||||
FSDataInputStream iStream = this.fs.open(this.assignmentFile);
|
||||
reader = new CsvReader(iStream, ',', Charset.forName("UTF-8"));
|
||||
reader.setUseTextQualifier(false);
|
||||
|
||||
// skip the headers
|
||||
@@ -1031,6 +1030,9 @@ public class MetricResolver {
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
} finally {
|
||||
if (reader != null) {
|
||||
reader.close();
|
||||
}
|
||||
balancerLock.writeLock().unlock();
|
||||
try {
|
||||
assignmentsIPRWLock.readLock().release();
|
||||
@@ -1052,12 +1054,10 @@ public class MetricResolver {
|
||||
nonCachedMetricsLocalLock.readLock().lock();
|
||||
try {
|
||||
if (!metricToHostMap.isEmpty()) {
|
||||
Path assignmentFile = new Path(balancerProperties.getAssignmentFile());
|
||||
FileSystem fs = getFileSystem(assignmentFile);
|
||||
if (!fs.exists(assignmentFile.getParent())) {
|
||||
fs.mkdirs(assignmentFile.getParent());
|
||||
if (!this.fs.exists(this.assignmentFile.getParent())) {
|
||||
this.fs.mkdirs(this.assignmentFile.getParent());
|
||||
}
|
||||
FSDataOutputStream oStream = fs.create(assignmentFile, true);
|
||||
FSDataOutputStream oStream = this.fs.create(this.assignmentFile, true);
|
||||
writer = new CsvWriter(oStream, ',', Charset.forName("UTF-8"));
|
||||
writer.setUseTextQualifier(false);
|
||||
writer.write("metric");
|
||||
@@ -1080,7 +1080,7 @@ public class MetricResolver {
|
||||
if (!assignmentsLastUpdatedInHdfs.get().succeeded()) {
|
||||
assignmentsLastUpdatedInHdfs.forceSet(now);
|
||||
}
|
||||
log.debug("Wrote {} assignments to hdfs lastHdfsUpdate = lastLocalUpdate ({})", metricToHostMap.size(),
|
||||
log.info("Wrote {} assignments to hdfs lastHdfsUpdate = lastLocalUpdate ({})", metricToHostMap.size(),
|
||||
new Date(assignmentsLastUpdatedLocal.get()));
|
||||
// remove metric from metricMap (ArrivalRate) if not being cached
|
||||
metricMap.entrySet().removeIf(e -> !metricToHostMap.containsKey(e.getKey()));
|
||||
|
||||
@@ -50,7 +50,7 @@ public class BalancerConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public MetricResolver metricResolver(CuratorFramework curatorFramework, BalancerProperties balancerProperties, CacheProperties cacheProperties,
|
||||
HealthChecker healthChecker) {
|
||||
HealthChecker healthChecker) throws Exception {
|
||||
MetricResolver metricResolver = new MetricResolver(curatorFramework, balancerProperties, cacheProperties, healthChecker);
|
||||
metricResolver.start();
|
||||
return metricResolver;
|
||||
|
||||
@@ -48,7 +48,7 @@ public class TestBalancerConfiguration {
|
||||
|
||||
@Bean
|
||||
public TestMetricResolver metricResolver(CuratorFramework curatorFramework, BalancerProperties balancerProperties, CacheProperties cacheProperties,
|
||||
HealthChecker healthChecker) {
|
||||
HealthChecker healthChecker) throws Exception {
|
||||
TestMetricResolver metricResolver = new TestMetricResolver(curatorFramework, balancerProperties, cacheProperties, healthChecker);
|
||||
metricResolver.start();
|
||||
return metricResolver;
|
||||
|
||||
@@ -20,7 +20,7 @@ public class TestMetricResolver extends MetricResolver {
|
||||
private static final Logger log = LoggerFactory.getLogger(TestMetricResolver.class);
|
||||
|
||||
public TestMetricResolver(CuratorFramework curatorFramework, BalancerProperties balancerProperties, CacheProperties cacheProperties,
|
||||
HealthChecker healthChecker) {
|
||||
HealthChecker healthChecker) throws Exception {
|
||||
super(curatorFramework, balancerProperties, cacheProperties, healthChecker);
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ timely:
|
||||
assignment-file: file://${java.io.tmpdir}/timely/balancer/assignments.csv
|
||||
server:
|
||||
ip: 127.0.0.1
|
||||
tcp-base-port: 4242
|
||||
tcp-base-port: 9242
|
||||
num-tcp-pools: 1
|
||||
tcp-buffer-size: 100
|
||||
tcp-client-pool:
|
||||
@@ -82,7 +82,7 @@ timely:
|
||||
jmx-enabled: true
|
||||
test-on-borrow: false
|
||||
test-on-return: false
|
||||
udp-base-port: 4245
|
||||
udp-base-port: 9245
|
||||
udp-client-pool:
|
||||
min-idle-per-key: 0
|
||||
max-idle-per-key: 40
|
||||
@@ -103,7 +103,7 @@ timely:
|
||||
http:
|
||||
host: localhost
|
||||
ip: 127.0.0.1
|
||||
base-port: 4243
|
||||
base-port: 9243
|
||||
redirect-path: /secure-me
|
||||
strict-transport-max-age: 604800
|
||||
cors:
|
||||
@@ -132,7 +132,7 @@ timely:
|
||||
test-on-return: false
|
||||
websocket:
|
||||
ip: 127.0.0.1
|
||||
base-port: 5244
|
||||
base-port: 9244
|
||||
timeout: 60
|
||||
subscription-lag: 120
|
||||
scanner-batch-size: 10000
|
||||
|
||||
+2
-2
@@ -4,13 +4,13 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>2.1.0</version>
|
||||
<version>2.2.1</version>
|
||||
</parent>
|
||||
<artifactId>timely-client</artifactId>
|
||||
<properties>
|
||||
<!-- PEP 440 compliant version gets substituted into src/main/python/template/setup.py -->
|
||||
<!-- use .dev0 instead of -SNAPSHOT -->
|
||||
<python.client.version>2.1.0</python.client.version>
|
||||
<python.client.version>2.2.1.dev0</python.client.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
|
||||
@@ -18,18 +18,27 @@ public class TcpClient implements AutoCloseable {
|
||||
private Socket sock = null;
|
||||
private BufferedWriter out = null;
|
||||
private long connectTime = 0L;
|
||||
private long backoff = 2000;
|
||||
private int bufferSize = -1;
|
||||
private long INIT_BACKOFF = 1000;
|
||||
private long MAX_BACKOFF = 60000;
|
||||
private long backoff = INIT_BACKOFF;
|
||||
private int bufferSize;
|
||||
private long latency;
|
||||
private int writesSinceFlush = 0;
|
||||
private long lastFlushTime = System.currentTimeMillis();
|
||||
|
||||
public TcpClient(String hostname, int port) {
|
||||
this(hostname, port, -1);
|
||||
}
|
||||
|
||||
public TcpClient(String hostname, int port, int bufferSize) {
|
||||
this(hostname, port, bufferSize, -1);
|
||||
}
|
||||
|
||||
public TcpClient(String hostname, int port, int bufferSize, long latency) {
|
||||
this.host = hostname;
|
||||
this.port = port;
|
||||
this.bufferSize = bufferSize;
|
||||
this.latency = latency;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,20 +63,54 @@ public class TcpClient implements AutoCloseable {
|
||||
if (connect() != 0) {
|
||||
throw new IOException();
|
||||
}
|
||||
out.write(metric);
|
||||
writesSinceFlush++;
|
||||
if (bufferSize > 0 && writesSinceFlush >= bufferSize) {
|
||||
flush();
|
||||
try {
|
||||
out.write(metric);
|
||||
writesSinceFlush++;
|
||||
if (bufferSize > 0 && writesSinceFlush >= bufferSize) {
|
||||
if (log.isTraceEnabled()) {
|
||||
log.trace(String.format("Flushing buffer writesSinceFlush >= %d", writesSinceFlush));
|
||||
}
|
||||
flush();
|
||||
}
|
||||
if (latency > 0 && (System.currentTimeMillis() - lastFlushTime) >= latency) {
|
||||
if (log.isTraceEnabled()) {
|
||||
log.trace(String.format("Flushing buffer timeSinceFlush >= %d", latency));
|
||||
}
|
||||
flush();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
reset();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void flush() throws IOException {
|
||||
if (null != out) {
|
||||
out.flush();
|
||||
writesSinceFlush = 0;
|
||||
try {
|
||||
long start = System.currentTimeMillis();
|
||||
out.flush();
|
||||
lastFlushTime = System.currentTimeMillis();
|
||||
if (log.isTraceEnabled()) {
|
||||
log.trace(String.format("Flushed %d metrics to socket in %d ms", writesSinceFlush, (lastFlushTime - start)));
|
||||
}
|
||||
writesSinceFlush = 0;
|
||||
} catch (IOException e) {
|
||||
log.error(String.format("Failed to flush %d metrics to socket", writesSinceFlush), e);
|
||||
reset();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void reset() {
|
||||
out = null;
|
||||
sock = null;
|
||||
backoff = INIT_BACKOFF;
|
||||
writesSinceFlush = 0;
|
||||
lastFlushTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the tcp connection to Timely
|
||||
*
|
||||
@@ -75,8 +118,8 @@ public class TcpClient implements AutoCloseable {
|
||||
* if an error occurs
|
||||
*/
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
log.trace("Shutting down connection to Timely at {}:{}", host, port);
|
||||
public synchronized void close() throws IOException {
|
||||
log.info(String.format("Shutting down connection to Timely at %s:%d", host, port));
|
||||
if (null != sock) {
|
||||
try {
|
||||
if (null != out) {
|
||||
@@ -87,7 +130,7 @@ public class TcpClient implements AutoCloseable {
|
||||
}
|
||||
sock.close();
|
||||
} catch (IOException e) {
|
||||
log.error("Error closing connection to Timely at " + host + ":" + port + ". Error: " + e.getMessage());
|
||||
log.error(String.format("Error closing connection to Timely at %s:%d", host, port), e);
|
||||
} finally {
|
||||
sock = null;
|
||||
}
|
||||
@@ -103,10 +146,10 @@ public class TcpClient implements AutoCloseable {
|
||||
sock = new Socket(host, port);
|
||||
osw = new OutputStreamWriter(sock.getOutputStream(), StandardCharsets.UTF_8);
|
||||
out = new BufferedWriter(osw);
|
||||
backoff = 2000;
|
||||
log.trace("Connected to Timely at {}:{}", host, port);
|
||||
backoff = INIT_BACKOFF;
|
||||
log.info(String.format("Connected to Timely at %s:%d", host, port));
|
||||
} catch (Exception e) {
|
||||
log.error("Error connecting to Timely at {}:{} - {}", host, port, e.getMessage());
|
||||
log.error(String.format("Error connecting to Timely at %s:%d", host, port), e);
|
||||
if (sock != null) {
|
||||
try {
|
||||
sock.close();
|
||||
@@ -132,12 +175,13 @@ public class TcpClient implements AutoCloseable {
|
||||
out = null;
|
||||
}
|
||||
}
|
||||
backoff = backoff * 2;
|
||||
log.info("Will retry connection in {} ms.", backoff);
|
||||
backoff = Math.min(MAX_BACKOFF, backoff * 2);
|
||||
if (log.isTraceEnabled()) {
|
||||
log.trace(String.format("Will retry connection in %d ms", backoff));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
log.warn("Not writing to Timely, waiting to reconnect");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -147,4 +191,22 @@ public class TcpClient implements AutoCloseable {
|
||||
public long getConnectTime() {
|
||||
return connectTime;
|
||||
}
|
||||
|
||||
public int getWritesSinceFlush() {
|
||||
return writesSinceFlush;
|
||||
}
|
||||
|
||||
public long getTimeSinceFlush() {
|
||||
return System.currentTimeMillis() - lastFlushTime;
|
||||
}
|
||||
|
||||
public synchronized boolean isConnected() {
|
||||
boolean isConnected = (null != sock && sock.isConnected());
|
||||
if (isConnected) {
|
||||
return true;
|
||||
} else {
|
||||
int status = connect();
|
||||
return status == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>2.1.0</version>
|
||||
</parent>
|
||||
<artifactId>collectd-nsq-plugin</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>collectd</groupId>
|
||||
<artifactId>collectd-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>collectd-plugin-parent</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<configuration>
|
||||
<artifactSet>
|
||||
<includes />
|
||||
</artifactSet>
|
||||
<filters>
|
||||
<filter>
|
||||
<artifact>*:*</artifact>
|
||||
<excludes>
|
||||
<exclude>**/module-info.class</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
</filters>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>shade</id>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<phase>package</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -1,32 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>2.1.0</version>
|
||||
</parent>
|
||||
<artifactId>collectd-plugin-parent</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>collectd</groupId>
|
||||
<artifactId>collectd-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.jcip</groupId>
|
||||
<artifactId>jcip-annotations</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-easymock-release-full</artifactId>
|
||||
<classifier>full</classifier>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
-254
@@ -1,254 +0,0 @@
|
||||
package timely.collectd.plugin;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.collectd.api.Collectd;
|
||||
import org.collectd.api.DataSource;
|
||||
import org.collectd.api.OConfigItem;
|
||||
import org.collectd.api.ValueList;
|
||||
|
||||
public abstract class CollectDPluginParent {
|
||||
|
||||
private static final String PUT = "put {0} {1} {2}{3}\n";
|
||||
private static final Pattern HADOOP_STATSD_PATTERN = Pattern.compile("([\\w-_]+)\\.([\\w-_]+)\\.([\\w-_]+)\\.([\\w-_]+)");
|
||||
private static final String INSTANCE = " instance=";
|
||||
private static final String NAME = " name=";
|
||||
private static final String SAMPLE = " sample=";
|
||||
private static final String CODE = " code=";
|
||||
private static final String PERIOD = ".";
|
||||
private static final String SAMPLE_TYPE = " sampleType=";
|
||||
private static final String COUNTER = "COUNTER";
|
||||
private static final String GAUGE = "GAUGE";
|
||||
private static final String DERIVE = "DERIVE";
|
||||
private static final String ABSOLUTE = "ABSOLUTE";
|
||||
private static final Pattern NSQ_PATTERN1 = Pattern.compile("([\\w-_]+)\\.([\\w-_]+)\\.([\\w-_]+)");
|
||||
private static final Pattern NSQ_PATTERN2 = Pattern.compile("([\\w-_]+)\\.([\\w-_]+)\\.([\\w-_]+)\\.([\\w-_]+)");
|
||||
private static final Pattern NSQ_PATTERN3 = Pattern.compile("([\\w-_]+)\\.([\\w-_]+)\\.([\\w-_]+)\\.([\\w-_]+)\\.([\\w-_#]+)\\.([\\w-_]+)");
|
||||
private static final Pattern ETHSTAT_PATTERN = Pattern.compile("([\\w-_]+)_queue_([\\w-_]+)_([\\w-_]+)");
|
||||
private static final String STATSD_PREFIX = "statsd";
|
||||
private static final String NSQ_PREFIX = STATSD_PREFIX + ".nsq.";
|
||||
private static final Pattern HAPROXY_PATTERN = Pattern.compile("\\[([\\w-_=]+),([\\w-_=]+)\\]");
|
||||
|
||||
private final SMARTCodeMapping smart = new SMARTCodeMapping();
|
||||
|
||||
protected Set<String> addlTags = new HashSet<>();
|
||||
|
||||
public int config(OConfigItem config) {
|
||||
for (OConfigItem child : config.getChildren()) {
|
||||
switch (child.getKey()) {
|
||||
case "Tags":
|
||||
case "tags":
|
||||
String[] additionalTags = child.getValues().get(0).getString().split(",");
|
||||
for (String t : additionalTags) {
|
||||
addlTags.add(" " + t.trim());
|
||||
}
|
||||
default:
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public abstract void write(String metric, OutputStream out);
|
||||
|
||||
public void process(ValueList vl, OutputStream out) {
|
||||
debugValueList(vl);
|
||||
|
||||
StringBuilder metric = new StringBuilder();
|
||||
Long timestamp = vl.getTime();
|
||||
StringBuilder tags = new StringBuilder();
|
||||
String host = vl.getHost();
|
||||
int idx = host.indexOf(PERIOD);
|
||||
if (-1 != idx) {
|
||||
tags.append(" host=").append(host.substring(0, idx));
|
||||
} else {
|
||||
tags.append(" host=").append(host);
|
||||
}
|
||||
int nIdx = host.indexOf('n');
|
||||
if (-1 != nIdx) {
|
||||
tags.append(" rack=").append(host.substring(0, nIdx));
|
||||
}
|
||||
for (String tag : addlTags) {
|
||||
tags.append(tag);
|
||||
}
|
||||
if (vl.getPlugin().equals(STATSD_PREFIX)) {
|
||||
Matcher m = HADOOP_STATSD_PATTERN.matcher(vl.getTypeInstance());
|
||||
Matcher n1 = NSQ_PATTERN1.matcher(vl.getTypeInstance());
|
||||
Matcher n2 = NSQ_PATTERN2.matcher(vl.getTypeInstance());
|
||||
Matcher n3 = NSQ_PATTERN3.matcher(vl.getTypeInstance());
|
||||
String instance = null;
|
||||
if (m.matches() && !vl.getTypeInstance().startsWith("nsq")) {
|
||||
// Here we are processing the statsd metrics coming from the
|
||||
// Hadoop Metrics2 StatsDSink without the host name.
|
||||
// The format of metric is:
|
||||
// serviceName.contextName.recordName.metricName. The recordName
|
||||
// is typically duplicative and is dropped here. The serviceName
|
||||
// is used as the instance.
|
||||
metric.append(STATSD_PREFIX).append(PERIOD).append(m.group(2)).append(PERIOD).append(m.group(4));
|
||||
instance = m.group(1);
|
||||
} else if (n1.matches() && vl.getTypeInstance().startsWith("nsq")) {
|
||||
metric.append(NSQ_PREFIX).append(n1.group(2)).append(PERIOD).append(n1.group(3));
|
||||
} else if (n2.matches() && vl.getTypeInstance().startsWith("nsq")) {
|
||||
metric.append(NSQ_PREFIX).append(n2.group(2)).append(PERIOD).append(n2.group(4));
|
||||
instance = n2.group(3);
|
||||
} else if (n3.matches() && vl.getTypeInstance().startsWith("nsq")) {
|
||||
metric.append(NSQ_PREFIX).append(n3.group(4)).append(PERIOD).append(n3.group(6));
|
||||
instance = n3.group(5);
|
||||
} else {
|
||||
// Handle StatsD metrics of unknown formats. If there is a
|
||||
// period in the metric name, use everything up to that as
|
||||
// the instance.
|
||||
int period = vl.getTypeInstance().indexOf('.');
|
||||
if (-1 == period) {
|
||||
metric.append(STATSD_PREFIX).append(PERIOD).append(vl.getTypeInstance());
|
||||
} else {
|
||||
instance = vl.getTypeInstance().substring(0, period);
|
||||
metric.append(STATSD_PREFIX).append(PERIOD).append(vl.getTypeInstance().substring(period + 1));
|
||||
}
|
||||
}
|
||||
timestamp = vl.getTime();
|
||||
if (null != instance) {
|
||||
tags.append(INSTANCE).append(instance);
|
||||
}
|
||||
} else if (vl.getPlugin().equals("ethstat")) {
|
||||
metric.append("sys.ethstat.");
|
||||
if (vl.getTypeInstance().contains("queue")) {
|
||||
Matcher m = ETHSTAT_PATTERN.matcher(vl.getTypeInstance());
|
||||
if (m.matches()) {
|
||||
metric.append(m.group(1)).append("_").append(m.group(3));
|
||||
tags.append(" queue=").append(m.group(2));
|
||||
} else {
|
||||
metric.append(vl.getTypeInstance());
|
||||
}
|
||||
} else {
|
||||
metric.append(vl.getTypeInstance());
|
||||
}
|
||||
tags.append(INSTANCE).append(vl.getPluginInstance());
|
||||
} else if (vl.getPlugin().equals("hddtemp")) {
|
||||
metric.append("sys.hddtemp.").append(vl.getType());
|
||||
tags.append(INSTANCE).append(vl.getTypeInstance());
|
||||
} else if (vl.getPlugin().equals("smart")) {
|
||||
int code = -1;
|
||||
String name = null;
|
||||
if (vl.getTypeInstance().startsWith("attribute-")) {
|
||||
int hyphen = vl.getTypeInstance().indexOf('-');
|
||||
code = Integer.parseInt(vl.getTypeInstance().substring(hyphen + 1));
|
||||
name = smart.get(code);
|
||||
}
|
||||
if (code == -1) {
|
||||
if (notEmpty(vl.getTypeInstance())) {
|
||||
metric.append("sys.smart.").append(vl.getTypeInstance());
|
||||
} else {
|
||||
metric.append("sys.smart.").append(vl.getType());
|
||||
}
|
||||
} else {
|
||||
metric.append("sys.smart.").append(name);
|
||||
tags.append(CODE).append(code);
|
||||
}
|
||||
tags.append(INSTANCE).append(vl.getPluginInstance());
|
||||
} else if (vl.getPlugin().equals("sensors")) {
|
||||
String instance = "";
|
||||
if (vl.getTypeInstance().startsWith("temp")) {
|
||||
instance = vl.getTypeInstance().substring(4);
|
||||
}
|
||||
metric.append("sys.sensors.").append(vl.getType()).append(PERIOD).append(vl.getPluginInstance());
|
||||
tags.append(INSTANCE).append(instance);
|
||||
} else if (vl.getPlugin().equals("haproxy")) {
|
||||
metric.append("sys.haproxy.").append(vl.getTypeInstance());
|
||||
Matcher m = HAPROXY_PATTERN.matcher(vl.getPluginInstance());
|
||||
if (m.matches()) {
|
||||
tags.append(" ").append(m.group(1));
|
||||
tags.append(" ").append(m.group(2));
|
||||
}
|
||||
} else if (vl.getPlugin().equals("ipmi")) {
|
||||
metric.append("sys.ipmi.").append(vl.getType());
|
||||
tags.append(INSTANCE).append(vl.getTypeInstance().replaceAll(" ", "_"));
|
||||
} else if (vl.getPlugin().equals("snmp")) {
|
||||
metric.append("sys.snmp.").append(vl.getType());
|
||||
tags.append(INSTANCE).append(vl.getTypeInstance().replaceAll(" ", "_"));
|
||||
} else if (vl.getPlugin().equals("GenericJMX")) {
|
||||
metric.append("sys.").append(vl.getPlugin()).append(PERIOD).append(vl.getType()).append(PERIOD).append(vl.getTypeInstance());
|
||||
String[] pluginInstanceSplit = vl.getPluginInstance().split("-");
|
||||
if (pluginInstanceSplit.length > 0) {
|
||||
tags.append(INSTANCE).append(pluginInstanceSplit[0].replaceAll(" ", "_"));
|
||||
}
|
||||
if (pluginInstanceSplit.length > 1) {
|
||||
tags.append(NAME).append(pluginInstanceSplit[1].replaceAll(" ", "_"));
|
||||
}
|
||||
} else if (notEmpty(vl.getTypeInstance()) && notEmpty(vl.getType()) && notEmpty(vl.getPluginInstance()) && notEmpty(vl.getPlugin())) {
|
||||
metric.append("sys.").append(vl.getPlugin()).append(PERIOD).append(vl.getType()).append(PERIOD).append(vl.getTypeInstance());
|
||||
tags.append(INSTANCE).append(vl.getPluginInstance().replaceAll(" ", "_"));
|
||||
} else if (notEmpty(vl.getTypeInstance()) && notEmpty(vl.getType()) && notEmpty(vl.getPlugin())) {
|
||||
metric.append("sys.").append(vl.getPlugin()).append(PERIOD).append(vl.getType()).append(PERIOD).append(vl.getTypeInstance());
|
||||
} else if (notEmpty(vl.getType()) && notEmpty(vl.getPluginInstance()) && notEmpty(vl.getPlugin())) {
|
||||
metric.append("sys.").append(vl.getPlugin()).append(PERIOD).append(vl.getType());
|
||||
tags.append(INSTANCE).append(vl.getPluginInstance().replaceAll(" ", "_"));
|
||||
} else if (notEmpty(vl.getType()) && notEmpty(vl.getPlugin())) {
|
||||
metric.append("sys.").append(vl.getPlugin()).append(PERIOD).append(vl.getType());
|
||||
} else {
|
||||
Collectd.logWarning("Unhandled metric: " + vl.toString());
|
||||
return;
|
||||
}
|
||||
final String metricName = metric.toString().replaceAll(" ", "_");
|
||||
for (int i = 0; i < vl.getValues().size(); i++) {
|
||||
StringBuilder tagsWithSample = new StringBuilder(tags.toString());
|
||||
String sampleName = vl.getDataSet().getDataSources().get(i).getName();
|
||||
int type = vl.getDataSet().getDataSources().get(i).getType();
|
||||
String sampleType = convertType(type);
|
||||
if (null != sampleName) {
|
||||
tagsWithSample.append(SAMPLE).append(sampleName);
|
||||
}
|
||||
if (null != sampleType) {
|
||||
tagsWithSample.append(SAMPLE_TYPE).append(sampleType);
|
||||
}
|
||||
Double value = vl.getValues().get(i).doubleValue();
|
||||
String datapoint = MessageFormat.format(PUT, metricName, timestamp.toString(), value.toString(), tagsWithSample.toString());
|
||||
Collectd.logDebug("Writing: " + datapoint);
|
||||
write(datapoint, out);
|
||||
}
|
||||
}
|
||||
|
||||
private void debugValueList(ValueList vl) {
|
||||
Collectd.logDebug("Input: " + vl.toString());
|
||||
Collectd.logDebug("Plugin: " + vl.getPlugin());
|
||||
Collectd.logDebug("PluginInstance: " + vl.getPluginInstance());
|
||||
Collectd.logDebug("Type: " + vl.getType());
|
||||
Collectd.logDebug("TypeInstance: " + vl.getTypeInstance());
|
||||
for (int i = 0; i < vl.getValues().size(); i++) {
|
||||
Number value = vl.getValues().get(i);
|
||||
DataSource ds = vl.getDataSet().getDataSources().get(i);
|
||||
Collectd.logDebug(convertType(ds.getType()) + " " + ds.getName() + " = " + value);
|
||||
}
|
||||
}
|
||||
|
||||
private String convertType(int type) {
|
||||
String result = null;
|
||||
switch (type) {
|
||||
case 0:
|
||||
result = COUNTER;
|
||||
break;
|
||||
case 1:
|
||||
result = GAUGE;
|
||||
break;
|
||||
case 2:
|
||||
result = DERIVE;
|
||||
break;
|
||||
case 3:
|
||||
result = ABSOLUTE;
|
||||
break;
|
||||
default:
|
||||
result = GAUGE;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean notEmpty(String arg) {
|
||||
return (null != arg) && !(arg.equals(""));
|
||||
}
|
||||
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
package timely.collectd.plugin;
|
||||
|
||||
import org.apache.commons.pool2.PooledObject;
|
||||
import org.apache.commons.pool2.PooledObjectFactory;
|
||||
import org.apache.commons.pool2.impl.DefaultPooledObject;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.collectd.api.OConfigItem;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class PooledCloseableHttpClientFactory implements PooledObjectFactory<CloseableHttpClient> {
|
||||
|
||||
private int connectionRequestTimeout = 10000; // 10 seconds in milliseconds
|
||||
private int connectTimeout = 30000; // 30 seconds in milliseconds
|
||||
private int socketTimeout = 60000; // 60 seconds in milliseconds
|
||||
private long connectionTimeToLive = 300000; // 300 seconds in milliseconds
|
||||
|
||||
public int config(OConfigItem config) {
|
||||
for (OConfigItem child : config.getChildren()) {
|
||||
switch (child.getKey()) {
|
||||
case "connectionRequestTimeout":
|
||||
case "ConnectionRequestTimeout":
|
||||
connectionRequestTimeout = Integer.parseInt(child.getValues().get(0).getString());
|
||||
break;
|
||||
case "connectTimeout":
|
||||
case "ConnectTimeout":
|
||||
connectTimeout = Integer.parseInt(child.getValues().get(0).getString());
|
||||
break;
|
||||
case "socketTimeout":
|
||||
case "SocketTimeout":
|
||||
socketTimeout = Integer.parseInt(child.getValues().get(0).getString());
|
||||
break;
|
||||
case "connectionTimeToLive":
|
||||
case "ConnectionTimeToLive":
|
||||
connectionTimeToLive = Long.parseLong(child.getValues().get(0).getString());
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PooledObject<CloseableHttpClient> makeObject() throws Exception {
|
||||
RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(connectionRequestTimeout).setConnectTimeout(connectTimeout)
|
||||
.setSocketTimeout(socketTimeout).build();
|
||||
HttpClientBuilder builder = HttpClientBuilder.create();
|
||||
builder.setDefaultRequestConfig(requestConfig);
|
||||
builder.setConnectionTimeToLive(connectionTimeToLive, TimeUnit.MILLISECONDS);
|
||||
return new DefaultPooledObject<>(builder.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyObject(PooledObject<CloseableHttpClient> pooledObject) throws Exception {
|
||||
try {
|
||||
pooledObject.getObject().close();
|
||||
} catch (Exception e) {
|
||||
// do nothing
|
||||
} finally {
|
||||
pooledObject.invalidate();
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateObject(PooledObject<CloseableHttpClient> pooledObject) {
|
||||
return pooledObject.getObject() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activateObject(PooledObject<CloseableHttpClient> pooledObject) throws Exception {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void passivateObject(PooledObject<CloseableHttpClient> pooledObject) throws Exception {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public void setConnectionRequestTimeout(int connectionRequestTimeout) {
|
||||
this.connectionRequestTimeout = connectionRequestTimeout;
|
||||
}
|
||||
|
||||
public void setConnectTimeout(int connectTimeout) {
|
||||
this.connectTimeout = connectTimeout;
|
||||
}
|
||||
|
||||
public void setSocketTimeout(int socketTimeout) {
|
||||
this.socketTimeout = socketTimeout;
|
||||
}
|
||||
|
||||
public void setConnectionTimeToLive(long connectionTimeToLive) {
|
||||
this.connectionTimeToLive = connectionTimeToLive;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,13 +1,13 @@
|
||||
package timely.collectd.plugin;
|
||||
|
||||
import java.net.Socket;
|
||||
|
||||
import org.apache.commons.pool2.PooledObject;
|
||||
import org.apache.commons.pool2.PooledObjectFactory;
|
||||
import org.apache.commons.pool2.impl.DefaultPooledObject;
|
||||
import org.collectd.api.Collectd;
|
||||
import org.collectd.api.OConfigItem;
|
||||
|
||||
import java.net.Socket;
|
||||
|
||||
public class PooledSocketFactory implements PooledObjectFactory<Socket> {
|
||||
|
||||
private String host = null;
|
||||
+7
-6
@@ -1,11 +1,5 @@
|
||||
package timely.collectd.plugin;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Random;
|
||||
|
||||
import org.apache.commons.pool2.impl.GenericObjectPool;
|
||||
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
|
||||
import org.apache.http.HttpStatus;
|
||||
@@ -21,6 +15,12 @@ import org.collectd.api.CollectdWriteInterface;
|
||||
import org.collectd.api.OConfigItem;
|
||||
import org.collectd.api.ValueList;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
*
|
||||
* CollectD plugin that writes metrics collected by the StatsD plugin to NSQ. NSQ can be configured to write statsd metrics to CollectD. If you do this, set the
|
||||
@@ -79,6 +79,7 @@ public class WriteNSQPlugin extends CollectDPluginParent implements CollectdConf
|
||||
} catch (IOException e1) {}
|
||||
try {
|
||||
clientPool.invalidateObject(client);
|
||||
client = null;
|
||||
} catch (Exception e2) {}
|
||||
}
|
||||
} finally {
|
||||
@@ -0,0 +1,99 @@
|
||||
package timely.collectd.plugin;
|
||||
|
||||
import org.apache.commons.pool2.impl.GenericObjectPool;
|
||||
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
|
||||
import org.collectd.api.Collectd;
|
||||
import org.collectd.api.CollectdConfigInterface;
|
||||
import org.collectd.api.CollectdShutdownInterface;
|
||||
import org.collectd.api.CollectdWriteInterface;
|
||||
import org.collectd.api.OConfigItem;
|
||||
import org.collectd.api.ValueList;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.Socket;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
*
|
||||
* CollectD plugin that writes metrics collected by the StatsD plugin to Timely.
|
||||
*
|
||||
*/
|
||||
public class WriteTimelyPlugin extends CollectDPluginParent implements CollectdConfigInterface, CollectdShutdownInterface, CollectdWriteInterface {
|
||||
|
||||
private GenericObjectPool<Socket> socketPool = null;
|
||||
|
||||
// pool should be limited by the number of WriteThreads configured in
|
||||
// collectd
|
||||
static final private int POOL_MAX_SIZE = Integer.MAX_VALUE;
|
||||
|
||||
public WriteTimelyPlugin() {
|
||||
Collectd.registerConfig(WriteTimelyPlugin.class.getName(), this);
|
||||
Collectd.registerShutdown(WriteTimelyPlugin.class.getName(), this);
|
||||
Collectd.registerWrite(WriteTimelyPlugin.class.getName(), this);
|
||||
}
|
||||
|
||||
public int write(ValueList vl) {
|
||||
|
||||
Socket socket = null;
|
||||
try {
|
||||
socket = socketPool.borrowObject();
|
||||
if (socket == null) {
|
||||
return -1;
|
||||
}
|
||||
super.process(vl, socket.getOutputStream());
|
||||
} catch (Exception e) {
|
||||
Collectd.logWarning(e.getMessage());
|
||||
try {
|
||||
// close socket so that the object pool will discard it and
|
||||
// reconnect
|
||||
if (socket != null) {
|
||||
socket.close();
|
||||
}
|
||||
} catch (IOException e1) {
|
||||
Collectd.logError(e1.getMessage());
|
||||
}
|
||||
return -1;
|
||||
} finally {
|
||||
if (socket != null) {
|
||||
socketPool.returnObject(socket);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(String metric, OutputStream out) {
|
||||
PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8), false);
|
||||
printWriter.write(metric);
|
||||
printWriter.flush();
|
||||
if (printWriter.checkError()) {
|
||||
throw new RuntimeException("Error writing to Timely");
|
||||
}
|
||||
}
|
||||
|
||||
public int shutdown() {
|
||||
socketPool.close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int config(OConfigItem config) {
|
||||
super.config(config);
|
||||
int retval = 0;
|
||||
PooledSocketFactory socketFactory = new PooledSocketFactory();
|
||||
retval = socketFactory.config(config);
|
||||
if (retval == 0) {
|
||||
GenericObjectPoolConfig<Socket> poolConfig = new GenericObjectPoolConfig<>();
|
||||
// use max size for maxTotal and maxIdle
|
||||
// no need to activate and passivate
|
||||
poolConfig.setMaxTotal(POOL_MAX_SIZE);
|
||||
poolConfig.setMaxIdle(POOL_MAX_SIZE);
|
||||
poolConfig.setTestOnReturn(true);
|
||||
socketPool = new GenericObjectPool<>(socketFactory, poolConfig);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
}
|
||||
+7
-8
@@ -1,12 +1,6 @@
|
||||
package timely.collectd.plugin;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.Collections;
|
||||
|
||||
import net.jcip.annotations.NotThreadSafe;
|
||||
import org.collectd.api.Collectd;
|
||||
import org.collectd.api.DataSet;
|
||||
import org.collectd.api.DataSource;
|
||||
@@ -21,7 +15,12 @@ import org.powermock.core.classloader.annotations.PowerMockIgnore;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
import net.jcip.annotations.NotThreadSafe;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.Collections;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({Collectd.class})
|
||||
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<FindBugsFilter>
|
||||
<Match>
|
||||
<Bug pattern="DM_DEFAULT_ENCODING"/>
|
||||
<Method name="connect" />
|
||||
<Class name="timely.collectd.plugin.WriteTimelyPlugin"/>
|
||||
</Match>
|
||||
</FindBugsFilter>
|
||||
@@ -1,24 +0,0 @@
|
||||
Configuration:
|
||||
status: warn
|
||||
monitorInterval: 60
|
||||
|
||||
Properties:
|
||||
Property:
|
||||
- name: PID
|
||||
value: "????"
|
||||
- name: LOG_PATTERN
|
||||
value: "%clr{%d{yyyy-MM-dd HH:mm:ss.SSS}}{faint} %clr{%5p} %clr{${sys:PID}}{magenta} %clr{---}{faint} %clr{[%15.15t]}{faint} %clr{%-40.40c{1.}}{cyan} %clr{:}{faint} %m%n%wEx"
|
||||
|
||||
Appenders:
|
||||
Console:
|
||||
name: Console
|
||||
target: SYSTEM_OUT
|
||||
follow: true
|
||||
PatternLayout:
|
||||
pattern: "${LOG_PATTERN}"
|
||||
|
||||
Loggers:
|
||||
Root:
|
||||
level: warn
|
||||
AppenderRef:
|
||||
- ref: Console
|
||||
@@ -4,9 +4,9 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>2.1.0</version>
|
||||
<version>2.2.1</version>
|
||||
</parent>
|
||||
<artifactId>collectd-timely-plugin</artifactId>
|
||||
<artifactId>timely-collectd</artifactId>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>collectd</groupId>
|
||||
@@ -16,25 +16,23 @@
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>jcl-over-slf4j</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>collectd-plugin-parent</artifactId>
|
||||
<artifactId>timely-common</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.jcip</groupId>
|
||||
<artifactId>jcip-annotations</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.powermock</groupId>
|
||||
<artifactId>powermock-easymock-release-full</artifactId>
|
||||
@@ -49,7 +47,17 @@
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<configuration>
|
||||
<artifactSet>
|
||||
<includes />
|
||||
<includes>
|
||||
<include>com.google.guava:guava</include>
|
||||
<include>commons-codec:commons-codec</include>
|
||||
<include>org.apache.commons:commons-lang3</include>
|
||||
<include>org.apache.commons:commons-pool2</include>
|
||||
<include>org.apache.httpcomponents:httpclient</include>
|
||||
<include>org.apache.httpcomponents:httpcore</include>
|
||||
<include>org.slf4j:jcl-over-slf4j</include>
|
||||
<include>org.slf4j:slf4j-api</include>
|
||||
<include>timely:timely-common</include>
|
||||
</includes>
|
||||
</artifactSet>
|
||||
<filters>
|
||||
<filter>
|
||||
@@ -0,0 +1,424 @@
|
||||
package timely.collectd.plugin;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.collectd.api.Collectd;
|
||||
import org.collectd.api.OConfigItem;
|
||||
import org.collectd.api.ValueList;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import timely.util.Exclusions;
|
||||
|
||||
public abstract class CollectDPluginParent {
|
||||
|
||||
private static final String PUT = "put {0} {1} {2} {3}";
|
||||
private static final String INSTANCE = "instance";
|
||||
private static final String NAME = "name";
|
||||
private static final String SAMPLE_TYPE = "sampleType";
|
||||
private static final String CODE = "code";
|
||||
private static final String PERIOD = ".";
|
||||
private static final String COUNTER = "COUNTER";
|
||||
private static final String GAUGE = "GAUGE";
|
||||
private static final String DERIVE = "DERIVE";
|
||||
private static final String ABSOLUTE = "ABSOLUTE";
|
||||
private static final Collection<String> HADOOP_CONTEXTS = Arrays.asList("NameNode", "DataNode", "JobManager", "NodeManager", "JobHistoryServer",
|
||||
"ResourceManager", "MRAppMaster");
|
||||
private static final Pattern HADOOP_PATTERN_4_GROUPS = Pattern.compile("([\\w-_]+)\\.([\\w-_]+)\\.([\\w-_]+)\\.([\\w-_]+)");
|
||||
private static final Pattern STATSD_PATTERN_3_GROUPS = Pattern.compile("([\\w-_]+)\\.([\\w-_]+)\\.([\\w-_]+)");
|
||||
private static final Pattern STATSD_PATTERN_4_GROUPS = Pattern.compile("([\\w-_]+)\\.([\\w-_]+)\\.([\\w-_]+)\\.([\\w-_]+)");
|
||||
private static final Pattern STATSD_PATTERN_6_GROUPS = Pattern.compile("([\\w-_]+)\\.([\\w-_]+)\\.([\\w-_]+)\\.([\\w-_]+)\\.([\\w-_#]+)\\.([\\w-_]+)");
|
||||
private static final Pattern ETHSTAT_QUEUE_PATTERN1 = Pattern.compile("([\\w-_]*)queue_([0-9]+)_([\\w-_]+)");
|
||||
private static final Pattern ETHSTAT_QUEUE_PATTERN2 = Pattern.compile("([\\w-_\\.]*)(tx|rx)([-_]?)([0-9]+)([._])([\\w-_]+)");
|
||||
private static final Pattern ETHSTAT_TRAFFIC_CLASS_PATTERN = Pattern.compile("([\\w-_\\.]*)(tc)([-_]?)([0-9]+)([._])([\\w-_]+)");
|
||||
private static final Pattern ETHSTAT_CHANNEL_PATTERN = Pattern.compile("(ch)([0-9]+)([._])([\\w-_]+)");
|
||||
private static final String STATSD_PREFIX = "statsd";
|
||||
private static final String NSQ_PREFIX = STATSD_PREFIX + ".nsq.";
|
||||
private static final Pattern HAPROXY_PATTERN = Pattern.compile("\\[([\\w-_=]+),([\\w-_=]+)\\]");
|
||||
private static final Logger log = LoggerFactory.getLogger(CollectDPluginParent.class);
|
||||
|
||||
private final SMARTCodeMapping smart = new SMARTCodeMapping();
|
||||
protected Map<String,String> addlTags = new TreeMap<>();
|
||||
private boolean debug = false;
|
||||
private Exclusions exclusions = new Exclusions();
|
||||
|
||||
public int config(OConfigItem config) {
|
||||
for (OConfigItem child : config.getChildren()) {
|
||||
switch (child.getKey().toLowerCase()) {
|
||||
case "tags":
|
||||
String tagValue = child.getValues().get(0).getString();
|
||||
Arrays.stream(tagValue.split(",")).map(String::trim).forEach(p -> {
|
||||
String[] pair = p.split("=");
|
||||
if (pair.length == 2) {
|
||||
addTag(addlTags, pair[0], pair[1]);
|
||||
}
|
||||
});
|
||||
break;
|
||||
case "filteredmetricsfile":
|
||||
setFilteredMetricsFile(child.getValues().get(0).getString());
|
||||
break;
|
||||
case "filteredtagsfile":
|
||||
setFilteredTagsFile(child.getValues().get(0).getString());
|
||||
break;
|
||||
case "debug":
|
||||
debug = child.getValues().get(0).getBoolean();
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void setFilteredMetricsFile(String filteredMetricsFile) {
|
||||
if (StringUtils.isNotBlank(filteredMetricsFile)) {
|
||||
exclusions.setFilteredMetricsFile(filteredMetricsFile);
|
||||
}
|
||||
}
|
||||
|
||||
public void setFilteredTagsFile(String filteredTagsFile) {
|
||||
if (StringUtils.isNotBlank(filteredTagsFile)) {
|
||||
exclusions.setFilteredTagsFile(filteredTagsFile);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void write(String metric, OutputStream out);
|
||||
|
||||
protected void addTag(Map<String,String> m, String k, String v) {
|
||||
if (k != null && !k.isBlank() && v != null && !v.isBlank()) {
|
||||
k = k.replaceAll("=", ":");
|
||||
v = v.replaceAll("=", ":");
|
||||
m.put(k.trim(), v.trim());
|
||||
}
|
||||
}
|
||||
|
||||
protected void addTag(Map<String,String> m, String kv) {
|
||||
if (kv != null && !kv.isBlank()) {
|
||||
String[] parts = kv.split("=");
|
||||
if (parts.length == 2) {
|
||||
addTag(m, parts[0], parts[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void process(ValueList vl, OutputStream out) {
|
||||
try {
|
||||
processInternal(vl, out);
|
||||
} catch (Exception e) {
|
||||
Collectd.logError(e.getMessage());
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
|
||||
private void processInternal(ValueList vl, OutputStream out) {
|
||||
debugValueList(vl);
|
||||
|
||||
StringBuilder metric = new StringBuilder();
|
||||
Long timestamp = vl.getTime();
|
||||
Map<String,String> tagMap = new TreeMap<>();
|
||||
String host = vl.getHost();
|
||||
int idx = host.indexOf(PERIOD);
|
||||
if (-1 != idx) {
|
||||
addTag(tagMap, "host", host.substring(0, idx));
|
||||
} else {
|
||||
addTag(tagMap, "host", host);
|
||||
}
|
||||
String[] hostSplit = host.split("\\.");
|
||||
int nIdx = hostSplit[0].lastIndexOf('n');
|
||||
if (-1 != nIdx) {
|
||||
addTag(tagMap, "rack", hostSplit[0].substring(0, nIdx));
|
||||
}
|
||||
tagMap.putAll(addlTags);
|
||||
|
||||
String plugin = vl.getPlugin();
|
||||
String pluginInstance = vl.getPluginInstance();
|
||||
String type = vl.getType();
|
||||
String typeInstance = vl.getTypeInstance();
|
||||
|
||||
switch (plugin) {
|
||||
case STATSD_PREFIX:
|
||||
Matcher hadoop_4_groups = HADOOP_PATTERN_4_GROUPS.matcher(typeInstance);
|
||||
Matcher statsd_3_groups = STATSD_PATTERN_3_GROUPS.matcher(typeInstance);
|
||||
Matcher statsd_4_groups = STATSD_PATTERN_4_GROUPS.matcher(typeInstance);
|
||||
Matcher statsd_6_groups = STATSD_PATTERN_6_GROUPS.matcher(typeInstance);
|
||||
String instance = null;
|
||||
boolean defaultCase = false;
|
||||
if (!typeInstance.startsWith("nsq")) {
|
||||
String[] parts = typeInstance.split("\\.");
|
||||
if (parts.length >= 4 && (HADOOP_CONTEXTS.contains(parts[0]) || hadoop_4_groups.matches())) {
|
||||
// Here we are processing the statsd metrics coming from the Hadoop Metrics2 StatsDSink without the host name.
|
||||
// The format of metric is: serviceName.contextName.recordName.metricName
|
||||
// The serviceName is used as the instance.
|
||||
instance = parts[0];
|
||||
String contextName = parts[1];
|
||||
int firstPeriod = typeInstance.indexOf(".");
|
||||
int lastPeriod = typeInstance.lastIndexOf(".");
|
||||
String metricName = typeInstance.substring(lastPeriod + 1);
|
||||
String recordName = typeInstance.substring(firstPeriod + 1, lastPeriod);
|
||||
// the recordName may contain useful tags such as op=<operation> and user<user>
|
||||
// in addition to a possibly duplicative recordName
|
||||
String[] recordNameSplits = recordName.split("\\.");
|
||||
metric.append(STATSD_PREFIX).append(PERIOD).append(contextName).append(PERIOD);
|
||||
for (String split : recordNameSplits) {
|
||||
// avoid duplication with either the contextName or instance
|
||||
if (!split.equalsIgnoreCase(contextName) && !split.equalsIgnoreCase(instance)) {
|
||||
if (split.startsWith("NNTopUserOpCounts") && split.contains("windowMs=")) {
|
||||
metric.append("NNTopUserOpCounts").append(PERIOD);
|
||||
addTag(tagMap, split.substring(split.indexOf("windowMs=")));
|
||||
} else if (split.contains("=")) {
|
||||
addTag(tagMap, split);
|
||||
} else {
|
||||
addTag(tagMap, "record", split);
|
||||
}
|
||||
}
|
||||
}
|
||||
metric.append(metricName);
|
||||
} else if (parts.length >= 2 && parts[1].equals("dwquery")) {
|
||||
// These come from Datawave's QueryIterator metrics - the first split part is the queryId
|
||||
// Use statsd plus the rest of the typeInstance after the first period as the metric name
|
||||
int x = typeInstance.indexOf(".");
|
||||
metric.append(STATSD_PREFIX).append(PERIOD).append(typeInstance.substring(x + 1));
|
||||
addTag(tagMap, "queryId", parts[0]);
|
||||
} else 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]);
|
||||
}
|
||||
} else if (statsd_4_groups.matches()) {
|
||||
// Here we are processing the statsd metrics coming from the Hadoop Metrics2 StatsDSink without the host name.
|
||||
// The format of metric is: serviceName.contextName.recordName.metricName. The recordName is typically duplicative
|
||||
// and is dropped here. The serviceName is used as the instance.
|
||||
metric.append(STATSD_PREFIX).append(PERIOD).append(statsd_4_groups.group(2)).append(PERIOD).append(statsd_4_groups.group(4));
|
||||
instance = statsd_4_groups.group(1);
|
||||
} else {
|
||||
defaultCase = true;
|
||||
}
|
||||
} else {
|
||||
if (statsd_3_groups.matches()) {
|
||||
metric.append(NSQ_PREFIX).append(statsd_3_groups.group(2)).append(PERIOD).append(statsd_3_groups.group(3));
|
||||
} else if (statsd_4_groups.matches()) {
|
||||
metric.append(NSQ_PREFIX).append(statsd_4_groups.group(2)).append(PERIOD).append(statsd_4_groups.group(4));
|
||||
instance = statsd_4_groups.group(3);
|
||||
} else if (statsd_6_groups.matches()) {
|
||||
metric.append(NSQ_PREFIX).append(statsd_6_groups.group(4)).append(PERIOD).append(statsd_6_groups.group(6));
|
||||
instance = statsd_6_groups.group(5);
|
||||
} else {
|
||||
defaultCase = true;
|
||||
}
|
||||
}
|
||||
if (defaultCase) {
|
||||
// Handle StatsD metrics of unknown formats. If there is a
|
||||
// period in the metric name, use everything up to that as
|
||||
// the instance.
|
||||
int period = typeInstance.indexOf('.');
|
||||
if (-1 == period) {
|
||||
metric.append(STATSD_PREFIX).append(PERIOD).append(typeInstance);
|
||||
} else {
|
||||
instance = typeInstance.substring(0, period);
|
||||
metric.append(STATSD_PREFIX).append(PERIOD).append(typeInstance.substring(period + 1));
|
||||
}
|
||||
}
|
||||
if (null != instance) {
|
||||
addTag(tagMap, INSTANCE, instance);
|
||||
}
|
||||
break;
|
||||
case "ethstat":
|
||||
metric.append("sys.ethstat.");
|
||||
if (typeInstance.matches(ETHSTAT_QUEUE_PATTERN1.pattern())) {
|
||||
Matcher ethstat_m = ETHSTAT_QUEUE_PATTERN1.matcher(typeInstance);
|
||||
if (ethstat_m.matches()) {
|
||||
metric.append(ethstat_m.group(1));
|
||||
metric.append("queue_");
|
||||
metric.append(ethstat_m.group(3));
|
||||
addTag(tagMap, "queue", ethstat_m.group(2));
|
||||
}
|
||||
} else if (typeInstance.matches(ETHSTAT_QUEUE_PATTERN2.pattern())) {
|
||||
Matcher ethstat_m = ETHSTAT_QUEUE_PATTERN2.matcher(typeInstance);
|
||||
if (ethstat_m.matches()) {
|
||||
metric.append(ethstat_m.group(1));
|
||||
metric.append(ethstat_m.group(2));
|
||||
metric.append("_queue_");
|
||||
metric.append(ethstat_m.group(6));
|
||||
addTag(tagMap, "queue", ethstat_m.group(4));
|
||||
}
|
||||
} else if (typeInstance.matches(ETHSTAT_TRAFFIC_CLASS_PATTERN.pattern())) {
|
||||
Matcher ethstat_m = ETHSTAT_TRAFFIC_CLASS_PATTERN.matcher(typeInstance);
|
||||
if (ethstat_m.matches()) {
|
||||
metric.append(ethstat_m.group(1));
|
||||
metric.append(ethstat_m.group(2));
|
||||
metric.append(ethstat_m.group(5));
|
||||
metric.append(ethstat_m.group(6));
|
||||
addTag(tagMap, "trafficClass", ethstat_m.group(4));
|
||||
}
|
||||
} else if (typeInstance.matches(ETHSTAT_CHANNEL_PATTERN.pattern())) {
|
||||
Matcher ethstat_m = ETHSTAT_CHANNEL_PATTERN.matcher(typeInstance);
|
||||
if (ethstat_m.matches()) {
|
||||
metric.append(ethstat_m.group(1));
|
||||
metric.append("_");
|
||||
metric.append(ethstat_m.group(4));
|
||||
addTag(tagMap, "channel", ethstat_m.group(2));
|
||||
}
|
||||
} else {
|
||||
metric.append(typeInstance);
|
||||
}
|
||||
addTag(tagMap, INSTANCE, pluginInstance);
|
||||
break;
|
||||
case "hddtemp":
|
||||
metric.append("sys.hddtemp.").append(type);
|
||||
addTag(tagMap, INSTANCE, typeInstance);
|
||||
break;
|
||||
case "smart":
|
||||
int code = -1;
|
||||
String name = null;
|
||||
if (typeInstance.startsWith("attribute-")) {
|
||||
int hyphen = typeInstance.indexOf('-');
|
||||
code = Integer.parseInt(typeInstance.substring(hyphen + 1));
|
||||
name = smart.get(code);
|
||||
}
|
||||
if (code == -1) {
|
||||
if (notEmpty(typeInstance)) {
|
||||
metric.append("sys.smart.").append(typeInstance);
|
||||
} else {
|
||||
metric.append("sys.smart.").append(type);
|
||||
}
|
||||
} else {
|
||||
metric.append("sys.smart.").append(name);
|
||||
addTag(tagMap, CODE, Integer.toString(code));
|
||||
}
|
||||
addTag(tagMap, INSTANCE, pluginInstance);
|
||||
break;
|
||||
case "sensors":
|
||||
if (typeInstance.startsWith("temp")) {
|
||||
addTag(tagMap, INSTANCE, typeInstance.substring(4));
|
||||
}
|
||||
metric.append("sys.sensors.").append(type).append(PERIOD).append(pluginInstance);
|
||||
break;
|
||||
case "haproxy":
|
||||
metric.append("sys.haproxy.").append(typeInstance);
|
||||
Matcher hadoop_m2 = HAPROXY_PATTERN.matcher(pluginInstance);
|
||||
if (hadoop_m2.matches()) {
|
||||
addTag(tagMap, hadoop_m2.group(1));
|
||||
addTag(tagMap, hadoop_m2.group(2));
|
||||
}
|
||||
break;
|
||||
case "ipmi":
|
||||
case "snmp":
|
||||
metric.append("sys.").append(plugin).append(PERIOD).append(type);
|
||||
addTag(tagMap, INSTANCE, typeInstance.replaceAll(" ", "_"));
|
||||
break;
|
||||
case "load":
|
||||
metric.append("sys.load.").append(plugin).append(PERIOD).append(type);
|
||||
// plugin returns 1 min, 5 min, 15 min averages, but Timely can
|
||||
// downsample on its own so we only use the first (1 min) value
|
||||
vl.setValues(Arrays.asList(vl.getValues().get(0)));
|
||||
break;
|
||||
case "GenericJMX":
|
||||
metric.append("sys.").append(plugin).append(PERIOD).append(type).append(PERIOD).append(typeInstance);
|
||||
String[] pluginInstanceSplit = pluginInstance.split("-");
|
||||
if (pluginInstanceSplit.length > 0) {
|
||||
addTag(tagMap, INSTANCE, pluginInstanceSplit[0].replaceAll(" ", "_"));
|
||||
}
|
||||
if (pluginInstanceSplit.length > 1) {
|
||||
addTag(tagMap, NAME, pluginInstanceSplit[1].replaceAll(" ", "_"));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (notEmpty(type) && notEmpty(typeInstance) && notEmpty(plugin) && notEmpty(pluginInstance)) {
|
||||
metric.append("sys.").append(plugin).append(PERIOD).append(type).append(PERIOD).append(typeInstance);
|
||||
addTag(tagMap, INSTANCE, pluginInstance.replaceAll(" ", "_"));
|
||||
} else if (notEmpty(type) && notEmpty(typeInstance) && notEmpty(plugin)) {
|
||||
metric.append("sys.").append(plugin).append(PERIOD).append(type).append(PERIOD).append(typeInstance);
|
||||
} else if (notEmpty(type) && notEmpty(plugin) && notEmpty(pluginInstance)) {
|
||||
metric.append("sys.").append(plugin).append(PERIOD).append(type);
|
||||
addTag(tagMap, INSTANCE, pluginInstance.replaceAll(" ", "_"));
|
||||
} else if (notEmpty(type) && notEmpty(plugin)) {
|
||||
metric.append("sys.").append(plugin).append(PERIOD).append(type);
|
||||
} else {
|
||||
Collectd.logWarning("Unhandled metric: " + vl);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
final String metricName = metric.toString().replaceAll(" ", "_");
|
||||
for (int i = 0; i < vl.getValues().size(); i++) {
|
||||
int dataSourceSampleType = vl.getDataSet().getDataSources().get(i).getType();
|
||||
String sampleType = convertType(dataSourceSampleType);
|
||||
if (null != sampleType) {
|
||||
addTag(tagMap, SAMPLE_TYPE, sampleType);
|
||||
}
|
||||
Double value = vl.getValues().get(i).doubleValue();
|
||||
String tagString = tagMap.entrySet().stream().map(e -> e.getKey() + "=" + e.getValue()).collect(Collectors.joining(" "));
|
||||
|
||||
if (metricName.isBlank() || timestamp == null || value == null) {
|
||||
logDebug(String.format("Not writing unhandled metric: plugin:%s pluginInstance:%s type:%s typeInstance:%s", plugin, pluginInstance, type,
|
||||
typeInstance));
|
||||
} else {
|
||||
String datapoint = MessageFormat.format(PUT, metricName, timestamp.toString(), value.toString(), tagString);
|
||||
if (exclusions.filterMetric(datapoint)) {
|
||||
logDebug(String.format("Not writing excluded metric: %s", datapoint));
|
||||
} else {
|
||||
datapoint = exclusions.filterExcludedTags(datapoint);
|
||||
logDebug(String.format("Writing: %s", datapoint));
|
||||
write(datapoint + "\n", out);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void logDebug(String s) {
|
||||
// collectd must be compiled with debug enabled in order for log level debug to work
|
||||
if (debug) {
|
||||
Collectd.logInfo(s);
|
||||
} else {
|
||||
Collectd.logDebug(s);
|
||||
}
|
||||
}
|
||||
|
||||
private void debugValueList(ValueList vl) {
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(String.format("Plugin:%s", vl.getPlugin()));
|
||||
if (vl.getPluginInstance() != null && !vl.getPluginInstance().isBlank()) {
|
||||
sb.append(String.format(" PluginInstance:%s", vl.getPluginInstance()));
|
||||
}
|
||||
sb.append(String.format(" Type:%s", vl.getType()));
|
||||
sb.append(String.format(" TypeInstance:%s", vl.getTypeInstance()));
|
||||
for (int i = 0; i < vl.getValues().size(); i++) {
|
||||
Number value = vl.getValues().get(i);
|
||||
sb.append(String.format(" Value:%s", value.toString()));
|
||||
}
|
||||
logDebug(sb.toString());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
logDebug(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private String convertType(int type) {
|
||||
switch (type) {
|
||||
case 0:
|
||||
return COUNTER;
|
||||
case 1:
|
||||
return GAUGE;
|
||||
case 2:
|
||||
return DERIVE;
|
||||
case 3:
|
||||
return ABSOLUTE;
|
||||
default:
|
||||
return GAUGE;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean notEmpty(String arg) {
|
||||
return (null != arg) && !(arg.equals(""));
|
||||
}
|
||||
}
|
||||
File renamed without changes.
@@ -0,0 +1,122 @@
|
||||
package timely.collectd.plugin;
|
||||
|
||||
import java.net.Socket;
|
||||
|
||||
import org.apache.commons.pool2.PooledObject;
|
||||
import org.apache.commons.pool2.PooledObjectFactory;
|
||||
import org.apache.commons.pool2.impl.DefaultPooledObject;
|
||||
import org.collectd.api.Collectd;
|
||||
import org.collectd.api.OConfigItem;
|
||||
|
||||
public class PooledSocketFactory implements PooledObjectFactory<Socket> {
|
||||
|
||||
private String host = null;
|
||||
private int port = 0;
|
||||
private static final long initialBackoff = 2000;
|
||||
private int socketTimeout = 60000; // 60 seconds in milliseconds
|
||||
private long connectionTimeToLive = 300000; // 300 seconds in milliseconds
|
||||
|
||||
public int config(OConfigItem config) {
|
||||
for (OConfigItem child : config.getChildren()) {
|
||||
switch (child.getKey()) {
|
||||
case "host":
|
||||
case "hostname":
|
||||
case "Host":
|
||||
case "HostName":
|
||||
host = child.getValues().get(0).getString();
|
||||
break;
|
||||
case "Port":
|
||||
case "port":
|
||||
port = Integer.parseInt(child.getValues().get(0).getString());
|
||||
break;
|
||||
case "socketTimeout":
|
||||
case "SocketTimeout":
|
||||
socketTimeout = Integer.parseInt(child.getValues().get(0).getString());
|
||||
break;
|
||||
case "connectionTimeToLive":
|
||||
case "ConnectionTimeToLive":
|
||||
connectionTimeToLive = Long.parseLong(child.getValues().get(0).getString());
|
||||
break;
|
||||
default:
|
||||
|
||||
}
|
||||
}
|
||||
if (null != host) {
|
||||
return 0;
|
||||
}
|
||||
if (host == null) {
|
||||
Collectd.logError("Timely host must be configured");
|
||||
}
|
||||
if (port == 0) {
|
||||
Collectd.logError("Timely port must be configured");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private Socket connect() {
|
||||
|
||||
Socket socket = null;
|
||||
long currentBackoff = initialBackoff;
|
||||
while (socket == null) {
|
||||
try {
|
||||
socket = new Socket(host, port);
|
||||
if (socketTimeout > -1) {
|
||||
socket.setSoTimeout(socketTimeout);
|
||||
}
|
||||
Collectd.logInfo("Connected to Timely at " + host + ":" + port + " from local port:" + socket.getLocalPort());
|
||||
} catch (Exception e) {
|
||||
Collectd.logError("Error connecting to Timely at " + host + ":" + port + ". Error: " + e.getMessage() + ". Will retry connection in "
|
||||
+ currentBackoff + " ms.");
|
||||
try {
|
||||
Thread.sleep(currentBackoff);
|
||||
} catch (InterruptedException e1) {
|
||||
|
||||
}
|
||||
// max out reconnect period at one minute
|
||||
currentBackoff = (currentBackoff * 2 > 60000) ? 60000 : currentBackoff * 2;
|
||||
}
|
||||
}
|
||||
return socket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PooledObject<Socket> makeObject() {
|
||||
return new DefaultPooledObject<>(connect());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyObject(PooledObject<Socket> pooledObject) {
|
||||
try {
|
||||
Collectd.logDebug("Shutting down connection to Timely at " + host + ":" + port);
|
||||
Socket socket = pooledObject.getObject();
|
||||
if (socket != null) {
|
||||
socket.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Collectd.logError("Error closing connection to Timely at " + host + ":" + port + ". Error: " + e.getMessage());
|
||||
} finally {
|
||||
pooledObject.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateObject(PooledObject<Socket> pooledObject) {
|
||||
if (connectionTimeToLive > -1) {
|
||||
if (System.currentTimeMillis() > pooledObject.getCreateTime() + connectionTimeToLive) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Socket socket = pooledObject.getObject();
|
||||
return socket != null && !socket.isClosed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activateObject(PooledObject<Socket> pooledObject) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void passivateObject(PooledObject<Socket> pooledObject) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
File renamed without changes.
@@ -0,0 +1,161 @@
|
||||
package timely.collectd.plugin;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Random;
|
||||
|
||||
import org.apache.commons.pool2.impl.GenericObjectPool;
|
||||
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.client.entity.EntityBuilder;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.collectd.api.Collectd;
|
||||
import org.collectd.api.CollectdConfigInterface;
|
||||
import org.collectd.api.CollectdShutdownInterface;
|
||||
import org.collectd.api.CollectdWriteInterface;
|
||||
import org.collectd.api.OConfigItem;
|
||||
import org.collectd.api.ValueList;
|
||||
|
||||
/**
|
||||
*
|
||||
* CollectD plugin that writes metrics collected by the StatsD plugin to NSQ. NSQ can be configured to write statsd metrics to CollectD. If you do this, set the
|
||||
* statsd prefix in NSQ to 'nsq'.
|
||||
*
|
||||
*/
|
||||
public class WriteNSQPlugin extends CollectDPluginParent implements CollectdConfigInterface, CollectdShutdownInterface, CollectdWriteInterface {
|
||||
|
||||
private String host = null;
|
||||
private int port = 0;
|
||||
private String topic = "metrics#ephemeral";
|
||||
private String endpoint = null;
|
||||
private GenericObjectPool<CloseableHttpClient> clientPool = null;
|
||||
private Random random = new Random();
|
||||
|
||||
// pool should be limited by the number of WriteThreads configured in
|
||||
// collectd
|
||||
static final private int POOL_MAX_SIZE = Integer.MAX_VALUE;
|
||||
|
||||
public WriteNSQPlugin() {
|
||||
Collectd.registerConfig(WriteNSQPlugin.class.getName(), this);
|
||||
Collectd.registerShutdown(WriteNSQPlugin.class.getName(), this);
|
||||
Collectd.registerWrite(WriteNSQPlugin.class.getName(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int write(ValueList vl) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
DataOutputStream out = new DataOutputStream(baos);
|
||||
super.process(vl, out);
|
||||
CloseableHttpClient client = null;
|
||||
try {
|
||||
out.flush();
|
||||
HttpPost post = new HttpPost(endpoint);
|
||||
EntityBuilder request = EntityBuilder.create();
|
||||
request.setBinary(baos.toByteArray());
|
||||
post.setEntity(request.build());
|
||||
client = clientPool.borrowObject();
|
||||
CloseableHttpResponse response = client.execute(post);
|
||||
try {
|
||||
int code = response.getStatusLine().getStatusCode();
|
||||
String msg = response.getStatusLine().getReasonPhrase();
|
||||
// Consume the entire response so the connection will be reused
|
||||
EntityUtils.consume(response.getEntity());
|
||||
if (code != HttpStatus.SC_OK) {
|
||||
Collectd.logInfo("Code: " + code + ", msg: " + msg);
|
||||
}
|
||||
} finally {
|
||||
response.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Collectd.logError("Error sending metrics to NSQ: " + e.getMessage());
|
||||
if (client != null) {
|
||||
try {
|
||||
client.close();
|
||||
} catch (IOException e1) {}
|
||||
try {
|
||||
clientPool.invalidateObject(client);
|
||||
client = null;
|
||||
} catch (Exception e2) {}
|
||||
}
|
||||
} finally {
|
||||
if (client != null) {
|
||||
clientPool.returnObject(client);
|
||||
}
|
||||
try {
|
||||
out.close();
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(String metric, OutputStream out) {
|
||||
try {
|
||||
((DataOutputStream) out).writeBytes(metric);
|
||||
} catch (IOException e) {
|
||||
Collectd.logError("Error writing metric: " + e.getMessage());
|
||||
try {
|
||||
out.close(); // Should cause IOException in write.
|
||||
} catch (IOException e1) {}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int shutdown() {
|
||||
Collectd.logInfo("Shutting down connection to NSQ at " + host + ":" + port);
|
||||
clientPool.close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int config(OConfigItem config) {
|
||||
super.config(config);
|
||||
GenericObjectPoolConfig<CloseableHttpClient> poolConfig = new GenericObjectPoolConfig<>();
|
||||
// use max size for maxTotal and maxIdle
|
||||
// no need to activate or passivate
|
||||
poolConfig.setMaxTotal(POOL_MAX_SIZE);
|
||||
poolConfig.setMaxIdle(POOL_MAX_SIZE);
|
||||
poolConfig.setTestOnReturn(true);
|
||||
PooledCloseableHttpClientFactory pooledCloseableHttpClientFactory = new PooledCloseableHttpClientFactory();
|
||||
pooledCloseableHttpClientFactory.config(config);
|
||||
|
||||
for (OConfigItem child : config.getChildren()) {
|
||||
switch (child.getKey()) {
|
||||
case "host":
|
||||
case "hostname":
|
||||
case "Host":
|
||||
case "HostName":
|
||||
String hostString = child.getValues().get(0).getString();
|
||||
String[] hosts = hostString.split(",");
|
||||
if (hosts.length == 1) {
|
||||
host = hosts[0];
|
||||
} else {
|
||||
host = hosts[random.nextInt(hosts.length)];
|
||||
}
|
||||
break;
|
||||
case "Port":
|
||||
case "port":
|
||||
port = Integer.parseInt(child.getValues().get(0).getString());
|
||||
break;
|
||||
case "topic":
|
||||
case "Topic":
|
||||
topic = child.getValues().get(0).getString();
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
if (host == null || port == 0 || topic == null) {
|
||||
Collectd.logError("NSQ host, port, and topic must be configured");
|
||||
return -1;
|
||||
}
|
||||
this.clientPool = new GenericObjectPool<>(pooledCloseableHttpClientFactory, poolConfig);
|
||||
this.endpoint = "http://" + host + ":" + port + "/mpub?topic=" + topic;
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
File renamed without changes.
+133
-32
@@ -3,6 +3,7 @@ package timely.collectd.plugin;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.collectd.api.Collectd;
|
||||
@@ -13,20 +14,19 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.powermock.api.easymock.PowerMock;
|
||||
import org.powermock.core.classloader.annotations.PowerMockIgnore;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
import net.jcip.annotations.NotThreadSafe;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PowerMockIgnore("jdk.internal.reflect.*")
|
||||
@PrepareForTest({Collectd.class})
|
||||
@NotThreadSafe
|
||||
public class PluginParentTest {
|
||||
|
||||
public class TestPlugin extends CollectDPluginParent {
|
||||
|
||||
public TestPlugin() {
|
||||
super.addlTags.add(" addl1=foo");
|
||||
super.addlTags.put("addl1", "foo");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -41,12 +41,13 @@ public class PluginParentTest {
|
||||
public String result = null;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
public void setup() {
|
||||
result = null;
|
||||
PowerMock.suppress(PowerMock.everythingDeclaredIn(Collectd.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStatsDHadoopFormat() throws Exception {
|
||||
public void testStatsDHadoopFormat() {
|
||||
ValueList vl = new ValueList();
|
||||
vl.setHost(HOST);
|
||||
vl.setPlugin("statsd");
|
||||
@@ -60,11 +61,11 @@ public class PluginParentTest {
|
||||
|
||||
TestPlugin test = new TestPlugin();
|
||||
test.process(vl, null);
|
||||
assertEquals("put statsd.dfs.BlocksRead 1456156976840 1.0 host=r01n01 rack=r01 addl1=foo instance=DataNode sample=value sampleType=GAUGE\n", result);
|
||||
assertEquals("put statsd.dfs.BlocksRead 1456156976840 1.0 addl1=foo host=r01n01 instance=DataNode rack=r01 sampleType=GAUGE\n", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStatsDUnknownFormat() throws Exception {
|
||||
public void testStatsDUnknownFormat() {
|
||||
ValueList vl = new ValueList();
|
||||
vl.setHost(HOST);
|
||||
vl.setPlugin("statsd");
|
||||
@@ -78,11 +79,11 @@ public class PluginParentTest {
|
||||
|
||||
TestPlugin test = new TestPlugin();
|
||||
test.process(vl, null);
|
||||
assertEquals("put statsd.baz 1456156976840 1.0 host=r01n01 rack=r01 addl1=foo sample=value sampleType=GAUGE\n", result);
|
||||
assertEquals("put statsd.baz 1456156976840 1.0 addl1=foo host=r01n01 rack=r01 sampleType=GAUGE\n", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStatsDUnknownFormat2() throws Exception {
|
||||
public void testStatsDUnknownFormat2() {
|
||||
ValueList vl = new ValueList();
|
||||
vl.setHost(HOST);
|
||||
vl.setPlugin("statsd");
|
||||
@@ -96,11 +97,11 @@ public class PluginParentTest {
|
||||
|
||||
TestPlugin test = new TestPlugin();
|
||||
test.process(vl, null);
|
||||
assertEquals("put statsd.baz 1456156976840 1.0 host=r01n01 rack=r01 addl1=foo instance=bar sample=value sampleType=GAUGE\n", result);
|
||||
assertEquals("put statsd.baz 1456156976840 1.0 addl1=foo host=r01n01 instance=bar rack=r01 sampleType=GAUGE\n", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHddTemp() throws Exception {
|
||||
public void testHddTemp() {
|
||||
ValueList vl = new ValueList();
|
||||
vl.setHost(HOST);
|
||||
vl.setPlugin("hddtemp");
|
||||
@@ -114,11 +115,11 @@ public class PluginParentTest {
|
||||
|
||||
TestPlugin test = new TestPlugin();
|
||||
test.process(vl, null);
|
||||
assertEquals("put sys.hddtemp.temperature 1456156976840 35.0 host=r01n01 rack=r01 addl1=foo instance=sda sample=value sampleType=GAUGE\n", result);
|
||||
assertEquals("put sys.hddtemp.temperature 1456156976840 35.0 addl1=foo host=r01n01 instance=sda rack=r01 sampleType=GAUGE\n", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSmart1() throws Exception {
|
||||
public void testSmart1() {
|
||||
ValueList vl = new ValueList();
|
||||
vl.setHost(HOST);
|
||||
vl.setPlugin("smart");
|
||||
@@ -132,11 +133,11 @@ public class PluginParentTest {
|
||||
|
||||
TestPlugin test = new TestPlugin();
|
||||
test.process(vl, null);
|
||||
assertEquals("put sys.smart.smart_badsectors 1456156976840 0.0 host=r01n01 rack=r01 addl1=foo instance=sda sample=value sampleType=GAUGE\n", result);
|
||||
assertEquals("put sys.smart.smart_badsectors 1456156976840 0.0 addl1=foo host=r01n01 instance=sda rack=r01 sampleType=GAUGE\n", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSmart2() throws Exception {
|
||||
public void testSmart2() {
|
||||
ValueList vl = new ValueList();
|
||||
vl.setHost(HOST);
|
||||
vl.setPlugin("smart");
|
||||
@@ -151,11 +152,11 @@ public class PluginParentTest {
|
||||
|
||||
TestPlugin test = new TestPlugin();
|
||||
test.process(vl, null);
|
||||
assertEquals("put sys.smart.raw-read-error-rate 1456156976840 0.0 host=r01n01 rack=r01 addl1=foo instance=sda sample=value sampleType=GAUGE\n", result);
|
||||
assertEquals("put sys.smart.raw-read-error-rate 1456156976840 0.0 addl1=foo host=r01n01 instance=sda rack=r01 sampleType=GAUGE\n", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSmartCode() throws Exception {
|
||||
public void testSmartCode() {
|
||||
ValueList vl = new ValueList();
|
||||
vl.setHost(HOST);
|
||||
vl.setPlugin("smart");
|
||||
@@ -170,12 +171,11 @@ public class PluginParentTest {
|
||||
|
||||
TestPlugin test = new TestPlugin();
|
||||
test.process(vl, null);
|
||||
assertEquals("put sys.smart.Total_LBAs_Read 1456156976840 0.0 host=r01n01 rack=r01 addl1=foo code=242 instance=sda sample=value sampleType=GAUGE\n",
|
||||
result);
|
||||
assertEquals("put sys.smart.Total_LBAs_Read 1456156976840 0.0 addl1=foo code=242 host=r01n01 instance=sda rack=r01 sampleType=GAUGE\n", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSnmp() throws Exception {
|
||||
public void testSnmp() {
|
||||
ValueList vl = new ValueList();
|
||||
vl.setHost(HOST);
|
||||
vl.setPlugin("snmp");
|
||||
@@ -190,7 +190,7 @@ public class PluginParentTest {
|
||||
|
||||
TestPlugin test = new TestPlugin();
|
||||
test.process(vl, null);
|
||||
assertEquals("put sys.snmp.if_octets 1456156976840 0.0 host=r01n01 rack=r01 addl1=foo instance=Ethernet1 sample=value sampleType=GAUGE\n", result);
|
||||
assertEquals("put sys.snmp.if_octets 1456156976840 0.0 addl1=foo host=r01n01 instance=Ethernet1 rack=r01 sampleType=GAUGE\n", result);
|
||||
|
||||
}
|
||||
|
||||
@@ -210,8 +210,7 @@ public class PluginParentTest {
|
||||
|
||||
TestPlugin test = new TestPlugin();
|
||||
test.process(vl, null);
|
||||
assertEquals("put sys.sensors.temperature.coretemp-isa-0000 1456156976840 35.0 host=r01n01 rack=r01 addl1=foo instance=1 sample=value sampleType=GAUGE\n",
|
||||
result);
|
||||
assertEquals("put sys.sensors.temperature.coretemp-isa-0000 1456156976840 35.0 addl1=foo host=r01n01 instance=1 rack=r01 sampleType=GAUGE\n", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -229,7 +228,7 @@ public class PluginParentTest {
|
||||
|
||||
TestPlugin test = new TestPlugin();
|
||||
test.process(vl, null);
|
||||
assertEquals("put sys.haproxy.run_queue 1456156976840 0.0 host=r01n01 rack=r01 addl1=foo sample=value sampleType=GAUGE\n", result);
|
||||
assertEquals("put sys.haproxy.run_queue 1456156976840 0.0 addl1=foo host=r01n01 rack=r01 sampleType=GAUGE\n", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -248,7 +247,7 @@ public class PluginParentTest {
|
||||
|
||||
TestPlugin test = new TestPlugin();
|
||||
test.process(vl, null);
|
||||
assertEquals("put sys.haproxy.queue_current 1456156976840 0.0 host=r01n01 rack=r01 addl1=foo proxy_name=proxy1 service_name=server1 sample=value sampleType=GAUGE\n",
|
||||
assertEquals("put sys.haproxy.queue_current 1456156976840 0.0 addl1=foo host=r01n01 proxy_name=proxy1 rack=r01 sampleType=GAUGE service_name=server1\n",
|
||||
result);
|
||||
}
|
||||
|
||||
@@ -268,20 +267,19 @@ public class PluginParentTest {
|
||||
|
||||
TestPlugin test = new TestPlugin();
|
||||
test.process(vl, null);
|
||||
assertEquals("put sys.ethstat.tx_comp_queue_full 1456156976840 6.0 host=r01n01 rack=r01 addl1=foo instance=eth0 sample=value sampleType=GAUGE\n",
|
||||
result);
|
||||
assertEquals("put sys.ethstat.tx_comp_queue_full 1456156976840 6.0 addl1=foo host=r01n01 instance=eth0 rack=r01 sampleType=GAUGE\n", result);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEthStatWithQueue() {
|
||||
public void testEthstatWithQueueStyle1() {
|
||||
ValueList vl = new ValueList();
|
||||
vl.setHost(HOST);
|
||||
vl.setPlugin("ethstat");
|
||||
vl.setPluginInstance("eth0");
|
||||
vl.setTime(TIME);
|
||||
vl.setType("derive");
|
||||
vl.setTypeInstance("rx_queue_1_bytes");
|
||||
vl.setTypeInstance("rx_queue_15_bytes");
|
||||
vl.setValues(Collections.singletonList((Number) 6.0D));
|
||||
DataSet ds = new DataSet("DERIVE");
|
||||
ds.addDataSource(new DataSource("value", 1, 6.0D, 100.0D));
|
||||
@@ -289,8 +287,83 @@ public class PluginParentTest {
|
||||
|
||||
TestPlugin test = new TestPlugin();
|
||||
test.process(vl, null);
|
||||
assertEquals("put sys.ethstat.rx_bytes 1456156976840 6.0 host=r01n01 rack=r01 addl1=foo queue=1 instance=eth0 sample=value sampleType=GAUGE\n", result);
|
||||
assertEquals("put sys.ethstat.rx_queue_bytes 1456156976840 6.0 addl1=foo host=r01n01 instance=eth0 queue=15 rack=r01 sampleType=GAUGE\n", result);
|
||||
|
||||
result = null;
|
||||
vl.setTypeInstance("queue_7_tx_bytes");
|
||||
test.process(vl, null);
|
||||
assertEquals("put sys.ethstat.queue_tx_bytes 1456156976840 6.0 addl1=foo host=r01n01 instance=eth0 queue=7 rack=r01 sampleType=GAUGE\n", result);
|
||||
|
||||
result = null;
|
||||
vl.setTypeInstance("queue_7_rx_xdp_drop");
|
||||
test.process(vl, null);
|
||||
assertEquals("put sys.ethstat.queue_rx_xdp_drop 1456156976840 6.0 addl1=foo host=r01n01 instance=eth0 queue=7 rack=r01 sampleType=GAUGE\n", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEthstatWithQueueStyle2() {
|
||||
ValueList vl = new ValueList();
|
||||
vl.setHost(HOST);
|
||||
vl.setPlugin("ethstat");
|
||||
vl.setPluginInstance("eth0");
|
||||
vl.setTime(TIME);
|
||||
vl.setType("derive");
|
||||
vl.setTypeInstance("rx-15.bytes");
|
||||
vl.setValues(Collections.singletonList((Number) 6.0D));
|
||||
DataSet ds = new DataSet("DERIVE");
|
||||
ds.addDataSource(new DataSource("value", 1, 6.0D, 100.0D));
|
||||
vl.setDataSet(ds);
|
||||
|
||||
TestPlugin test = new TestPlugin();
|
||||
|
||||
test.process(vl, null);
|
||||
assertEquals("put sys.ethstat.rx_queue_bytes 1456156976840 6.0 addl1=foo host=r01n01 instance=eth0 queue=15 rack=r01 sampleType=GAUGE\n", result);
|
||||
|
||||
result = null;
|
||||
vl.setTypeInstance("tx15_xdp_err");
|
||||
test.process(vl, null);
|
||||
assertEquals("put sys.ethstat.tx_queue_xdp_err 1456156976840 6.0 addl1=foo host=r01n01 instance=eth0 queue=15 rack=r01 sampleType=GAUGE\n", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEthstatWithTrafficClass() {
|
||||
ValueList vl = new ValueList();
|
||||
vl.setHost(HOST);
|
||||
vl.setPlugin("ethstat");
|
||||
vl.setPluginInstance("eth0");
|
||||
vl.setTime(TIME);
|
||||
vl.setType("derive");
|
||||
vl.setTypeInstance("veb.tc_15_tx_bytes");
|
||||
vl.setValues(Collections.singletonList((Number) 6.0D));
|
||||
DataSet ds = new DataSet("DERIVE");
|
||||
ds.addDataSource(new DataSource("value", 1, 6.0D, 100.0D));
|
||||
vl.setDataSet(ds);
|
||||
|
||||
TestPlugin test = new TestPlugin();
|
||||
|
||||
test.process(vl, null);
|
||||
assertEquals("put sys.ethstat.veb.tc_tx_bytes 1456156976840 6.0 addl1=foo host=r01n01 instance=eth0 rack=r01 sampleType=GAUGE trafficClass=15\n",
|
||||
result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEthstatWithChannel() {
|
||||
ValueList vl = new ValueList();
|
||||
vl.setHost(HOST);
|
||||
vl.setPlugin("ethstat");
|
||||
vl.setPluginInstance("eth0");
|
||||
vl.setTime(TIME);
|
||||
vl.setType("derive");
|
||||
vl.setTypeInstance("ch44_events");
|
||||
vl.setValues(Collections.singletonList((Number) 6.0D));
|
||||
DataSet ds = new DataSet("DERIVE");
|
||||
ds.addDataSource(new DataSource("value", 1, 6.0D, 100.0D));
|
||||
vl.setDataSet(ds);
|
||||
|
||||
TestPlugin test = new TestPlugin();
|
||||
|
||||
test.process(vl, null);
|
||||
assertEquals("put sys.ethstat.ch_events 1456156976840 6.0 addl1=foo channel=44 host=r01n01 instance=eth0 rack=r01 sampleType=GAUGE\n", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -308,9 +381,37 @@ public class PluginParentTest {
|
||||
|
||||
TestPlugin test = new TestPlugin();
|
||||
test.process(vl, null);
|
||||
assertEquals("put sys.ipmi.temperature 1456156976840 6.0 host=r01n01 rack=r01 addl1=foo instance=LAN_NIC_Temp_system_board_(3.2) sample=value sampleType=GAUGE\n",
|
||||
assertEquals("put sys.ipmi.temperature 1456156976840 6.0 addl1=foo host=r01n01 instance=LAN_NIC_Temp_system_board_(3.2) rack=r01 sampleType=GAUGE\n",
|
||||
result);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExclusions() {
|
||||
ValueList vl = new ValueList();
|
||||
vl.setHost(HOST);
|
||||
vl.setPlugin("ethstat");
|
||||
vl.setPluginInstance("eth0");
|
||||
vl.setTime(TIME);
|
||||
vl.setType("derive");
|
||||
vl.setTypeInstance("rx_queue_1_bytes");
|
||||
vl.setValues(Collections.singletonList((Number) 6.0D));
|
||||
DataSet ds = new DataSet("DERIVE");
|
||||
ds.addDataSource(new DataSource("value", 1, 6.0D, 100.0D));
|
||||
vl.setDataSet(ds);
|
||||
|
||||
TestPlugin test = new TestPlugin();
|
||||
URL filteredMetricsFile = getClass().getClassLoader().getResource("filteredMetrics.txt");
|
||||
test.setFilteredMetricsFile(filteredMetricsFile.getPath());
|
||||
URL filteredTagsFile = getClass().getClassLoader().getResource("filteredTags.txt");
|
||||
test.setFilteredTagsFile(filteredTagsFile.getPath());
|
||||
|
||||
test.process(vl, null);
|
||||
assertEquals("put sys.ethstat.rx_queue_bytes 1456156976840 6.0 addl1=foo host=r01n01 queue=1 rack=r01\n", result);
|
||||
|
||||
result = null;
|
||||
vl.setPlugin("interface");
|
||||
vl.setTypeInstance("if_octets");
|
||||
assertNull(result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
package timely.collectd.plugin;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.collectd.api.Collectd;
|
||||
import org.collectd.api.DataSet;
|
||||
import org.collectd.api.DataSource;
|
||||
import org.collectd.api.OConfigItem;
|
||||
import org.collectd.api.ValueList;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.powermock.api.easymock.PowerMock;
|
||||
import org.powermock.core.classloader.annotations.PowerMockIgnore;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({Collectd.class})
|
||||
@PowerMockIgnore({"javax.management.*", "jdk.internal.reflect.*"})
|
||||
public class WriteTimelyPluginTest {
|
||||
|
||||
private WriteTimelyPlugin plugin = null;
|
||||
private FakeServer server = null;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
PowerMock.suppress(PowerMock.everythingDeclaredIn(Collectd.class));
|
||||
server = new FakeServer();
|
||||
}
|
||||
|
||||
private ValueList createMetric() {
|
||||
ValueList val = new ValueList();
|
||||
val.setHost("r001n01.localdomain");
|
||||
val.setTime(System.currentTimeMillis());
|
||||
val.setPlugin("hddtemp");
|
||||
val.setPluginInstance(null);
|
||||
val.setType("temperature");
|
||||
val.setTypeInstance("sda");
|
||||
val.setValues(Collections.singletonList((Number) new Double(2.0)));
|
||||
DataSet ds = new DataSet("test");
|
||||
ds.addDataSource(new DataSource("test", DataSource.TYPE_COUNTER, 0, 100));
|
||||
val.setDataSet(ds);
|
||||
return val;
|
||||
}
|
||||
|
||||
private void setupPlugin() throws Exception {
|
||||
OConfigItem host = new OConfigItem("Host");
|
||||
host.addValue(server.getHost());
|
||||
OConfigItem port = new OConfigItem("Port");
|
||||
port.addValue(Integer.toString(server.getPort()));
|
||||
OConfigItem config = new OConfigItem("");
|
||||
config.addChild(host);
|
||||
config.addChild(port);
|
||||
plugin = new WriteTimelyPlugin();
|
||||
Assert.assertEquals(0, plugin.config(config));
|
||||
// Seed with one metric to create the connection
|
||||
Assert.assertEquals(0, plugin.write(createMetric()));
|
||||
Thread.sleep(100);
|
||||
Assert.assertTrue(server.messageReceived());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWrite() throws Exception {
|
||||
Thread t = new Thread(server);
|
||||
t.start();
|
||||
setupPlugin();
|
||||
while (!server.ready()) {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
Assert.assertEquals(0, plugin.write(createMetric()));
|
||||
Thread.sleep(100);
|
||||
Assert.assertTrue(server.messageReceived());
|
||||
plugin.shutdown();
|
||||
server.shutdown();
|
||||
t.join();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteAfterServerRestart() throws Exception {
|
||||
Thread t = new Thread(server);
|
||||
t.start();
|
||||
setupPlugin();
|
||||
while (!server.ready()) {
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
Assert.assertEquals(0, plugin.write(createMetric()));
|
||||
Thread.sleep(100);
|
||||
Assert.assertTrue(server.messageReceived());
|
||||
server.shutdown();
|
||||
t.join();
|
||||
Thread.sleep(2000);
|
||||
|
||||
server.create();
|
||||
Thread t2 = new Thread(server);
|
||||
t2.start();
|
||||
// Need to call this again because the server is not guaranteed to be
|
||||
// listening on the same local port as the first time that it was
|
||||
// started
|
||||
setupPlugin();
|
||||
while (!server.ready()) {
|
||||
Thread.sleep(1000);
|
||||
// Keep sending metrics to plugin to force reconnect
|
||||
int result = plugin.write(createMetric());
|
||||
System.out.println("Wrote to client, result: " + result);
|
||||
Assert.assertEquals(0, result);
|
||||
}
|
||||
Assert.assertEquals(0, plugin.write(createMetric()));
|
||||
Thread.sleep(1000);
|
||||
Assert.assertTrue(server.messageReceived());
|
||||
plugin.shutdown();
|
||||
server.shutdown();
|
||||
t2.join();
|
||||
}
|
||||
|
||||
private static class FakeServer implements Runnable {
|
||||
|
||||
private ServerSocket server = null;
|
||||
private BufferedReader reader = null;
|
||||
private String host = null;
|
||||
private int port = 0;
|
||||
private Socket s = null;
|
||||
private boolean received = false;
|
||||
|
||||
public FakeServer() throws Exception {
|
||||
create();
|
||||
}
|
||||
|
||||
public void create() throws Exception {
|
||||
server = new ServerSocket(port);
|
||||
server.setReceiveBufferSize(8192);
|
||||
host = server.getInetAddress().getHostAddress();
|
||||
port = server.getLocalPort();
|
||||
System.out.println("Local port " + port);
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void shutdown() throws Exception {
|
||||
System.out.println("Closing server.");
|
||||
s.close();
|
||||
s = null;
|
||||
reader.close();
|
||||
reader = null;
|
||||
server.close();
|
||||
server = null;
|
||||
}
|
||||
|
||||
public boolean ready() throws Exception {
|
||||
return (s != null && s.isConnected());
|
||||
}
|
||||
|
||||
synchronized public boolean messageReceived() {
|
||||
try {
|
||||
return Boolean.valueOf(this.received);
|
||||
} finally {
|
||||
this.received = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
s = server.accept();
|
||||
System.out.println("Client connected.");
|
||||
reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
|
||||
while (server != null && !server.isClosed() && s != null && s.isConnected()) {
|
||||
String line;
|
||||
try {
|
||||
line = reader.readLine();
|
||||
} catch (Exception e) {
|
||||
// Might have been closed
|
||||
System.out.println("Closed by Exception: " + e.getMessage());
|
||||
return;
|
||||
}
|
||||
if (null != line) {
|
||||
synchronized (this) {
|
||||
this.received = true;
|
||||
}
|
||||
System.out.println(line);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Assert.fail(e.getMessage());
|
||||
}
|
||||
System.out.println("Exiting run method.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
sys.ethstat.*_to_.*
|
||||
sys.interface.if_packets
|
||||
sys.interface.if_octets
|
||||
@@ -0,0 +1,3 @@
|
||||
sys.interface.if_packets sampleType,instance
|
||||
sys.interface.if_octets sampleType,instance
|
||||
sys.ethstat.rx_queue_bytes sampleType,instance
|
||||
+1
-5
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>2.1.0</version>
|
||||
<version>2.2.1</version>
|
||||
</parent>
|
||||
<artifactId>timely-common</artifactId>
|
||||
<dependencies>
|
||||
@@ -72,10 +72,6 @@
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-jackson</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.projectreactor.netty</groupId>
|
||||
<artifactId>reactor-netty</artifactId>
|
||||
|
||||
@@ -32,6 +32,7 @@ public class QueryRequest extends AuthenticatedRequest implements HttpGetRequest
|
||||
private boolean counter = false;
|
||||
private long counterMax = 0;
|
||||
private long resetValue = 0;
|
||||
private String interval = null;
|
||||
|
||||
public RateOption() {}
|
||||
|
||||
@@ -84,12 +85,21 @@ public class QueryRequest extends AuthenticatedRequest implements HttpGetRequest
|
||||
this.resetValue = resetValue;
|
||||
}
|
||||
|
||||
public String getInterval() {
|
||||
return interval;
|
||||
}
|
||||
|
||||
public void setInterval(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();
|
||||
}
|
||||
|
||||
@@ -210,7 +221,7 @@ public class QueryRequest extends AuthenticatedRequest implements HttpGetRequest
|
||||
private String aggregator;
|
||||
private String metric;
|
||||
private boolean rate = false;
|
||||
private RateOption rateOptions = null;
|
||||
private RateOption rateOptions = new RateOption();
|
||||
private Optional<String> downsample = Optional.empty();
|
||||
private Map<String,String> tags = new LinkedHashMap<>();
|
||||
private Collection<Filter> filters = new ArrayList<>();
|
||||
@@ -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(rateOptions[x]);
|
||||
break;
|
||||
case 2:
|
||||
options.setCounterMax(Long.parseLong(rateOptions[x]));
|
||||
break;
|
||||
case 3:
|
||||
options.setResetValue(Long.parseLong(rateOptions[x]));
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -37,6 +37,9 @@ public class RemoteAuthenticationProvider implements AuthenticationProvider {
|
||||
public static final String ISSUERS_HEADER = "X-ProxiedIssuersChain";
|
||||
|
||||
public RemoteAuthenticationProvider(WebClient.Builder builder, SecurityProperties securityProperties) {
|
||||
log.debug("creating RemoteAuthenticationProvider with authorizationUrl:{} anonymousHttp:{} anonymousWs:{} requiredRoles:{} requiredAuths{}",
|
||||
securityProperties.getAuthorizationUrl(), securityProperties.isAllowAnonymousHttpAccess(),
|
||||
securityProperties.isAllowAnonymousWsAccess(), securityProperties.getRequiredRoles(), securityProperties.getRequiredAuths());
|
||||
this.webClient = builder.baseUrl(securityProperties.getAuthorizationUrl()).build();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package timely.auth;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
@@ -51,10 +51,10 @@ public class TimelyUser implements Serializable {
|
||||
this.userType = DnUtils.isServerDN(subjectDn) ? UserType.SERVER : UserType.USER;
|
||||
this.email = null;
|
||||
this.login = ProxiedEntityUtils.getShortName(dn.subjectDN());
|
||||
this.auths = auths == null ? Collections.emptyList() : new LinkedHashSet<>(auths);
|
||||
this.unmodifiableAuths = Collections.unmodifiableCollection(this.auths);
|
||||
this.roles = roles == null ? Collections.emptyList() : new LinkedHashSet<>(roles);
|
||||
this.unmodifiableRoles = Collections.unmodifiableCollection(this.roles);
|
||||
this.auths = auths == null ? Collections.emptySortedSet() : new TreeSet<>(auths);
|
||||
this.unmodifiableAuths = Collections.unmodifiableSortedSet(new TreeSet<>(this.auths));
|
||||
this.roles = roles == null ? Collections.emptySortedSet() : new TreeSet<>(roles);
|
||||
this.unmodifiableRoles = Collections.unmodifiableSortedSet(new TreeSet(this.roles));
|
||||
this.roleToAuthMapping = null;
|
||||
this.creationTime = System.currentTimeMillis();
|
||||
this.expirationTime = -1L;
|
||||
@@ -89,10 +89,10 @@ public class TimelyUser implements Serializable {
|
||||
this.email = email;
|
||||
this.dn = dn;
|
||||
this.userType = userType;
|
||||
this.auths = auths == null ? Collections.emptyList() : new LinkedHashSet<>(auths);
|
||||
this.unmodifiableAuths = Collections.unmodifiableCollection(this.auths);
|
||||
this.roles = roles == null ? Collections.emptyList() : new LinkedHashSet<>(roles);
|
||||
this.unmodifiableRoles = Collections.unmodifiableCollection(this.roles);
|
||||
this.auths = auths == null ? Collections.emptySortedSet() : new TreeSet<>(auths);
|
||||
this.unmodifiableAuths = Collections.unmodifiableSortedSet(new TreeSet<>(this.auths));
|
||||
this.roles = roles == null ? Collections.emptySortedSet() : new TreeSet<>(roles);
|
||||
this.unmodifiableRoles = Collections.unmodifiableSortedSet(new TreeSet<>(this.roles));
|
||||
this.roleToAuthMapping = roleToAuthMapping == null ? LinkedHashMultimap.create() : LinkedHashMultimap.create(roleToAuthMapping);
|
||||
this.creationTime = creationTime;
|
||||
this.expirationTime = expirationTime;
|
||||
|
||||
@@ -205,10 +205,9 @@ public class AuthenticationService {
|
||||
String message = "";
|
||||
if (!missingRoles.isEmpty() && !missingAuths.isEmpty()) {
|
||||
message = "User:" + primaryUser.getName() + " is missing role(s):" + missingRoles + " and auth(s):" + missingAuths;
|
||||
|
||||
} else if (!missingRoles.isEmpty()) {
|
||||
message = "User:" + primaryUser.getName() + " is missing role(s):" + missingRoles;
|
||||
} else if (missingAuths.isEmpty()) {
|
||||
} else if (!missingAuths.isEmpty()) {
|
||||
message = "User:" + primaryUser.getName() + " is missing auths(s):" + missingAuths;
|
||||
}
|
||||
log.debug(message);
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
package timely.common.component;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.web.client.RestTemplateCustomizer;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import timely.common.configuration.RestClientProperties;
|
||||
|
||||
/**
|
||||
* Customizes Spring {@link RestTemplate} instances by using our configured SSL certificate to present a client certificate whenever asked by remote services.
|
||||
*/
|
||||
@Component
|
||||
@Order(100) // execute this after standard customizers so we're sure to overwrite the client
|
||||
// request factory
|
||||
@ConditionalOnBean(name = "outboundJDKSslContext")
|
||||
public class ClientCertRestTemplateCustomizer implements RestTemplateCustomizer {
|
||||
|
||||
private final SSLContext sslContext;
|
||||
private final int maxConnectionsTotal;
|
||||
private final int maxConnectionsPerRoute;
|
||||
|
||||
@Autowired
|
||||
public ClientCertRestTemplateCustomizer(@Qualifier("outboundJDKSslContext") SSLContext sslContext, RestClientProperties restClientProperties) {
|
||||
this.sslContext = sslContext;
|
||||
this.maxConnectionsTotal = restClientProperties.getMaxConnectionsTotal();
|
||||
this.maxConnectionsPerRoute = restClientProperties.getMaxConnectionsPerRoute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customize(RestTemplate restTemplate) {
|
||||
restTemplate.setRequestFactory(clientHttpRequestFactory());
|
||||
}
|
||||
|
||||
protected ClientHttpRequestFactory clientHttpRequestFactory() {
|
||||
HttpClient httpClient = customizeHttpClient(HttpClients.custom(), sslContext).build();
|
||||
return new HttpComponentsClientHttpRequestFactory(httpClient);
|
||||
}
|
||||
|
||||
protected HttpClientBuilder customizeHttpClient(HttpClientBuilder httpClientBuilder, SSLContext sslContext) {
|
||||
if (sslContext != null) {
|
||||
httpClientBuilder.setSSLContext(sslContext);
|
||||
}
|
||||
httpClientBuilder.setMaxConnTotal(maxConnectionsTotal);
|
||||
httpClientBuilder.setMaxConnPerRoute(maxConnectionsPerRoute);
|
||||
// TODO: We're allowing all hosts, since the cert presented by the service we're
|
||||
// calling likely won't match its hostname (e.g., a docker host name)
|
||||
// Instead, we could list the expected cert as a property (or use our server
|
||||
// cert), and verify that the presented name matches.
|
||||
return httpClientBuilder.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE);
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package timely.common.configuration;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.web.reactive.function.client.WebClientCustomizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
|
||||
|
||||
import io.netty.handler.ssl.SslContext;
|
||||
import reactor.netty.http.client.HttpClient;
|
||||
|
||||
/**
|
||||
* Customizes the Spring-provided {@link org.springframework.web.reactive.function.client.WebClient.Builder} with an {@link SslContext} that will provide a
|
||||
* client certificate to the remote server if one is requested.
|
||||
*/
|
||||
@Configuration
|
||||
@Order(100) // execute this after standard customizers to ensure that we overwrite the client connector
|
||||
@ConditionalOnBean(name = "outboundNettySslContext")
|
||||
public class ClientCertWebClientCustomizer {
|
||||
|
||||
@Bean
|
||||
public WebClientCustomizer webClientCustomizer(@Qualifier("outboundNettySslContext") SslContext sslContext) {
|
||||
return webClientBuilder -> {
|
||||
HttpClient httpClient = HttpClient.create().secure(sslContextSpec -> sslContextSpec.sslContext(sslContext));
|
||||
ReactorClientHttpConnector clientHttpConnector = new ReactorClientHttpConnector(httpClient);
|
||||
webClientBuilder.clientConnector(clientHttpConnector);
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -9,9 +9,12 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
|
||||
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
import io.netty.handler.ssl.SslContext;
|
||||
import reactor.netty.http.client.HttpClient;
|
||||
import timely.auth.FileUserDetailsService;
|
||||
import timely.auth.RemoteAuthenticationProvider;
|
||||
import timely.auth.SubjectIssuerDNPair;
|
||||
@@ -30,7 +33,11 @@ public class SecurityConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnExpression("T(org.apache.commons.lang3.StringUtils).isNotEmpty('${timely.security.authorization-url:}')")
|
||||
public RemoteAuthenticationProvider remoteAuthenticationProvider(SecurityProperties securityProperties, WebClient.Builder builder) {
|
||||
public RemoteAuthenticationProvider remoteAuthenticationProvider(SecurityProperties securityProperties, WebClient.Builder builder,
|
||||
@Qualifier("outboundNettySslContext") SslContext sslContext) {
|
||||
HttpClient httpClient = HttpClient.create().secure(sslContextSpec -> sslContextSpec.sslContext(sslContext));
|
||||
ReactorClientHttpConnector clientHttpConnector = new ReactorClientHttpConnector(httpClient);
|
||||
builder.clientConnector(clientHttpConnector);
|
||||
return new RemoteAuthenticationProvider(builder, securityProperties);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
package timely.common.configuration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.NestedConfigurationProperty;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
@@ -106,13 +102,6 @@ public class SecurityProperties {
|
||||
this.requiredAuths = requiredAuths;
|
||||
}
|
||||
|
||||
public void setRequiredAuths(String requiredAuths) {
|
||||
if (StringUtils.isNotBlank(requiredAuths)) {
|
||||
this.requiredAuths = Arrays.stream(StringUtils.split(requiredAuths)).filter(Objects::nonNull).filter(s -> StringUtils.isNotBlank(s))
|
||||
.map(String::trim).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getRequiredRoles() {
|
||||
return requiredRoles;
|
||||
}
|
||||
@@ -121,10 +110,4 @@ public class SecurityProperties {
|
||||
this.requiredRoles = requiredRoles;
|
||||
}
|
||||
|
||||
public void setRequiredRoles(String requiredRoles) {
|
||||
if (StringUtils.isNotBlank(requiredRoles)) {
|
||||
this.requiredRoles = Arrays.stream(StringUtils.split(requiredRoles)).filter(Objects::nonNull).filter(s -> StringUtils.isNotBlank(s))
|
||||
.map(String::trim).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@ package timely.common.configuration;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
@@ -18,9 +20,13 @@ import io.netty.handler.ssl.SslContext;
|
||||
@ConditionalOnExpression("!T(org.springframework.util.StringUtils).isEmpty('${timely.security.client-ssl.key-store-file:}')")
|
||||
public class SslClientConfig {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(SslClientConfig.class);
|
||||
|
||||
@Bean
|
||||
@Qualifier("outboundJDKSslContext")
|
||||
public SSLContext outboundJDKSslContext(SslClientProperties sslClientProperties) throws Exception {
|
||||
log.debug("Creating outboundJDKSslContext using keyStoreFile:{} trustStoreFile:{}", sslClientProperties.getKeyStoreFile(),
|
||||
sslClientProperties.getTrustStoreFile());
|
||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
sslContext.init(SslHelper.getKeyManagerFactory(sslClientProperties).getKeyManagers(),
|
||||
SslHelper.getTrustManagerFactory(sslClientProperties).getTrustManagers(), null);
|
||||
@@ -30,6 +36,8 @@ public class SslClientConfig {
|
||||
@Bean
|
||||
@Qualifier("outboundNettySslContext")
|
||||
public SslContext outboundNettySslContext(SslClientProperties sslClientProperties) throws Exception {
|
||||
log.debug("Creating outboundNettySslContext using keyStoreFile:{} trustStoreFile:{}", sslClientProperties.getKeyStoreFile(),
|
||||
sslClientProperties.getTrustStoreFile());
|
||||
return SslHelper.getSslContext(sslClientProperties);
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,7 @@ import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
@ConfigurationProperties(prefix = "timely.security.client-ssl")
|
||||
public class SslClientProperties implements SslProperties {
|
||||
|
||||
private String[] ciphers = new String[] {"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_128_GCM_SHA256",
|
||||
"TLS_RSA_WITH_AES_128_CBC_SHA", "SSL_RSA_WITH_3DES_EDE_CBC_SHA"};
|
||||
private String[] ciphers;
|
||||
private String[] enabledProtocols;
|
||||
private String keyStoreType;
|
||||
private String keyStoreFile;
|
||||
|
||||
@@ -39,9 +39,11 @@ public class SslServerConfig {
|
||||
Boolean generate = sslServerProperties.isUseGeneratedKeypair();
|
||||
SslContextBuilder sslContextBuilder;
|
||||
if (generate) {
|
||||
log.debug("Using generated self signed server certificate");
|
||||
log.debug("Creating nettySslContext using generated self signed server certificate");
|
||||
sslContextBuilder = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey());
|
||||
} else {
|
||||
log.debug("Creating nettySslContext using keyStoreFile:{} trustStoreFile:{}", sslServerProperties.getKeyStoreFile(),
|
||||
sslServerProperties.getTrustStoreFile());
|
||||
sslContextBuilder = SslHelper.getSslContextBuilder(sslServerProperties);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
package timely.common.configuration;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import timely.util.Exclusions;
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties({AccumuloProperties.class, CacheProperties.class, CorsProperties.class, HttpProperties.class, MetaCacheProperties.class,
|
||||
RestClientProperties.class, ScanProperties.class, SecurityProperties.class, ServerProperties.class, SslClientProperties.class,
|
||||
@@ -10,4 +14,15 @@ import org.springframework.context.annotation.Configuration;
|
||||
|
||||
public class TimelyCommonConfiguration {
|
||||
|
||||
@Bean
|
||||
public Exclusions exclusions(TimelyProperties timelyProperties) {
|
||||
Exclusions exclusions = new Exclusions();
|
||||
if (StringUtils.isNotBlank(timelyProperties.getFilteredMetricsFile())) {
|
||||
exclusions.setFilteredMetricsFile(timelyProperties.getFilteredMetricsFile());
|
||||
}
|
||||
if (StringUtils.isNotBlank(timelyProperties.getFilteredTagsFile())) {
|
||||
exclusions.setFilteredTagsFile(timelyProperties.getFilteredTagsFile());
|
||||
}
|
||||
return exclusions;
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,9 @@ public class TimelyProperties {
|
||||
private int instance = 1;
|
||||
private int portIncrement = 100;
|
||||
private String defaultVisibility = null;
|
||||
private int tagFilterCacheSize = 10000;
|
||||
private String filteredMetricsFile = null;
|
||||
private String filteredTagsFile = null;
|
||||
|
||||
public boolean isTest() {
|
||||
return test;
|
||||
@@ -91,4 +94,28 @@ public class TimelyProperties {
|
||||
this.metricsReportIgnoredTags = metricsReportIgnoredTags;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setTagFilterCacheSize(int tagFilterCacheSize) {
|
||||
this.tagFilterCacheSize = tagFilterCacheSize;
|
||||
}
|
||||
|
||||
public int getTagFilterCacheSize() {
|
||||
return tagFilterCacheSize;
|
||||
}
|
||||
|
||||
public void setFilteredMetricsFile(String filteredMetricsFile) {
|
||||
this.filteredMetricsFile = filteredMetricsFile;
|
||||
}
|
||||
|
||||
public String getFilteredMetricsFile() {
|
||||
return filteredMetricsFile;
|
||||
}
|
||||
|
||||
public void setFilteredTagsFile(String filteredTagsFile) {
|
||||
this.filteredTagsFile = filteredTagsFile;
|
||||
}
|
||||
|
||||
public String getFilteredTagsFile() {
|
||||
return filteredTagsFile;
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import java.util.stream.Stream;
|
||||
|
||||
import org.apache.commons.lang3.builder.CompareToBuilder;
|
||||
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonAnySetter;
|
||||
@@ -90,7 +91,7 @@ public class Tag implements Comparable<Tag>, Serializable {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.toString().hashCode();
|
||||
return new HashCodeBuilder().append(this.key).append(this.value).toHashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import timely.model.Tag;
|
||||
|
||||
@@ -24,9 +25,7 @@ public class TagListParser implements Parser<List<Tag>>, Combiner<Collection<Tag
|
||||
if (!p.isEmpty()) {
|
||||
Tag tag = tagParser.parse(p);
|
||||
// unescape commas in the key and value of the tag
|
||||
tag.setKey(tag.getKey().replaceAll("\\\\,", ","));
|
||||
tag.setValue(tag.getValue().replaceAll("\\\\,", ","));
|
||||
tags.add(tag);
|
||||
tags.add(unescapeCommas(tag));
|
||||
}
|
||||
}
|
||||
return tags;
|
||||
@@ -36,7 +35,9 @@ public class TagListParser implements Parser<List<Tag>>, Combiner<Collection<Tag
|
||||
public String combine(Collection<Tag> tags) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if (!tags.isEmpty()) {
|
||||
tags.forEach(p -> builder.append(tagParser.combine(p)).append(','));
|
||||
tags.forEach(p -> {
|
||||
builder.append(tagParser.combine(escapeCommas(p))).append(',');
|
||||
});
|
||||
builder.setLength(builder.length() - 1);
|
||||
}
|
||||
return builder.toString();
|
||||
@@ -48,11 +49,26 @@ public class TagListParser implements Parser<List<Tag>>, Combiner<Collection<Tag
|
||||
* @return string representation
|
||||
*/
|
||||
public String combine(Map<String,String> tags) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if (!tags.isEmpty()) {
|
||||
tags.forEach((k, v) -> builder.append(tagParser.combine(new Tag(k, v))).append(','));
|
||||
builder.setLength(builder.length() - 1);
|
||||
}
|
||||
return builder.toString();
|
||||
return combine(tags.entrySet().stream().map(e -> new Tag(e.getKey(), e.getValue())).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
private Tag escapeCommas(Tag tag) {
|
||||
return escapeCommas(tag.getKey(), tag.getValue());
|
||||
}
|
||||
|
||||
private Tag escapeCommas(String k, String v) {
|
||||
k = k.replaceAll(",", "\\\\,");
|
||||
v = v.replaceAll(",", "\\\\,");
|
||||
return new Tag(k, v);
|
||||
}
|
||||
|
||||
private Tag unescapeCommas(Tag tag) {
|
||||
return unescapeCommas(tag.getKey(), tag.getValue());
|
||||
}
|
||||
|
||||
private Tag unescapeCommas(String k, String v) {
|
||||
k = k.replaceAll("\\\\,", ",");
|
||||
v = v.replaceAll("\\\\,", ",");
|
||||
return new Tag(k, v);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
package timely.util;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import timely.model.Metric;
|
||||
import timely.model.Tag;
|
||||
import timely.model.parse.MetricParser;
|
||||
|
||||
public class Exclusions {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(Exclusions.class);
|
||||
private static final MetricParser metricParser = new MetricParser();
|
||||
private List<String> filteredMetrics = new ArrayList<>();
|
||||
private Map<String,Set<String>> filteredTags = new LinkedHashMap<>();
|
||||
|
||||
public interface LineHandler {
|
||||
void handleLine(String line);
|
||||
}
|
||||
|
||||
public void readFile(String file, LineHandler lineHandler) {
|
||||
File f = new File(file);
|
||||
if (f.exists() && f.isFile() && f.canRead()) {
|
||||
try (InputStream iStream = new FileInputStream(f);
|
||||
InputStreamReader streamReader = new InputStreamReader(iStream, StandardCharsets.UTF_8);
|
||||
BufferedReader reader = new BufferedReader(streamReader)) {
|
||||
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
try {
|
||||
lineHandler.handleLine(line);
|
||||
} catch (Exception e) {
|
||||
log.error(MessageFormat.format("Error reading line {0}", line), e);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error(MessageFormat.format("Error reading file {0}", file), e);
|
||||
}
|
||||
} else {
|
||||
log.error(MessageFormat.format("File ''{0}'' either does not exist or is not readable", file));
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getFilteredMetrics(String filteredMetricsFile) {
|
||||
List<String> filteredMetricRegexes = new ArrayList<>();
|
||||
readFile(filteredMetricsFile, (line) -> {
|
||||
if (!line.endsWith(".*")) {
|
||||
line = line + ".*";
|
||||
}
|
||||
filteredMetricRegexes.add(line);
|
||||
});
|
||||
return filteredMetricRegexes;
|
||||
}
|
||||
|
||||
public Map<String,Set<String>> getFilteredTags(String filteredTagsFile) {
|
||||
Map<String,Set<String>> filteredTagsForMetrics = new LinkedHashMap<>();
|
||||
readFile(filteredTagsFile, (line) -> {
|
||||
int x = line.indexOf(" ");
|
||||
String metric = line.substring(0, x);
|
||||
String tags = line.substring(x + 1).trim();
|
||||
Set<String> tagSet = Arrays.stream(tags.split(",")).map(tag -> tag.trim()).collect(Collectors.toSet());
|
||||
filteredTagsForMetrics.put(metric, tagSet);
|
||||
});
|
||||
return filteredTagsForMetrics;
|
||||
}
|
||||
|
||||
public void setFilteredMetricsFile(String filteredMetricsFile) {
|
||||
this.filteredMetrics = getFilteredMetrics(filteredMetricsFile);
|
||||
}
|
||||
|
||||
public void setFilteredTagsFile(String filteredTagsFile) {
|
||||
this.filteredTags = getFilteredTags(filteredTagsFile);
|
||||
}
|
||||
|
||||
// format put metric timestamp value tag1=value1 tag2=value2 tag3=value3
|
||||
// where the tags are sorted
|
||||
public boolean filterMetric(String metricPutLine) {
|
||||
String metricLine = buildMetricLine(metricPutLine);
|
||||
for (String filteredRegex : filteredMetrics) {
|
||||
if (metricLine.matches(filteredRegex)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean filterMetric(Metric metric) {
|
||||
String metricLine = buildMetricLine(metric);
|
||||
for (String filteredRegex : filteredMetrics) {
|
||||
if (metricLine.matches(filteredRegex)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected String buildMetricLine(String metricPutLine) {
|
||||
Metric metric = metricParser.parse(metricPutLine);
|
||||
return buildMetricLine(metric);
|
||||
}
|
||||
|
||||
protected String buildMetricLine(Metric metric) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(metric.getName()).append(" ");
|
||||
metric.getTags().stream().forEach(t -> sb.append(t.join()).append(" "));
|
||||
return sb.toString().trim();
|
||||
}
|
||||
|
||||
public String filterExcludedTags(String metricLineOrig) {
|
||||
if (filteredTags.isEmpty()) {
|
||||
return metricLineOrig;
|
||||
}
|
||||
Metric metric = metricParser.parse(metricLineOrig);
|
||||
filterExcludedTags(metric);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("put ");
|
||||
sb.append(metric.getName()).append(" ");
|
||||
sb.append(metric.getValue().getTimestamp()).append(" ");
|
||||
sb.append(metric.getValue().getMeasure()).append(" ");
|
||||
metric.getTags().stream().forEach(t -> sb.append(t.join()).append(" "));
|
||||
return sb.toString().trim();
|
||||
}
|
||||
|
||||
public void filterExcludedTags(Metric metric) {
|
||||
if (!filteredTags.isEmpty()) {
|
||||
Set<String> tags = filteredTags.get(metric.getName());
|
||||
if (tags != null && !tags.isEmpty()) {
|
||||
List<Tag> filteredTags = metric.getTags().stream().filter(t -> !tags.contains(t.getKey())).collect(Collectors.toList());
|
||||
metric.setTags(filteredTags);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package timely.util;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ExclusionTest {
|
||||
|
||||
@Test
|
||||
public void testLoadFilteredMetricsFile() {
|
||||
Exclusions exclusions = new Exclusions();
|
||||
URL url = getClass().getClassLoader().getResource("filteredMetrics.txt");
|
||||
List<String> metricExclusions = exclusions.getFilteredMetrics(url.getFile());
|
||||
Assert.assertEquals(4, metricExclusions.size());
|
||||
System.out.println(metricExclusions);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadFilteredTagsFile() {
|
||||
Exclusions exclusions = new Exclusions();
|
||||
URL url = getClass().getClassLoader().getResource("filteredTags.txt");
|
||||
Map<String,Set<String>> filteredTags = exclusions.getFilteredTags(url.getFile());
|
||||
Assert.assertEquals(2, filteredTags.size());
|
||||
System.out.println(filteredTags);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMetricExclusions() {
|
||||
Exclusions exclusions = new Exclusions();
|
||||
URL filteredMetrics = getClass().getClassLoader().getResource("filteredMetrics.txt");
|
||||
URL filteredTags = getClass().getClassLoader().getResource("filteredTags.txt");
|
||||
exclusions.setFilteredMetricsFile(filteredMetrics.getFile());
|
||||
exclusions.setFilteredTagsFile(filteredTags.getFile());
|
||||
|
||||
String metric1 = "put sys.interface.if_octets 1740090590221 71838.0 host=localhost instance=veth88545ad sampleType=DERIVE";
|
||||
Assert.assertTrue(exclusions.filterMetric(metric1));
|
||||
String metric2 = "put sys.interface.if_errors 1740090590221 71838.0 host=localhost instance=veth88545ad sampleType=DERIVE";
|
||||
Assert.assertFalse(exclusions.filterMetric(metric2));
|
||||
Assert.assertEquals("put sys.interface.if_octets 1740090590221 71838.0 host=localhost", exclusions.filterExcludedTags(metric1));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
sys.ethstat.(tx|rx)[-]?[0-9]+[_.]
|
||||
sys.ethstat.*_to_.*
|
||||
sys.interface.if_packets
|
||||
sys.interface.if_octets
|
||||
@@ -0,0 +1,2 @@
|
||||
sys.interface.if_packets sampleType,instance
|
||||
sys.interface.if_octets sampleType,instance
|
||||
@@ -7,9 +7,9 @@
|
||||
</formats>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>timely-app/dist</directory>
|
||||
<outputDirectory>timely-app</outputDirectory>
|
||||
<directory>timely-datasource/dist</directory>
|
||||
<outputDirectory>timely-datasource</outputDirectory>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
<includeBaseDirectory>false</includeBaseDirectory>
|
||||
</assembly>
|
||||
</assembly>
|
||||
+2
-2
@@ -4,9 +4,9 @@
|
||||
<parent>
|
||||
<groupId>timely</groupId>
|
||||
<artifactId>timely</artifactId>
|
||||
<version>2.1.0</version>
|
||||
<version>2.2.1</version>
|
||||
</parent>
|
||||
<artifactId>timely-app</artifactId>
|
||||
<artifactId>timely-datasource</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
node_modules/
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
module.exports = {
|
||||
...require('@grafana/toolkit/src/config/prettier.plugin.config.json'),
|
||||
};
|
||||
@@ -1,18 +0,0 @@
|
||||
//+build mage
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
// mage:import
|
||||
_ "github.com/grafana/grafana-plugin-sdk-go/build"
|
||||
)
|
||||
|
||||
// CheckCheck builds production back-end components.
|
||||
func CheckCheck() {
|
||||
fmt.Println("hello! TODO.... (the other commands are imported)")
|
||||
}
|
||||
|
||||
// Default configures the default target.
|
||||
var Default = CheckCheck
|
||||
@@ -1,6 +0,0 @@
|
||||
# Timely Data Source Plugin
|
||||
|
||||
Timely is a time series database application that provides secure access to time
|
||||
series data. Timely is written in Java, uses
|
||||
[Apache Accumulo](https://accumuloProperties.apache.org/) for backend storage, and has
|
||||
a configurable length memory cache.
|
||||
@@ -1,26 +0,0 @@
|
||||
# Test against the latest version of this Node.js version
|
||||
environment:
|
||||
nodejs_version: '10'
|
||||
|
||||
# Local NPM Modules
|
||||
cache:
|
||||
- node_modules
|
||||
|
||||
# Install scripts. (runs after repo cloning)
|
||||
install:
|
||||
# Get the latest stable version of Node.js or io.js
|
||||
- ps: Install-Product node $env:nodejs_version
|
||||
# install modules
|
||||
- npm install -g yarn --quiet
|
||||
- yarn install --pure-lockfile
|
||||
|
||||
# Post-install test scripts.
|
||||
test_script:
|
||||
# Output useful info for debugging.
|
||||
- node --version
|
||||
- npm --version
|
||||
|
||||
# Run the build
|
||||
build_script:
|
||||
- yarn dev # This will also run prettier!
|
||||
- yarn build # make sure both scripts work
|
||||
@@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<testsuites name="jest tests" tests="1" failures="0" time="1.179">
|
||||
<testsuite name="placeholder test" errors="0" failures="0" skipped="0" timestamp="2021-10-22T20:15:17" time="0.552" tests="1">
|
||||
<testcase classname="placeholder test should return true" name="placeholder test should return true" time="0.003">
|
||||
</testcase>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
Vendored
-6
@@ -1,6 +0,0 @@
|
||||
# Timely Data Source Plugin
|
||||
|
||||
Timely is a time series database application that provides secure access to time
|
||||
series data. Timely is written in Java, uses
|
||||
[Apache Accumulo](https://accumulo.apache.org/) for backend storage, and has
|
||||
a configurable length memory cache.
|
||||
Vendored
-2
@@ -1,2 +0,0 @@
|
||||
define((function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=71)}({71:function(e,t,n){}})}));
|
||||
//# sourceMappingURL=dark.js.map
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"sources":["webpack:///webpack/bootstrap"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s"],"mappings":"sCACE,IAAIA,EAAmB,GAGvB,SAASC,EAAoBC,GAG5B,GAAGF,EAAiBE,GACnB,OAAOF,EAAiBE,GAAUC,QAGnC,IAAIC,EAASJ,EAAiBE,GAAY,CACzCG,EAAGH,EACHI,GAAG,EACHH,QAAS,IAUV,OANAI,EAAQL,GAAUM,KAAKJ,EAAOD,QAASC,EAAQA,EAAOD,QAASF,GAG/DG,EAAOE,GAAI,EAGJF,EAAOD,QA0Df,OArDAF,EAAoBQ,EAAIF,EAGxBN,EAAoBS,EAAIV,EAGxBC,EAAoBU,EAAI,SAASR,EAASS,EAAMC,GAC3CZ,EAAoBa,EAAEX,EAASS,IAClCG,OAAOC,eAAeb,EAASS,EAAM,CAAEK,YAAY,EAAMC,IAAKL,KAKhEZ,EAAoBkB,EAAI,SAAShB,GACX,oBAAXiB,QAA0BA,OAAOC,aAC1CN,OAAOC,eAAeb,EAASiB,OAAOC,YAAa,CAAEC,MAAO,WAE7DP,OAAOC,eAAeb,EAAS,aAAc,CAAEmB,OAAO,KAQvDrB,EAAoBsB,EAAI,SAASD,EAAOE,GAEvC,GADU,EAAPA,IAAUF,EAAQrB,EAAoBqB,IAC/B,EAAPE,EAAU,OAAOF,EACpB,GAAW,EAAPE,GAA8B,iBAAVF,GAAsBA,GAASA,EAAMG,WAAY,OAAOH,EAChF,IAAII,EAAKX,OAAOY,OAAO,MAGvB,GAFA1B,EAAoBkB,EAAEO,GACtBX,OAAOC,eAAeU,EAAI,UAAW,CAAET,YAAY,EAAMK,MAAOA,IACtD,EAAPE,GAA4B,iBAATF,EAAmB,IAAI,IAAIM,KAAON,EAAOrB,EAAoBU,EAAEe,EAAIE,EAAK,SAASA,GAAO,OAAON,EAAMM,IAAQC,KAAK,KAAMD,IAC9I,OAAOF,GAIRzB,EAAoB6B,EAAI,SAAS1B,GAChC,IAAIS,EAAST,GAAUA,EAAOqB,WAC7B,WAAwB,OAAOrB,EAAgB,SAC/C,WAA8B,OAAOA,GAEtC,OADAH,EAAoBU,EAAEE,EAAQ,IAAKA,GAC5BA,GAIRZ,EAAoBa,EAAI,SAASiB,EAAQC,GAAY,OAAOjB,OAAOkB,UAAUC,eAAe1B,KAAKuB,EAAQC,IAGzG/B,EAAoBkC,EAAI,IAIjBlC,EAAoBA,EAAoBmC,EAAI,I","file":"dark.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 71);\n"],"sourceRoot":""}
|
||||
Vendored
-2
@@ -1,2 +0,0 @@
|
||||
define((function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=70)}({70:function(e,t,n){}})}));
|
||||
//# sourceMappingURL=light.js.map
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"sources":["webpack:///webpack/bootstrap"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s"],"mappings":"sCACE,IAAIA,EAAmB,GAGvB,SAASC,EAAoBC,GAG5B,GAAGF,EAAiBE,GACnB,OAAOF,EAAiBE,GAAUC,QAGnC,IAAIC,EAASJ,EAAiBE,GAAY,CACzCG,EAAGH,EACHI,GAAG,EACHH,QAAS,IAUV,OANAI,EAAQL,GAAUM,KAAKJ,EAAOD,QAASC,EAAQA,EAAOD,QAASF,GAG/DG,EAAOE,GAAI,EAGJF,EAAOD,QA0Df,OArDAF,EAAoBQ,EAAIF,EAGxBN,EAAoBS,EAAIV,EAGxBC,EAAoBU,EAAI,SAASR,EAASS,EAAMC,GAC3CZ,EAAoBa,EAAEX,EAASS,IAClCG,OAAOC,eAAeb,EAASS,EAAM,CAAEK,YAAY,EAAMC,IAAKL,KAKhEZ,EAAoBkB,EAAI,SAAShB,GACX,oBAAXiB,QAA0BA,OAAOC,aAC1CN,OAAOC,eAAeb,EAASiB,OAAOC,YAAa,CAAEC,MAAO,WAE7DP,OAAOC,eAAeb,EAAS,aAAc,CAAEmB,OAAO,KAQvDrB,EAAoBsB,EAAI,SAASD,EAAOE,GAEvC,GADU,EAAPA,IAAUF,EAAQrB,EAAoBqB,IAC/B,EAAPE,EAAU,OAAOF,EACpB,GAAW,EAAPE,GAA8B,iBAAVF,GAAsBA,GAASA,EAAMG,WAAY,OAAOH,EAChF,IAAII,EAAKX,OAAOY,OAAO,MAGvB,GAFA1B,EAAoBkB,EAAEO,GACtBX,OAAOC,eAAeU,EAAI,UAAW,CAAET,YAAY,EAAMK,MAAOA,IACtD,EAAPE,GAA4B,iBAATF,EAAmB,IAAI,IAAIM,KAAON,EAAOrB,EAAoBU,EAAEe,EAAIE,EAAK,SAASA,GAAO,OAAON,EAAMM,IAAQC,KAAK,KAAMD,IAC9I,OAAOF,GAIRzB,EAAoB6B,EAAI,SAAS1B,GAChC,IAAIS,EAAST,GAAUA,EAAOqB,WAC7B,WAAwB,OAAOrB,EAAgB,SAC/C,WAA8B,OAAOA,GAEtC,OADAH,EAAoBU,EAAEE,EAAQ,IAAKA,GAC5BA,GAIRZ,EAAoBa,EAAI,SAASiB,EAAQC,GAAY,OAAOjB,OAAOkB,UAAUC,eAAe1B,KAAKuB,EAAQC,IAGzG/B,EAAoBkC,EAAI,IAIjBlC,EAAoBA,EAAoBmC,EAAI,I","file":"light.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 70);\n"],"sourceRoot":""}
|
||||
Vendored
-3
@@ -1,3 +0,0 @@
|
||||
/*! For license information please see module.js.LICENSE.txt */
|
||||
define(["react","@grafana/ui","react-dom","lodash","@grafana/runtime","@grafana/data"],(function(e,t,n,r,o,i){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=72)}([function(t,n){t.exports=e},function(e,t,n){e.exports=n(48)()},function(e,t){e.exports=function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e},e.exports.default=e.exports,e.exports.__esModule=!0},function(e,t){e.exports=function(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e},e.exports.default=e.exports,e.exports.__esModule=!0},function(e,t){function n(){return e.exports=n=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},e.exports.default=e.exports,e.exports.__esModule=!0,n.apply(this,arguments)}e.exports=n,e.exports.default=e.exports,e.exports.__esModule=!0},function(e,t){e.exports=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o},e.exports.default=e.exports,e.exports.__esModule=!0},function(e,t,n){var r;!function(){"use strict";var n={}.hasOwnProperty;function o(){for(var e=[],t=0;t<arguments.length;t++){var r=arguments[t];if(r){var i=typeof r;if("string"===i||"number"===i)e.push(r);else if(Array.isArray(r)){if(r.length){var a=o.apply(null,r);a&&e.push(a)}}else if("object"===i)if(r.toString===Object.prototype.toString)for(var s in r)n.call(r,s)&&r[s]&&e.push(s);else e.push(r.toString())}}return e.join(" ")}e.exports?(o.default=o,e.exports=o):void 0===(r=function(){return o}.apply(t,[]))||(e.exports=r)}()},function(e,n){e.exports=t},function(e,t,n){var r=n(50);e.exports=function(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,r(e,t)},e.exports.default=e.exports,e.exports.__esModule=!0},,function(e,t){e.exports=n},function(e,t){e.exports=r},function(e,t){e.exports=o},function(e,t,n){"use strict";e.exports=function e(t,n){if(t===n)return!0;if(t&&n&&"object"==typeof t&&"object"==typeof n){if(t.constructor!==n.constructor)return!1;var r,o,i;if(Array.isArray(t)){if((r=t.length)!=n.length)return!1;for(o=r;0!=o--;)if(!e(t[o],n[o]))return!1;return!0}if(t.constructor===RegExp)return t.source===n.source&&t.flags===n.flags;if(t.valueOf!==Object.prototype.valueOf)return t.valueOf()===n.valueOf();if(t.toString!==Object.prototype.toString)return t.toString()===n.toString();if((r=(i=Object.keys(t)).length)!==Object.keys(n).length)return!1;for(o=r;0!=o--;)if(!Object.prototype.hasOwnProperty.call(n,i[o]))return!1;for(o=r;0!=o--;){var a=i[o];if(!e(t[a],n[a]))return!1}return!0}return t!=t&&n!=n}},function(e,t,n){"use strict";e.exports=function(e,t,n,r,o,i,a,s){if(!e){var l;if(void 0===t)l=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var u=[n,r,o,i,a,s],c=0;(l=new Error(t.replace(/%s/g,(function(){return u[c++]})))).name="Invariant Violation"}throw l.framesToPop=1,l}}},function(e,t,n){"use strict";var r=n(26),o="function"==typeof Symbol&&"symbol"==typeof Symbol("foo"),i=Object.prototype.toString,a=Array.prototype.concat,s=Object.defineProperty,l=s&&function(){var e={};try{for(var t in s(e,"x",{enumerable:!1,value:e}),e)return!1;return e.x===e}catch(e){return!1}}(),u=function(e,t,n,r){var o;(!(t in e)||"function"==typeof(o=r)&&"[object Function]"===i.call(o)&&r())&&(l?s(e,t,{configurable:!0,enumerable:!1,value:n,writable:!0}):e[t]=n)},c=function(e,t){var n=arguments.length>2?arguments[2]:{},i=r(t);o&&(i=a.call(i,Object.getOwnPropertySymbols(t)));for(var s=0;s<i.length;s+=1)u(e,i[s],t[i[s]],n[i[s]])};c.supportsDescriptors=!!l,e.exports=c},function(e,t,n){"use strict";var r=function(){};e.exports=r},function(e,t,n){"use strict";function r(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}n.d(t,"a",(function(){return r}))},function(e,t){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(e){"object"==typeoLine truncated
|
||||
//# sourceMappingURL=module.js.map
|
||||
-87
@@ -1,87 +0,0 @@
|
||||
/*!
|
||||
Copyright (c) 2018 Jed Watson.
|
||||
Licensed under the MIT License (MIT), see
|
||||
http://jedwatson.github.io/classnames
|
||||
*/
|
||||
|
||||
/*! *****************************************************************************
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
***************************************************************************** */
|
||||
|
||||
/**
|
||||
* A better abstraction over CSS.
|
||||
*
|
||||
* @copyright Oleg Isonen (Slobodskoi) / Isonen 2014-present
|
||||
* @website https://github.com/cssinjs/jss
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
/** @license React v16.13.1
|
||||
* react-is.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/**!
|
||||
* @fileOverview Kickass library to create and place poppers near their reference elements.
|
||||
* @version 1.16.1
|
||||
* @license
|
||||
* Copyright (c) 2016 Federico Zivolo and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**!
|
||||
* @fileOverview Kickass library to create and place poppers near their reference elements.
|
||||
* @version 1.16.1-lts
|
||||
* @license
|
||||
* Copyright (c) 2016 Federico Zivolo and contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
-1
@@ -1 +0,0 @@
|
||||
{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///external \"react\"","webpack:///../node_modules/prop-types/index.js","webpack:///../node_modules/@babel/runtime/helpers/assertThisInitialized.js","webpack:///../node_modules/@babel/runtime/helpers/defineProperty.js","webpack:///../node_modules/@babel/runtime/helpers/extends.js","webpack:///../node_modules/@babel/runtime/helpers/objectWithoutPropertiesLoose.js","webpack:///../node_modules/classnames/index.js","webpack:///external \"@grafana/ui\"","webpack:///../node_modules/@babel/runtime/helpers/inheritsLoose.js","webpack:///external \"react-dom\"","webpack:///external \"lodash\"","webpack:///external \"@grafana/runtime\"","webpack:///../node_modules/fast-deep-equal/index.js","webpack:///../node_modules/invariant/browser.js","webpack:///../node_modules/define-properties/index.js","webpack:///../node_modules/warning/warning.js","webpack:///../node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js","webpack:///../node_modules/webpack/buildin/global.js","webpack:///../node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js","webpack:///../node_modules/function-bind/index.js","webpack:///../node_modules/call-bind/index.js","webpack:///../node_modules/popper.js/dist/esm/popper.js","webpack:///../node_modules/@hypnosphi/create-react-context/lib/index.js","webpack:///../node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js","webpack:///../node_modules/object-keys/index.js","webpack:///../node_modules/object-keys/isArguments.js","webpack:///../node_modules/call-bind/callBound.js","webpack:///../node_modules/get-intrinsic/index.js","webpack:///../node_modules/has-symbols/shams.js","webpack:///../node_modules/object-is/implementation.js","webpack:///../node_modules/object-is/polyfill.js","webpack:///../node_modules/regexp.prototype.flags/implementation.js","webpack:///../node_modules/regexp.prototype.flags/polyfill.js","webpack:///../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js","webpack:///../node_modules/css-loader/dist/runtime/api.js","webpack:///external \"@grafana/data\"","webpack:///../node_modules/dayjs/dayjs.min.js","webpack:///../node_modules/lodash.debounce/index.js","webpack:///../node_modules/deep-equal/index.js","webpack:///../node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js","webpack:///../node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js","webpack:///../node_modules/@babel/runtime/helpers/esm/iterableToArray.js","webpack:///../node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js","webpack:///../node_modules/@babel/runtime/helpers/esm/nonIterableRest.js","webpack:///../node_modules/@material-ui/core/node_modules/popper.js/dist/esm/popper.js","webpack:///../node_modules/prop-types/factoryWithThrowingShims.js","webpack:///../node_modules/prop-types/lib/ReactPropTypesSecret.js","webpack:///../node_modules/@babel/runtime/helpers/setPrototypeOf.js","webpack:///../node_modules/object-keys/implementation.js","webpack:///../node_modules/is-arguments/index.js","webpack:///../node_modules/has-symbols/index.js","webpack:///../node_modules/function-bind/implementation.js","webpack:///../node_modules/has/src/index.js","webpack:///../node_modules/object-is/index.js","webpack:///../node_modules/object-is/shim.js","webpack:///../node_modules/is-regex/index.js","webpack:///../node_modules/regexp.prototype.flags/index.js","webpack:///../node_modules/regexp.prototype.flags/shim.js","webpack:///../node_modules/is-date-object/index.js","webpack:///../node_modules/@hypnosphi/create-react-context/lib/implementation.js","webpack:///../node_modules/gud/index.js","webpack:///../node_modules/react-is/index.js","webpack:///../node_modules/react-is/cjs/react-is.production.min.js","webpack:///./static/css/timely-bootstrap.css?617f","webpack:///./static/css/timely-bootstrap.css","webpack:///./static/css/timely.css?f98e","webpack:///./static/css/timely.css","webpack:///../node_modules/tslib/tslib.es6.js","webpack:///../node_modules/rxjs/dist/esm5/internal/util/isFunction.js","webpack:///../node_modules/rxjs/dist/esm5/internal/util/lift.js","webpack:///../node_modules/rxjs/node_modules/tslib/tslib.es6.js","webpack:///../node_modules/rxjs/dist/esm5/internal/util/UnsubscriptionError.js","webpack:///../node_modules/rxjs/dist/esm5/internal/util/createErrorClass.js","webpack:///../node_modules/rxjs/dist/esm5/internal/util/arrRemove.js","webpack:///../node_modules/rxjs/dist/esm5/internal/Subscription.js","webpack:///../node_modules/rxjs/dist/esm5/internal/config.js","webpack:///../node_modules/rxjs/dist/esm5/internal/scheduler/timeoutProvider.js","webpack:///../node_modules/rxjs/dist/esm5/internal/util/reportUnhandledError.js","webpack:///../node_modules/rxjs/dist/esm5/internal/util/noop.js","webpack:///../node_modules/rxjs/dist/esm5/internal/NotificationFactories.js","webpack:///../node_modules/rxjs/dist/esm5/internal/util/errorContext.js","webpack:///../node_modules/rxjs/dist/esm5/inteLine truncated
|
||||
Vendored
-40
@@ -1,40 +0,0 @@
|
||||
{
|
||||
"type": "datasource",
|
||||
"name": "Timely",
|
||||
"id": "nsa-timely-datasource",
|
||||
"category": "tsdb",
|
||||
"metrics": true,
|
||||
"backend": true,
|
||||
"alerting": true,
|
||||
"executable": "timely_datasource_backend",
|
||||
"info": {
|
||||
"description": "Open source time series database backed by Accumulo",
|
||||
"author": {
|
||||
"name": "National Security Agency"
|
||||
},
|
||||
"keywords": ["Simple"],
|
||||
"logos": {
|
||||
"small": "static/img/timely_square_small.png",
|
||||
"large": "static/img/timely_square_large.png"
|
||||
},
|
||||
"links": [
|
||||
{
|
||||
"name": "Website",
|
||||
"url": "https://code.nsa.gov/timely"
|
||||
},
|
||||
{
|
||||
"name": "License",
|
||||
"url": "https://github.com/NationalSecurityAgency/timely/blob/master/LICENSE"
|
||||
}
|
||||
],
|
||||
"screenshots": [],
|
||||
"version": "2.1.0",
|
||||
"updated": "2024-02-26"
|
||||
},
|
||||
"dependencies": {
|
||||
"classnames": "2.2.6",
|
||||
"slate-plain-serializer": "0.7.10",
|
||||
"grafanaVersion": "6.5.x",
|
||||
"plugins": []
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
$box-shadow-dimensions: 0 0 0 0.2rem;
|
||||
$placeholder-color: #6c757d;
|
||||
|
||||
.rbt {
|
||||
&-input-multi {
|
||||
// Bootstrap 4 focus style
|
||||
&.focus {
|
||||
background-color: #fff;
|
||||
border-color: #80bdff;
|
||||
box-shadow: $box-shadow-dimensions rgba(0, 123, 255, 0.25);
|
||||
color: #495057;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
&.is-invalid.focus {
|
||||
border-color: #dc3545;
|
||||
box-shadow: $box-shadow-dimensions rgba(220, 53, 69, 0.25);
|
||||
}
|
||||
|
||||
&.is-valid.focus {
|
||||
border-color: #28a745;
|
||||
box-shadow: $box-shadow-dimensions rgba(40, 167, 69, 0.25);
|
||||
}
|
||||
|
||||
input {
|
||||
// Firefox
|
||||
&::-moz-placeholder {
|
||||
color: $placeholder-color;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
// Internet Explorer 10+
|
||||
&:-ms-input-placeholder {
|
||||
color: $placeholder-color;
|
||||
}
|
||||
|
||||
// Safari and Chrome
|
||||
&::-webkit-input-placeholder {
|
||||
color: $placeholder-color;
|
||||
}
|
||||
}
|
||||
|
||||
// Override height in main CSS file :/
|
||||
& .rbt-input-main,
|
||||
&.form-control-lg .rbt-input-main,
|
||||
&.form-control-sm .rbt-input-main {
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
&-token {
|
||||
margin: 1px 3px 2px 0;
|
||||
}
|
||||
}
|
||||
-201
@@ -1,201 +0,0 @@
|
||||
.rbt .rbt-input-main::-ms-clear {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* Menu
|
||||
*/
|
||||
.rbt-menu {
|
||||
margin-bottom: 2px !important;
|
||||
}
|
||||
|
||||
.rbt-menu > .dropdown-item {
|
||||
overflow: hidden !important;
|
||||
text-overflow: ellipsis !important;
|
||||
}
|
||||
|
||||
.rbt-menu > .dropdown-item:focus {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.rbt-menu-pagination-option {
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multi-select Input
|
||||
*/
|
||||
.rbt-input-multi {
|
||||
cursor: text !important;
|
||||
overflow: hidden !important;
|
||||
position: relative !important;
|
||||
}
|
||||
|
||||
.rbt-input-multi.focus {
|
||||
border-color: #80bdff !important;
|
||||
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25) !important;
|
||||
color: #495057 !important;
|
||||
outline: 0 !important;
|
||||
}
|
||||
|
||||
.rbt-input-multi.form-control {
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
.rbt-input-multi.form-control[disabled] {
|
||||
background-color: #e9ecef !important;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
.rbt-input-multi.is-invalid.focus {
|
||||
border-color: #dc3545 !important;
|
||||
box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25) !important;
|
||||
}
|
||||
|
||||
.rbt-input-multi.is-valid.focus {
|
||||
border-color: #28a745 !important;
|
||||
box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25) !important;
|
||||
}
|
||||
|
||||
.rbt-input-multi input::-moz-placeholder {
|
||||
color: #6c757d !important;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
.rbt-input-multi input:-ms-input-placeholder {
|
||||
color: #6c757d !important;
|
||||
}
|
||||
|
||||
.rbt-input-multi input::-webkit-input-placeholder {
|
||||
color: #6c757d !important;
|
||||
}
|
||||
|
||||
.rbt-input-multi .rbt-input-wrapper {
|
||||
align-items: flex-start !important;
|
||||
display: flex !important;
|
||||
flex-wrap: wrap !important;
|
||||
margin-bottom: -4px !important;
|
||||
margin-top: -1px !important;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
.rbt-input-multi .rbt-input-main {
|
||||
margin: 1px 0 4px !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close Button
|
||||
*/
|
||||
.rbt-close {
|
||||
z-index: 1 !important;
|
||||
}
|
||||
|
||||
.rbt-close-lg {
|
||||
font-size: 24px !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* Token
|
||||
*/
|
||||
.rbt-token {
|
||||
background-color: #e7f4ff !important;
|
||||
border: 0 !important;
|
||||
border-radius: 0.25rem !important;
|
||||
color: #007bff !important;
|
||||
display: inline-block !important;
|
||||
line-height: 1em !important;
|
||||
margin: 1px 3px 2px 0 !important;
|
||||
padding: 4px 7px !important;
|
||||
position: relative !important;
|
||||
}
|
||||
|
||||
.rbt-token-disabled {
|
||||
background-color: rgba(0, 0, 0, 0.1) !important;
|
||||
color: #495057 !important;
|
||||
pointer-events: none !important;
|
||||
}
|
||||
|
||||
.rbt-token-removeable {
|
||||
cursor: pointer !important;
|
||||
padding-right: 21px !important;
|
||||
}
|
||||
|
||||
.rbt-token-active {
|
||||
background-color: #007bff !important;
|
||||
color: #fff !important;
|
||||
outline: none !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
.rbt-token .rbt-token-remove-button {
|
||||
bottom: 0 !important;
|
||||
color: inherit !important;
|
||||
font-size: inherit !important;
|
||||
font-weight: normal !important;
|
||||
opacity: 1 !important;
|
||||
outline: none !important;
|
||||
padding: 3px 7px !important;
|
||||
position: absolute !important;
|
||||
right: 0 !important;
|
||||
text-shadow: none !important;
|
||||
top: -2px !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loader + CloseButton container
|
||||
*/
|
||||
.rbt-aux {
|
||||
align-items: center !important;
|
||||
display: flex !important;
|
||||
bottom: 0 !important;
|
||||
justify-content: center !important;
|
||||
pointer-events: none !important;
|
||||
/* Don't block clicks on the input */
|
||||
position: absolute !important;
|
||||
right: 0 !important;
|
||||
top: 0 !important;
|
||||
width: 34px !important;
|
||||
}
|
||||
|
||||
.rbt-aux-lg {
|
||||
width: 46px !important;
|
||||
}
|
||||
|
||||
.rbt-aux .rbt-close {
|
||||
margin-top: -4px !important;
|
||||
pointer-events: auto !important;
|
||||
/* Override pointer-events: none; above */
|
||||
}
|
||||
|
||||
.has-aux .rbt-input {
|
||||
padding-right: 34px !important;
|
||||
}
|
||||
|
||||
.rbt-highlight-text {
|
||||
background-color: inherit !important;
|
||||
color: inherit !important;
|
||||
font-weight: bold !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* Input Groups
|
||||
*/
|
||||
.input-group > .rbt {
|
||||
flex: 1 !important;
|
||||
}
|
||||
|
||||
.input-group > .rbt .rbt-input-hint,
|
||||
.input-group > .rbt .rbt-aux {
|
||||
z-index: 5 !important;
|
||||
}
|
||||
|
||||
.input-group > .rbt:not(:first-child) .form-control {
|
||||
border-top-left-radius: 0 !important;
|
||||
border-bottom-left-radius: 0 !important;
|
||||
}
|
||||
|
||||
.input-group > .rbt:not(:last-child) .form-control {
|
||||
border-top-right-radius: 0 !important;
|
||||
border-bottom-right-radius: 0 !important;
|
||||
}
|
||||
@@ -1,240 +0,0 @@
|
||||
$animation: loader-animation 600ms infinite linear;
|
||||
$inset: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||
$placeholder-color: #999;
|
||||
|
||||
.rbt {
|
||||
&-menu {
|
||||
margin-bottom: 2px; // Spacing for dropup
|
||||
|
||||
& > li a {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
&-pagination-option {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
// Hide IE's native "clear" button
|
||||
& .rbt-input-main::-ms-clear {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&-input-multi {
|
||||
cursor: text;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
height: auto;
|
||||
|
||||
// Apply Bootstrap focus styles
|
||||
&.focus {
|
||||
box-shadow: $inset, 0 0 8px rgba(102, 175, 233, 0.6);
|
||||
border-color: #66afe9;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
// BS4 uses the :disabled pseudo-class, which doesn't work with non-inputs.
|
||||
&.form-control[disabled] {
|
||||
background-color: #e9ecef;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
// Apply Bootstrap placeholder styles
|
||||
input {
|
||||
// Firefox
|
||||
&::-moz-placeholder {
|
||||
color: $placeholder-color;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
// Internet Explorer 10+
|
||||
&:-ms-input-placeholder {
|
||||
color: $placeholder-color;
|
||||
}
|
||||
|
||||
// Safari and Chrome
|
||||
&::-webkit-input-placeholder {
|
||||
color: $placeholder-color;
|
||||
}
|
||||
}
|
||||
|
||||
.rbt-input-wrapper {
|
||||
align-items: flex-start;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: -4px;
|
||||
margin-top: -1px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.rbt-input-main {
|
||||
// Set input height for cross-browser consistency
|
||||
height: 20px;
|
||||
margin: 1px 0 4px;
|
||||
}
|
||||
|
||||
&.input,
|
||||
&.form-control {
|
||||
&-lg {
|
||||
.rbt-input-main {
|
||||
height: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
&-sm {
|
||||
.rbt-input-main {
|
||||
height: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-close {
|
||||
z-index: 1;
|
||||
|
||||
&-lg {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
&-token {
|
||||
background-color: #e7f4ff;
|
||||
border: 0;
|
||||
border-radius: 2px;
|
||||
color: #1f8dd6;
|
||||
display: inline-block;
|
||||
line-height: 1em;
|
||||
margin: 0 3px 3px 0;
|
||||
padding: 4px 7px;
|
||||
position: relative;
|
||||
|
||||
&-disabled {
|
||||
background-color: #ddd;
|
||||
color: #888;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&-removeable {
|
||||
cursor: pointer;
|
||||
padding-right: 21px;
|
||||
}
|
||||
|
||||
&-active {
|
||||
background-color: #1f8dd6;
|
||||
color: #fff;
|
||||
outline: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
& &-remove-button {
|
||||
bottom: 0;
|
||||
color: inherit;
|
||||
font-size: inherit;
|
||||
font-weight: normal;
|
||||
opacity: 1;
|
||||
outline: none;
|
||||
padding: 3px 7px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
text-shadow: none;
|
||||
top: -2px;
|
||||
}
|
||||
}
|
||||
|
||||
&-loader {
|
||||
-moz-animation: $animation;
|
||||
-webkit-animation: $animation;
|
||||
animation: $animation;
|
||||
border: 1px solid #d5d5d5;
|
||||
border-radius: 50%;
|
||||
border-top-color: #1f8dd6;
|
||||
display: block;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
|
||||
&-lg {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
&-aux {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
bottom: 0;
|
||||
justify-content: center;
|
||||
pointer-events: none; /* Don't block clicks on the input */
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 34px;
|
||||
|
||||
&-lg {
|
||||
width: 46px;
|
||||
}
|
||||
|
||||
& .rbt-close {
|
||||
margin-top: -4px;
|
||||
pointer-events: auto; /* Override pointer-events: none; above */
|
||||
}
|
||||
}
|
||||
|
||||
.has-aux &-input {
|
||||
padding-right: 34px;
|
||||
}
|
||||
|
||||
&-highlight-text {
|
||||
background-color: inherit;
|
||||
color: inherit;
|
||||
font-weight: bold;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Input Groups */
|
||||
.input-group > .rbt {
|
||||
flex: 1;
|
||||
|
||||
// Form-controls within input-groups have a higher z-index.
|
||||
& .rbt-input-hint,
|
||||
& .rbt-aux {
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
&:not(:first-child) .form-control {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
&:not(:last-child) .form-control {
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Validation States */
|
||||
.has-error .rbt-input-multi.focus {
|
||||
border-color: #843534;
|
||||
box-shadow: $inset, 0 0 6px #ce8483;
|
||||
}
|
||||
|
||||
.has-warning .rbt-input-multi.focus {
|
||||
border-color: #66512c;
|
||||
box-shadow: $inset, 0 0 6px #c0a16b;
|
||||
}
|
||||
|
||||
.has-success .rbt-input-multi.focus {
|
||||
border-color: #2b542c;
|
||||
box-shadow: $inset, 0 0 6px #67b168;
|
||||
}
|
||||
|
||||
@keyframes loader-animation {
|
||||
to {
|
||||
transform: rotate(1turn);
|
||||
}
|
||||
}
|
||||
-10602
File diff suppressed because it is too large.
Load diff
-20322
File diff suppressed because it is too large.
Load diff
-20321
File diff suppressed because it is too large.
Load diff
-1
@@ -1 +0,0 @@
|
||||
div.timely .dropdown-item,div.timely .dropdown-item-text,div.timely input.form-control{color:#c7d0d9;background-color:#0b0c0e}.dropdown-item:active,.dropdown-item:focus,div.timely .dropdown-item.active,div.timely .dropdown-item:hover{background-color:#4f5255}.dropdown-item:disabled,div.timely .dropdown-header,div.timely .dropdown-item.disabled{color:#0b0c0e}div.timely .dropdown-menu{background-color:#0b0c0e;box-shadow:0 2px 2px 2px #31343b}div.timely input.form-control:focus{color:#c7d0d9;outline:0;box-shadow:0 0 0 2px #141619,0 0 0 4px #1f60c4;outline-offset:2px;transition:all .2s cubic-bezier(.19,1,.22,1) 0s}div.timely mark.rbt-highlight-text{background:linear-gradient(90deg,#56585c,#4c5057);color:#ff0}
|
||||
-1
@@ -1 +0,0 @@
|
||||
div.timely input.form-control{color:#464c54;background-color:#fff}div.timely .dropdown-item,div.timely .dropdown-item-text{color:#464c54}.dropdown-item:active,.dropdown-item:focus,div.timely .dropdown-item.active,div.timely .dropdown-item:hover{color:#464c54;background-color:#e3e6e9}.dropdown-item:disabled,div.timely .dropdown-item.disabled{color:#abadaf}div.timely .dropdown-header{color:#464c54}div.timely .dropdown-menu{box-shadow:0 4px 2px 0 #cbcbcb}div.timely input.form-control:focus{color:#464c54;outline:0;box-shadow:0 0 0 2px #fff,0 0 0 4px #5794f2;outline-offset:2px;transition:all .2s cubic-bezier(.19,1,.22,1) 0s}div.timely mark.rbt-highlight-text{background:linear-gradient(90deg,#bfc0c1,#abadaf);color:#ff0}
|
||||
@@ -1,11 +0,0 @@
|
||||
module github.com/NationalSecurityAgency/timely-datasource
|
||||
|
||||
go 1.14
|
||||
|
||||
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
|
||||
)
|
||||
@@ -1,780 +0,0 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/apache/arrow/go/arrow v0.0.0-20210223225224-5bea62493d91 h1:rbe942bXzd2vnds4y9fYQL8X4yFltXoZsKW7KtG+TFM=
|
||||
github.com/apache/arrow/go/arrow v0.0.0-20210223225224-5bea62493d91/go.mod h1:c9sxoIT3YgLxH4UhLOCKaBlEojuMhVYpk4Ntv3opUTQ=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
|
||||
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
|
||||
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE=
|
||||
github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
|
||||
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
|
||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.1 h1:jAbXjIeW2ZSW2AwFxlGTDoc2CjI2XujLkV3ArsZFCvc=
|
||||
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/flatbuffers v1.11.0 h1:O7CEyB8Cb3/DmtxODGtLHcEvpr81Jm5qLg/hsHnxA2A=
|
||||
github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.111.0 h1:7eqLgAdDYeELVokRCeDEobYQJy5/E5C43tZkb/xH66Q=
|
||||
github.com/grafana/grafana-plugin-sdk-go v0.111.0/go.mod h1:D7x3ah+1d4phNXpbnOaxa/osSaZlwh9/ZUnGGzegRbk=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
|
||||
github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI=
|
||||
github.com/hashicorp/go-hclog v0.16.1 h1:IVQwpTGNRRIHafnTs2dQLIk4ENtneRIEEJWOVDqz99o=
|
||||
github.com/hashicorp/go-hclog v0.16.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-plugin v1.2.2 h1:mgDpq0PkoK5gck2w4ivaMpWRHv/matdOR4xmeScmf/w=
|
||||
github.com/hashicorp/go-plugin v1.2.2/go.mod h1:F9eH4LrE/ZsRdbwhfjs9k9HoDUwAHnYtXdgmf1AVNs0=
|
||||
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
||||
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
||||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ=
|
||||
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||
github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE=
|
||||
github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
|
||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
||||
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
|
||||
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
|
||||
github.com/magefile/mage v1.11.0 h1:C/55Ywp9BpgVVclD3lRnSYCwXTYxmSppIgLeDYlNuls=
|
||||
github.com/magefile/mage v1.11.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
|
||||
github.com/mattetti/filebuffer v1.0.1 h1:gG7pyfnSIZCxdoKq+cPa8T0hhYtD9NxCdI4D7PTjRLM=
|
||||
github.com/mattetti/filebuffer v1.0.1/go.mod h1:YdMURNDOttIiruleeVr6f56OrMc+MydEnTcXwtkxNVs=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
|
||||
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
|
||||
github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
|
||||
github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
|
||||
github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
|
||||
github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||
github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
|
||||
github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
|
||||
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
|
||||
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
||||
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU=
|
||||
github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ=
|
||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
||||
github.com/prometheus/common v0.23.0/go.mod h1:H6QK/N6XVT42whUeIdI3dp36w49c+/iMDk7UAI2qm7Q=
|
||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||
github.com/prometheus/common v0.29.0 h1:3jqPBvKT4OHAbje2Ql7KeaaSicDBCxMYwEJU1zRJceE=
|
||||
github.com/prometheus/common v0.29.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
|
||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200911024640-645f7a48b24f h1:Yv4xsIx7HZOoyUGSJ2ksDyWE2qIBXROsZKt2ny3hCGM=
|
||||
google.golang.org/genproto v0.0.0-20200911024640-645f7a48b24f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.37.1 h1:ARnQJNWxGyYJpdf/JXscNlQr/uv607ZPU9Z7ogHi+iI=
|
||||
google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v0.0.0-20200910201057-6591123024b3/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
|
||||
@@ -1,8 +0,0 @@
|
||||
// This file is needed because it is used by vscode and other tools that
|
||||
// call `jest` directly. However, unless you are doing anything special
|
||||
// do not edit this file
|
||||
|
||||
const standard = require('@grafana/toolkit/src/config/jest.plugin.config');
|
||||
|
||||
// This process will use the same config that `yarn test` is using
|
||||
module.exports = standard.jestConfig();
|
||||
@@ -1,42 +0,0 @@
|
||||
{
|
||||
"name": "timely-datasource",
|
||||
"version": "2.1.0",
|
||||
"description": "Timely",
|
||||
"backend": true,
|
||||
"alerting": true,
|
||||
"executable": "timely_datasource_backend",
|
||||
"scripts": {
|
||||
"build": "grafana-toolkit plugin:build",
|
||||
"test": "grafana-toolkit plugin:test",
|
||||
"dev": "grafana-toolkit plugin:dev",
|
||||
"watch": "grafana-toolkit plugin:dev --watch"
|
||||
},
|
||||
"author": "Grafana Labs",
|
||||
"license": "Apache-2.0",
|
||||
"devDependencies": {
|
||||
"@grafana/toolkit": "^8.4.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12 <17"
|
||||
},
|
||||
"dependencies": {
|
||||
"@grafana/data": "^8.4.5",
|
||||
"@grafana/runtime": "^8.4.5",
|
||||
"@grafana/slate-react": "0.22.10-grafana",
|
||||
"@grafana/ui": "^8.4.5",
|
||||
"@material-ui/core": "^4.12.3",
|
||||
"@types/classnames": "2.3.1",
|
||||
"@types/lodash": "4.14.176",
|
||||
"@types/react-bootstrap-typeahead": "5.1.8",
|
||||
"@types/slate-plain-serializer": "0.7.1",
|
||||
"@types/slate-react": "0.50.1",
|
||||
"classnames": "2.3.1",
|
||||
"dayjs": "1.10.7",
|
||||
"react-bootstrap-typeahead": "5.1.1",
|
||||
"rxjs": "7.3.0",
|
||||
"slate-plain-serializer": "0.7.13",
|
||||
"tmpl": "1.0.5",
|
||||
"tslib": "^2.3.1",
|
||||
"ws": "5.2.3"
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
package main
|
||||
|
||||
type TimelyQueryForm struct {
|
||||
Metric string `json:"metric"`
|
||||
Alias string `json:"alias"`
|
||||
Aggregator string `json:"aggregator"`
|
||||
DisableDownsampling bool `json:"disableDownsampling"`
|
||||
DownsampleAggregator string `json:"downsampleAggregator"`
|
||||
DownsampleFillPolicy string `json:"downsampleFillPolicy"`
|
||||
DownsampleInterval string `json:"downsampleInterval"`
|
||||
Tags map[string]string `json:"tags"`
|
||||
Filters []Filter `json:"filters"`
|
||||
ShouldComputeRate bool `json:"shouldComputeRate"`
|
||||
IsCounter bool `json:"isCounter"`
|
||||
CounterMax string `json:"counterMax"`
|
||||
CounterResetValue string `json:"counterResetValue"`
|
||||
Tsuids []string `json:"tsuids"`
|
||||
QueryType string `json:"queryType"`
|
||||
RefId string `json:"refId"`
|
||||
Datasource string `json:"datasource"`
|
||||
DatasourceId int64 `json:"datasourceId"`
|
||||
IntervalMs int64 `json:"intervalMs"`
|
||||
MaxDataPoints int64 `json:"maxDataPoints"`
|
||||
OrgId int64 `json:"ordId"`
|
||||
}
|
||||
|
||||
type TimelyQueryServer struct {
|
||||
Metric string `json:"metric"`
|
||||
Aggregator string `json:"aggregator"`
|
||||
DisableDownsampling bool `json:"disableDownsampling"`
|
||||
DownsampleAggregator string `json:"downsampleAggregator"`
|
||||
DownsampleFillPolicy string `json:"downsampleFillPolicy"`
|
||||
DownsampleInterval string `json:"downsampleInterval"`
|
||||
Tags map[string]string `json:"tags"`
|
||||
Filters []Filter `json:"filters"`
|
||||
ShouldComputeRate bool `json:"shouldComputeRate"`
|
||||
IsCounter bool `json:"isCounter"`
|
||||
CounterMax string `json:"counterMax"`
|
||||
CounterResetValue string `json:"counterResetValue"`
|
||||
Tsuids []string `json:"tsuids"`
|
||||
QueryType string `json:"queryType"`
|
||||
RefId string `json:"refId"`
|
||||
}
|
||||
|
||||
type Filter struct {
|
||||
Type string `json:"type"`
|
||||
TagK string `json:"tagk"`
|
||||
Filter string `json:"filter"`
|
||||
GroupBy bool `json:"groupBy"`
|
||||
}
|
||||
|
||||
type RateOptions struct {
|
||||
Counter bool `json:"counter"`
|
||||
CounterMax int32 `json:"counterMax"`
|
||||
ResetValue int32 `json:"resetValue"`
|
||||
}
|
||||
|
||||
type TimelyQuery struct {
|
||||
Metric string `json:"metric"`
|
||||
Aggregator string `json:"aggregator"`
|
||||
Rate bool `json:"rate"`
|
||||
RateOptions RateOptions `json:"rateOptions"`
|
||||
Downsample string `json:"downsample"`
|
||||
Tags map[string]string `json:"tags"`
|
||||
Filters []Filter `json:"filters"`
|
||||
Tsuids []string `json:"tsuids"`
|
||||
}
|
||||
|
||||
type TimelyRequest struct {
|
||||
MsResolution bool `json:"msResolution"`
|
||||
GlobalAnnotations bool `json:"globalAnnotations"`
|
||||
Start int64 `json:"start"`
|
||||
End int64 `json:"end"`
|
||||
Queries []TimelyQuery `json:"queries"`
|
||||
}
|
||||
|
||||
type TimelyResponse struct {
|
||||
Metric string `json:"metric"`
|
||||
Tags map[string]string `json:"tags"`
|
||||
AggregatedTags []string `json:"aggregatedTags"`
|
||||
DataPoints map[int64]float64 `json:"dps"`
|
||||
}
|
||||
|
||||
type TimelyDataSourceOptions struct {
|
||||
TimelyHost string `json:"timelyHost"`
|
||||
HttpsPort string `json:"httpsPort"`
|
||||
OauthPassThru bool `json:"oauthPassThru"`
|
||||
UseClientCertWhenOAuthMissing bool `json:"useClientCertWhenOAuthMissing"`
|
||||
ClientCertificatePath string `json:"clientCertificatePath"`
|
||||
ClientKeyPath string `json:"clientKeyPath"`
|
||||
CertificateAuthorityPath string `json:"certificateAuthorityPath"`
|
||||
AllowInsecureSsl bool `json:"allowInsecureSsl"`
|
||||
}
|
||||
|
||||
type TimelyErrorResponse struct {
|
||||
ResponseCode int32 `json:responseCode`
|
||||
Message string `json:message`
|
||||
DetailMessage string `json:detailMessage`
|
||||
}
|
||||
@@ -1,183 +0,0 @@
|
||||
import { DataSourcePluginOptionsEditorProps } from '@grafana/data';
|
||||
import { LegacyForms } from '@grafana/ui';
|
||||
import { TimelyDataSourceOptions } from './types';
|
||||
import * as React from 'react';
|
||||
|
||||
const { FormField, Switch } = LegacyForms;
|
||||
|
||||
interface Props extends DataSourcePluginOptionsEditorProps<TimelyDataSourceOptions> {}
|
||||
|
||||
interface State {}
|
||||
|
||||
export class ConfigEditor extends React.PureComponent<Props, State> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
onTimelyHostChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const { onOptionsChange, options } = this.props;
|
||||
const jsonData = {
|
||||
...options.jsonData,
|
||||
timelyHost: event.target.value,
|
||||
};
|
||||
onOptionsChange({ ...options, jsonData });
|
||||
};
|
||||
|
||||
onHttpsPortChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const { onOptionsChange, options } = this.props;
|
||||
const jsonData = {
|
||||
...options.jsonData,
|
||||
httpsPort: event.target.value,
|
||||
};
|
||||
onOptionsChange({ ...options, jsonData });
|
||||
};
|
||||
|
||||
onUseOAuthChange = (event: React.SyntheticEvent<HTMLInputElement>) => {
|
||||
const { onOptionsChange, options } = this.props;
|
||||
const jsonData = {
|
||||
...options.jsonData,
|
||||
oauthPassThru: event.currentTarget.checked,
|
||||
};
|
||||
onOptionsChange({ ...options, jsonData });
|
||||
};
|
||||
|
||||
onUseClientCertWhenOAuthMissingChange = (event: React.SyntheticEvent<HTMLInputElement>) => {
|
||||
const { onOptionsChange, options } = this.props;
|
||||
const jsonData = {
|
||||
...options.jsonData,
|
||||
useClientCertWhenOAuthMissing: event.currentTarget.checked,
|
||||
};
|
||||
onOptionsChange({ ...options, jsonData });
|
||||
};
|
||||
|
||||
onClientCertificatePathChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const { onOptionsChange, options } = this.props;
|
||||
const jsonData = {
|
||||
...options.jsonData,
|
||||
clientCertificatePath: event.target.value,
|
||||
};
|
||||
onOptionsChange({ ...options, jsonData });
|
||||
};
|
||||
|
||||
onClientKeyPathChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const { onOptionsChange, options } = this.props;
|
||||
const jsonData = {
|
||||
...options.jsonData,
|
||||
clientKeyPath: event.target.value,
|
||||
};
|
||||
onOptionsChange({ ...options, jsonData });
|
||||
};
|
||||
|
||||
onCertificateAuthorityPathChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const { onOptionsChange, options } = this.props;
|
||||
const jsonData = {
|
||||
...options.jsonData,
|
||||
certificateAuthorityPath: event.target.value,
|
||||
};
|
||||
onOptionsChange({ ...options, jsonData });
|
||||
};
|
||||
|
||||
onAllowInsecureSslChange = (event: React.SyntheticEvent<HTMLInputElement>) => {
|
||||
const { onOptionsChange, options } = this.props;
|
||||
const jsonData = {
|
||||
...options.jsonData,
|
||||
allowInsecureSsl: event.currentTarget.checked,
|
||||
};
|
||||
onOptionsChange({ ...options, jsonData });
|
||||
};
|
||||
|
||||
render() {
|
||||
const { options } = this.props;
|
||||
const { jsonData } = options;
|
||||
|
||||
return (
|
||||
<div className="gf-form-group">
|
||||
<div className="gf-form">
|
||||
<FormField
|
||||
label={'Hostname or IP'}
|
||||
labelWidth={10}
|
||||
inputWidth={20}
|
||||
disabled={false}
|
||||
onChange={this.onTimelyHostChange}
|
||||
tooltip={'Hostname or IP of Timely Server'}
|
||||
value={jsonData.timelyHost || ''}
|
||||
placeholder={'localhost'}
|
||||
/>
|
||||
</div>
|
||||
<div className="gf-form">
|
||||
<FormField
|
||||
label={'Https port'}
|
||||
labelWidth={10}
|
||||
inputWidth={20}
|
||||
onChange={this.onHttpsPortChange}
|
||||
value={jsonData.httpsPort || ''}
|
||||
placeholder={'4243'}
|
||||
/>
|
||||
</div>
|
||||
<div className="gf-form">
|
||||
<Switch
|
||||
label={'Use OAuth token'}
|
||||
labelClass="width-10"
|
||||
tooltipPlacement={'top'}
|
||||
tooltip={'Send OAuth token if available'}
|
||||
checked={jsonData.oauthPassThru || false}
|
||||
onChange={this.onUseOAuthChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="gf-form">
|
||||
<Switch
|
||||
label={'Client cert for users'}
|
||||
labelClass="width-10"
|
||||
tooltipPlacement={'top'}
|
||||
tooltip={'If user is missing OAuth token, use client cert instead'}
|
||||
checked={jsonData.useClientCertWhenOAuthMissing || false}
|
||||
onChange={this.onUseClientCertWhenOAuthMissingChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="gf-form">
|
||||
<FormField
|
||||
label={'Client cert path'}
|
||||
labelWidth={10}
|
||||
inputWidth={30}
|
||||
disabled={false}
|
||||
onChange={this.onClientCertificatePathChange}
|
||||
tooltip={'Full path to client certificate'}
|
||||
value={jsonData.clientCertificatePath || ''}
|
||||
/>
|
||||
</div>
|
||||
<div className="gf-form">
|
||||
<FormField
|
||||
label={'Client key path'}
|
||||
labelWidth={10}
|
||||
inputWidth={30}
|
||||
disabled={false}
|
||||
onChange={this.onClientKeyPathChange}
|
||||
tooltip={'Full path to client key'}
|
||||
value={jsonData.clientKeyPath || ''}
|
||||
/>
|
||||
</div>
|
||||
<div className="gf-form">
|
||||
<FormField
|
||||
label={'CA path'}
|
||||
labelWidth={10}
|
||||
inputWidth={30}
|
||||
disabled={false}
|
||||
onChange={this.onCertificateAuthorityPathChange}
|
||||
tooltip={'Full path to certificate authority'}
|
||||
value={jsonData.certificateAuthorityPath || ''}
|
||||
/>
|
||||
</div>
|
||||
<div className="gf-form">
|
||||
<Switch
|
||||
label={'Allow insecure ssl'}
|
||||
labelClass="width-10"
|
||||
tooltipPlacement={'top'}
|
||||
tooltip={'Allow ssl connection with unverified or self-signed certificates'}
|
||||
checked={jsonData.allowInsecureSsl || false}
|
||||
onChange={this.onAllowInsecureSslChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,423 +0,0 @@
|
||||
import _ from 'lodash';
|
||||
import { QueryEditorProps } from '@grafana/data';
|
||||
import { Input, Select, LegacyForms } from '@grafana/ui';
|
||||
import React, { Component } from 'react';
|
||||
import { TimelyDataSource } from './TimelyDataSource';
|
||||
import { TimelyDataSourceOptions, TimelyErrors, TimelyQueryForm } from './types';
|
||||
import { SelectableValue } from '@grafana/data/types/select';
|
||||
import dayjs from 'dayjs';
|
||||
import { TagEditor } from './TagEditor';
|
||||
import { AsyncTypeahead, TypeaheadModel } from 'react-bootstrap-typeahead';
|
||||
|
||||
const { Switch } = LegacyForms;
|
||||
|
||||
export type Props = QueryEditorProps<TimelyDataSource, TimelyQueryForm, TimelyDataSourceOptions>;
|
||||
|
||||
interface State {
|
||||
aggregatorTypes: string[];
|
||||
errors: TimelyErrors;
|
||||
query: TimelyQueryForm;
|
||||
queryOptionsLoading: boolean;
|
||||
queryOptions: TypeaheadModel[];
|
||||
}
|
||||
|
||||
export class QueryEditor extends Component<Props, State> {
|
||||
metricArray: string[] = [];
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
const defaultQuery: Partial<TimelyQueryForm> = {
|
||||
metric: '',
|
||||
alias: '',
|
||||
aggregator: 'none',
|
||||
refId: 'A',
|
||||
queryType: 'metricQuery',
|
||||
disableDownsampling: false,
|
||||
downsampleFillPolicy: 'none',
|
||||
downsampleInterval: '1m',
|
||||
downsampleAggregator: 'avg',
|
||||
shouldComputeRate: false,
|
||||
isCounter: false,
|
||||
tags: {},
|
||||
};
|
||||
this.state = {
|
||||
aggregatorTypes: ['none', 'avg', 'dev', 'max', 'min', 'sum', 'count'],
|
||||
errors: {
|
||||
downsample: undefined,
|
||||
},
|
||||
query: Object.assign({}, defaultQuery, props.query),
|
||||
queryOptionsLoading: false,
|
||||
queryOptions: [],
|
||||
};
|
||||
this.getAggregators();
|
||||
this.getMetrics();
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps: Readonly<Props>, nextState: Readonly<State>, nextContext: any): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
onMetricTextChange = (value: string) => {
|
||||
this.setState((state, props) => {
|
||||
var query = Object.assign(state.query, { metric: value });
|
||||
this.updateQuery(query);
|
||||
return { query: query };
|
||||
});
|
||||
};
|
||||
|
||||
onAliasChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const value = e.target.value;
|
||||
this.setState((state, props) => {
|
||||
var query = Object.assign(state.query, { alias: value });
|
||||
this.updateQuery(query);
|
||||
return { query: query };
|
||||
});
|
||||
};
|
||||
|
||||
onAggregatorChange = (option: SelectableValue<string>) => {
|
||||
if (option.value) {
|
||||
const value = option.value;
|
||||
this.setState((state, props) => {
|
||||
var query = Object.assign(state.query, { aggregator: value });
|
||||
this.updateQuery(query);
|
||||
return { query: query };
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
onDownsampleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const value = e.target.value;
|
||||
this.setState((state, props) => {
|
||||
var query = Object.assign(state.query, { downsampleInterval: value });
|
||||
this.updateQuery(query);
|
||||
return { query: query };
|
||||
});
|
||||
};
|
||||
|
||||
onDownsampleAggregatorChange = (option: SelectableValue<string>) => {
|
||||
if (option.value) {
|
||||
const value = option.value;
|
||||
this.setState((state, props) => {
|
||||
var query = Object.assign(state.query, { downsampleAggregator: value });
|
||||
this.updateQuery(query);
|
||||
return { query: query };
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
onDisableDownsamplingChange = (option: React.FormEvent<HTMLInputElement>) => {
|
||||
const checked = option.currentTarget.checked;
|
||||
this.setState((state, props) => {
|
||||
var query = Object.assign(state.query, { disableDownsampling: checked });
|
||||
this.updateQuery(query);
|
||||
return { query: query };
|
||||
});
|
||||
};
|
||||
|
||||
onRateChange = (option: React.FormEvent<HTMLInputElement>) => {
|
||||
const checked = option.currentTarget.checked;
|
||||
this.setState((state, props) => {
|
||||
var query = Object.assign(state.query, { shouldComputeRate: checked });
|
||||
this.updateQuery(query);
|
||||
return { query: query };
|
||||
});
|
||||
};
|
||||
|
||||
onCounterChange = (option: React.FormEvent<HTMLInputElement>) => {
|
||||
const checked = option.currentTarget.checked;
|
||||
this.setState((state, props) => {
|
||||
var query = Object.assign(state.query, { isCounter: checked });
|
||||
this.updateQuery(query);
|
||||
return { query: query };
|
||||
});
|
||||
};
|
||||
|
||||
onCounterMaxChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const value = e.target.value;
|
||||
this.setState((state, props) => {
|
||||
var query = Object.assign(state.query, { counterMax: value });
|
||||
this.updateQuery(query);
|
||||
return { query: query };
|
||||
});
|
||||
};
|
||||
|
||||
onCounterResetValueChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const value = e.target.value;
|
||||
this.setState((state, props) => {
|
||||
var query = Object.assign(state.query, { counterResetValue: value });
|
||||
this.updateQuery(query);
|
||||
return { query: query };
|
||||
});
|
||||
};
|
||||
|
||||
updateQuery = (query: TimelyQueryForm) => {
|
||||
this.props.onChange(query);
|
||||
this.props.onRunQuery();
|
||||
};
|
||||
|
||||
updateQueryFromState = () => {
|
||||
const query = this.state.query;
|
||||
this.props.onChange(query);
|
||||
this.props.onRunQuery();
|
||||
};
|
||||
|
||||
validate = () => {
|
||||
const { disableDownsampling, downsampleInterval } = this.state.query;
|
||||
|
||||
if (!disableDownsampling) {
|
||||
try {
|
||||
let valid = false;
|
||||
if (downsampleInterval) {
|
||||
valid = dayjs('', '').isValid();
|
||||
}
|
||||
if (!valid) {
|
||||
this.setState((state, props) => {
|
||||
this.setState(
|
||||
{
|
||||
errors: {
|
||||
downsample: "You must supply a downsample interval (e.g. '1m' or '1h').",
|
||||
},
|
||||
},
|
||||
this.updateQueryFromState
|
||||
);
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
this.setState(
|
||||
{
|
||||
errors: {
|
||||
downsample: "You must supply a downsample interval (e.g. '1m' or '1h').",
|
||||
},
|
||||
},
|
||||
this.updateQueryFromState
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
getAggregators = () => {
|
||||
this.props.datasource.getResource('/api/aggregators').then((result: any) => {
|
||||
if (result && _.isArray(result)) {
|
||||
this.setState({ aggregatorTypes: result }, this.updateQueryFromState);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
getMetrics = () => {
|
||||
this.props.datasource.getResource('/api/suggest', { type: 'metrics', max: '-1' }).then((result: any) => {
|
||||
if (result && _.isArray(result)) {
|
||||
const metrics: string[] = result;
|
||||
this.metricArray = metrics
|
||||
.map((value) => {
|
||||
return value;
|
||||
})
|
||||
.concat();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
updateTags = (tags: { [key: string]: string }) => {
|
||||
this.setState((state, props) => {
|
||||
var query = Object.assign(state.query, { tags: tags });
|
||||
this.updateQuery(query);
|
||||
return { query: query };
|
||||
});
|
||||
};
|
||||
|
||||
handleSearch = (query: string) => {
|
||||
const results = this.metricArray
|
||||
.filter((metric) => query === '' || metric.toLowerCase().includes(query.toLowerCase()))
|
||||
.map((value) => {
|
||||
return value;
|
||||
});
|
||||
this.setState({ queryOptions: results });
|
||||
};
|
||||
|
||||
getInputValue = (id: string): string | null => {
|
||||
var fullId = 'div#' + id + ' div div input.rbt-input-main';
|
||||
var inputElement = document.querySelector(fullId);
|
||||
if (inputElement !== null) {
|
||||
return (inputElement as HTMLInputElement).value;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
render() {
|
||||
var queryEditorId = Math.random().toString(36).substr(2, 9);
|
||||
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 aggregatorOptions: Array<{}> = _.map(this.state.aggregatorTypes, (value: string) => ({
|
||||
label: value,
|
||||
value: value,
|
||||
}));
|
||||
const { queryOptionsLoading, queryOptions } = this.state;
|
||||
|
||||
var multiplier = 7.5;
|
||||
var metricWidth = 300;
|
||||
if (metric !== undefined && metric!.length * multiplier > metricWidth) {
|
||||
metricWidth = Math.ceil(metric!.length * multiplier);
|
||||
}
|
||||
var aliasWidth = 175;
|
||||
if (alias !== undefined && alias!.length * multiplier > aliasWidth) {
|
||||
aliasWidth = Math.ceil(alias!.length * multiplier);
|
||||
}
|
||||
|
||||
var dynamicStyle =
|
||||
'div.timely-query input.form-control, div#timelyQuery-' +
|
||||
queryEditorId +
|
||||
' { ' +
|
||||
'width:' +
|
||||
metricWidth +
|
||||
'px!important ' +
|
||||
'}';
|
||||
|
||||
dynamicStyle += '#timelyAlias-' + queryEditorId + ' { ' + 'width:' + aliasWidth + 'px!important ' + '}';
|
||||
|
||||
return (
|
||||
<div className="timely-edior-row">
|
||||
<div className="gf-form-inline">
|
||||
<style>{dynamicStyle}</style>
|
||||
<div className="gf-form timely">
|
||||
<label className="gf-form-label width-10">Metric</label>
|
||||
<div id={'timelyQuery-' + queryEditorId} className="timely timely-query">
|
||||
<AsyncTypeahead
|
||||
id={'timelyQuery-' + queryEditorId + '-Typeahead'}
|
||||
inputProps={{ spellCheck: false }}
|
||||
defaultInputValue={metric}
|
||||
isLoading={queryOptionsLoading}
|
||||
onSearch={(query) => {
|
||||
this.setState({ queryOptionsLoading: true });
|
||||
this.handleSearch(query);
|
||||
this.setState({ queryOptionsLoading: false });
|
||||
}}
|
||||
onChange={(e) => {
|
||||
var inputValue = this.getInputValue('timelyQuery-' + queryEditorId);
|
||||
if (inputValue !== null) {
|
||||
this.onMetricTextChange(inputValue);
|
||||
}
|
||||
}}
|
||||
onBlur={(e) => {
|
||||
var inputValue = this.getInputValue('timelyQuery-' + queryEditorId);
|
||||
if (inputValue !== null) {
|
||||
this.onMetricTextChange(inputValue);
|
||||
}
|
||||
}}
|
||||
onFocus={(e) => {
|
||||
var inputValue = this.getInputValue('timelyQuery-' + queryEditorId);
|
||||
if (queryOptions.length === 0 || inputValue === null || inputValue.length === 0) {
|
||||
this.handleSearch('');
|
||||
}
|
||||
}}
|
||||
options={queryOptions}
|
||||
selectHintOnEnter={true}
|
||||
align={'left'}
|
||||
allowNew={true}
|
||||
newSelectionPrefix={''}
|
||||
paginate={true}
|
||||
paginationText={'more'}
|
||||
minLength={0}
|
||||
maxResults={100}
|
||||
caseSensitive={false}
|
||||
placeholder={'metric'}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="gf-form timely">
|
||||
<label className="gf-form-label width-5">Alias</label>
|
||||
<Input
|
||||
id={'timelyAlias-' + queryEditorId}
|
||||
className="min-width-10 flex-grow-1"
|
||||
spellCheck={false}
|
||||
value={alias || ''}
|
||||
onChange={this.onAliasChange}
|
||||
placeholder={'series alias'}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<TagEditor tags={tags} parent={this} />
|
||||
<div className="gf-form-inline">
|
||||
<div className="gf-form timely">
|
||||
<label className="gf-form-label width-10">Downsample</label>
|
||||
<Input
|
||||
className={'min-width-5 flex-grow-1'}
|
||||
spellCheck={false}
|
||||
value={downsampleInterval || ''}
|
||||
onChange={this.onDownsampleChange}
|
||||
placeholder={'interval'}
|
||||
/>
|
||||
</div>
|
||||
<div className="gf-form timely">
|
||||
<label className="gf-form-label width-10">Downsample Aggregator</label>
|
||||
<Select
|
||||
className={'min-width-5 flex-grow-1'}
|
||||
isSearchable={false}
|
||||
options={aggregatorOptions}
|
||||
value={downsampleAggregator}
|
||||
placeholder={'aggregator'}
|
||||
onChange={this.onDownsampleAggregatorChange}
|
||||
menuPlacement={'bottom'}
|
||||
/>
|
||||
</div>
|
||||
<div className="gf-form timely">
|
||||
<Switch
|
||||
label={'Disable downsampling'}
|
||||
labelClass="width-10"
|
||||
checked={disableDownsampling || false}
|
||||
onChange={this.onDisableDownsamplingChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="gf-form-inline">
|
||||
<div className="gf-form timely">
|
||||
<label className="gf-form-label width-10">All Results Aggregator</label>
|
||||
<Select
|
||||
className={'min-width-5 flex-grow-1'}
|
||||
isSearchable={false}
|
||||
options={aggregatorOptions}
|
||||
value={aggregator}
|
||||
placeholder={'aggregator'}
|
||||
onChange={this.onAggregatorChange}
|
||||
menuPlacement={'bottom'}
|
||||
/>
|
||||
</div>
|
||||
<div className="gf-form timely">
|
||||
<Switch
|
||||
label={'Rate'}
|
||||
labelClass="width-5"
|
||||
checked={shouldComputeRate || false}
|
||||
onChange={this.onRateChange}
|
||||
/>
|
||||
<div hidden={!shouldComputeRate}>
|
||||
<Switch
|
||||
label={'Counter'}
|
||||
labelClass="width-10"
|
||||
checked={isCounter || false}
|
||||
onChange={this.onCounterChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="gf-form timely" hidden={!shouldComputeRate || !isCounter}>
|
||||
<label className="gf-form-label width-10">Max Value</label>
|
||||
<Input
|
||||
className={'min-width-6 flex-grow-1'}
|
||||
spellCheck={false}
|
||||
value={counterMax || ''}
|
||||
onChange={this.onCounterMaxChange}
|
||||
placeholder={'max value'}
|
||||
/>
|
||||
<label className="gf-form-label width-10">Reset Value</label>
|
||||
<Input
|
||||
className={'min-width-6 flex-grow-1'}
|
||||
spellCheck={false}
|
||||
value={counterResetValue || ''}
|
||||
onChange={this.onCounterResetValueChange}
|
||||
placeholder={'reset value'}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,519 +0,0 @@
|
||||
import React, { Component } from 'react';
|
||||
import { QueryEditor } from './QueryEditor';
|
||||
import { withStyles } from '@material-ui/core/styles';
|
||||
import { Tooltip } from '@material-ui/core';
|
||||
import { Icon } from '@grafana/ui';
|
||||
import _ from 'lodash';
|
||||
import { AsyncTypeahead, TypeaheadModel } from 'react-bootstrap-typeahead';
|
||||
|
||||
export interface Props {
|
||||
tags: { [key: string]: string };
|
||||
parent: QueryEditor;
|
||||
}
|
||||
|
||||
interface State {
|
||||
tags: Tag[];
|
||||
tagKeyOptionsLoading: boolean;
|
||||
tagKeyOptions: TypeaheadModel[];
|
||||
tagValueOptionsLoading: boolean;
|
||||
tagValueOptions: TypeaheadModel[];
|
||||
}
|
||||
|
||||
interface Tag {
|
||||
key: string;
|
||||
value: string;
|
||||
editing: boolean;
|
||||
errors: string[] | undefined;
|
||||
}
|
||||
|
||||
const HtmlTooltip = withStyles((theme) => ({
|
||||
tooltip: {
|
||||
backgroundColor: '#f5f5f9',
|
||||
color: 'rgba(0, 0, 0, 0.87)',
|
||||
maxWidth: 220,
|
||||
fontSize: theme.typography.pxToRem(12),
|
||||
border: '1px solid #dadde9',
|
||||
},
|
||||
}))(Tooltip);
|
||||
|
||||
export class TagEditor extends Component<Props, State> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
tags: Object.entries(props.tags)
|
||||
.map(([key, value]) => ({
|
||||
key: key,
|
||||
value: value,
|
||||
editing: false,
|
||||
errors: undefined,
|
||||
}))
|
||||
.concat(),
|
||||
tagKeyOptionsLoading: false,
|
||||
tagKeyOptions: [],
|
||||
tagValueOptionsLoading: false,
|
||||
tagValueOptions: [],
|
||||
};
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps: Readonly<Props>, nextState: Readonly<State>, nextContext: any): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
validateTags = (tags: Tag[], tagNumber: number): boolean => {
|
||||
var count = new Map<string, number>();
|
||||
var anyErrors = false;
|
||||
tags.forEach((tag) => {
|
||||
var n = count.get(tag.key);
|
||||
if (n === undefined) {
|
||||
count.set(tag.key, 1);
|
||||
} else {
|
||||
count.set(tag.key, n! + 1);
|
||||
}
|
||||
});
|
||||
|
||||
var tagsToValidate: Tag[];
|
||||
if (tagNumber === undefined) {
|
||||
tagsToValidate = tags;
|
||||
} else {
|
||||
tagsToValidate = tags.filter((t, i) => i === tagNumber);
|
||||
}
|
||||
|
||||
tagsToValidate.forEach((tag, i) => {
|
||||
tag.errors = [];
|
||||
if (tag.key.length > 0 && count.get(tag.key)! > 1) {
|
||||
tag.errors.push("duplicate tag key '" + tag.key + "'");
|
||||
anyErrors = true;
|
||||
}
|
||||
if (tag.key.length === 0) {
|
||||
tag.errors.push('tag key can not be empty');
|
||||
anyErrors = true;
|
||||
}
|
||||
if (tag.value.length === 0) {
|
||||
tag.errors.push('tag value can not be empty');
|
||||
anyErrors = true;
|
||||
}
|
||||
if (tag.errors.length === 0) {
|
||||
tag.errors = undefined;
|
||||
}
|
||||
});
|
||||
|
||||
return anyErrors;
|
||||
};
|
||||
|
||||
addTag = () => {
|
||||
this.setState((state, props) => {
|
||||
const stateTags = state.tags;
|
||||
var tags = [
|
||||
...stateTags,
|
||||
{
|
||||
key: '',
|
||||
value: '',
|
||||
editing: true,
|
||||
errors: ['tag key can not be empty', 'tag value can not be empty'],
|
||||
},
|
||||
];
|
||||
return { tags: tags };
|
||||
});
|
||||
};
|
||||
|
||||
removeTag = (tagNumber: number) => {
|
||||
this.setState((state, props) => {
|
||||
const tags = state.tags;
|
||||
tags.splice(tagNumber, 1);
|
||||
this.updateTags(tags);
|
||||
return { tags: tags };
|
||||
});
|
||||
};
|
||||
|
||||
beginEdit = (tagNumber: number) => {
|
||||
this.setState((state, props) => {
|
||||
const tags = state.tags;
|
||||
var tag = tags.filter((t, i) => i === tagNumber).pop();
|
||||
if (tag !== undefined) {
|
||||
tag.editing = true;
|
||||
}
|
||||
return { tags: tags };
|
||||
});
|
||||
};
|
||||
|
||||
endEdit = (tagNumber: number) => {
|
||||
this.setState((state, props) => {
|
||||
const tags = state.tags;
|
||||
var tag = tags.filter((t, i) => i === tagNumber).pop();
|
||||
if (tag !== undefined && this.validateTags(tags, tagNumber) === false) {
|
||||
tag.editing = false;
|
||||
this.updateTags(tags);
|
||||
}
|
||||
return { tags: tags };
|
||||
});
|
||||
};
|
||||
|
||||
updateTagKey = (tagNumber: number, newKey: string) => {
|
||||
this.setState((state, props) => {
|
||||
var tags = state.tags;
|
||||
var tag = tags.filter((t, i) => i === tagNumber).pop();
|
||||
if (tag !== undefined) {
|
||||
tag.key = newKey;
|
||||
}
|
||||
this.validateTags(tags, tagNumber);
|
||||
return { tags: tags };
|
||||
});
|
||||
};
|
||||
|
||||
updateTagValue = (tagNumber: number, newValue: string) => {
|
||||
this.setState((state, props) => {
|
||||
var tags = state.tags;
|
||||
var tag = tags.filter((t, i) => i === tagNumber).pop();
|
||||
if (tag !== undefined) {
|
||||
tag.value = newValue;
|
||||
}
|
||||
this.validateTags(tags, tagNumber);
|
||||
return { tags: tags };
|
||||
});
|
||||
};
|
||||
|
||||
updateTags = (tags: Tag[]) => {
|
||||
var entries = Object.fromEntries([...tags.values()].map((tag) => [tag.key, tag.value]).concat());
|
||||
this.props.parent.updateTags(entries);
|
||||
};
|
||||
|
||||
handleTagKeySearch = (query: string, metric: string | undefined) => {
|
||||
if (metric !== undefined) {
|
||||
this.props.parent.props.datasource
|
||||
.postResource('/api/suggest', {
|
||||
type: 'tagk',
|
||||
m: metric,
|
||||
max: '1000',
|
||||
})
|
||||
.then((result: any) => {
|
||||
if (result && _.isArray(result)) {
|
||||
const tagKeyArray: string[] = result;
|
||||
var tags = this.state.tags;
|
||||
|
||||
// find all tag keys that are being used in non-edited tags
|
||||
var existingTags = tags
|
||||
.filter((t) => t.editing === false)
|
||||
.map((t) => {
|
||||
return t.key;
|
||||
})
|
||||
.concat();
|
||||
|
||||
// exclude keys that are bing used
|
||||
var filteredResults = tagKeyArray.filter((t) => {
|
||||
return existingTags.find((existing) => t === existing) === undefined;
|
||||
});
|
||||
|
||||
// exclude keys that don't match the search (if there is one)
|
||||
filteredResults = filteredResults
|
||||
.filter((tagKey) => query === '' || tagKey.toLowerCase().includes(query.toLowerCase()))
|
||||
.map((value) => {
|
||||
return value;
|
||||
});
|
||||
this.setState({ tagKeyOptions: filteredResults });
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
handleTagValueSearch = (query: string, metric: string | undefined, tagKey: string | undefined) => {
|
||||
if (metric !== undefined && tagKey !== undefined) {
|
||||
this.props.parent.props.datasource
|
||||
.postResource('/api/suggest', {
|
||||
type: 'tagv',
|
||||
m: metric,
|
||||
t: tagKey,
|
||||
max: '1000',
|
||||
})
|
||||
.then((result: any) => {
|
||||
if (result && _.isArray(result)) {
|
||||
const tagValueArray: string[] = ['.*', ...result];
|
||||
const filteredResults = tagValueArray
|
||||
.filter((tagValue) => query === '' || tagValue.toLowerCase().includes(query.toLowerCase()))
|
||||
.map((value) => {
|
||||
return value;
|
||||
});
|
||||
this.setState({ tagValueOptions: filteredResults });
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
getInputValue = (id: string): string | null => {
|
||||
var fullId = 'div#' + id + ' div div input.rbt-input-main';
|
||||
var inputElement = document.querySelector(fullId);
|
||||
if (inputElement !== null) {
|
||||
return (inputElement as HTMLInputElement).value;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
render() {
|
||||
const { tagKeyOptionsLoading, tagKeyOptions, tagValueOptionsLoading, tagValueOptions } = this.state;
|
||||
var { tags } = this.state;
|
||||
var tagEditorId = Math.random().toString(36).substr(2, 9);
|
||||
var lastSearchMetric: string;
|
||||
const { metric } = this.props.parent.state.query;
|
||||
var allowAddNewTag = tags.filter((t) => t.editing === true).length === 0;
|
||||
|
||||
return (
|
||||
<div className="gf-form-inline">
|
||||
<div className="gf-form timely">
|
||||
<label className="gf-form-label width-10">Tags</label>
|
||||
{[...tags.values()].map((tag, tagNum) => (
|
||||
<div key={tagNum.toString()} id={'timelytag-' + tagNum.toString()}>
|
||||
<div hidden={tag.editing}>
|
||||
<label className="gf-form-label">
|
||||
{tag.key} = {tag.value}
|
||||
<div className="timely tag edit">
|
||||
<HtmlTooltip title={'edit tag'} placement={'bottom'}>
|
||||
<Icon
|
||||
name="edit"
|
||||
tabIndex={0}
|
||||
onClick={(e) => {
|
||||
this.beginEdit(tagNum);
|
||||
}}
|
||||
onKeyPress={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
this.beginEdit(tagNum);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</HtmlTooltip>
|
||||
</div>
|
||||
<div className="timely tag delete">
|
||||
<HtmlTooltip title={'delete tag'} placement={'bottom'}>
|
||||
<Icon
|
||||
name="trash-alt"
|
||||
tabIndex={0}
|
||||
onClick={(e) => {
|
||||
this.removeTag(tagNum);
|
||||
}}
|
||||
onKeyPress={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
this.removeTag(tagNum);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</HtmlTooltip>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<div className="gf-form" hidden={!tag.editing}>
|
||||
<div
|
||||
id={'timelyTagKey-' + tagEditorId + '-' + tagNum.toString()}
|
||||
className="timely timely-tag-key"
|
||||
onMouseLeave={(e) => {
|
||||
var inputValue = this.getInputValue('timelyTagKey-' + tagEditorId + '-' + tagNum.toString());
|
||||
if (inputValue !== null) {
|
||||
this.updateTagKey(tagNum, inputValue);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<AsyncTypeahead
|
||||
id={'timelyTagKey-' + tagEditorId + '-Typeahead'}
|
||||
selected={[tag.key]}
|
||||
isLoading={tagKeyOptionsLoading}
|
||||
inputProps={{ spellCheck: false }}
|
||||
onSearch={(query) => {
|
||||
this.setState({ tagKeyOptionsLoading: true });
|
||||
lastSearchMetric = metric!;
|
||||
this.handleTagKeySearch(query, metric);
|
||||
this.setState({ tagKeyOptionsLoading: false });
|
||||
}}
|
||||
onChange={(e) => {
|
||||
var inputValue = this.getInputValue('timelyTagKey-' + tagEditorId + '-' + tagNum.toString());
|
||||
if (inputValue !== null) {
|
||||
this.updateTagKey(tagNum, inputValue);
|
||||
}
|
||||
}}
|
||||
onBlur={(e) => {
|
||||
var inputValue = this.getInputValue('timelyTagKey-' + tagEditorId + '-' + tagNum.toString());
|
||||
if (inputValue !== null) {
|
||||
this.updateTagKey(tagNum, inputValue);
|
||||
}
|
||||
}}
|
||||
onFocus={(e) => {
|
||||
var inputValue = this.getInputValue('timelyTagKey-' + tagEditorId + '-' + tagNum.toString());
|
||||
if (
|
||||
tagKeyOptions.length === 0 ||
|
||||
inputValue === null ||
|
||||
inputValue.length === 0 ||
|
||||
metric !== lastSearchMetric
|
||||
) {
|
||||
this.setState({ tagKeyOptionsLoading: true });
|
||||
lastSearchMetric = metric!;
|
||||
this.handleTagKeySearch('', metric);
|
||||
this.setState({ tagKeyOptionsLoading: false });
|
||||
}
|
||||
}}
|
||||
onKeyDown={(e) => {
|
||||
var inputValue = this.getInputValue('timelyTagKey-' + tagEditorId + '-' + tagNum.toString());
|
||||
if (
|
||||
tagKeyOptions.length === 0 ||
|
||||
inputValue === null ||
|
||||
inputValue.length === 0 ||
|
||||
metric !== lastSearchMetric
|
||||
) {
|
||||
this.setState({ tagKeyOptionsLoading: true });
|
||||
lastSearchMetric = metric!;
|
||||
this.handleTagKeySearch('', metric);
|
||||
this.setState({ tagKeyOptionsLoading: false });
|
||||
}
|
||||
}}
|
||||
autoFocus={tag.key.length === 0}
|
||||
options={tagKeyOptions}
|
||||
selectHintOnEnter={false}
|
||||
align={'left'}
|
||||
allowNew={true}
|
||||
newSelectionPrefix={''}
|
||||
paginate={true}
|
||||
paginationText={'more'}
|
||||
minLength={0}
|
||||
maxResults={100}
|
||||
caseSensitive={false}
|
||||
placeholder={'key'}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
id={'timelyTagValue-' + tagEditorId + '-' + tagNum.toString()}
|
||||
className="timely timely-tag-value"
|
||||
onMouseLeave={(e) => {
|
||||
var inputValue = this.getInputValue('timelyTagValue-' + tagEditorId + '-' + tagNum.toString());
|
||||
if (inputValue !== null) {
|
||||
this.updateTagValue(tagNum, inputValue);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<AsyncTypeahead
|
||||
id={'timelyTagValue-' + tagEditorId + '-Typeahead'}
|
||||
selected={[tag.value]}
|
||||
isLoading={tagValueOptionsLoading}
|
||||
inputProps={{ spellCheck: false }}
|
||||
onSearch={(query) => {
|
||||
this.setState({ tagValueOptionsLoading: true });
|
||||
this.handleTagValueSearch(query, metric, tag.key);
|
||||
this.setState({ tagValueOptionsLoading: false });
|
||||
}}
|
||||
onChange={(e) => {
|
||||
var inputValue = this.getInputValue('timelyTagValue-' + tagEditorId + '-' + tagNum.toString());
|
||||
if (inputValue !== null) {
|
||||
this.updateTagValue(tagNum, inputValue);
|
||||
}
|
||||
}}
|
||||
onBlur={(e) => {
|
||||
var inputValue = this.getInputValue('timelyTagValue-' + tagEditorId + '-' + tagNum.toString());
|
||||
if (inputValue !== null) {
|
||||
this.updateTagValue(tagNum, inputValue);
|
||||
}
|
||||
}}
|
||||
onFocus={(e) => {
|
||||
var inputValue = this.getInputValue('timelyTagValue-' + tagEditorId + '-' + tagNum.toString());
|
||||
if (tagValueOptions.length === 0 || inputValue === null || inputValue.length === 0) {
|
||||
this.setState({ tagValueOptionsLoading: true });
|
||||
this.handleTagValueSearch('', metric, tag.key);
|
||||
this.setState({ tagValueOptionsLoading: false });
|
||||
}
|
||||
}}
|
||||
onKeyDown={(e) => {
|
||||
var inputValue = this.getInputValue('timelyTagValue-' + tagEditorId + '-' + tagNum.toString());
|
||||
if (tagValueOptions.length === 0 || inputValue === null || inputValue.length === 0) {
|
||||
this.setState({ tagValueOptionsLoading: true });
|
||||
this.handleTagValueSearch('', metric, tag.key);
|
||||
this.setState({ tagValueOptionsLoading: false });
|
||||
}
|
||||
}}
|
||||
options={tagValueOptions}
|
||||
selectHintOnEnter={false}
|
||||
align={'left'}
|
||||
allowNew={true}
|
||||
newSelectionPrefix={''}
|
||||
paginate={true}
|
||||
paginationText={'more'}
|
||||
minLength={0}
|
||||
maxResults={100}
|
||||
caseSensitive={false}
|
||||
placeholder={'value'}
|
||||
/>
|
||||
</div>
|
||||
<label className="gf-form-label max-width-5 flex-shrink-1">
|
||||
{tag.errors !== undefined && (
|
||||
<div className="timely tag error">
|
||||
<HtmlTooltip
|
||||
title={
|
||||
<React.Fragment>
|
||||
<ul>
|
||||
{tag.errors.map((error) => {
|
||||
return <li key={error}>{error}</li>;
|
||||
})}
|
||||
</ul>
|
||||
</React.Fragment>
|
||||
}
|
||||
placement={'bottom'}
|
||||
>
|
||||
<Icon name="exclamation-triangle" />
|
||||
</HtmlTooltip>
|
||||
</div>
|
||||
)}
|
||||
{tag.errors === undefined && (
|
||||
<div className="timely tag save">
|
||||
<HtmlTooltip title={'save tag'} placement={'bottom'}>
|
||||
<Icon
|
||||
name="save"
|
||||
tabIndex={0}
|
||||
onClick={(e) => {
|
||||
this.endEdit(tagNum);
|
||||
}}
|
||||
onKeyPress={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
this.endEdit(tagNum);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</HtmlTooltip>
|
||||
</div>
|
||||
)}
|
||||
<div className="timely tag delete">
|
||||
<HtmlTooltip title={'delete tag'} placement={'bottom'}>
|
||||
<Icon
|
||||
name="trash-alt"
|
||||
tabIndex={0}
|
||||
onClick={(e) => {
|
||||
this.removeTag(tagNum);
|
||||
}}
|
||||
onKeyPress={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
this.removeTag(tagNum);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</HtmlTooltip>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
<div className="gf-form" hidden={!allowAddNewTag}>
|
||||
<label className="gf-form-label">
|
||||
<div className="timely tag addtag">
|
||||
<HtmlTooltip title={'add tag'} placement={'bottom'}>
|
||||
<Icon
|
||||
name="plus"
|
||||
tabIndex={0}
|
||||
onClick={(e) => {
|
||||
this.addTag();
|
||||
}}
|
||||
onKeyPress={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
this.addTag();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</HtmlTooltip>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1,5 +0,0 @@
|
||||
describe('placeholder test', () => {
|
||||
it('should return true', () => {
|
||||
expect(true).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,54 +0,0 @@
|
||||
$box-shadow-dimensions: 0 0 0 0.2rem;
|
||||
$placeholder-color: #6c757d;
|
||||
|
||||
.rbt {
|
||||
&-input-multi {
|
||||
// Bootstrap 4 focus style
|
||||
&.focus {
|
||||
background-color: #fff;
|
||||
border-color: #80bdff;
|
||||
box-shadow: $box-shadow-dimensions rgba(0, 123, 255, 0.25);
|
||||
color: #495057;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
&.is-invalid.focus {
|
||||
border-color: #dc3545;
|
||||
box-shadow: $box-shadow-dimensions rgba(220, 53, 69, 0.25);
|
||||
}
|
||||
|
||||
&.is-valid.focus {
|
||||
border-color: #28a745;
|
||||
box-shadow: $box-shadow-dimensions rgba(40, 167, 69, 0.25);
|
||||
}
|
||||
|
||||
input {
|
||||
// Firefox
|
||||
&::-moz-placeholder {
|
||||
color: $placeholder-color;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
// Internet Explorer 10+
|
||||
&:-ms-input-placeholder {
|
||||
color: $placeholder-color;
|
||||
}
|
||||
|
||||
// Safari and Chrome
|
||||
&::-webkit-input-placeholder {
|
||||
color: $placeholder-color;
|
||||
}
|
||||
}
|
||||
|
||||
// Override height in main CSS file :/
|
||||
& .rbt-input-main,
|
||||
&.form-control-lg .rbt-input-main,
|
||||
&.form-control-sm .rbt-input-main {
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
&-token {
|
||||
margin: 1px 3px 2px 0;
|
||||
}
|
||||
}
|
||||
@@ -1,201 +0,0 @@
|
||||
.rbt .rbt-input-main::-ms-clear {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* Menu
|
||||
*/
|
||||
.rbt-menu {
|
||||
margin-bottom: 2px !important;
|
||||
}
|
||||
|
||||
.rbt-menu > .dropdown-item {
|
||||
overflow: hidden !important;
|
||||
text-overflow: ellipsis !important;
|
||||
}
|
||||
|
||||
.rbt-menu > .dropdown-item:focus {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.rbt-menu-pagination-option {
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multi-select Input
|
||||
*/
|
||||
.rbt-input-multi {
|
||||
cursor: text !important;
|
||||
overflow: hidden !important;
|
||||
position: relative !important;
|
||||
}
|
||||
|
||||
.rbt-input-multi.focus {
|
||||
border-color: #80bdff !important;
|
||||
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25) !important;
|
||||
color: #495057 !important;
|
||||
outline: 0 !important;
|
||||
}
|
||||
|
||||
.rbt-input-multi.form-control {
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
.rbt-input-multi.form-control[disabled] {
|
||||
background-color: #e9ecef !important;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
.rbt-input-multi.is-invalid.focus {
|
||||
border-color: #dc3545 !important;
|
||||
box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25) !important;
|
||||
}
|
||||
|
||||
.rbt-input-multi.is-valid.focus {
|
||||
border-color: #28a745 !important;
|
||||
box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25) !important;
|
||||
}
|
||||
|
||||
.rbt-input-multi input::-moz-placeholder {
|
||||
color: #6c757d !important;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
.rbt-input-multi input:-ms-input-placeholder {
|
||||
color: #6c757d !important;
|
||||
}
|
||||
|
||||
.rbt-input-multi input::-webkit-input-placeholder {
|
||||
color: #6c757d !important;
|
||||
}
|
||||
|
||||
.rbt-input-multi .rbt-input-wrapper {
|
||||
align-items: flex-start !important;
|
||||
display: flex !important;
|
||||
flex-wrap: wrap !important;
|
||||
margin-bottom: -4px !important;
|
||||
margin-top: -1px !important;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
.rbt-input-multi .rbt-input-main {
|
||||
margin: 1px 0 4px !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close Button
|
||||
*/
|
||||
.rbt-close {
|
||||
z-index: 1 !important;
|
||||
}
|
||||
|
||||
.rbt-close-lg {
|
||||
font-size: 24px !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* Token
|
||||
*/
|
||||
.rbt-token {
|
||||
background-color: #e7f4ff !important;
|
||||
border: 0 !important;
|
||||
border-radius: 0.25rem !important;
|
||||
color: #007bff !important;
|
||||
display: inline-block !important;
|
||||
line-height: 1em !important;
|
||||
margin: 1px 3px 2px 0 !important;
|
||||
padding: 4px 7px !important;
|
||||
position: relative !important;
|
||||
}
|
||||
|
||||
.rbt-token-disabled {
|
||||
background-color: rgba(0, 0, 0, 0.1) !important;
|
||||
color: #495057 !important;
|
||||
pointer-events: none !important;
|
||||
}
|
||||
|
||||
.rbt-token-removeable {
|
||||
cursor: pointer !important;
|
||||
padding-right: 21px !important;
|
||||
}
|
||||
|
||||
.rbt-token-active {
|
||||
background-color: #007bff !important;
|
||||
color: #fff !important;
|
||||
outline: none !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
.rbt-token .rbt-token-remove-button {
|
||||
bottom: 0 !important;
|
||||
color: inherit !important;
|
||||
font-size: inherit !important;
|
||||
font-weight: normal !important;
|
||||
opacity: 1 !important;
|
||||
outline: none !important;
|
||||
padding: 3px 7px !important;
|
||||
position: absolute !important;
|
||||
right: 0 !important;
|
||||
text-shadow: none !important;
|
||||
top: -2px !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loader + CloseButton container
|
||||
*/
|
||||
.rbt-aux {
|
||||
align-items: center !important;
|
||||
display: flex !important;
|
||||
bottom: 0 !important;
|
||||
justify-content: center !important;
|
||||
pointer-events: none !important;
|
||||
/* Don't block clicks on the input */
|
||||
position: absolute !important;
|
||||
right: 0 !important;
|
||||
top: 0 !important;
|
||||
width: 34px !important;
|
||||
}
|
||||
|
||||
.rbt-aux-lg {
|
||||
width: 46px !important;
|
||||
}
|
||||
|
||||
.rbt-aux .rbt-close {
|
||||
margin-top: -4px !important;
|
||||
pointer-events: auto !important;
|
||||
/* Override pointer-events: none; above */
|
||||
}
|
||||
|
||||
.has-aux .rbt-input {
|
||||
padding-right: 34px !important;
|
||||
}
|
||||
|
||||
.rbt-highlight-text {
|
||||
background-color: inherit !important;
|
||||
color: inherit !important;
|
||||
font-weight: bold !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* Input Groups
|
||||
*/
|
||||
.input-group > .rbt {
|
||||
flex: 1 !important;
|
||||
}
|
||||
|
||||
.input-group > .rbt .rbt-input-hint,
|
||||
.input-group > .rbt .rbt-aux {
|
||||
z-index: 5 !important;
|
||||
}
|
||||
|
||||
.input-group > .rbt:not(:first-child) .form-control {
|
||||
border-top-left-radius: 0 !important;
|
||||
border-bottom-left-radius: 0 !important;
|
||||
}
|
||||
|
||||
.input-group > .rbt:not(:last-child) .form-control {
|
||||
border-top-right-radius: 0 !important;
|
||||
border-bottom-right-radius: 0 !important;
|
||||
}
|
||||
@@ -1,240 +0,0 @@
|
||||
$animation: loader-animation 600ms infinite linear;
|
||||
$inset: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||
$placeholder-color: #999;
|
||||
|
||||
.rbt {
|
||||
&-menu {
|
||||
margin-bottom: 2px; // Spacing for dropup
|
||||
|
||||
& > li a {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
&-pagination-option {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
// Hide IE's native "clear" button
|
||||
& .rbt-input-main::-ms-clear {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&-input-multi {
|
||||
cursor: text;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
height: auto;
|
||||
|
||||
// Apply Bootstrap focus styles
|
||||
&.focus {
|
||||
box-shadow: $inset, 0 0 8px rgba(102, 175, 233, 0.6);
|
||||
border-color: #66afe9;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
// BS4 uses the :disabled pseudo-class, which doesn't work with non-inputs.
|
||||
&.form-control[disabled] {
|
||||
background-color: #e9ecef;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
// Apply Bootstrap placeholder styles
|
||||
input {
|
||||
// Firefox
|
||||
&::-moz-placeholder {
|
||||
color: $placeholder-color;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
// Internet Explorer 10+
|
||||
&:-ms-input-placeholder {
|
||||
color: $placeholder-color;
|
||||
}
|
||||
|
||||
// Safari and Chrome
|
||||
&::-webkit-input-placeholder {
|
||||
color: $placeholder-color;
|
||||
}
|
||||
}
|
||||
|
||||
.rbt-input-wrapper {
|
||||
align-items: flex-start;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: -4px;
|
||||
margin-top: -1px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.rbt-input-main {
|
||||
// Set input height for cross-browser consistency
|
||||
height: 20px;
|
||||
margin: 1px 0 4px;
|
||||
}
|
||||
|
||||
&.input,
|
||||
&.form-control {
|
||||
&-lg {
|
||||
.rbt-input-main {
|
||||
height: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
&-sm {
|
||||
.rbt-input-main {
|
||||
height: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-close {
|
||||
z-index: 1;
|
||||
|
||||
&-lg {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
&-token {
|
||||
background-color: #e7f4ff;
|
||||
border: 0;
|
||||
border-radius: 2px;
|
||||
color: #1f8dd6;
|
||||
display: inline-block;
|
||||
line-height: 1em;
|
||||
margin: 0 3px 3px 0;
|
||||
padding: 4px 7px;
|
||||
position: relative;
|
||||
|
||||
&-disabled {
|
||||
background-color: #ddd;
|
||||
color: #888;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&-removeable {
|
||||
cursor: pointer;
|
||||
padding-right: 21px;
|
||||
}
|
||||
|
||||
&-active {
|
||||
background-color: #1f8dd6;
|
||||
color: #fff;
|
||||
outline: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
& &-remove-button {
|
||||
bottom: 0;
|
||||
color: inherit;
|
||||
font-size: inherit;
|
||||
font-weight: normal;
|
||||
opacity: 1;
|
||||
outline: none;
|
||||
padding: 3px 7px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
text-shadow: none;
|
||||
top: -2px;
|
||||
}
|
||||
}
|
||||
|
||||
&-loader {
|
||||
-moz-animation: $animation;
|
||||
-webkit-animation: $animation;
|
||||
animation: $animation;
|
||||
border: 1px solid #d5d5d5;
|
||||
border-radius: 50%;
|
||||
border-top-color: #1f8dd6;
|
||||
display: block;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
|
||||
&-lg {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
&-aux {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
bottom: 0;
|
||||
justify-content: center;
|
||||
pointer-events: none; /* Don't block clicks on the input */
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 34px;
|
||||
|
||||
&-lg {
|
||||
width: 46px;
|
||||
}
|
||||
|
||||
& .rbt-close {
|
||||
margin-top: -4px;
|
||||
pointer-events: auto; /* Override pointer-events: none; above */
|
||||
}
|
||||
}
|
||||
|
||||
.has-aux &-input {
|
||||
padding-right: 34px;
|
||||
}
|
||||
|
||||
&-highlight-text {
|
||||
background-color: inherit;
|
||||
color: inherit;
|
||||
font-weight: bold;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Input Groups */
|
||||
.input-group > .rbt {
|
||||
flex: 1;
|
||||
|
||||
// Form-controls within input-groups have a higher z-index.
|
||||
& .rbt-input-hint,
|
||||
& .rbt-aux {
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
&:not(:first-child) .form-control {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
&:not(:last-child) .form-control {
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Validation States */
|
||||
.has-error .rbt-input-multi.focus {
|
||||
border-color: #843534;
|
||||
box-shadow: $inset, 0 0 6px #ce8483;
|
||||
}
|
||||
|
||||
.has-warning .rbt-input-multi.focus {
|
||||
border-color: #66512c;
|
||||
box-shadow: $inset, 0 0 6px #c0a16b;
|
||||
}
|
||||
|
||||
.has-success .rbt-input-multi.focus {
|
||||
border-color: #2b542c;
|
||||
box-shadow: $inset, 0 0 6px #67b168;
|
||||
}
|
||||
|
||||
@keyframes loader-animation {
|
||||
to {
|
||||
transform: rotate(1turn);
|
||||
}
|
||||
}
|
||||
-10602
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"extends": "@grafana/toolkit/src/config/tsconfig.plugin.json",
|
||||
"include": ["src", "types"],
|
||||
"paths": {
|
||||
"@grafana/slate-react": ["./node_modules/@types/slate-react"]
|
||||
},
|
||||
"compilerOptions": {
|
||||
"esModuleInterop": true,
|
||||
"rootDir": "./src",
|
||||
"baseUrl": "./src",
|
||||
"typeRoots": ["./node_modules/@types"],
|
||||
"jsx": "react",
|
||||
"allowJs": true
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
Loaded 100 of 246 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user